Skip to content

Commit 19586a0

Browse files
authored
Merge branch 'main' into remote-debugger-empty-stack-exc
2 parents 6ff8ddc + 8c79678 commit 19586a0

46 files changed

Lines changed: 433 additions & 160 deletions

Some content is hidden

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

Doc/library/argparse.rst

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -637,25 +637,22 @@ are set.
637637

638638
.. versionadded:: 3.14
639639

640-
To highlight inline code in your description or epilog text, you can use
641-
backticks::
640+
To highlight inline code in your description, epilog, or argument ``help``
641+
text, you can use single or double backticks::
642642

643643
>>> parser = argparse.ArgumentParser(
644644
... formatter_class=argparse.RawDescriptionHelpFormatter,
645+
... description='Run ``python -m myapp`` to start.',
645646
... epilog='''Examples:
646647
... `python -m myapp --verbose`
647-
... `python -m myapp --config settings.json`
648+
... ``python -m myapp --config settings.json``
648649
... ''')
650+
>>> parser.add_argument('--foo', help='set the `foo` value')
649651

650652
When colors are enabled, the text inside backticks will be displayed in a
651653
distinct color to help examples stand out. When colors are disabled, backticks
652654
are preserved as-is, which is readable in plain text.
653655

654-
.. note::
655-
656-
Backtick markup only applies to description and epilog text. It does not
657-
apply to individual argument ``help`` strings.
658-
659656
.. versionadded:: 3.15
660657

661658

