Skip to content

Commit 0c3cfa2

Browse files
authored
Merge branch 'main' into 68968-assertEqual
2 parents 42efe70 + 44b5c21 commit 0c3cfa2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+1180
-749
lines changed

.github/workflows/doc.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,26 @@ jobs:
7979
# Build docs with the '-n' (nit-picky) option, convert warnings to errors (-W)
8080
make -C Doc/ PYTHON=../python SPHINXOPTS="-q -n -W --keep-going" html 2>&1
8181
82+
# This build doesn't use problem matchers or check annotations
83+
# It also does not run 'make check', as sphinx-lint is not installed into the
84+
# environment.
85+
build_doc_oldest_supported_sphinx:
86+
name: 'Docs (Oldest Sphinx)'
87+
runs-on: ubuntu-latest
88+
timeout-minutes: 60
89+
steps:
90+
- uses: actions/checkout@v3
91+
- name: 'Set up Python'
92+
uses: actions/setup-python@v4
93+
with:
94+
python-version: '3.11' # known to work with Sphinx 3.2
95+
cache: 'pip'
96+
cache-dependency-path: 'Doc/requirements-oldest-sphinx.txt'
97+
- name: 'Install build dependencies'
98+
run: make -C Doc/ venv REQUIREMENTS="requirements-oldest-sphinx.txt"
99+
- name: 'Build HTML documentation'
100+
run: make -C Doc/ SPHINXOPTS="-q" SPHINXERRORHANDLING="-W --keep-going" html
101+
82102
# Run "doctest" on HEAD as new syntax doesn't exist in the latest stable release
83103
doctest:
84104
name: 'Doctest'

Doc/Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ JOBS = auto
1313
PAPER =
1414
SOURCES =
1515
DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py)
16+
REQUIREMENTS = requirements.txt
1617
SPHINXERRORHANDLING = -W
1718

1819
# Internal variables.
@@ -154,8 +155,8 @@ venv:
154155
echo "To recreate it, remove it first with \`make clean-venv'."; \
155156
else \
156157
$(PYTHON) -m venv $(VENVDIR); \
157-
$(VENVDIR)/bin/python3 -m pip install -U pip setuptools; \
158-
$(VENVDIR)/bin/python3 -m pip install -r requirements.txt; \
158+
$(VENVDIR)/bin/python3 -m pip install --upgrade pip; \
159+
$(VENVDIR)/bin/python3 -m pip install -r $(REQUIREMENTS); \
159160
echo "The venv has been created in the $(VENVDIR) directory"; \
160161
fi
161162

