Skip to content

Commit 476edeb

Browse files
author
Erlend E. Aasland
committed
Sync with 'main' bco. pythonGH-27654
2 parents 3ed9af6 + 2b496e7 commit 476edeb

24 files changed

+326
-111
lines changed

Doc/bugs.rst

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,6 @@ taken on the bug.
8080
Article which goes into some detail about how to create a useful bug report.
8181
This describes what kind of information is useful and why it is useful.
8282

83-
`Bug Report Writing Guidelines <https://developer.mozilla.org/en-US/docs/Mozilla/QA/Bug_writing_guidelines>`_
84-
Information about writing a good bug report. Some of this is specific to the
85-
Mozilla project, but describes general good practices.
86-
8783
.. _contributing-to-python:
8884

8985
Getting started contributing to Python yourself

Doc/library/csv.rst

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ The :mod:`csv` module defines the following functions:
9494
:class:`Dialect` class or one of the strings returned by the
9595
:func:`list_dialects` function. The other optional *fmtparams* keyword arguments
9696
can be given to override individual formatting parameters in the current
97-
dialect. For full details about the dialect and formatting parameters, see
98-
section :ref:`csv-fmt-params`. To make it
97+
dialect. For full details about dialects and formatting parameters, see
98+
the :ref:`csv-fmt-params` section. To make it
9999
as easy as possible to interface with modules which implement the DB API, the
100100
value :const:`None` is written as the empty string. While this isn't a
101101
reversible transformation, it makes it easier to dump SQL NULL data values to
@@ -117,7 +117,7 @@ The :mod:`csv` module defines the following functions:
117117
Associate *dialect* with *name*. *name* must be a string. The
118118
dialect can be specified either by passing a sub-class of :class:`Dialect`, or
119119
by *fmtparams* keyword arguments, or both, with keyword arguments overriding
120-
parameters of the dialect. For full details about the dialect and formatting
120+
parameters of the dialect. For full details about dialects and formatting
121121
parameters, see section :ref:`csv-fmt-params`.
122122

123123

@@ -225,9 +225,21 @@ The :mod:`csv` module defines the following classes:
225225

226226
.. class:: Dialect
227227

228-
The :class:`Dialect` class is a container class relied on primarily for its
229-
attributes, which are used to define the parameters for a specific
230-
:class:`reader` or :class:`writer` instance.
228+
The :class:`Dialect` class is a container class whose attributes contain
229+
information for how to handle doublequotes, whitespace, delimiters, etc.
230+
Due to the lack of a strict CSV specification, different applications
231+
produce subtly different CSV data. :class:`Dialect` instances define how
232+
:class:`reader` and :class:`writer` instances behave.
233+
234+
All available :class:`Dialect` names are returned by :func:`list_dialects`,
235+
and they can be registered with specific :class:`reader` and :class:`writer`
236+
classes through their initializer (``__init__``) functions like this::
237+
238+
import csv
239+
240+
with open('students.csv', 'w', newline='') as csvfile:
241+
writer = csv.writer(csvfile, dialect='unix')
242+
^^^^^^^^^^^^^^
231243

232244

233245
.. class:: excel()
@@ -419,8 +431,8 @@ Reader objects (:class:`DictReader` instances and objects returned by the
419431

420432
Return the next row of the reader's iterable object as a list (if the object
421433
was returned from :func:`reader`) or a dict (if it is a :class:`DictReader`
422-
instance), parsed according to the current dialect. Usually you should call
423-
this as ``next(reader)``.
434+
instance), parsed according to the current :class:`Dialect`. Usually you
435+
should call this as ``next(reader)``.
424436

425437

426438
Reader objects have the following public attributes:
@@ -460,9 +472,9 @@ read CSV files (assuming they support complex numbers at all).
460472

461473
.. method:: csvwriter.writerow(row)
462474

463-
Write the *row* parameter to the writer's file object, formatted according to
464-
the current dialect. Return the return value of the call to the *write* method
465-
of the underlying file object.
475+
Write the *row* parameter to the writer's file object, formatted according
476+
to the current :class:`Dialect`. Return the return value of the call to the
477+
*write* method of the underlying file object.
466478

467479
.. versionchanged:: 3.5
468480
Added support of arbitrary iterables.

Doc/library/errno.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,3 +637,8 @@ defined by the module. The specific list of defined symbols is available as
637637