Doc/whatsnew/3.15.rst

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,47 @@ Improved error messages
492492
^^^^^^^^^^^^^^
493493
AttributeError: 'Container' object has no attribute 'area'. Did you mean '.inner.area' instead of '.area'?
494494
495+
* When an :exc:`AttributeError` on a builtin type has no close match via
496+
Levenshtein distance, the error message now checks a static table of common
497+
method names from other languages (JavaScript, Java, Ruby, C#) and suggests
498+
the Python equivalent:
499+
500+
.. doctest::
501+
502+
>>> [1, 2, 3].push(4) # doctest: +ELLIPSIS
503+
Traceback (most recent call last):
504+
...
505+
AttributeError: 'list' object has no attribute 'push'. Did you mean '.append'?
506+
507+
>>> 'hello'.toUpperCase() # doctest: +ELLIPSIS
508+
Traceback (most recent call last):
509+
...
510+
AttributeError: 'str' object has no attribute 'toUpperCase'. Did you mean '.upper'?
511+
512+
When the Python equivalent is a language construct rather than a method,
513+
the hint describes the construct directly:
514+
515+
.. doctest::
516+
517+
>>> {}.put("a", 1) # doctest: +ELLIPSIS
518+
Traceback (most recent call last):
519+
...
520+
AttributeError: 'dict' object has no attribute 'put'. Use d[k] = v.
521+
522+
When a mutable method is called on an immutable type, the hint suggests
523+
the mutable counterpart:
524+
525+
.. doctest::
526+
527+
>>> (1, 2, 3).append(4) # doctest: +ELLIPSIS
528+
Traceback (most recent call last):
529+
...
530+
AttributeError: 'tuple' object has no attribute 'append'. Did you mean to use a 'list' object?
531+
532+
These hints also work for subclasses of builtin types.
533+
534+
(Contributed by Matt Van Horn in :gh:`146406`.)
535+
495536
* The interpreter now tries to provide a suggestion when
496537
:func:`delattr` fails due to a missing attribute.
497538
When an attribute name that closely resembles an existing attribute is used,
@@ -715,10 +756,14 @@ argparse
715756
default to ``True``. This enables suggestions for mistyped arguments by default.
716757
(Contributed by Jakob Schluse in :gh:`140450`.)
717758

718-
* Added backtick markup support in description and epilog text to highlight
719-
inline code when color output is enabled.
759+
* Added backtick markup support in :class:`~argparse.ArgumentParser` description
760+
and epilog text to highlight inline code when color output is enabled.
720761
(Contributed by Savannah Ostrowski in :gh:`142390`.)
721762

763+
* Extended backtick markup to argument ``help`` text and added support for
764+
double backticks (RST inline-literal style).
765+
(Contributed by Hugo van Kemenade in :gh:`149375`.)
766+
722767

723768
array
724769
-----

Include/internal/pycore_debug_offsets.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,16 @@ typedef struct _Py_DebugOffsets {
158158
uint64_t tp_name;
159159
uint64_t tp_repr;
160160
uint64_t tp_flags;
161+
uint64_t tp_basicsize;
162+
uint64_t tp_dictoffset;
161163
} type_object;
162164

165+
// PyHeapTypeObject offset;
166+
struct _heap_type_object {
167+
uint64_t size;
168+
uint64_t ht_cached_keys;
169+
} heap_type_object;
170+
163171
// PyTuple object offset;
164172
struct _tuple_object {
165173
uint64_t size;
@@ -330,6 +338,12 @@ typedef struct _Py_DebugOffsets {
330338
.tp_name = offsetof(PyTypeObject, tp_name), \
331339
.tp_repr = offsetof(PyTypeObject, tp_repr), \
332340
.tp_flags = offsetof(PyTypeObject, tp_flags), \
341+
.tp_basicsize = offsetof(PyTypeObject, tp_basicsize), \
342+
.tp_dictoffset = offsetof(PyTypeObject, tp_dictoffset), \
343+
}, \
344+
.heap_type_object = { \
345+
.size = sizeof(PyHeapTypeObject), \
346+
.ht_cached_keys = offsetof(PyHeapTypeObject, ht_cached_keys), \
333347
}, \
334348
.tuple_object = { \
335349
.size = sizeof(PyTupleObject), \

Lib/argparse.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -529,16 +529,16 @@ def _apply_text_markup(self, text):
529529
"""Apply color markup to text.
530530
531531
Supported markup:
532-
`...` - inline code (rendered with prog_extra color)
532+
`...` or ``...`` - inline code (rendered with prog_extra color)
533533
534534
When colors are disabled, backticks are preserved as-is.
535535
"""
536536
t = self._theme
537537
if not t.reset:
538538
return text
539539
text = _re.sub(
540-
r'`([^`]+)`',
541-
rf'{t.prog_extra}\1{t.reset}',
540+
r'(`{1,2})([^`]+)\1',
541+
rf'{t.prog_extra}\2{t.reset}',
542542
text,
543543
)
544544
return text
@@ -682,7 +682,7 @@ def _format_args(self, action, default_metavar):
682682
def _expand_help(self, action):
683683
help_string = self._get_help_string(action)
684684
if '%' not in help_string:
685-
return help_string
685+
return self._apply_text_markup(help_string)
686686
params = dict(vars(action), prog=self._prog)
687687
for name in list(params):
688688
value = params[name]
@@ -726,7 +726,9 @@ def colorize(match):
726726
# bare %s etc. - format with full params dict, no colorization
727727
return spec % params
728728

729-
return _re.sub(fmt_spec, colorize, help_string, flags=_re.VERBOSE)
729+
return self._apply_text_markup(
730+
_re.sub(fmt_spec, colorize, help_string, flags=_re.VERBOSE)
731+
)
730732

731733
def _iter_indented_subactions(self, action):
732734
try:
@@ -2758,7 +2760,7 @@ def _check_value(self, action, value):
27582760

27592761
if value not in choices:
27602762
args = {'value': str(value),
2761-
'choices': ', '.join(map(str, action.choices))}
2763+
'choices': ', '.join(repr(str(choice)) for choice in action.choices)}
27622764
msg = _('invalid choice: %(value)r (choose from %(choices)s)')
27632765

27642766
if self.suggest_on_error and isinstance(value, str):

Lib/ast.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ def main(args=None):
666666

667667
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
668668
parser.add_argument('infile', nargs='?', default='-',
669-
help='the file to parse; defaults to stdin')
669+
help='the file to parse; defaults to `stdin`')
670670
parser.add_argument('-m', '--mode', default='exec',
671671
choices=('exec', 'single', 'eval', 'func_type'),
672672
help='specify what kind of code must be parsed')
@@ -679,8 +679,8 @@ def main(args=None):
679679
help='indentation of nodes (number of spaces)')
680680
parser.add_argument('--feature-version',
681681
type=str, default=None, metavar='VERSION',
682-
help='Python version in the format 3.x '
683-
'(for example, 3.10)')
682+
help='Python version in the format `3.x` '
683+
'(for example, `3.10`)')
684684
parser.add_argument('-O', '--optimize',
685685
type=int, default=-1, metavar='LEVEL',
686686
help='optimization level for parser')