Doc/c-api/unicode.rst

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,15 @@ APIs:
509509
arguments.
510510
511511
512+
.. c:function:: PyObject* PyUnicode_FromObject(PyObject *obj)
513+
514+
Copy an instance of a Unicode subtype to a new true Unicode object if
515+
necessary. If *obj* is already a true Unicode object (not a subtype),
516+
return the reference with incremented refcount.
517+
518+
Objects other than Unicode or its subtypes will cause a :exc:`TypeError`.
519+
520+
512521
.. c:function:: PyObject* PyUnicode_FromEncodedObject(PyObject *obj, \
513522
const char *encoding, const char *errors)
514523
@@ -616,15 +625,6 @@ APIs:
616625
.. versionadded:: 3.3
617626
618627
619-
.. c:function:: PyObject* PyUnicode_FromObject(PyObject *obj)
620-
621-
Copy an instance of a Unicode subtype to a new true Unicode object if
622-
necessary. If *obj* is already a true Unicode object (not a subtype),
623-
return the reference with incremented refcount.
624-
625-
Objects other than Unicode or its subtypes will cause a :exc:`TypeError`.
626-
627-
628628
Locale Encoding
629629
"""""""""""""""
630630

Doc/library/datetime.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,10 @@ Other constructors, all class methods:
896896
in UTC. As such, the recommended way to create an object representing the
897897
current time in UTC is by calling ``datetime.now(timezone.utc)``.
898898

899+
.. deprecated:: 3.12
900+
901+
Use :meth:`datetime.now` with :attr:`UTC` instead.
902+
899903

900904
.. classmethod:: datetime.fromtimestamp(timestamp, tz=None)
901905

@@ -964,6 +968,10 @@ Other constructors, all class methods:
964968
:c:func:`gmtime` function. Raise :exc:`OSError` instead of
965969
:exc:`ValueError` on :c:func:`gmtime` failure.
966970

971+
.. deprecated:: 3.12
972+
973+
Use :meth:`datetime.fromtimestamp` with :attr:`UTC` instead.
974+
967975

968976
.. classmethod:: datetime.fromordinal(ordinal)
969977

Doc/library/sqlite3.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ Module functions
310310
to avoid data corruption.
311311
See :attr:`threadsafety` for more information.
312312

313-
:param Connection factory:
313+
:param ~sqlite3.Connection factory:
314314
A custom subclass of :class:`Connection` to create the connection with,
315315
if not the default :class:`Connection` class.
316316

@@ -337,7 +337,7 @@ Module functions
337337
The default will change to ``False`` in a future Python release.
338338
:type autocommit: bool
339339

340-
:rtype: Connection
340+
:rtype: ~sqlite3.Connection
341341

342342
.. audit-event:: sqlite3.connect database sqlite3.connect
343343
.. audit-event:: sqlite3.connect/handle connection_handle sqlite3.connect
@@ -1129,7 +1129,7 @@ Connection objects
11291129
Works even if the database is being accessed by other clients
11301130
or concurrently by the same connection.
11311131

1132-
:param Connection target:
1132+
:param ~sqlite3.Connection target:
11331133
The database connection to save the backup to.
11341134

11351135
:param int pages:

Doc/library/unittest.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2281,7 +2281,8 @@ Loading and running tests
22812281

22822282
The *testRunner* argument can either be a test runner class or an already
22832283
created instance of it. By default ``main`` calls :func:`sys.exit` with
2284-
an exit code indicating success or failure of the tests run.
2284+
an exit code indicating success (0) or failure (1) of the tests run.
2285+
An exit code of 5 indicates that no tests were run.
22852286

22862287
The *testLoader* argument has to be a :class:`TestLoader` instance,
22872288
and defaults to :data:`defaultTestLoader`.

Doc/requirements-oldest-sphinx.txt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Requirements to build the Python documentation, for the oldest supported
2+
# Sphinx version.
3+
#
4+
# We pin Sphinx and all of its dependencies to ensure a consistent environment.
5+
6+
blurb
7+
python-docs-theme>=2022.1
8+
9+
# Generated from:
10+
# pip install "Sphinx~=3.2.0" "docutils<0.17" "Jinja2<3" "MarkupSafe<2"
11+
# pip freeze
12+
#
13+
# Sphinx 3.2 comes from ``needs_sphinx = '3.2'`` in ``Doc/conf.py``.
14+
# Docutils<0.17, Jinja2<3, and MarkupSafe<2 are additionally specified as
15+
# Sphinx 3.2 is incompatible with newer releases of these packages.
16+
17+
Sphinx==3.2.1
18+
alabaster==0.7.13
19+
Babel==2.12.1
20+
certifi==2022.12.7
21+
charset-normalizer==3.1.0
22+
colorama==0.4.6
23+
docutils==0.16
24+
idna==3.4
25+
imagesize==1.4.1
26+
Jinja2==2.11.3
27+
MarkupSafe==1.1.1
28+
packaging==23.1
29+
Pygments==2.15.1
30+
requests==2.29.0
31+
snowballstemmer==2.2.0
32+
sphinxcontrib-applehelp==1.0.4
33+
sphinxcontrib-devhelp==1.0.2
34+
sphinxcontrib-htmlhelp==2.0.1
35+
sphinxcontrib-jsmath==1.0.1
36+
sphinxcontrib-qthelp==1.0.3
37+
sphinxcontrib-serializinghtml==1.1.5
38+
urllib3==1.26.15

Doc/whatsnew/3.12.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,11 @@ Other Language Changes
237237
wrapped by a :exc:`RuntimeError`. Context information is added to the
238238
exception as a :pep:`678` note. (Contributed by Irit Katriel in :gh:`77757`.)
239239

240+
* When a ``try-except*`` construct handles the entire :exc:`ExceptionGroup`
241+
and raises one other exception, that exception is no longer wrapped in an
242+
:exc:`ExceptionGroup`. (Contributed by Irit Katriel in :gh:`103590`.)
243+
244+
240245
New Modules
241246
===========
242247

Grammar/python.gram

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -881,14 +881,13 @@ fstring_middle[expr_ty]:
881881
| fstring_replacement_field
882882
| t=FSTRING_MIDDLE { _PyPegen_constant_from_token(p, t) }
883883
fstring_replacement_field[expr_ty]:
884-
| '{' a=(yield_expr | star_expressions) debug_expr="="? conversion=[fstring_conversion] format=[fstring_full_format_spec] '}' {
885-
_PyPegen_formatted_value(p, a, debug_expr, conversion, format, EXTRA)
886-
}
884+
| '{' a=(yield_expr | star_expressions) debug_expr="="? conversion=[fstring_conversion] format=[fstring_full_format_spec] rbrace='}' {
885+
_PyPegen_formatted_value(p, a, debug_expr, conversion, format, rbrace, EXTRA) }
887886
| invalid_replacement_field
888-
fstring_conversion[expr_ty]:
887+
fstring_conversion[ResultTokenWithMetadata*]:
889888
| conv_token="!" conv=NAME { _PyPegen_check_fstring_conversion(p, conv_token, conv) }
890-
fstring_full_format_spec[expr_ty]:
891-
| ':' spec=fstring_format_spec* { spec ? _PyAST_JoinedStr((asdl_expr_seq*)spec, EXTRA) : NULL }
889+
fstring_full_format_spec[ResultTokenWithMetadata*]:
890+
| colon=':' spec=fstring_format_spec* { _PyPegen_setup_full_format_spec(p, colon, (asdl_expr_seq *) spec, EXTRA) }
892891
fstring_format_spec[expr_ty]:
893892
| t=FSTRING_MIDDLE { _PyPegen_constant_from_token(p, t) }
894893
| fstring_replacement_field

Include/internal/pycore_fileutils_windows.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,24 @@ static inline BOOL _Py_GetFileInformationByName(
7575
return GetFileInformationByName(FileName, FileInformationClass, FileInfoBuffer, FileInfoBufferSize);
7676
}
7777

78+
static inline BOOL _Py_GetFileInformationByName_ErrorIsTrustworthy(int error)
79+
{
80+
switch(error) {
81+
case ERROR_FILE_NOT_FOUND:
82+
case ERROR_PATH_NOT_FOUND:
83+
case ERROR_NOT_READY:
84+
case ERROR_BAD_NET_NAME:
85+
case ERROR_BAD_NETPATH:
86+
case ERROR_BAD_PATHNAME:
87+
case ERROR_INVALID_NAME:
88+
case ERROR_FILENAME_EXCED_RANGE:
89+
return TRUE;
90+
case ERROR_NOT_SUPPORTED:
91+
return FALSE;
92+
}
93+
return FALSE;
94+
}
95+
7896
#endif
7997

8098
#endif

Lib/_strptime.py

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -290,22 +290,6 @@ def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon):
290290
return 1 + days_to_week + day_of_week
291291

292292

293-
def _calc_julian_from_V(iso_year, iso_week, iso_weekday):
294-
"""Calculate the Julian day based on the ISO 8601 year, week, and weekday.
295-
ISO weeks start on Mondays, with week 01 being the week containing 4 Jan.
296-
ISO week days range from 1 (Monday) to 7 (Sunday).
297-
"""
298-
correction = datetime_date(iso_year, 1, 4).isoweekday() + 3
299-
ordinal = (iso_week * 7) + iso_weekday - correction
300-
# ordinal may be negative or 0 now, which means the date is in the previous
301-
# calendar year
302-
if ordinal < 1:
303-
ordinal += datetime_date(iso_year, 1, 1).toordinal()
304-
iso_year -= 1
305-
ordinal -= datetime_date(iso_year, 1, 1).toordinal()
306-
return iso_year, ordinal
307-
308-
309293
def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
310294
"""Return a 2-tuple consisting of a time struct and an int containing
311295
the number of microseconds based on the input string and the
@@ -483,7 +467,8 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
483467
else:
484468
tz = value
485469
break
486-
# Deal with the cases where ambiguities arize
470+
471+
# Deal with the cases where ambiguities arise
487472
# don't assume default values for ISO week/year
488473
if year is None and iso_year is not None:
489474
if iso_week is None or weekday is None:
@@ -511,7 +496,6 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
511496
elif year is None:
512497
year = 1900
513498

