Skip to content

Commit 65000f9

Browse files
authored
Merge branch 'main' into remove-requires-working-socket-from-some-of-test-asyncgen
2 parents 00fce42 + f157485 commit 65000f9

29 files changed

+848
-371
lines changed

Doc/library/calendar.rst

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,46 +146,61 @@ interpreted as prescribed by the ISO 8601 standard. Year 0 is 1 BC, year -1 is
146146
the specified width, representing an empty day. The *weekday* parameter
147147
is unused.
148148

149-
.. method:: formatweek(theweek, w=0)
149+
.. method:: formatweek(theweek, w=0, highlight_day=None)
150150

151151
Return a single week in a string with no newline. If *w* is provided, it
152152
specifies the width of the date columns, which are centered. Depends
153153
on the first weekday as specified in the constructor or set by the
154154
:meth:`setfirstweekday` method.
155155

156+
.. versionchanged:: next
157+
If *highlight_day* is given, this date is highlighted in color.
158+
This can be :ref:`controlled using environment variables
159+
<using-on-controlling-color>`.
160+
161+
156162
.. method:: formatweekday(weekday, width)
157163

158164
Return a string representing the name of a single weekday formatted to
159165
the specified *width*. The *weekday* parameter is an integer representing
160166
the day of the week, where ``0`` is Monday and ``6`` is Sunday.
161167

168+
162169
.. method:: formatweekheader(width)
163170

164171
Return a string containing the header row of weekday names, formatted
165172
with the given *width* for each column. The names depend on the locale
166173
settings and are padded to the specified width.
167174

168-
.. method:: formatmonth(theyear, themonth, w=0, l=0)
175+
176+
.. method:: formatmonth(theyear, themonth, w=0, l=0, highlight_day=None)
169177

170178
Return a month's calendar in a multi-line string. If *w* is provided, it
171179
specifies the width of the date columns, which are centered. If *l* is
172180
given, it specifies the number of lines that each week will use. Depends
173181
on the first weekday as specified in the constructor or set by the
174182
:meth:`setfirstweekday` method.
175183

184+
.. versionchanged:: next
185+
If *highlight_day* is given, this date is highlighted in color.
186+
This can be :ref:`controlled using environment variables
187+
<using-on-controlling-color>`.
188+
189+
176190
.. method:: formatmonthname(theyear, themonth, width=0, withyear=True)
177191

178192
Return a string representing the month's name centered within the
179193
specified *width*. If *withyear* is ``True``, include the year in the
180194
output. The *theyear* and *themonth* parameters specify the year
181195
and month for the name to be formatted respectively.
182196

197+
183198
.. method:: prmonth(theyear, themonth, w=0, l=0)
184199

185200
Print a month's calendar as returned by :meth:`formatmonth`.
186201

187202

188-
.. method:: formatyear(theyear, w=2, l=1, c=6, m=3)
203+
.. method:: formatyear(theyear, w=2, l=1, c=6, m=3, highlight_day=None)
189204

190205
Return a *m*-column calendar for an entire year as a multi-line string.
191206
Optional parameters *w*, *l*, and *c* are for date column width, lines per
@@ -194,6 +209,11 @@ interpreted as prescribed by the ISO 8601 standard. Year 0 is 1 BC, year -1 is
194209
:meth:`setfirstweekday` method. The earliest year for which a calendar
195210
can be generated is platform-dependent.
196211

212+
.. versionchanged:: next
213+
If *highlight_day* is given, this date is highlighted in color.
214+
This can be :ref:`controlled using environment variables
215+
<using-on-controlling-color>`.
216+
197217

198218
.. method:: pryear(theyear, w=2, l=1, c=6, m=3)
199219

@@ -549,7 +569,7 @@ The :mod:`calendar` module defines the following exceptions:
549569

550570
.. _calendar-cli:
551571

552-
Command-Line Usage
572+
Command-line usage
553573
------------------
554574

555575
.. versionadded:: 2.5
@@ -687,6 +707,9 @@ The following options are accepted:
687707
The number of months printed per row.
688708
Defaults to 3.
689709

710+
.. versionchanged:: next
711+
By default, today's date is highlighted in color and can be
712+
:ref:`controlled using environment variables <using-on-controlling-color>`.
690713

691714
*HTML-mode options:*
692715

Doc/library/ctypes.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,6 +2182,28 @@ Utility functions
21822182
.. audit-event:: ctypes.wstring_at ptr,size ctypes.wstring_at
21832183

21842184