638638
Quota exceeded
639639

640+
.. data:: EQFULL
641+
642+
Interface output queue is full
643+
644+
.. versionadded:: 3.11

Doc/tutorial/errors.rst

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,10 @@ For example, the following code will print B, C, D in that order::
147147
Note that if the *except clauses* were reversed (with ``except B`` first), it
148148
would have printed B, B, B --- the first matching *except clause* is triggered.
149149

150-
The last *except clause* may omit the exception name(s), to serve as a wildcard.
151-
Use this with extreme caution, since it is easy to mask a real programming error
152-
in this way! It can also be used to print an error message and then re-raise
153-
the exception (allowing a caller to handle the exception as well)::
150+
All exceptions inherit from :exc:`BaseException`, and so it can be used to serve
151+
as a wildcard. Use this with extreme caution, since it is easy to mask a real
152+
programming error in this way! It can also be used to print an error message and
153+
then re-raise the exception (allowing a caller to handle the exception as well)::
154154

155155
import sys
156156

@@ -162,10 +162,13 @@ the exception (allowing a caller to handle the exception as well)::
162162
print("OS error: {0}".format(err))
163163
except ValueError:
164164
print("Could not convert data to an integer.")
165-
except:
166-
print("Unexpected error:", sys.exc_info()[0])
165+
except BaseException as err:
166+
print(f"Unexpected {err=}, {type(err)=}")
167167
raise
168168

169+
Alternatively the last except clause may omit the exception name(s), however the exception
170+
value must then be retrieved from ``sys.exc_info()[1]``.
171+
169172
The :keyword:`try` ... :keyword:`except` statement has an optional *else
170173
clause*, which, when present, must follow all *except clauses*. It is useful
171174
for code that must be executed if the *try clause* does not raise an exception.
@@ -493,5 +496,3 @@ used in a way that ensures they are always cleaned up promptly and correctly. ::
493496
After the statement is executed, the file *f* is always closed, even if a
494497
problem was encountered while processing the lines. Objects which, like files,
495498
provide predefined clean-up actions will indicate this in their documentation.
496-
497-