514-
515499
# If we know the week of the year and what day of that week, we can figure
516500
# out the Julian day of the year.
517501
if julian is None and weekday is not None:
@@ -520,7 +504,10 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
520504
julian = _calc_julian_from_U_or_W(year, week_of_year, weekday,
521505
week_starts_Mon)
522506
elif iso_year is not None and iso_week is not None:
523-
year, julian = _calc_julian_from_V(iso_year, iso_week, weekday + 1)
507+
datetime_result = datetime_date.fromisocalendar(iso_year, iso_week, weekday + 1)
508+
year = datetime_result.year
509+
month = datetime_result.month
510+
day = datetime_result.day
524511
if julian is not None and julian <= 0:
525512
year -= 1
526513
yday = 366 if calendar.isleap(year) else 365

Lib/asyncio/selector_events.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,8 @@ def __init__(self, loop, sock, protocol, extra=None, server=None):
794794
self._buffer = collections.deque()
795795
self._conn_lost = 0 # Set when call to connection_lost scheduled.
796796
self._closing = False # Set when close() called.
797+
self._paused = False # Set when pause_reading() called
798+
797799
if self._server is not None:
798800
self._server._attach()
799801
loop._transports[self._sock_fd] = self
@@ -839,6 +841,25 @@ def get_protocol(self):
839841
def is_closing(self):
840842
return self._closing
841843

