From 83d6172f7f9465ae0bcfb879ee387408b84ce909 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Thu, 27 Feb 2025 20:04:17 -0500 Subject: [PATCH 1/4] Revert sys.ps1 and sys.ps2 after code interact --- Lib/code.py | 12 ++++++++++-- Lib/test/test_code_module.py | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/Lib/code.py b/Lib/code.py index 1cc2ed8b1dbf28..777b073afd6232 100644 --- a/Lib/code.py +++ b/Lib/code.py @@ -218,12 +218,14 @@ def interact(self, banner=None, exitmsg=None): """ try: - sys.ps1 + _ps1 = sys.ps1 except AttributeError: + _ps1 = None sys.ps1 = ">>> " try: - sys.ps2 + _ps2 = sys.ps2 except AttributeError: + _ps2 = None sys.ps2 = "... " cprt = 'Type "help", "copyright", "credits" or "license" for more information.' if banner is None: @@ -287,6 +289,12 @@ def interact(self, banner=None, exitmsg=None): if _quit is not None: builtins.quit = _quit + if _ps1 is None: + del sys.ps1 + + if _ps2 is None: + del sys.ps2 + if exitmsg is None: self.write('now exiting %s...\n' % self.__class__.__name__) elif exitmsg != '': diff --git a/Lib/test/test_code_module.py b/Lib/test/test_code_module.py index faa0b38f8373e3..2050b216437847 100644 --- a/Lib/test/test_code_module.py +++ b/Lib/test/test_code_module.py @@ -39,19 +39,47 @@ def setUp(self): self.mock_sys() def test_ps1(self): - self.infunc.side_effect = EOFError('Finished') + self.infunc.side_effect = [ + "import code", + "code.sys.ps1", + EOFError('Finished') + ] self.console.interact() - self.assertEqual(self.sysmod.ps1, '>>> ') + output = ''.join(''.join(call[1]) for call in self.stdout.method_calls) + self.assertIn('>>> ', output) + self.assertFalse(hasattr(self.sysmod, 'ps1')) + + self.infunc.side_effect = [ + "import code", + "code.sys.ps1", + EOFError('Finished') + ] self.sysmod.ps1 = 'custom1> ' self.console.interact() + output = ''.join(''.join(call[1]) for call in self.stdout.method_calls) + self.assertIn('custom1> ', output) self.assertEqual(self.sysmod.ps1, 'custom1> ') def test_ps2(self): - self.infunc.side_effect = EOFError('Finished') + self.infunc.side_effect = [ + "import code", + "code.sys.ps2", + EOFError('Finished') + ] self.console.interact() - self.assertEqual(self.sysmod.ps2, '... ') + output = ''.join(''.join(call[1]) for call in self.stdout.method_calls) + self.assertIn('... ', output) + self.assertFalse(hasattr(self.sysmod, 'ps2')) + + self.infunc.side_effect = [ + "import code", + "code.sys.ps2", + EOFError('Finished') + ] self.sysmod.ps2 = 'custom2> ' self.console.interact() + output = ''.join(''.join(call[1]) for call in self.stdout.method_calls) + self.assertIn('custom2> ', output) self.assertEqual(self.sysmod.ps2, 'custom2> ') def test_console_stderr(self): From a23db4ee6cd59d551380d67529879c9b4bc61aa5 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 01:10:18 +0000 Subject: [PATCH 2/4] =?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 --- .../next/Library/2025-02-28-01-10-14.gh-issue-130660.VIThEz.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2025-02-28-01-10-14.gh-issue-130660.VIThEz.rst diff --git a/Misc/NEWS.d/next/Library/2025-02-28-01-10-14.gh-issue-130660.VIThEz.rst b/Misc/NEWS.d/next/Library/2025-02-28-01-10-14.gh-issue-130660.VIThEz.rst new file mode 100644 index 00000000000000..92984e7e2d53c8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-02-28-01-10-14.gh-issue-130660.VIThEz.rst @@ -0,0 +1 @@ +``sys.ps1`` and ``sys.ps2`` are now restored after :func:`code.interact` call. From 1ab293906b97b663a6865c523cd75eca8f6ae05e Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Thu, 27 Feb 2025 21:40:21 -0500 Subject: [PATCH 3/4] Use a bool to indicate whether we need to delete ps1/ps2 --- Lib/code.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Lib/code.py b/Lib/code.py index 777b073afd6232..41331dfd071f11 100644 --- a/Lib/code.py +++ b/Lib/code.py @@ -218,15 +218,18 @@ def interact(self, banner=None, exitmsg=None): """ try: - _ps1 = sys.ps1 + sys.ps1 + delete_ps1_after = False except AttributeError: - _ps1 = None sys.ps1 = ">>> " + delete_ps1_after = True try: _ps2 = sys.ps2 + delete_ps2_after = False except AttributeError: - _ps2 = None sys.ps2 = "... " + delete_ps2_after = True + cprt = 'Type "help", "copyright", "credits" or "license" for more information.' if banner is None: self.write("Python %s on %s\n%s\n(%s)\n" % @@ -289,10 +292,10 @@ def interact(self, banner=None, exitmsg=None): if _quit is not None: builtins.quit = _quit - if _ps1 is None: + if delete_ps1_after: del sys.ps1 - if _ps2 is None: + if delete_ps2_after: del sys.ps2 if exitmsg is None: From 4b4d660c4a9ee594c7724df97a1ffeaf0351e7d8 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Fri, 28 Feb 2025 12:21:56 -0500 Subject: [PATCH 4/4] Use assertNotHasAttr --- Lib/test/test_code_module.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_code_module.py b/Lib/test/test_code_module.py index 2050b216437847..57fb130070b34e 100644 --- a/Lib/test/test_code_module.py +++ b/Lib/test/test_code_module.py @@ -47,7 +47,7 @@ def test_ps1(self): self.console.interact() output = ''.join(''.join(call[1]) for call in self.stdout.method_calls) self.assertIn('>>> ', output) - self.assertFalse(hasattr(self.sysmod, 'ps1')) + self.assertNotHasAttr(self.sysmod, 'ps1') self.infunc.side_effect = [ "import code", @@ -69,7 +69,7 @@ def test_ps2(self): self.console.interact() output = ''.join(''.join(call[1]) for call in self.stdout.method_calls) self.assertIn('... ', output) - self.assertFalse(hasattr(self.sysmod, 'ps2')) + self.assertNotHasAttr(self.sysmod, 'ps2') self.infunc.side_effect = [ "import code",