Lib/functools.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,84 +88,84 @@ def wraps(wrapped,
8888

8989
def _gt_from_lt(self, other, NotImplemented=NotImplemented):
9090
'Return a > b. Computed by @total_ordering from (not a < b) and (a != b).'
91-
op_result = self.__lt__(other)
91+
op_result = type(self).__lt__(self, other)
9292
if op_result is NotImplemented:
9393
return op_result
9494
return not op_result and self != other
9595

9696
def _le_from_lt(self, other, NotImplemented=NotImplemented):
9797
'Return a <= b. Computed by @total_ordering from (a < b) or (a == b).'
98-
op_result = self.__lt__(other)
98+
op_result = type(self).__lt__(self, other)
9999
if op_result is NotImplemented:
100100
return op_result
101101
return op_result or self == other
102102

103103
def _ge_from_lt(self, other, NotImplemented=NotImplemented):
104104
'Return a >= b. Computed by @total_ordering from (not a < b).'
105-
op_result = self.__lt__(other)
105+
op_result = type(self).__lt__(self, other)
106106
if op_result is NotImplemented:
107107
return op_result
108108
return not op_result
109109

110110
def _ge_from_le(self, other, NotImplemented=NotImplemented):
111111
'Return a >= b. Computed by @total_ordering from (not a <= b) or (a == b).'
112-
op_result = self.__le__(other)
112+
op_result = type(self).__le__(self, other)
113113
if op_result is NotImplemented:
114114
return op_result
115115
return not op_result or self == other
116116

117117
def _lt_from_le(self, other, NotImplemented=NotImplemented):
118118
'Return a < b. Computed by @total_ordering from (a <= b) and (a != b).'
119-
op_result = self.__le__(other)
119+
op_result = type(self).__le__(self, other)
120120
if op_result is NotImplemented:
121121
return op_result
122122
return op_result and self != other
123123

124124
def _gt_from_le(self, other, NotImplemented=NotImplemented):
125125
'Return a > b. Computed by @total_ordering from (not a <= b).'
126-
op_result = self.__le__(other)
126+
op_result = type(self).__le__(self, other)
127127
if op_result is NotImplemented:
128128
return op_result
129129
return not op_result
130130

131131
def _lt_from_gt(self, other, NotImplemented=NotImplemented):
132132
'Return a < b. Computed by @total_ordering from (not a > b) and (a != b).'
133-
op_result = self.__gt__(other)
133+
op_result = type(self).__gt__(self, other)
134134
if op_result is NotImplemented:
135135
return op_result
136136
return not op_result and self != other
137137

138138
def _ge_from_gt(self, other, NotImplemented=NotImplemented):
139139
'Return a >= b. Computed by @total_ordering from (a > b) or (a == b).'
140-
op_result = self.__gt__(other)
140+
op_result = type(self).__gt__(self, other)
141141
if op_result is NotImplemented:
142142
return op_result
143143
return op_result or self == other
144144

145145
def _le_from_gt(self, other, NotImplemented=NotImplemented):
146146
'Return a <= b. Computed by @total_ordering from (not a > b).'
147-
op_result = self.__gt__(other)
147+
op_result = type(self).__gt__(self, other)
148148
if op_result is NotImplemented:
149149
return op_result
150150
return not op_result
151151

152152
def _le_from_ge(self, other, NotImplemented=NotImplemented):
153153
'Return a <= b. Computed by @total_ordering from (not a >= b) or (a == b).'
154-
op_result = self.__ge__(other)
154+
op_result = type(self).__ge__(self, other)
155155
if op_result is NotImplemented:
156156
return op_result
157157
return not op_result or self == other
158158

159159
def _gt_from_ge(self, other, NotImplemented=NotImplemented):
160160
'Return a > b. Computed by @total_ordering from (a >= b) and (a != b).'
161-
op_result = self.__ge__(other)
161+
op_result = type(self).__ge__(self, other)
162162
if op_result is NotImplemented:
163163
return op_result
164164
return op_result and self != other
165165

166166
def _lt_from_ge(self, other, NotImplemented=NotImplemented):
167167
'Return a < b. Computed by @total_ordering from (not a >= b).'
168-
op_result = self.__ge__(other)
168+
op_result = type(self).__ge__(self, other)
169169
if op_result is NotImplemented:
170170
return op_result
171171
return not op_result

Lib/os.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,8 +461,7 @@ def fwalk(top=".", topdown=True, onerror=None, *, follow_symlinks=False, dir_fd=
461461
dirs.remove('CVS') # don't visit CVS directories
462462
"""
463463
sys.audit("os.fwalk", top, topdown, onerror, follow_symlinks, dir_fd)
464-
if not isinstance(top, int) or not hasattr(top, '__index__'):
465-
top = fspath(top)
464+
top = fspath(top)
466465
# Note: To guard against symlink races, we use the standard
467466
# lstat()/open()/fstat() trick.
468467
if not follow_symlinks:

Lib/sqlite3/test/dbapi.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import threading
2727
import unittest
2828

29-
from test.support import check_disallow_instantiation, threading_helper
29+
from test.support import check_disallow_instantiation, threading_helper, bigmemtest
3030
from test.support.os_helper import TESTFN, unlink
3131

3232

@@ -758,9 +758,35 @@ def test_script_error_normal(self):
758758
def test_cursor_executescript_as_bytes(self):
759759
con = sqlite.connect(":memory:")
760760
cur = con.cursor()
761-
with self.assertRaises(ValueError) as cm:
761+
with self.assertRaises(TypeError):
762762
cur.executescript(b"create table test(foo); insert into test(foo) values (5);")
763-
self.assertEqual(str(cm.exception), 'script argument must be unicode.')
763+
764+
def test_cursor_executescript_with_null_characters(self):
765+
con = sqlite.connect(":memory:")
766+
cur = con.cursor()
767+
with self.assertRaises(ValueError):
768+
cur.executescript("""
769+
create table a(i);\0
770+
insert into a(i) values (5);
771+
""")
772+
773+
def test_cursor_executescript_with_surrogates(self):
774+
con = sqlite.connect(":memory:")
775+
cur = con.cursor()
776+
with self.assertRaises(UnicodeEncodeError):
777+
cur.executescript("""
778+
create table a(s);
779+
insert into a(s) values ('\ud8ff');
780+
""")
781+
782+
@unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
783+
@bigmemtest(size=2**31, memuse=3, dry_run=False)
784+
def test_cursor_executescript_too_large_script(self, maxsize):
785+
con = sqlite.connect(":memory:")
786+
cur = con.cursor()
787+
for size in 2**31-1, 2**31:
788+
with self.assertRaises(sqlite.DataError):
789+
cur.executescript("create table a(s);".ljust(size))
764790

765791
def test_connection_execute(self):
766792
con = sqlite.connect(":memory:")
@@ -969,6 +995,7 @@ def suite():
969995
CursorTests,
970996
ExtensionTests,
971997
ModuleTests,
998+
OpenTests,
972999
SqliteOnConflictTests,
9731000
ThreadTests,
9741001
UninitialisedConnectionTests,

Lib/sqlite3/test/hooks.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import sqlite3 as sqlite
2525

2626
from test.support.os_helper import TESTFN, unlink
27-
27+
from .userfunctions import with_tracebacks
2828

2929
class CollationTests(unittest.TestCase):
3030
def test_create_collation_not_string(self):
@@ -145,7 +145,6 @@ def progress():
145145
""")
146146
self.assertTrue(progress_calls)
147147

148-
149148
def test_opcode_count(self):
150149
"""
151150
Test that the opcode argument is respected.
@@ -198,6 +197,32 @@ def progress():
198197
con.execute("select 1 union select 2 union select 3").fetchall()
199198
self.assertEqual(action, 0, "progress handler was not cleared")
200199

200+
@with_tracebacks(['bad_progress', 'ZeroDivisionError'])
201+
def test_error_in_progress_handler(self):
202+
con = sqlite.connect(":memory:")
203+
def bad_progress():
204+
1 / 0
205+
con.set_progress_handler(bad_progress, 1)
206+
with self.assertRaises(sqlite.OperationalError):
207+
con.execute("""
208+
create table foo(a, b)
209+
""")
210+
211+
@with_tracebacks(['__bool__', 'ZeroDivisionError'])
212+
def test_error_in_progress_handler_result(self):
213+
con = sqlite.connect(":memory:")
214+
class BadBool:
215+
def __bool__(self):
216+
1 / 0
217+
def bad_progress():
218+
return BadBool()
219+
con.set_progress_handler(bad_progress, 1)
220+
with self.assertRaises(sqlite.OperationalError):
221+
con.execute("""
222+
create table foo(a, b)
223+
""")
224+
225+
201226
class TraceCallbackTests(unittest.TestCase):
202227
def test_trace_callback_used(self):
203228
"""

Lib/sqlite3/test/regression.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
# 3. This notice may not be removed or altered from any source distribution.
2222

2323
import datetime
24+
import sys
2425
import unittest
2526
import sqlite3 as sqlite
2627
import weakref
@@ -273,7 +274,7 @@ def test_connection_call(self):
273274
Call a connection with a non-string SQL request: check error handling
274275
of the statement constructor.
275276
"""
276-
self.assertRaises(TypeError, self.con, 1)
277+
self.assertRaises(TypeError, self.con, b"select 1")
277278

278279
def test_collation(self):
279280
def collation_cb(a, b):
@@ -344,6 +345,26 @@ def test_null_character(self):
344345
self.assertRaises(ValueError, cur.execute, " \0select 2")
345346
self.assertRaises(ValueError, cur.execute, "select 2\0")
346347

348+
def test_surrogates(self):
349+
con = sqlite.connect(":memory:")
350+
self.assertRaises(UnicodeEncodeError, con, "select '\ud8ff'")
351+
self.assertRaises(UnicodeEncodeError, con, "select '\udcff'")
352+
cur = con.cursor()
353+
self.assertRaises(UnicodeEncodeError, cur.execute, "select '\ud8ff'")
354+
self.assertRaises(UnicodeEncodeError, cur.execute, "select '\udcff'")
355+
356+
@unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
357+
@support.bigmemtest(size=2**31, memuse=4, dry_run=False)
358+
def test_large_sql(self, maxsize):
359+
# Test two cases: size+1 > INT_MAX and size+1 <= INT_MAX.
360+
for size in (2**31, 2**31-2):
361+
con = sqlite.connect(":memory:")
362+
sql = "select 1".ljust(size)
363+
self.assertRaises(sqlite.DataError, con, sql)
364+
cur = con.cursor()
365+
self.assertRaises(sqlite.DataError, cur.execute, sql)
366+
del sql
367+
347368
def test_commit_cursor_reset(self):
348369
"""
349370
Connection.commit() did reset cursors, which made sqlite3

0 commit comments

Comments
 (0)