844+
def is_reading(self):
845+
return not self.is_closing() and not self._paused
846+
847+
def pause_reading(self):
848+
if not self.is_reading():
849+
return
850+
self._paused = True
851+
self._loop._remove_reader(self._sock_fd)
852+
if self._loop.get_debug():
853+
logger.debug("%r pauses reading", self)
854+
855+
def resume_reading(self):
856+
if self._closing or not self._paused:
857+
return
858+
self._paused = False
859+
self._add_reader(self._sock_fd, self._read_ready)
860+
if self._loop.get_debug():
861+
logger.debug("%r resumes reading", self)
862+
842863
def close(self):
843864
if self._closing:
844865
return
@@ -898,9 +919,8 @@ def get_write_buffer_size(self):
898919
return sum(map(len, self._buffer))
899920

900921
def _add_reader(self, fd, callback, *args):
901-
if self._closing:
922+
if not self.is_reading():
902923
return
903-
904924
self._loop._add_reader(fd, callback, *args)
905925

906926

@@ -915,7 +935,6 @@ def __init__(self, loop, sock, protocol, waiter=None,
915935
self._read_ready_cb = None
916936
super().__init__(loop, sock, protocol, extra, server)
917937
self._eof = False
918-
self._paused = False
919938
self._empty_waiter = None
920939
if _HAS_SENDMSG:
921940
self._write_ready = self._write_sendmsg
@@ -943,25 +962,6 @@ def set_protocol(self, protocol):
943962

944963
super().set_protocol(protocol)
945964

946-
def is_reading(self):
947-
return not self._paused and not self._closing
948-
949-
def pause_reading(self):
950-
if self._closing or self._paused:
951-
return
952-
self._paused = True
953-
self._loop._remove_reader(self._sock_fd)
954-
if self._loop.get_debug():
955-
logger.debug("%r pauses reading", self)
956-
957-
def resume_reading(self):
958-
if self._closing or not self._paused:
959-
return
960-
self._paused = False
961-
self._add_reader(self._sock_fd, self._read_ready)
962-
if self._loop.get_debug():
963-
logger.debug("%r resumes reading", self)
964-
965965
def _read_ready(self):
966966
self._read_ready_cb()
967967

Lib/asyncio/unix_events.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,13 +485,21 @@ def __init__(self, loop, pipe, protocol, waiter=None, extra=None):
485485

486486
self._loop.call_soon(self._protocol.connection_made, self)
487487
# only start reading when connection_made() has been called
488-
self._loop.call_soon(self._loop._add_reader,
488+
self._loop.call_soon(self._add_reader,
489489
self._fileno, self._read_ready)
490490
if waiter is not None:
491491
# only wake up the waiter when connection_made() has been called
492492
self._loop.call_soon(futures._set_result_unless_cancelled,
493493
waiter, None)
494494

495+
def _add_reader(self, fd, callback):
496+
if not self.is_reading():
497+
return
498+
self._loop._add_reader(fd, callback)
499+
500+
def is_reading(self):
501+
return not self._paused and not self._closing
502+
495503
def __repr__(self):
496504
info = [self.__class__.__name__]
497505
if self._pipe is None:
@@ -532,7 +540,7 @@ def _read_ready(self):
532540
self._loop.call_soon(self._call_connection_lost, None)
533541

534542
def pause_reading(self):
535-
if self._closing or self._paused:
543+
if not self.is_reading():
536544
return
537545
self._paused = True
538546
self._loop._remove_reader(self._fileno)

0 commit comments

Comments
 (0)