Skip to content

Commit ed63156

Browse files
committed
Merge upstream/main
Resolved conflict in Lib/profiling/sampling/sample.py by keeping only the BinaryCollector import which is still used in the file.
2 parents f88c01f + 487e91c commit ed63156

27 files changed

+302
-112
lines changed

Doc/library/datetime.rst

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2651,9 +2651,42 @@ Broadly speaking, ``d.strftime(fmt)`` acts like the :mod:`time` module's
26512651
``time.strftime(fmt, d.timetuple())`` although not all objects support a
26522652
:meth:`~date.timetuple` method.
26532653

2654-
For the :meth:`.datetime.strptime` class method, the default value is
2655-
``1900-01-01T00:00:00.000``: any components not specified in the format string
2656-
will be pulled from the default value. [#]_
2654+
For the :meth:`.datetime.strptime` and :meth:`.date.strptime` class methods,
2655+
the default value is ``1900-01-01T00:00:00.000``: any components not specified
2656+
in the format string will be pulled from the default value.
2657+
2658+
.. note::
2659+
When used to parse partial dates lacking a year, :meth:`.datetime.strptime`
2660+
and :meth:`.date.strptime` will raise when encountering February 29 because
2661+
the default year of 1900 is *not* a leap year. Always add a default leap
2662+
year to partial date strings before parsing.
2663+
2664+
2665+
.. testsetup::
2666+
2667+
# doctest seems to turn the warning into an error which makes it
2668+
# show up and require matching and prevents the actual interesting
2669+
# exception from being raised.
2670+
# Manually apply the catch_warnings context manager
2671+
import warnings
2672+
catch_warnings = warnings.catch_warnings()
2673+
catch_warnings.__enter__()
2674+
warnings.simplefilter("ignore")
2675+
2676+
.. testcleanup::
2677+
2678+
catch_warnings.__exit__()
2679+
2680+
.. doctest::
2681+
2682+
>>> from datetime import datetime
2683+
>>> value = "2/29"
2684+
>>> datetime.strptime(value, "%m/%d")
2685+
Traceback (most recent call last):
2686+
...
2687+
ValueError: day 29 must be in range 1..28 for month 2 in year 1900
2688+
>>> datetime.strptime(f"1904 {value}", "%Y %m/%d")
2689+
datetime.datetime(1904, 2, 29, 0, 0)
26572690

26582691
Using ``datetime.strptime(date_string, format)`` is equivalent to::
26592692

@@ -2790,7 +2823,7 @@ Notes:
27902823
include a year in the format. If the value you need to parse lacks a year,
27912824
append an explicit dummy leap year. Otherwise your code will raise an
27922825
exception when it encounters leap day because the default year used by the
2793-
parser is not a leap year. Users run into this bug every four years...
2826+
parser (1900) is not a leap year. Users run into that bug every leap year.
27942827

27952828
.. doctest::
27962829

@@ -2817,5 +2850,3 @@ Notes:
28172850
.. [#] See R. H. van Gent's `guide to the mathematics of the ISO 8601 calendar
28182851
<https://web.archive.org/web/20220531051136/https://webspace.science.uu.nl/~gent0113/calendar/isocalendar.htm>`_
28192852
for a good explanation.
2820-
2821-
.. [#] Passing ``datetime.strptime('Feb 29', '%b %d')`` will fail since 1900 is not a leap year.

Doc/library/pdb.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,8 @@ can be overridden by the local file.
520520
To remove all commands from a breakpoint, type ``commands`` and follow it
521521
immediately with ``end``; that is, give no commands.
522522

523-
With no *bpnumber* argument, ``commands`` refers to the last breakpoint set.
523+
With no *bpnumber* argument, ``commands`` refers to the most recently set
524+
breakpoint that still exists.
524525

525526
You can use breakpoint commands to start your program up again. Simply use
526527
the :pdbcmd:`continue` command, or :pdbcmd:`step`,

Include/internal/pycore_parser.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@ extern "C" {
1414
#include "pycore_pyarena.h" // PyArena
1515

1616
_Py_DECLARE_STR(empty, "")
17-
#if defined(Py_DEBUG) && defined(Py_GIL_DISABLED)
1817
#define _parser_runtime_state_INIT \
1918
{ \
20-
.mutex = {0}, \
2119
.dummy_name = { \
2220
.kind = Name_kind, \
2321
.v.Name.id = &_Py_STR(empty), \
@@ -28,20 +26,6 @@ _Py_DECLARE_STR(empty, "")
2826
.end_col_offset = 0, \
2927
}, \
3028
}
31-
#else
32-
#define _parser_runtime_state_INIT \
33-
{ \
34-
.dummy_name = { \
35-
.kind = Name_kind, \
36-
.v.Name.id = &_Py_STR(empty), \
37-
.v.Name.ctx = Load, \
38-
.lineno = 1, \
39-
.col_offset = 0, \
40-
.end_lineno = 1, \
41-
.end_col_offset = 0, \
42-
}, \
43-
}
44-
#endif
4529

4630
extern struct _mod* _PyParser_ASTFromString(
4731
const char *str,

Include/internal/pycore_runtime_structs.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,7 @@ struct _fileutils_state {
7777
struct _parser_runtime_state {
7878
#ifdef Py_DEBUG
7979
long memo_statistics[_PYPEGEN_NSTATISTICS];
80-
#ifdef Py_GIL_DISABLED
8180
PyMutex mutex;
82-
#endif
8381
#else
8482
int _not_used;
8583
#endif

Include/internal/pycore_tracemalloc.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ struct _PyTraceMalloc_Config {
2121
} initialized;
2222

2323
/* Is tracemalloc tracing memory allocations?
24-
Variable protected by the TABLES_LOCK(). */
24+
Variable protected by the TABLES_LOCK() and stored atomically.
25+
Atomic store is used so that it can read without locking for the
26+
general case of checking if tracemalloc is enabled.
27+
*/
2528
int tracing;
2629

2730
/* limit of the number of frames in a traceback, 1 by default.

Lib/asyncio/__main__.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,15 @@ def run(self):
8686
global return_code
8787

8888
try:
89-
banner = (
90-
f'asyncio REPL {sys.version} on {sys.platform}\n'
91-
f'Use "await" directly instead of "asyncio.run()".\n'
92-
f'Type "help", "copyright", "credits" or "license" '
93-
f'for more information.\n'
94-
)
95-
96-
console.write(banner)
89+
if not sys.flags.quiet:
90+
banner = (
91+
f'asyncio REPL {sys.version} on {sys.platform}\n'
92+
f'Use "await" directly instead of "asyncio.run()".\n'
93+
f'Type "help", "copyright", "credits" or "license" '
94+
f'for more information.\n'
95+
)
96+
97+
console.write(banner)
9798

9899
if startup_path := os.getenv("PYTHONSTARTUP"):
99100
sys.audit("cpython.run_startup", startup_path)

Lib/pdb.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -391,17 +391,22 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None,
391391
# Read ~/.pdbrc and ./.pdbrc
392392
self.rcLines = []
393393
if readrc:
394+
home_rcfile = os.path.expanduser("~/.pdbrc")
395+
local_rcfile = os.path.abspath(".pdbrc")
396+
394397
try:
395-
with open(os.path.expanduser('~/.pdbrc'), encoding='utf-8') as rcFile:
396-
self.rcLines.extend(rcFile)
397-
except OSError:
398-
pass
399-
try:
400-
with open(".pdbrc", encoding='utf-8') as rcFile:
401-
self.rcLines.extend(rcFile)
398+
with open(home_rcfile, encoding='utf-8') as rcfile:
399+
self.rcLines.extend(rcfile)
402400
except OSError:
403401
pass
404402

403+
if local_rcfile != home_rcfile:
404+
try:
405+
with open(local_rcfile, encoding='utf-8') as rcfile:
406+
self.rcLines.extend(rcfile)
407+
except OSError:
408+
pass
409+
405410
self.commands = {} # associates a command list to breakpoint numbers
406411
self.commands_defining = False # True while in the process of defining
407412
# a command list
@@ -1315,7 +1320,14 @@ def do_commands(self, arg):
13151320
reached.
13161321
"""
13171322
if not arg:
1318-
bnum = len(bdb.Breakpoint.bpbynumber) - 1
1323+
for bp in reversed(bdb.Breakpoint.bpbynumber):
1324+
if bp is None:
1325+
continue
1326+
bnum = bp.number
1327+
break
1328+
else:
1329+
self.error('cannot set commands: no existing breakpoint')
1330+
return
13191331
else:
13201332
try:
13211333
bnum = int(arg)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import locale
2+
3+
4+
def fmt(value: int | float, decimals: int = 1) -> str:
5+
return locale.format_string(f'%.{decimals}f', value, grouping=True)

Lib/profiling/sampling/_heatmap_assets/heatmap.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,10 +577,12 @@ function populateBytecodePanel(panel, button) {
577577
else if (specPct >= 33) specClass = 'medium';
578578

579579
// Build specialization summary
580+
const instruction_word = instructions.length === 1 ? 'instruction' : 'instructions';
581+
const sample_word = totalSamples === 1 ? 'sample' : 'samples';
580582
let html = `<div class="bytecode-spec-summary ${specClass}">
581583
<span class="spec-pct">${specPct}%</span>
582584
<span class="spec-label">specialized</span>
583-
<span class="spec-detail">(${specializedCount}/${instructions.length} instructions, ${specializedSamples.toLocaleString()}/${totalSamples.toLocaleString()} samples)</span>
585+
<span class="spec-detail">(${specializedCount}/${instructions.length} ${instruction_word}, ${specializedSamples.toLocaleString()}/${totalSamples.toLocaleString()} ${sample_word})</span>
584586
</div>`;
585587

586588
html += '<div class="bytecode-header">' +

Lib/profiling/sampling/cli.py

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

33
import argparse
44
import importlib.util
5+
import locale
56
import os
67
import selectors
78
import socket
@@ -673,6 +674,16 @@ def _validate_args(args, parser):
673674

674675
def main():
675676
"""Main entry point for the CLI."""
677+
# Set locale for number formatting, restore on exit
678+
old_locale = locale.setlocale(locale.LC_ALL, None)
679+
locale.setlocale(locale.LC_ALL, "")
680+
try:
681+
_main()
682+
finally:
683+
locale.setlocale(locale.LC_ALL, old_locale)
684+
685+
686+
def _main():
676687
# Create the main parser
677688
parser = argparse.ArgumentParser(
678689
description=_HELP_DESCRIPTION,

0 commit comments

Comments
 (0)