2185+
.. function:: memoryview_at(ptr, size, readonly=False)
2186+
2187+
Return a :class:`memoryview` object of length *size* that references memory
2188+
starting at *void \*ptr*.
2189+
2190+
If *readonly* is true, the returned :class:`!memoryview` object can
2191+
not be used to modify the underlying memory.
2192+
(Changes made by other means will still be reflected in the returned
2193+
object.)
2194+
2195+
This function is similar to :func:`string_at` with the key
2196+
difference of not making a copy of the specified memory.
2197+
It is a semantically equivalent (but more efficient) alternative to
2198+
``memoryview((c_byte * size).from_address(ptr))``.
2199+
(While :meth:`~_CData.from_address` only takes integers, *ptr* can also
2200+
be given as a :class:`ctypes.POINTER` or a :func:`~ctypes.byref` object.)
2201+
2202+
.. audit-event:: ctypes.memoryview_at address,size,readonly
2203+
2204+
.. versionadded:: next
2205+
2206+
21852207
.. _ctypes-data-types:
21862208

21872209
Data types

Doc/library/faulthandler.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ Fault handler state
9191
The dump now mentions if a garbage collector collection is running
9292
if *all_threads* is true.
9393

94+
.. versionchanged:: next
95+
Only the current thread is dumped if the :term:`GIL` is disabled to
96+
prevent the risk of data races.
97+
9498
.. function:: disable()
9599

96100
Disable the fault handler: uninstall the signal handlers installed by

Doc/whatsnew/3.14.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,19 @@ ast
296296
* The ``repr()`` output for AST nodes now includes more information.
297297
(Contributed by Tomas R in :gh:`116022`.)
298298

299+
300+
calendar
301+
--------
302+
303+
* By default, today's date is highlighted in color in :mod:`calendar`'s
304+
:ref:`command-line <calendar-cli>` text output.
305+
This can be controlled via the :envvar:`PYTHON_COLORS` environment
306+
variable as well as the canonical |NO_COLOR|_
307+
and |FORCE_COLOR|_ environment variables.
308+
See also :ref:`using-on-controlling-color`.
309+
(Contributed by Hugo van Kemenade in :gh:`128317`.)
310+
311+
299312
concurrent.futures
300313
------------------
301314

@@ -330,6 +343,14 @@ ctypes
330343
* On Windows, the :func:`~ctypes.CopyComPointer` function is now public.
331344
(Contributed by Jun Komoda in :gh:`127275`.)
332345

346+
* :func:`ctypes.memoryview_at` now exists to create a
347+
:class:`memoryview` object that refers to the supplied pointer and
348+
length. This works like :func:`ctypes.string_at` except it avoids a
349+
buffer copy, and is typically useful when implementing pure Python
350+
callback functions that are passed dynamically-sized buffers.
351+
(Contributed by Rian Hunter in :gh:`112018`.)
352+
353+
333354
datetime
334355
--------
335356

Include/cpython/pyerrors.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ PyAPI_FUNC(void) _PyErr_ChainExceptions1(PyObject *);
9494

9595
/* In exceptions.c */
9696

97+
PyAPI_FUNC(int) _PyUnicodeError_GetParams(
98+
PyObject *self,
99+
PyObject **obj, Py_ssize_t *objlen,
100+
Py_ssize_t *start, Py_ssize_t *end,
101+
int as_bytes);
102+
97103
PyAPI_FUNC(PyObject*) PyUnstable_Exc_PrepReraiseStar(
98104
PyObject *orig,
99105
PyObject *excs);

Lib/_colorize.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66

77

88
class ANSIColors:
9+
BACKGROUND_YELLOW = "\x1b[43m"
910
BOLD_GREEN = "\x1b[1;32m"
1011
BOLD_MAGENTA = "\x1b[1;35m"
1112
BOLD_RED = "\x1b[1;31m"
13+
BLACK = "\x1b[30m"
1214
GREEN = "\x1b[32m"
1315
GREY = "\x1b[90m"
1416
MAGENTA = "\x1b[35m"

Lib/calendar.py

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -349,11 +349,27 @@ def formatday(self, day, weekday, width):
349349
s = '%2i' % day # right-align single-digit days
350350
return s.center(width)
351351

352-
def formatweek(self, theweek, width):
352+
def formatweek(self, theweek, width, *, highlight_day=None):
353353
"""
354354
Returns a single week in a string (no newline).
355355
"""
356-
return ' '.join(self.formatday(d, wd, width) for (d, wd) in theweek)
356+
if highlight_day:
357+
from _colorize import get_colors
358+
359+
ansi = get_colors()
360+
highlight = f"{ansi.BLACK}{ansi.BACKGROUND_YELLOW}"
361+
reset = ansi.RESET
362+
else:
363+
highlight = reset = ""
364+
365+
return ' '.join(
366+
(
367+
f"{highlight}{self.formatday(d, wd, width)}{reset}"
368+
if d == highlight_day
369+
else self.formatday(d, wd, width)
370+
)
371+
for (d, wd) in theweek
372+
)
357373