Lib/asyncio/__main__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@ def interrupt(self) -> None:
159159
parser = argparse.ArgumentParser(
160160
prog="python3 -m asyncio",
161161
description="Interactive asyncio shell and CLI tools",
162-
color=True,
163162
)
164163
subparsers = parser.add_subparsers(help="sub-commands", dest="command")
165164
ps = subparsers.add_parser(

Lib/calendar.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,7 @@ def main(args=None):
922922
"-t", "--type",
923923
default="text",
924924
choices=("text", "html"),
925-
help="output type (text or html)"
925+
help="output type (`text` or `html`)"
926926
)
927927
parser.add_argument(
928928
"-f", "--first-weekday",

Lib/code.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ def interact(banner=None, readfunc=None, local=None, exitmsg=None, local_exit=Fa
385385
if __name__ == "__main__":
386386
import argparse
387387

388-
parser = argparse.ArgumentParser(color=True)
388+
parser = argparse.ArgumentParser()
389389
parser.add_argument('-q', action='store_true',
390390
help="don't print version and copyright messages")
391391
args = parser.parse_args()

Lib/compileall.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,6 @@ def main():
326326

327327
parser = argparse.ArgumentParser(
328328
description='Utilities to support installing Python libraries.',
329-
color=True,
330329
)
331330
parser.add_argument('-l', action='store_const', const=0,
332331
default=None, dest='maxlevels',
@@ -338,10 +337,10 @@ def main():
338337
parser.add_argument('-f', action='store_true', dest='force',
339338
help='force rebuild even if timestamps are up to date')
340339
parser.add_argument('-q', action='count', dest='quiet', default=0,
341-
help='output only error messages; -qq will suppress '
340+
help='output only error messages; `-qq` will suppress '
342341
'the error messages as well.')
343342
parser.add_argument('-b', action='store_true', dest='legacy',
344-
help='use legacy (pre-PEP3147) compiled file locations')
343+
help='use legacy (pre-PEP 3147) compiled file locations')
345344
parser.add_argument('-d', metavar='DESTDIR', dest='ddir', default=None,
346345
help=('directory to prepend to file paths for use in '
347346
'compile-time tracebacks and in runtime '
@@ -367,28 +366,28 @@ def main():
367366
'of each file considered for compilation'))
368367
parser.add_argument('-i', metavar='FILE', dest='flist',
369368
help=('add all the files and directories listed in '
370-
'FILE to the list considered for compilation; '
371-
'if "-", names are read from stdin'))
369+
'`FILE` to the list considered for compilation; '
370+
'if `"-"`, names are read from `stdin`'))
372371
parser.add_argument('compile_dest', metavar='FILE|DIR', nargs='*',
373372
help=('zero or more file and directory names '
374373
'to compile; if no arguments given, defaults '
375-
'to the equivalent of -l sys.path'))
374+
'to the equivalent of `-l` `sys.path`'))
376375
parser.add_argument('-j', '--workers', default=1,
377376
type=int, help='Run compileall concurrently')
378377
invalidation_modes = [mode.name.lower().replace('_', '-')
379378
for mode in py_compile.PycInvalidationMode]
380379
parser.add_argument('--invalidation-mode',
381380
choices=sorted(invalidation_modes),
382-
help=('set .pyc invalidation mode; defaults to '
383-
'"checked-hash" if the SOURCE_DATE_EPOCH '
381+
help=('set `.pyc` invalidation mode; defaults to '
382+
'`"checked-hash"` if the `SOURCE_DATE_EPOCH` '
384383
'environment variable is set, and '
385-
'"timestamp" otherwise.'))
384+
'`"timestamp"` otherwise.'))
386385
parser.add_argument('-o', action='append', type=int, dest='opt_levels',
387386
help=('Optimization levels to run compilation with. '
388-
'Default is -1 which uses the optimization level '
389-
'of the Python interpreter itself (see -O).'))
387+
'Default is `-1` which uses the optimization level '
388+
'of the Python interpreter itself (see `-O`).'))
390389
parser.add_argument('-e', metavar='DIR', dest='limit_sl_dest',
391-
help='Ignore symlinks pointing outsite of the DIR')
390+
help='Ignore symlinks pointing outsite of the `DIR`')
392391
parser.add_argument('--hardlink-dupes', action='store_true',
393392
dest='hardlink_dupes',
394393
help='Hardlink duplicated pyc files')

Lib/dis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,7 @@ def dis(self):
11461146
def main(args=None):
11471147
import argparse
11481148

1149-
parser = argparse.ArgumentParser(color=True)
1149+
parser = argparse.ArgumentParser()
11501150
parser.add_argument('-C', '--show-caches', action='store_true',
11511151
help='show inline caches')
11521152
parser.add_argument('-O', '--show-offsets', action='store_true',

0 commit comments

Comments
 (0)