Skip to content

Commit c549329

Browse files
committed
[GR-12617] Small fixes to get Numpy to build from git
PullRequest: graalpython/321
2 parents 277959c + c2793e9 commit c549329

File tree

9 files changed

+381
-14
lines changed

9 files changed

+381
-14
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
#
4+
# The Universal Permissive License (UPL), Version 1.0
5+
#
6+
# Subject to the condition set forth below, permission is hereby granted to any
7+
# person obtaining a copy of this software, associated documentation and/or
8+
# data (collectively the "Software"), free of charge and under any and all
9+
# copyright rights in the Software, and any and all patent rights owned or
10+
# freely licensable by each licensor hereunder covering either (i) the
11+
# unmodified Software as contributed to or provided by such licensor, or (ii)
12+
# the Larger Works (as defined below), to deal in both
13+
#
14+
# (a) the Software, and
15+
#
16+
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17+
# one is included with the Software each a "Larger Work" to which the Software
18+
# is contributed by such licensors),
19+
#
20+
# without restriction, including without limitation the rights to copy, create
21+
# derivative works of, display, perform, and distribute the Software and make,
22+
# use, sell, offer for sale, import, export, have made, and have sold the
23+
# Software and the Larger Work(s), and to sublicense the foregoing rights on
24+
# either these or other terms.
25+
#
26+
# This license is subject to the following condition:
27+
#
28+
# The above copyright notice and either this complete permission notice or at a
29+
# minimum a reference to the UPL must be included in all copies or substantial
30+
# portions of the Software.
31+
#
32+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+
# SOFTWARE.
39+
40+
from . import context
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
#
4+
# The Universal Permissive License (UPL), Version 1.0
5+
#
6+
# Subject to the condition set forth below, permission is hereby granted to any
7+
# person obtaining a copy of this software, associated documentation and/or
8+
# data (collectively the "Software"), free of charge and under any and all
9+
# copyright rights in the Software, and any and all patent rights owned or
10+
# freely licensable by each licensor hereunder covering either (i) the
11+
# unmodified Software as contributed to or provided by such licensor, or (ii)
12+
# the Larger Works (as defined below), to deal in both
13+
#
14+
# (a) the Software, and
15+
#
16+
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17+
# one is included with the Software each a "Larger Work" to which the Software
18+
# is contributed by such licensors),
19+
#
20+
# without restriction, including without limitation the rights to copy, create
21+
# derivative works of, display, perform, and distribute the Software and make,
22+
# use, sell, offer for sale, import, export, have made, and have sold the
23+
# Software and the Larger Work(s), and to sublicense the foregoing rights on
24+
# either these or other terms.
25+
#
26+
# This license is subject to the following condition:
27+
#
28+
# The above copyright notice and either this complete permission notice or at a
29+
# minimum a reference to the UPL must be included in all copies or substantial
30+
# portions of the Software.
31+
#
32+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+
# SOFTWARE.
39+
40+
from . import reduction
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
#
4+
# The Universal Permissive License (UPL), Version 1.0
5+
#
6+
# Subject to the condition set forth below, permission is hereby granted to any
7+
# person obtaining a copy of this software, associated documentation and/or
8+
# data (collectively the "Software"), free of charge and under any and all
9+
# copyright rights in the Software, and any and all patent rights owned or
10+
# freely licensable by each licensor hereunder covering either (i) the
11+
# unmodified Software as contributed to or provided by such licensor, or (ii)
12+
# the Larger Works (as defined below), to deal in both
13+
#
14+
# (a) the Software, and
15+
#
16+
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17+
# one is included with the Software each a "Larger Work" to which the Software
18+
# is contributed by such licensors),
19+
#
20+
# without restriction, including without limitation the rights to copy, create
21+
# derivative works of, display, perform, and distribute the Software and make,
22+
# use, sell, offer for sale, import, export, have made, and have sold the
23+
# Software and the Larger Work(s), and to sublicense the foregoing rights on
24+
# either these or other terms.
25+
#
26+
# This license is subject to the following condition:
27+
#
28+
# The above copyright notice and either this complete permission notice or at a
29+
# minimum a reference to the UPL must be included in all copies or substantial
30+
# portions of the Software.
31+
#
32+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+
# SOFTWARE.
39+
40+
from . import context

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,9 @@ def func(x):
121121
old_name = code.co_filename
122122
_imp._fix_co_filename(code, old_name + '_more_path')
123123
assert code.co_filename == old_name + '_more_path'
124+
125+
126+
def test_recursive_import_from():
127+
if sys.version_info.minor >= 6:
128+
import package.recpkg
129+
assert package.recpkg.context is package.recpkg.reduction.context

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ public abstract static class ChdirNode extends PythonBuiltinNode {
246246
PNone chdir(String spath) {
247247
Env env = getContext().getEnv();
248248
try {
249-
TruffleFile dir = env.getTruffleFile(spath);
249+
TruffleFile dir = env.getTruffleFile(spath).getAbsoluteFile();
250250
env.setCurrentWorkingDirectory(dir);
251251
return PNone.NONE;
252252
} catch (UnsupportedOperationException | IllegalArgumentException | SecurityException e) {
@@ -1531,4 +1531,13 @@ protected String doGeneric(Object x) {
15311531
return recursive.execute(strNode.executeWith(PythonBuiltinClassType.PString, x, PNone.NO_VALUE, PNone.NO_VALUE));
15321532
}
15331533
}
1534+
1535+
@Builtin(name = "cpu_count", fixedNumOfPositionalArgs = 0)
1536+
@GenerateNodeFactory
1537+
abstract static class CpuCountNode extends PythonBuiltinNode {
1538+
@Specialization
1539+
int getCpuCount() {
1540+
return Runtime.getRuntime().availableProcessors();
1541+
}
1542+
}
15341543
}

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

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
*/
4141
package com.oracle.graal.python.builtins.modules;
4242

43+
import java.io.File;
4344
import java.io.IOException;
4445
import java.lang.ProcessBuilder.Redirect;
4546
import java.nio.ByteBuffer;
@@ -48,22 +49,29 @@
4849
import java.nio.channels.WritableByteChannel;
4950
import java.util.ArrayList;
5051
import java.util.List;
52+
import java.util.Map;
5153

5254
import com.oracle.graal.python.builtins.Builtin;
5355
import com.oracle.graal.python.builtins.CoreFunctions;
5456
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
5557
import com.oracle.graal.python.builtins.PythonBuiltins;
5658
import com.oracle.graal.python.builtins.objects.PNone;
59+
import com.oracle.graal.python.builtins.objects.bytes.BytesNodes;
60+
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
5761
import com.oracle.graal.python.builtins.objects.list.PList;
5862
import com.oracle.graal.python.builtins.objects.module.PythonModule;
5963
import com.oracle.graal.python.builtins.objects.str.PString;
60-
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
64+
import com.oracle.graal.python.nodes.expression.CastToBooleanNode;
65+
import com.oracle.graal.python.nodes.expression.CastToListNode;
6166
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
6267
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
68+
import com.oracle.graal.python.nodes.util.CastToIndexNode;
69+
import com.oracle.graal.python.nodes.util.CastToStringNode;
6370
import com.oracle.graal.python.runtime.PosixResources;
6471
import com.oracle.graal.python.runtime.PythonContext;
6572
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
6673
import com.oracle.truffle.api.TruffleOptions;
74+
import com.oracle.truffle.api.dsl.Cached;
6775
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
6876
import com.oracle.truffle.api.dsl.NodeFactory;
6977
import com.oracle.truffle.api.dsl.Specialization;
@@ -80,14 +88,15 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
8088
"errpipe_read", "errpipe_write", "restore_signals", "call_setsid", "preexec_fn"})
8189
@GenerateNodeFactory
8290
abstract static class ForkExecNode extends PythonBuiltinNode {
83-
@SuppressWarnings("unused")
84-
@TruffleBoundary
91+
@Child BytesNodes.ToBytesNode toBytes = BytesNodes.ToBytesNode.create();
92+
8593
@Specialization
86-
synchronized int forkExec(PList args, PTuple executable_list, boolean close_fds,
87-
PTuple fdsToKeep, PNone cwd, PNone env,
94+
@TruffleBoundary
95+
synchronized int forkExec(PList args, @SuppressWarnings("unused") PList execList, @SuppressWarnings("unused") boolean closeFds,
96+
@SuppressWarnings("unused") PList fdsToKeep, String cwd, PList env,
8897
int p2cread, int p2cwrite, int c2pread, int c2pwrite,
89-
int errread, int errwrite, int errpipe_read, int errpipe_write,
90-
boolean restore_signals, boolean call_setsid, PNone preexec_fn) {
98+
int errread, int errwrite, @SuppressWarnings("unused") int errpipe_read, int errpipe_write,
99+
@SuppressWarnings("unused") boolean restore_signals, @SuppressWarnings("unused") boolean call_setsid, @SuppressWarnings("unused") PNone preexec_fn) {
91100
PythonContext context = getContext();
92101
PosixResources resources = context.getResources();
93102
if (!context.isExecutableAccessAllowed()) {
@@ -119,10 +128,6 @@ synchronized int forkExec(PList args, PTuple executable_list, boolean close_fds,
119128
}
120129
}
121130

122-
Channel stdin = null;
123-
Channel stdout = null;
124-
Channel stderr = null;
125-
126131
ProcessBuilder pb = new ProcessBuilder(argStrings);
127132
if (p2cread != -1 && p2cwrite != -1) {
128133
pb.redirectInput(Redirect.PIPE);
@@ -142,6 +147,26 @@ synchronized int forkExec(PList args, PTuple executable_list, boolean close_fds,
142147
pb.redirectError(Redirect.INHERIT);
143148
}
144149

150+
try {
151+
if (getContext().getEnv().getTruffleFile(cwd).exists()) {
152+
pb.directory(new File(cwd));
153+
} else {
154+
throw raise(PythonBuiltinClassType.OSError, "working directory %s is not accessible", cwd);
155+
}
156+
} catch (SecurityException e) {
157+
throw raise(PythonBuiltinClassType.OSError, e.getMessage());
158+
}
159+
160+
Map<String, String> environment = pb.environment();
161+
for (Object keyValue : env.getSequenceStorage().getInternalArray()) {
162+
if (keyValue instanceof PBytes) {
163+
String[] string = new String(toBytes.execute(keyValue)).split("=", 2);
164+
if (string.length == 2) {
165+
environment.put(string[0], string[1]);
166+
}
167+
}
168+
}
169+
145170
try {
146171
Process process = pb.start();
147172
if (p2cwrite != -1) {
@@ -177,5 +202,49 @@ synchronized int forkExec(PList args, PTuple executable_list, boolean close_fds,
177202
return -1;
178203
}
179204
}
205+
206+
@Specialization(replaces = "forkExec")
207+
int forkExecDefault(Object args, Object executable_list, Object close_fds,
208+
Object fdsToKeep, Object cwd, Object env,
209+
Object p2cread, Object p2cwrite, Object c2pread, Object c2pwrite,
210+
Object errread, Object errwrite, Object errpipe_read, Object errpipe_write,
211+
Object restore_signals, Object call_setsid, PNone preexec_fn,
212+
@Cached("create()") CastToListNode castArgs,
213+
@Cached("create()") CastToListNode castExecList,
214+
@Cached("createIfTrueNode()") CastToBooleanNode castCloseFds,
215+
@Cached("create()") CastToListNode castFdsToKeep,
216+
@Cached("create()") CastToStringNode castCwd,
217+
@Cached("create()") CastToListNode castEnv,
218+
@Cached("create()") CastToIndexNode castP2cread,
219+
@Cached("create()") CastToIndexNode castP2cwrite,
220+
@Cached("create()") CastToIndexNode castC2pread,
221+
@Cached("create()") CastToIndexNode castC2pwrite,
222+
@Cached("create()") CastToIndexNode castErrread,
223+
@Cached("create()") CastToIndexNode castErrwrite,
224+
@Cached("create()") CastToIndexNode castErrpipeRead,
225+
@Cached("create()") CastToIndexNode castErrpipeWrite,
226+
@Cached("createIfTrueNode()") CastToBooleanNode castRestoreSignals,
227+
@Cached("createIfTrueNode()") CastToBooleanNode castSetsid) {
228+
229+
String actualCwd;
230+
if (cwd instanceof PNone) {
231+
actualCwd = getContext().getEnv().getCurrentWorkingDirectory().getPath();
232+
} else {
233+
actualCwd = castCwd.execute(cwd);
234+
}
235+
236+
PList actualEnv;
237+
if (env instanceof PNone) {
238+
actualEnv = factory().createList();
239+
} else {
240+
actualEnv = castEnv.executeWith(env);
241+
}
242+
243+
return forkExec(castArgs.executeWith(args), castExecList.executeWith(executable_list), castCloseFds.executeWith(close_fds),
244+
castFdsToKeep.executeWith(fdsToKeep), actualCwd, actualEnv,
245+
castP2cread.execute(p2cread), castP2cwrite.execute(p2cwrite), castC2pread.execute(c2pread), castC2pwrite.execute(c2pwrite),
246+
castErrread.execute(errread), castErrwrite.execute(errwrite), castErrpipeRead.execute(errpipe_read), castErrpipeWrite.execute(errpipe_write),
247+
castRestoreSignals.executeWith(restore_signals), castSetsid.executeWith(call_setsid), preexec_fn);
248+
}
180249
}
181250
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,7 @@ void setSlice(SequenceStorage store, SliceInfo sinfo, SequenceStorage sequence,
10641064

10651065
@Specialization(guards = "!compatibleAssign(self, sequence)")
10661066
void doError(@SuppressWarnings("unused") SequenceStorage self, @SuppressWarnings("unused") SliceInfo info, SequenceStorage sequence) {
1067-
throw new SequenceStoreException(sequence);
1067+
throw new SequenceStoreException(sequence.getIndicativeValue());
10681068
}
10691069

10701070
protected static boolean isValidReplacement(Class<? extends SequenceStorage> cachedClass, SequenceStorage s, SliceInfo info) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/statement/ImportFromNode.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,20 @@
2525
*/
2626
package com.oracle.graal.python.nodes.statement;
2727

28+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__NAME__;
2829
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GETATTRIBUTE__;
2930
import static com.oracle.graal.python.runtime.exception.PythonErrorType.ImportError;
3031

3132
import com.oracle.graal.python.builtins.objects.function.PArguments;
33+
import com.oracle.graal.python.builtins.objects.str.PString;
34+
import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
35+
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
3236
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
3337
import com.oracle.graal.python.nodes.frame.WriteNode;
38+
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
39+
import com.oracle.graal.python.nodes.subscript.GetItemNode;
3440
import com.oracle.graal.python.runtime.exception.PException;
41+
import com.oracle.truffle.api.CompilerDirectives;
3542
import com.oracle.truffle.api.frame.VirtualFrame;
3643
import com.oracle.truffle.api.nodes.ExplodeLoop;
3744

@@ -40,7 +47,11 @@ public class ImportFromNode extends AbstractImportNode {
4047
private final int level;
4148
private final String[] fromlist;
4249
@Children private final WriteNode[] aslist;
50+
@Child private GetAttributeNode getName;
51+
@Child private GetItemNode getItem;
52+
@Child private ReadAttributeFromObjectNode readModules;
4353
@Child private LookupAndCallBinaryNode readNode = LookupAndCallBinaryNode.create(__GETATTRIBUTE__);
54+
private final IsBuiltinClassProfile attrErrorProfile = IsBuiltinClassProfile.create();
4455

4556
public static ImportFromNode create(String importee, String[] fromlist, WriteNode[] readNodes, int level) {
4657
return new ImportFromNode(importee, fromlist, readNodes, level);
@@ -68,7 +79,32 @@ public void executeVoid(VirtualFrame frame) {
6879
try {
6980
writeNode.doWrite(frame, readNode.executeObject(importedModule, attr));
7081
} catch (PException e) {
71-
throw raise(ImportError, "cannot import name '%s'", attr);
82+
e.expectAttributeError(attrErrorProfile);
83+
if (getName == null) {
84+
CompilerDirectives.transferToInterpreterAndInvalidate();
85+
getName = insert(GetAttributeNode.create(__NAME__, null));
86+
}
87+
try {
88+
String pkgname;
89+
Object pkgname_o = getName.executeObject(importedModule);
90+
if (pkgname_o instanceof PString) {
91+
pkgname = ((PString) pkgname_o).getValue();
92+
} else if (pkgname_o instanceof String) {
93+
pkgname = (String) pkgname_o;
94+
} else {
95+
throw e;
96+
}
97+
String fullname = pkgname + "." + attr;
98+
if (getItem == null) {
99+
CompilerDirectives.transferToInterpreterAndInvalidate();
100+
getItem = insert(GetItemNode.create());
101+
readModules = insert(ReadAttributeFromObjectNode.create());
102+
}
103+
Object sysModules = readModules.execute(getCore().lookupBuiltinModule("sys"), "modules");
104+
writeNode.doWrite(frame, getItem.execute(sysModules, fullname));
105+
} catch (PException e2) {
106+
throw raise(ImportError, "cannot import name '%s'", attr);
107+
}
72108
}
73109
}
74110
}

0 commit comments

Comments
 (0)