Skip to content

Commit 1e0bfd0

Browse files
Merge branch 'main' into patch-3
2 parents 400df48 + 15f6479 commit 1e0bfd0

File tree

8 files changed

+32
-7
lines changed

8 files changed

+32
-7
lines changed

Doc/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
# Skip if downstream redistributors haven't installed them
4545
_OPTIONAL_EXTENSIONS = (
46+
'linklint.ext',
4647
'notfound.extension',
4748
'sphinxext.opengraph',
4849
)

Doc/library/stdtypes.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4536,7 +4536,7 @@ copying.
45364536
types such as :class:`bytes` and :class:`bytearray`, an element is a single
45374537
byte, but other types such as :class:`array.array` may have bigger elements.
45384538

4539-
``len(view)`` is equal to the length of :class:`~memoryview.tolist`, which
4539+
``len(view)`` is equal to the length of :meth:`~memoryview.tolist`, which
45404540
is the nested list representation of the view. If ``view.ndim = 1``,
45414541
this is equal to the number of elements in the view.
45424542

Doc/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@ sphinx-notfound-page~=1.0.0
1818
# to install that as well.
1919
python-docs-theme>=2023.3.1,!=2023.7
2020

21+
linklint
22+
2123
-c constraints.txt

Lib/sqlite3/__main__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,11 @@ def main(*args):
133133
theme = get_theme()
134134
s = theme.syntax
135135

136-
sys.ps1 = f"{s.prompt}sqlite> {s.reset}"
137-
sys.ps2 = f"{s.prompt} ... {s.reset}"
136+
# Use RL_PROMPT_START_IGNORE (\001) and RL_PROMPT_END_IGNORE (\002) to
137+
# bracket non-printing characters. This tells readline to ignore them
138+
# when calculating screen space for redisplay during history scrolling.
139+
sys.ps1 = f"\001{s.prompt}\002sqlite> \001{s.reset}\002"
140+
sys.ps2 = f"\001{s.prompt}\002 ... \001{s.reset}\002"
138141

139142
con = sqlite3.connect(args.filename, isolation_level=None)
140143
try:

Lib/test/test_lazy_import/__init__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import os
1313

1414
from test import support
15+
from test.support.script_helper import assert_python_ok
1516

1617
try:
1718
import _testcapi
@@ -219,6 +220,16 @@ def test_lazy_import_type_cant_construct(self):
219220
"""LazyImportType should not be directly constructible."""
220221
self.assertRaises(TypeError, types.LazyImportType, {}, "module")
221222

223+
@support.requires_subprocess()
224+
def test_lazy_import_type_attributes_accessible(self):
225+
"""Check that static PyLazyImport_Type is initialized at startup."""
226+
code = textwrap.dedent("""
227+
lazy import json
228+
print(globals()["json"].resolve)
229+
""")
230+
proc = assert_python_ok("-c", code)
231+
self.assertIn(b"<built-in method resolve of lazy_import object at", proc.out)
232+
222233

223234
class SyntaxRestrictionTests(unittest.TestCase):
224235
"""Tests for syntax restrictions on lazy imports."""

Lib/test/test_sqlite3/test_cli.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ def test_cli_on_disk_db(self):
8080
@force_not_colorized_test_class
8181
class InteractiveSession(unittest.TestCase):
8282
MEMORY_DB_MSG = "Connected to a transient in-memory database"
83-
PS1 = "sqlite> "
84-
PS2 = "... "
83+
PS1 = "\001\002sqlite> \001\002"
84+
PS2 = "\001\002 ... \001\002"
8585

8686
def run_cli(self, *args, commands=()):
8787
with (
@@ -202,8 +202,8 @@ def test_interact_on_disk_file(self):
202202
def test_color(self):
203203
with unittest.mock.patch("_colorize.can_colorize", return_value=True):
204204
out, err = self.run_cli(commands="TEXT\n")
205-
self.assertIn("\x1b[1;35msqlite> \x1b[0m", out)
206-
self.assertIn("\x1b[1;35m ... \x1b[0m\x1b", out)
205+
self.assertIn("\x01\x1b[1;35m\x02sqlite> \x01\x1b[0m\x02", out)
206+
self.assertIn("\x01\x1b[1;35m\x02 ... \x01\x1b[0m\x02\x01\x1b", out)
207207
out, err = self.run_cli(commands=("sel;",))
208208
self.assertIn('\x1b[1;35mOperationalError (SQLITE_ERROR)\x1b[0m: '
209209
'\x1b[35mnear "sel": syntax error\x1b[0m', err)
@@ -212,6 +212,10 @@ def test_color(self):
212212
@requires_subprocess()
213213
@force_not_colorized_test_class
214214
class Completion(unittest.TestCase):
215+
# run_pty() creates a real terminal environment, where sqlite3 CLI
216+
# SqliteInteractiveConsole invokes GNU Readline for input. Readline's
217+
# _rl_strip_prompt() strips \001 and \002 from the output, so test
218+
# assertions use the plain prompt.
215219
PS1 = "sqlite> "
216220

217221
@classmethod
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :mod:`sqlite3`'s :ref:`interactive shell <sqlite3-cli>` keeping part of
2+
previous commands when scrolling history.

Objects/object.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "pycore_instruction_sequence.h" // _PyInstructionSequence_Type
1818
#include "pycore_interpframe.h" // _PyFrame_Stackbase()
1919
#include "pycore_interpolation.h" // _PyInterpolation_Type
20+
#include "pycore_lazyimportobject.h" // PyLazyImport_Type
2021
#include "pycore_list.h" // _PyList_DebugMallocStats()
2122
#include "pycore_long.h" // _PyLong_GetZero()
2223
#include "pycore_memoryobject.h" // _PyManagedBuffer_Type
@@ -2540,6 +2541,7 @@ static PyTypeObject* static_types[] = {
25402541
&PyGen_Type,
25412542
&PyGetSetDescr_Type,
25422543
&PyInstanceMethod_Type,
2544+
&PyLazyImport_Type,
25432545
&PyListIter_Type,
25442546
&PyListRevIter_Type,
25452547
&PyList_Type,

0 commit comments

Comments
 (0)