Skip to content

Commit ae18f13

Browse files
committed
[GR-23097] SignalNode hanles PInt as the signalnum and produces correct errors on invalid arguments.
PullRequest: graalpython/936
2 parents d8e0f1d + e3afb0e commit ae18f13

File tree

2 files changed

+37
-18
lines changed

2 files changed

+37
-18
lines changed

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2018, 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
@@ -37,8 +37,21 @@
3737
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3838
# SOFTWARE.
3939

40+
import unittest
4041
import sys
4142

43+
class SignalTests(unittest.TestCase):
44+
def test_args_validation(self):
45+
try:
46+
import _signal
47+
except ImportError:
48+
import signal as _signal
49+
self.assertRaises(OverflowError, lambda : _signal.signal(0x8000000000000000, 0))
50+
self.assertRaises(OverflowError, lambda : _signal.signal(0x800000000000000, 0))
51+
self.assertRaises(TypeError, lambda : _signal.signal(_signal.SIGALRM, 0x100))
52+
self.assertRaises(TypeError, lambda : _signal.signal(_signal.SIGALRM, 'string'))
53+
54+
4255
def test_alarm2():
4356
try:
4457
import _signal

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

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,18 @@
4040
*/
4141
package com.oracle.graal.python.builtins.modules;
4242

43-
import static java.lang.StrictMath.toIntExact;
44-
4543
import java.util.List;
4644
import java.util.concurrent.ConcurrentHashMap;
4745
import java.util.concurrent.ConcurrentLinkedDeque;
4846
import java.util.concurrent.Semaphore;
4947

5048
import com.oracle.graal.python.builtins.Builtin;
5149
import com.oracle.graal.python.builtins.CoreFunctions;
52-
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
5350
import com.oracle.graal.python.builtins.PythonBuiltins;
5451
import com.oracle.graal.python.builtins.objects.PNone;
5552
import com.oracle.graal.python.builtins.objects.ints.PInt;
5653
import com.oracle.graal.python.builtins.objects.module.PythonModule;
54+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
5755
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
5856
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
5957
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
@@ -69,6 +67,7 @@
6967
import com.oracle.truffle.api.dsl.NodeFactory;
7068
import com.oracle.truffle.api.dsl.Specialization;
7169
import com.oracle.truffle.api.dsl.TypeSystemReference;
70+
import com.oracle.truffle.api.library.CachedLibrary;
7271
import com.oracle.truffle.api.object.HiddenKey;
7372

7473
@CoreFunctions(defineModule = "_signal")
@@ -205,23 +204,25 @@ Object defaultIntHandler(@SuppressWarnings("unused") Object[] args) {
205204
@Builtin(name = "signal", minNumOfPositionalArgs = 3, declaresExplicitSelf = true)
206205
@GenerateNodeFactory
207206
abstract static class SignalNode extends PythonTernaryBuiltinNode {
208-
private int getSignum(long signum) {
209-
try {
210-
return toIntExact(signum);
211-
} catch (ArithmeticException ae) {
212-
throw raise(PythonBuiltinClassType.OverflowError, "Python int too large to convert to C int");
213-
}
207+
208+
@Specialization(guards = "!idNumLib.isCallable(idNum)", limit = "1")
209+
Object signalId(@SuppressWarnings("unused") PythonModule self, Object signal, Object idNum,
210+
@SuppressWarnings("unused") @CachedLibrary("idNum") PythonObjectLibrary idNumLib,
211+
@CachedLibrary("signal") PythonObjectLibrary signalLib) {
212+
// Note: CPython checks if id is the same reference as SIG_IGN/SIG_DFL constants, which
213+
// are instances of Handlers enum
214+
// The -1 fallback will be correctly reported as an error later on
215+
int id = idNum instanceof Integer ? (int) idNum : -1;
216+
return signal(signalLib.asSize(signal), id);
214217
}
215218

216-
@Specialization
217219
@TruffleBoundary
218-
Object signal(@SuppressWarnings("unused") PythonModule self, long signalNumber, int id) {
219-
int signum = getSignum(signalNumber);
220+
private Object signal(int signum, int id) {
220221
Object retval;
221222
try {
222223
retval = Signals.setSignalHandler(signum, id);
223224
} catch (IllegalArgumentException e) {
224-
throw raise(PythonErrorType.ValueError, e);
225+
throw raise(PythonErrorType.TypeError, "TypeError: signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
225226
}
226227
if ((int) retval == Signals.SIG_UNKNOWN) {
227228
if (signalHandlers.containsKey(signum)) {
@@ -234,12 +235,17 @@ Object signal(@SuppressWarnings("unused") PythonModule self, long signalNumber,
234235
return retval;
235236
}
236237

237-
@Specialization
238-
@TruffleBoundary
239-
Object signal(PythonModule self, long signalNumber, Object handler,
238+
@Specialization(guards = "handlerLib.isCallable(handler)", limit = "1")
239+
Object signalHandler(PythonModule self, Object signal, Object handler,
240+
@SuppressWarnings("unused") @CachedLibrary("handler") PythonObjectLibrary handlerLib,
241+
@CachedLibrary("signal") PythonObjectLibrary signalLib,
240242
@Cached("create()") ReadAttributeFromObjectNode readQueueNode,
241243
@Cached("create()") ReadAttributeFromObjectNode readSemaNode) {
242-
int signum = getSignum(signalNumber);
244+
return signal(self, signalLib.asSize(signal), handler, readQueueNode, readSemaNode);
245+
}
246+
247+
@TruffleBoundary
248+
private Object signal(PythonModule self, int signum, Object handler, ReadAttributeFromObjectNode readQueueNode, ReadAttributeFromObjectNode readSemaNode) {
243249
ConcurrentLinkedDeque<SignalTriggerAction> queue = getQueue(self, readQueueNode);
244250
Semaphore semaphore = getSemaphore(self, readSemaNode);
245251
Object retval;

0 commit comments

Comments
 (0)