Skip to content

Commit 66afc14

Browse files
committed
[GR-20576] Fix Python 3 stdlib unittest runner
PullRequest: graalpython/777
2 parents aaf80e2 + 4312a3b commit 66afc14

File tree

14 files changed

+147
-24
lines changed

14 files changed

+147
-24
lines changed

ci.jsonnet

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ overlay: "9c01bf051c60a83731b2cabd5b06c50e31624741" }
1+
{ overlay: "c73a52e014ae17658cb055f67f58408f590b99ff" }

graalpython/com.oracle.graal.python.shell/src/com/oracle/graal/python/shell/GraalPythonMain.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -129,6 +129,7 @@ protected List<String> preprocessArguments(List<String> givenArgs, Map<String, S
129129
case "-O":
130130
case "-OO":
131131
case "-R":
132+
case "-d":
132133
break;
133134
case "-q":
134135
quietFlag = true;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.io.IOException;
2929
import java.util.ArrayList;
3030
import java.util.concurrent.ConcurrentHashMap;
31+
import java.util.concurrent.Semaphore;
3132
import java.util.function.Supplier;
3233
import java.util.logging.Level;
3334

@@ -132,6 +133,14 @@ public final class PythonLanguage extends TruffleLanguage<PythonContext> {
132133

133134
@CompilationFinal(dimensions = 1) private static final Object[] CONTEXT_INSENSITIVE_SINGLETONS = new Object[]{PNone.NONE, PNone.NO_VALUE, PEllipsis.INSTANCE, PNotImplemented.NOT_IMPLEMENTED};
134135

136+
/**
137+
* Named semaphores are shared between all processes in a system, and they persist until the
138+
* system is shut down, unless explicitly removed. We interpret this as meaning they all exist
139+
* globally per language instance, that is, they are shared between different Contexts in the
140+
* same engine.
141+
*/
142+
public final ConcurrentHashMap<String, Semaphore> namedSemaphores = new ConcurrentHashMap<>();
143+
135144
/*
136145
* We need to store this here, because the check is on the language and can come from a thread
137146
* that has no context, but we enable or disable threads with a context option. So we store this

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -158,6 +158,7 @@
158158
import com.oracle.graal.python.builtins.objects.superobject.SuperBuiltins;
159159
import com.oracle.graal.python.builtins.objects.thread.LockBuiltins;
160160
import com.oracle.graal.python.builtins.objects.thread.RLockBuiltins;
161+
import com.oracle.graal.python.builtins.objects.thread.SemLockBuiltins;
161162
import com.oracle.graal.python.builtins.objects.thread.ThreadBuiltins;
162163
import com.oracle.graal.python.builtins.objects.traceback.TracebackBuiltins;
163164
import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins;
@@ -373,6 +374,7 @@ private static final PythonBuiltins[] initializeBuiltins() {
373374
new LZMACompressorBuiltins(),
374375
new LZMADecompressorBuiltins(),
375376
new MultiprocessingModuleBuiltins(),
377+
new SemLockBuiltins(),
376378
new GraalPythonModuleBuiltins()));
377379
if (!TruffleOptions.AOT) {
378380
ServiceLoader<PythonBuiltins> providers = ServiceLoader.load(PythonBuiltins.class, Python3Core.class.getClassLoader());

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -54,7 +54,9 @@ public abstract class PythonBuiltins {
5454

5555
/**
5656
* Initialize everything that is truly independent of commandline arguments and that can be
57-
* initialized and frozen into an SVM image.
57+
* initialized and frozen into an SVM image. When in a subclass, any modifications to
58+
* {@link #builtinConstants} or such should be made before calling
59+
* {@code super.initialize(core)}.
5860
*/
5961
public void initialize(PythonCore core) {
6062
if (builtinFunctions.size() > 0) {

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

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -41,18 +41,25 @@
4141
package com.oracle.graal.python.builtins.modules;
4242

4343
import java.util.List;
44+
import java.util.concurrent.Semaphore;
4445

46+
import com.oracle.graal.python.PythonLanguage;
4547
import com.oracle.graal.python.builtins.Builtin;
4648
import com.oracle.graal.python.builtins.CoreFunctions;
4749
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4850
import com.oracle.graal.python.builtins.PythonBuiltins;
51+
import com.oracle.graal.python.builtins.objects.PNone;
4952
import com.oracle.graal.python.builtins.objects.thread.PSemLock;
5053
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
5154
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
5255
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
56+
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
5357
import com.oracle.graal.python.nodes.util.CastToJavaIntNode;
58+
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
5459
import com.oracle.graal.python.runtime.PythonCore;
60+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5561
import com.oracle.truffle.api.dsl.Cached;
62+
import com.oracle.truffle.api.dsl.CachedLanguage;
5663
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
5764
import com.oracle.truffle.api.dsl.NodeFactory;
5865
import com.oracle.truffle.api.dsl.Specialization;
@@ -76,21 +83,69 @@ public void initialize(PythonCore core) {
7683
abstract static class ConstructSemLockNode extends PythonBuiltinNode {
7784
@Specialization
7885
PSemLock construct(LazyPythonClass cls, Object kindObj, Object valueObj, Object maxvalueObj, Object nameObj, Object unlinkObj,
86+
@Cached CastToJavaStringNode castNameNode,
7987
@Cached CastToJavaIntNode castKindToIntNode,
8088
@Cached CastToJavaIntNode castValueToIntNode,
8189
@Cached CastToJavaIntNode castMaxvalueToIntNode,
82-
@Cached CastToJavaIntNode castUnlinkToIntNode) {
90+
@Cached CastToJavaIntNode castUnlinkToIntNode,
91+
@CachedLanguage PythonLanguage lang) {
8392
int kind = castKindToIntNode.execute(kindObj);
8493
if (kind != PSemLock.RECURSIVE_MUTEX && kind != PSemLock.SEMAPHORE) {
8594
throw raise(PythonBuiltinClassType.ValueError, "unrecognized kind");
8695
}
8796
int value = castValueToIntNode.execute(valueObj);
88-
int maxvalue = castMaxvalueToIntNode.execute(maxvalueObj);
97+
castMaxvalueToIntNode.execute(maxvalueObj); // executed for the side-effect, but ignored
98+
// on posix
99+
Semaphore semaphore = newSemaphore(value);
89100
int unlink = castUnlinkToIntNode.execute(unlinkObj);
90-
if (unlink != 0) {
91-
throw raise(PythonBuiltinClassType.SystemError, "semaphore unlinking is not yet implemented");
101+
String name = castNameNode.execute(nameObj);
102+
if (unlink == 0) {
103+
// CPython creates a named semaphore, and if unlink != 0 unlinks
104+
// it directly so it cannot be access by other processes. We
105+
// have to explicitly link it, so we do that here if we
106+
// must. CPython always uses O_CREAT | O_EXCL for creating named
107+
// semaphores, so a conflict raises.
108+
if (semaphoreExists(lang, name)) {
109+
throw raise(PythonBuiltinClassType.FileExistsError, "Semaphore name taken: '%s'", name);
110+
} else {
111+
semaphorePut(lang, semaphore, name);
112+
}
92113
}
93-
return factory().createSemLock(cls, kind, value, maxvalue, nameObj);
114+
return factory().createSemLock(cls, name, kind, semaphore);
115+
}
116+
117+
@TruffleBoundary
118+
private static Object semaphorePut(PythonLanguage lang, Semaphore semaphore, String name) {
119+
return lang.namedSemaphores.put(name, semaphore);
120+
}
121+
122+
@TruffleBoundary
123+
private static boolean semaphoreExists(PythonLanguage lang, String name) {
124+
return lang.namedSemaphores.containsKey(name);
125+
}
126+
127+
@TruffleBoundary
128+
private static Semaphore newSemaphore(int value) {
129+
return new Semaphore(value);
130+
}
131+
}
132+
133+
@GenerateNodeFactory
134+
@Builtin(name = "sem_unlink", parameterNames = {"name"})
135+
abstract static class SemUnlink extends PythonUnaryBuiltinNode {
136+
@Specialization
137+
PNone doit(String name,
138+
@CachedLanguage PythonLanguage lang) {
139+
Semaphore prev = semaphoreRemove(name, lang);
140+
if (prev == null) {
141+
throw raise(PythonBuiltinClassType.FileNotFoundError, "No such file or directory: 'semaphores:/%s'", name);
142+
}
143+
return PNone.NONE;
144+
}
145+
146+
@TruffleBoundary
147+
private static Semaphore semaphoreRemove(String name, PythonLanguage lang) {
148+
return lang.namedSemaphores.remove(name);
94149
}
95150
}
96151
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PSemLock.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -52,14 +52,15 @@ public final class PSemLock extends AbstractPythonLock {
5252

5353
private final Semaphore semaphore;
5454
private final int kind;
55+
private final String name;
5556

5657
private int lastThreadID = -1;
5758
private int count;
5859

59-
@TruffleBoundary
60-
public PSemLock(LazyPythonClass cls, int kind, int value) {
60+
public PSemLock(LazyPythonClass cls, String name, int kind, Semaphore sharedSemaphore) {
6161
super(cls);
62-
semaphore = new Semaphore(value);
62+
this.name = name;
63+
this.semaphore = sharedSemaphore;
6364
this.kind = kind;
6465
}
6566

@@ -129,4 +130,8 @@ public boolean isMine() {
129130
public int getKind() {
130131
return kind;
131132
}
133+
134+
public String getName() {
135+
return name;
136+
}
132137
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/SemLockBuiltins.java

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -55,6 +55,8 @@
5555
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
5656
import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
5757
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
58+
import com.oracle.graal.python.runtime.PythonCore;
59+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5860
import com.oracle.truffle.api.dsl.Cached;
5961
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
6062
import com.oracle.truffle.api.dsl.NodeFactory;
@@ -69,6 +71,12 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
6971
return SemLockBuiltinsFactory.getFactories();
7072
}
7173

74+
@Override
75+
public void initialize(PythonCore core) {
76+
builtinConstants.put("SEM_VALUE_MAX", Integer.MAX_VALUE);
77+
super.initialize(core);
78+
}
79+
7280
@Builtin(name = "_count", minNumOfPositionalArgs = 1)
7381
@GenerateNodeFactory
7482
abstract static class CountNode extends PythonUnaryBuiltinNode {
@@ -96,6 +104,43 @@ int getValue(PSemLock self) {
96104
}
97105
}
98106

107+
@Builtin(name = "handle", minNumOfPositionalArgs = 1, isGetter = true)
108+
@GenerateNodeFactory
109+
abstract static class GetHandleNode extends PythonUnaryBuiltinNode {
110+
@Specialization
111+
@TruffleBoundary
112+
int getHandle(PSemLock self) {
113+
return self.hashCode();
114+
}
115+
}
116+
117+
@Builtin(name = "name", minNumOfPositionalArgs = 1, isGetter = true)
118+
@GenerateNodeFactory
119+
abstract static class GetNameNode extends PythonUnaryBuiltinNode {
120+
@Specialization
121+
Object getName(@SuppressWarnings("unused") PSemLock self) {
122+
return PNone.NONE;
123+
}
124+
}
125+
126+
@Builtin(name = "maxvalue", minNumOfPositionalArgs = 1, isGetter = true)
127+
@GenerateNodeFactory
128+
abstract static class GetMaxValue extends PythonUnaryBuiltinNode {
129+
@Specialization
130+
Object getMax(@SuppressWarnings("unused") PSemLock self) {
131+
return Integer.MAX_VALUE;
132+
}
133+
}
134+
135+
@Builtin(name = "kind", minNumOfPositionalArgs = 1, isGetter = true)
136+
@GenerateNodeFactory
137+
abstract static class GetKindNode extends PythonUnaryBuiltinNode {
138+
@Specialization
139+
int getKind(PSemLock self) {
140+
return self.getKind();
141+
}
142+
}
143+
99144
@Builtin(name = "acquire", minNumOfPositionalArgs = 1, parameterNames = {"self", "blocking", "timeout"})
100145
@GenerateNodeFactory
101146
abstract static class AcquireNode extends PythonTernaryBuiltinNode {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PythonObjectFactory.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -31,6 +31,7 @@
3131
import java.nio.channels.SeekableByteChannel;
3232
import java.nio.file.DirectoryStream;
3333
import java.util.Map;
34+
import java.util.concurrent.Semaphore;
3435

3536
import com.oracle.graal.python.PythonLanguage;
3637
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
@@ -823,8 +824,8 @@ public PThread createPythonThread(LazyPythonClass cls, Thread thread) {
823824
return trace(new PThread(cls, thread));
824825
}
825826

826-
public PSemLock createSemLock(LazyPythonClass cls, int kind, int value, @SuppressWarnings("unused") int maxvalue, @SuppressWarnings("unused") Object nameObj) {
827-
return trace(new PSemLock(cls, kind, value));
827+
public PSemLock createSemLock(LazyPythonClass cls, String name, int kind, Semaphore sharedSemaphore) {
828+
return trace(new PSemLock(cls, name, kind, sharedSemaphore));
828829
}
829830

830831
public PScandirIterator createScandirIterator(LazyPythonClass cls, String path, DirectoryStream<TruffleFile> next) {

graalpython/lib-python/3/multiprocessing/context.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@ def _check_available(self):
311311
'forkserver': ForkServerContext(),
312312
}
313313
_default_context = DefaultContext(_concrete_contexts['fork'])
314+
# BEGIN TRUFFLE PATCH
315+
_default_context = DefaultContext(_concrete_contexts['spawn'])
316+
# END TRUFFLE PATCH
314317

315318
else:
316319

mx.graalpython/copyrights/oracle.copyright.hash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
22
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33
#
44
# The Universal Permissive License (UPL), Version 1.0

mx.graalpython/copyrights/oracle.copyright.star

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0

mx.graalpython/mx_graalpython.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ def nativeclean(args):
215215

216216
def python3_unittests(args):
217217
"""run the cPython stdlib unittests"""
218-
python(["graalpython/com.oracle.graal.python.test/src/python_unittests.py", "-v"] + args)
218+
mx.run([sys.executable, "graalpython/com.oracle.graal.python.test/src/python_unittests.py", "-v"] + args)
219219

220220

221221
def retag_unittests(args):

mx.graalpython/suite.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@
4444
},
4545
{
4646
"name": "sulong",
47-
"version": "48aa9f2523f7ecfcd09b748c3c8696efeddd2291",
47+
"version": "f0d558f462231679629b663fc62323b1c70d4ea9",
4848
"subdir": True,
4949
"urls": [
5050
{"url": "https://github.com/oracle/graal", "kind": "git"},
5151
]
5252
},
5353
{
5454
"name": "regex",
55-
"version": "48aa9f2523f7ecfcd09b748c3c8696efeddd2291",
55+
"version": "f0d558f462231679629b663fc62323b1c70d4ea9",
5656
"subdir": True,
5757
"urls": [
5858
{"url": "https://github.com/oracle/graal", "kind": "git"},

0 commit comments

Comments
 (0)