From ec2856cb052c0b61645cea81dab0ac605560cd29 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Tue, 25 Aug 2020 20:23:57 +0100 Subject: [PATCH 1/9] bpo-41602: add tests for sigint handling in runpy --- Lib/test/test_runpy.py | 87 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index f8274a981cb1c0..06f0a0c2b9c66e 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -1,15 +1,17 @@ # Test the runpy module -import unittest -import os +import contextlib +import importlib.machinery, importlib.util import os.path -import sys +import pathlib +import py_compile import re +import subprocess +import sys import tempfile -import importlib, importlib.machinery, importlib.util -import py_compile +import textwrap +import unittest import warnings -import pathlib -from test.support import verbose, no_tracing +from test.support import no_tracing, verbose from test.support.import_helper import forget, make_legacy_pyc, unload from test.support.os_helper import create_empty_file, temp_dir from test.support.script_helper import make_script, make_zip_script @@ -752,5 +754,76 @@ def test_encoding(self): self.assertEqual(result['s'], "non-ASCII: h\xe9") +class TestExit(unittest.TestCase): + @staticmethod + @contextlib.contextmanager + def tmp_path(*args, **kwargs): + with temp_dir() as tmp_fn: + yield pathlib.Path(tmp_fn) + + + def run(self, *args, **kwargs): + with self.tmp_path() as tmp: + self.ham = ham = tmp / "ham.py" + ham.write_text( + textwrap.dedent( + """\ + raise KeyboardInterrupt + """ + ) + ) + super().run(*args, **kwargs) + + def assertSigInt(self, *args, **kwargs): + proc = subprocess.run(*args, **kwargs, text=True, stderr=subprocess.PIPE) + self.assertTrue(proc.stderr.endswith("\nKeyboardInterrupt\n")) + self.assertEqual(proc.returncode, -2) + + def test_pymain_run_file(self): + self.assertSigInt([sys.executable, self.ham]) + + def test_pymain_run_file_runpy_run_module(self): + tmp = self.ham.parent + run_module = tmp / "run_module.py" + run_module.write_text( + textwrap.dedent( + """\ + import runpy + runpy.run_module("ham") + """ + ) + ) + self.assertSigInt([sys.executable, run_module], cwd=tmp) + + def test_pymain_run_file_runpy_run_module_as_main(self): + tmp = self.ham.parent + run_module_as_main = tmp / "run_module_as_main.py" + run_module_as_main.write_text( + textwrap.dedent( + """\ + import runpy + runpy._run_module_as_main("ham") + """ + ) + ) + self.assertSigInt([sys.executable, run_module_as_main], cwd=tmp) + + def test_pymain_run_command_run_module(self): + self.assertSigInt( + [sys.executable, "-c", "import runpy; runpy.run_module('ham')"], + cwd=self.ham.parent, + ) + + def test_pymain_run_command(self): + self.assertSigInt([sys.executable, "-c", "import ham"], cwd=self.ham.parent) + + def test_pymain_run_stdin(self): + self.assertSigInt([sys.executable], input="import ham", cwd=self.ham.parent) + + def test_pymain_run_module(self): + ham = self.ham + self.assertSigInt([sys.executable, "-m", ham.stem], cwd=ham.parent) + + if __name__ == "__main__": unittest.main() From 78ba11c1d43c11cb748d56f36ccefeaa79db1ecb Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Tue, 25 Aug 2020 19:25:38 +0000 Subject: [PATCH 2/9] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst diff --git a/Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst b/Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst new file mode 100644 index 00000000000000..195b4c8a9074e6 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst @@ -0,0 +1 @@ +add tests for sigint handling in runpy \ No newline at end of file From ce4601a1dda21a8facf02554004dfcc58300898c Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Tue, 25 Aug 2020 21:25:23 +0100 Subject: [PATCH 3/9] check for STATUS_CONTROL_C_EXIT on windows --- Lib/test/test_runpy.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index 06f0a0c2b9c66e..2954dfedc7e428 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -5,6 +5,7 @@ import pathlib import py_compile import re +import signal import subprocess import sys import tempfile @@ -755,6 +756,12 @@ def test_encoding(self): class TestExit(unittest.TestCase): + STATUS_CONTROL_C_EXIT = 0xC000013A + EXPECTED_CODE = ( + STATUS_CONTROL_C_EXIT + if sys.platform == "win32" + else -signal.SIGINT + ) @staticmethod @contextlib.contextmanager def tmp_path(*args, **kwargs): @@ -777,7 +784,7 @@ def run(self, *args, **kwargs): def assertSigInt(self, *args, **kwargs): proc = subprocess.run(*args, **kwargs, text=True, stderr=subprocess.PIPE) self.assertTrue(proc.stderr.endswith("\nKeyboardInterrupt\n")) - self.assertEqual(proc.returncode, -2) + self.assertEqual(proc.returncode, self.EXPECTED_CODE) def test_pymain_run_file(self): self.assertSigInt([sys.executable, self.ham]) From a42916bbc696e33b900a4655d8dee2fc3a58b5c0 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Tue, 25 Aug 2020 22:42:26 +0100 Subject: [PATCH 4/9] REVERTME: flip the assertion to make the tests pass --- Lib/test/test_runpy.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index 2954dfedc7e428..501cf6b54bc51f 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -781,10 +781,10 @@ def run(self, *args, **kwargs): ) super().run(*args, **kwargs) - def assertSigInt(self, *args, **kwargs): + def assertSigInt(self, *args, expected_code=EXPECTED_CODE, **kwargs): proc = subprocess.run(*args, **kwargs, text=True, stderr=subprocess.PIPE) self.assertTrue(proc.stderr.endswith("\nKeyboardInterrupt\n")) - self.assertEqual(proc.returncode, self.EXPECTED_CODE) + self.assertEqual(proc.returncode, expected_code) def test_pymain_run_file(self): self.assertSigInt([sys.executable, self.ham]) @@ -829,7 +829,11 @@ def test_pymain_run_stdin(self): def test_pymain_run_module(self): ham = self.ham - self.assertSigInt([sys.executable, "-m", ham.stem], cwd=ham.parent) + self.assertSigInt( + [sys.executable, "-m", ham.stem], + cwd=ham.parent, + expected_code=1, # TODO: should be self.EXPECTED_CODE + ) if __name__ == "__main__": From c483f653ec4f02e408051343e329fe37bd414e68 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Tue, 25 Aug 2020 23:47:21 +0100 Subject: [PATCH 5/9] bpo-41635: noop to work around flaky test From de65294551d8af254e77a1c3ba4edab8e7f6b44e Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Wed, 16 Sep 2020 21:51:13 +0100 Subject: [PATCH 6/9] raise SIGINT exit code on KeyboardInterrupt from pymain_run_module Co-Authored-By: Guido van Rossum --- Modules/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Modules/main.c b/Modules/main.c index 4a76f4461bf610..5b63f2a5b847f9 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -288,6 +288,9 @@ pymain_run_module(const wchar_t *modname, int set_argv0) return pymain_exit_err_print(); } result = PyObject_Call(runmodule, runargs, NULL); + if (!result && PyErr_Occurred() == PyExc_KeyboardInterrupt) { + _Py_UnhandledKeyboardInterrupt = 1; + } Py_DECREF(runpy); Py_DECREF(runmodule); Py_DECREF(module); From 0b325b62af7fbaee2bbce85607cd0efae4f687f5 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Wed, 16 Sep 2020 21:51:55 +0100 Subject: [PATCH 7/9] Revert "REVERTME: flip the assertion to make the tests pass" This reverts commit a42916bbc696e33b900a4655d8dee2fc3a58b5c0. --- Lib/test/test_runpy.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index 501cf6b54bc51f..2954dfedc7e428 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -781,10 +781,10 @@ def run(self, *args, **kwargs): ) super().run(*args, **kwargs) - def assertSigInt(self, *args, expected_code=EXPECTED_CODE, **kwargs): + def assertSigInt(self, *args, **kwargs): proc = subprocess.run(*args, **kwargs, text=True, stderr=subprocess.PIPE) self.assertTrue(proc.stderr.endswith("\nKeyboardInterrupt\n")) - self.assertEqual(proc.returncode, expected_code) + self.assertEqual(proc.returncode, self.EXPECTED_CODE) def test_pymain_run_file(self): self.assertSigInt([sys.executable, self.ham]) @@ -829,11 +829,7 @@ def test_pymain_run_stdin(self): def test_pymain_run_module(self): ham = self.ham - self.assertSigInt( - [sys.executable, "-m", ham.stem], - cwd=ham.parent, - expected_code=1, # TODO: should be self.EXPECTED_CODE - ) + self.assertSigInt([sys.executable, "-m", ham.stem], cwd=ham.parent) if __name__ == "__main__": From 4486dcd7f60eb70987d88dc65f838dfe97fe76c7 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Tue, 22 Sep 2020 10:09:14 +0100 Subject: [PATCH 8/9] reset _Py_UnhandledKeyboardInterrupt before calling runpy._run_module_as_main --- Modules/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/main.c b/Modules/main.c index 5b63f2a5b847f9..2cc891f61aadd1 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -287,6 +287,7 @@ pymain_run_module(const wchar_t *modname, int set_argv0) Py_DECREF(module); return pymain_exit_err_print(); } + _Py_UnhandledKeyboardInterrupt = 0; result = PyObject_Call(runmodule, runargs, NULL); if (!result && PyErr_Occurred() == PyExc_KeyboardInterrupt) { _Py_UnhandledKeyboardInterrupt = 1; From 19f40f7e4a15877a2dc45d35cb2cffa51f0c7bd7 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Tue, 22 Sep 2020 07:25:44 -0700 Subject: [PATCH 9/9] Capitalization and punctuation in blurb. Co-authored-by: Victor Stinner --- Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst b/Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst index 195b4c8a9074e6..fa3d2f1aa374ec 100644 --- a/Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst +++ b/Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst @@ -1 +1 @@ -add tests for sigint handling in runpy \ No newline at end of file +Add tests for SIGINT handling in the runpy module. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy