summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2023-11-14 12:25:19 (GMT)
committerGitHub <noreply@github.com>2023-11-14 12:25:19 (GMT)
commitc003de946793fe2f4e168ba231ea4ee9e88cc3fe (patch)
tree4f8203f488beee20cd0e32bb7c4c4bd1fb13ae41
parent18b88fecc9ddae7924a161c247c977412f177a51 (diff)
downloadcpython-c003de946793fe2f4e168ba231ea4ee9e88cc3fe.zip
cpython-c003de946793fe2f4e168ba231ea4ee9e88cc3fe.tar.gz
cpython-c003de946793fe2f4e168ba231ea4ee9e88cc3fe.tar.bz2
[3.12] gh-110944: Move pty helper to test.support and add basic pdb completion test (GH-111826) (GH-112024)
gh-110944: Move pty helper to test.support and add basic pdb completion test (GH-111826) (cherry picked from commit 1c7ed7e9ebc53290c831d7b610219fa737153a1b) Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com>
-rw-r--r--Lib/test/support/pty_helper.py60
-rw-r--r--Lib/test/test_pdb.py30
-rw-r--r--Lib/test/test_readline.py55
3 files changed, 91 insertions, 54 deletions
diff --git a/Lib/test/support/pty_helper.py b/Lib/test/support/pty_helper.py
new file mode 100644
index 0000000..11037d2
--- /dev/null
+++ b/Lib/test/support/pty_helper.py
@@ -0,0 +1,60 @@
+"""
+Helper to run a script in a pseudo-terminal.
+"""
+import os
+import selectors
+import subprocess
+import sys
+from contextlib import ExitStack
+from errno import EIO
+
+from test.support.import_helper import import_module
+
+def run_pty(script, input=b"dummy input\r", env=None):
+ pty = import_module('pty')
+ output = bytearray()
+ [master, slave] = pty.openpty()
+ args = (sys.executable, '-c', script)
+ proc = subprocess.Popen(args, stdin=slave, stdout=slave, stderr=slave, env=env)
+ os.close(slave)
+ with ExitStack() as cleanup:
+ cleanup.enter_context(proc)
+ def terminate(proc):
+ try:
+ proc.terminate()
+ except ProcessLookupError:
+ # Workaround for Open/Net BSD bug (Issue 16762)
+ pass
+ cleanup.callback(terminate, proc)
+ cleanup.callback(os.close, master)
+ # Avoid using DefaultSelector and PollSelector. Kqueue() does not
+ # work with pseudo-terminals on OS X < 10.9 (Issue 20365) and Open
+ # BSD (Issue 20667). Poll() does not work with OS X 10.6 or 10.4
+ # either (Issue 20472). Hopefully the file descriptor is low enough
+ # to use with select().
+ sel = cleanup.enter_context(selectors.SelectSelector())
+ sel.register(master, selectors.EVENT_READ | selectors.EVENT_WRITE)
+ os.set_blocking(master, False)
+ while True:
+ for [_, events] in sel.select():
+ if events & selectors.EVENT_READ:
+ try:
+ chunk = os.read(master, 0x10000)
+ except OSError as err:
+ # Linux raises EIO when slave is closed (Issue 5380)
+ if err.errno != EIO:
+ raise
+ chunk = b""
+ if not chunk:
+ return output
+ output.extend(chunk)
+ if events & selectors.EVENT_WRITE:
+ try:
+ input = input[os.write(master, input):]
+ except OSError as err:
+ # Apparently EIO means the slave was closed
+ if err.errno != EIO:
+ raise
+ input = b"" # Stop writing
+ if not input:
+ sel.modify(master, selectors.EVENT_READ)
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index 49a87b1..08b2867 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -15,6 +15,8 @@ from contextlib import ExitStack, redirect_stdout
from io import StringIO
from test import support
from test.support import os_helper
+from test.support.import_helper import import_module
+from test.support.pty_helper import run_pty
# This little helper class is essential for testing pdb under doctest.
from test.test_doctest import _FakeInput
from unittest.mock import patch
@@ -2627,6 +2629,34 @@ class ChecklineTests(unittest.TestCase):
self.assertFalse(db.checkline(os_helper.TESTFN, lineno))
+@support.requires_subprocess()
+class PdbTestReadline(unittest.TestCase):
+ def setUpClass():
+ # Ensure that the readline module is loaded
+ # If this fails, the test is skipped because SkipTest will be raised
+ readline = import_module('readline')
+ if readline.__doc__ and "libedit" in readline.__doc__:
+ raise unittest.SkipTest("libedit readline is not supported for pdb")
+
+ def test_basic_completion(self):
+ script = textwrap.dedent("""
+ import pdb; pdb.Pdb().set_trace()
+ # Concatenate strings so that the output doesn't appear in the source
+ print('hello' + '!')
+ """)
+
+ # List everything starting with 'co', there should be multiple matches
+ # then add ntin and complete 'contin' to 'continue'
+ input = b"co\t\tntin\t\n"
+
+ output = run_pty(script, input)
+
+ self.assertIn(b'commands', output)
+ self.assertIn(b'condition', output)
+ self.assertIn(b'continue', output)
+ self.assertIn(b'hello!', output)
+
+
def load_tests(loader, tests, pattern):
from test import test_pdb
tests.addTest(doctest.DocTestSuite(test_pdb))
diff --git a/Lib/test/test_readline.py b/Lib/test/test_readline.py
index 59dbef9..835280f 100644
--- a/Lib/test/test_readline.py
+++ b/Lib/test/test_readline.py
@@ -1,18 +1,15 @@
"""
Very minimal unittests for parts of the readline module.
"""
-from contextlib import ExitStack
-from errno import EIO
import locale
import os
-import selectors
-import subprocess
import sys
import tempfile
import unittest
from test.support import verbose
from test.support.import_helper import import_module
from test.support.os_helper import unlink, temp_dir, TESTFN
+from test.support.pty_helper import run_pty
from test.support.script_helper import assert_python_ok
# Skip tests if there is no readline module
@@ -304,55 +301,5 @@ readline.write_history_file(history_file)
self.assertEqual(lines[-1].strip(), b"last input")
-def run_pty(script, input=b"dummy input\r", env=None):
- pty = import_module('pty')
- output = bytearray()
- [master, slave] = pty.openpty()
- args = (sys.executable, '-c', script)
- proc = subprocess.Popen(args, stdin=slave, stdout=slave, stderr=slave, env=env)
- os.close(slave)
- with ExitStack() as cleanup:
- cleanup.enter_context(proc)
- def terminate(proc):
- try:
- proc.terminate()
- except ProcessLookupError:
- # Workaround for Open/Net BSD bug (Issue 16762)
- pass
- cleanup.callback(terminate, proc)
- cleanup.callback(os.close, master)
- # Avoid using DefaultSelector and PollSelector. Kqueue() does not
- # work with pseudo-terminals on OS X < 10.9 (Issue 20365) and Open
- # BSD (Issue 20667). Poll() does not work with OS X 10.6 or 10.4
- # either (Issue 20472). Hopefully the file descriptor is low enough
- # to use with select().
- sel = cleanup.enter_context(selectors.SelectSelector())
- sel.register(master, selectors.EVENT_READ | selectors.EVENT_WRITE)
- os.set_blocking(master, False)
- while True:
- for [_, events] in sel.select():
- if events & selectors.EVENT_READ:
- try:
- chunk = os.read(master, 0x10000)
- except OSError as err:
- # Linux raises EIO when slave is closed (Issue 5380)
- if err.errno != EIO:
- raise
- chunk = b""
- if not chunk:
- return output
- output.extend(chunk)
- if events & selectors.EVENT_WRITE:
- try:
- input = input[os.write(master, input):]
- except OSError as err:
- # Apparently EIO means the slave was closed
- if err.errno != EIO:
- raise
- input = b"" # Stop writing
- if not input:
- sel.modify(master, selectors.EVENT_READ)
-
-
if __name__ == "__main__":
unittest.main()