358374
def formatweekday(self, day, width):
359375
"""
@@ -388,10 +404,11 @@ def prmonth(self, theyear, themonth, w=0, l=0):
388404
"""
389405
print(self.formatmonth(theyear, themonth, w, l), end='')
390406

391-
def formatmonth(self, theyear, themonth, w=0, l=0):
407+
def formatmonth(self, theyear, themonth, w=0, l=0, *, highlight_day=None):
392408
"""
393409
Return a month's calendar string (multi-line).
394410
"""
411+
highlight_day = highlight_day.day if highlight_day else None
395412
w = max(2, w)
396413
l = max(1, l)
397414
s = self.formatmonthname(theyear, themonth, 7 * (w + 1) - 1)
@@ -400,11 +417,11 @@ def formatmonth(self, theyear, themonth, w=0, l=0):
400417
s += self.formatweekheader(w).rstrip()
401418
s += '\n' * l
402419
for week in self.monthdays2calendar(theyear, themonth):
403-
s += self.formatweek(week, w).rstrip()
420+
s += self.formatweek(week, w, highlight_day=highlight_day).rstrip()
404421
s += '\n' * l
405422
return s
406423

407-
def formatyear(self, theyear, w=2, l=1, c=6, m=3):
424+
def formatyear(self, theyear, w=2, l=1, c=6, m=3, *, highlight_day=None):
408425
"""
409426
Returns a year's calendar as a multi-line string.
410427
"""
@@ -428,15 +445,24 @@ def formatyear(self, theyear, w=2, l=1, c=6, m=3):
428445
headers = (header for k in months)
429446
a(formatstring(headers, colwidth, c).rstrip())
430447
a('\n'*l)
448+
449+
if highlight_day and highlight_day.month in months:
450+
month_pos = months.index(highlight_day.month)
451+
else:
452+
month_pos = None
453+
431454
# max number of weeks for this row
432455
height = max(len(cal) for cal in row)
433456
for j in range(height):
434457
weeks = []
435-
for cal in row:
458+
for k, cal in enumerate(row):
436459
if j >= len(cal):
437460
weeks.append('')
438461
else:
439-
weeks.append(self.formatweek(cal[j], w))
462+
day = highlight_day.day if k == month_pos else None
463+
weeks.append(
464+
self.formatweek(cal[j], w, highlight_day=day)
465+
)
440466
a(formatstring(weeks, colwidth, c).rstrip())
441467
a('\n' * l)
442468
return ''.join(v)
@@ -765,6 +791,7 @@ def main(args=None):
765791
sys.exit(1)
766792

767793
locale = options.locale, options.encoding
794+
today = datetime.date.today()
768795

769796
if options.type == "html":
770797
if options.month:
@@ -781,7 +808,7 @@ def main(args=None):
781808
optdict = dict(encoding=encoding, css=options.css)
782809
write = sys.stdout.buffer.write
783810
if options.year is None:
784-
write(cal.formatyearpage(datetime.date.today().year, **optdict))
811+
write(cal.formatyearpage(today.year, **optdict))
785812
else:
786813
write(cal.formatyearpage(options.year, **optdict))
787814
else:
@@ -797,10 +824,15 @@ def main(args=None):
797824
if options.month is not None:
798825
_validate_month(options.month)
799826
if options.year is None:
800-
result = cal.formatyear(datetime.date.today().year, **optdict)
827+
optdict["highlight_day"] = today
828+
result = cal.formatyear(today.year, **optdict)
801829
elif options.month is None:
830+
if options.year == today.year:
831+
optdict["highlight_day"] = today
802832
result = cal.formatyear(options.year, **optdict)
803833
else:
834+
if options.year == today.year and options.month == today.month:
835+
optdict["highlight_day"] = today
804836
result = cal.formatmonth(options.year, options.month, **optdict)
805837
write = sys.stdout.write
806838
if options.encoding:

Lib/ctypes/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ def WinError(code=None, descr=None):
524524
# functions
525525

526526
from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
527+
from _ctypes import _memoryview_at_addr
527528

528529
## void *memmove(void *, const void *, size_t);
529530
memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
@@ -549,6 +550,14 @@ def string_at(ptr, size=-1):
549550
Return the byte string at void *ptr."""
550551
return _string_at(ptr, size)
551552

553+
_memoryview_at = PYFUNCTYPE(
554+
py_object, c_void_p, c_ssize_t, c_int)(_memoryview_at_addr)
555+
def memoryview_at(ptr, size, readonly=False):
556+
"""memoryview_at(ptr, size[, readonly]) -> memoryview
557+
558+
Return a memoryview representing the memory at void *ptr."""
559+
return _memoryview_at(ptr, size, bool(readonly))
560+
552561
try:
553562
from _ctypes import _wstring_at_addr
554563
except ImportError:

0 commit comments

Comments
 (0)