Skip to content

Commit

Permalink
Merge branch 'main' into RotatingFileHandler-empty-rollover
Browse files Browse the repository at this point in the history
  • Loading branch information
serhiy-storchaka committed Aug 7, 2024
2 parents 2696138 + 3e753c6 commit 29f5b2b
Show file tree
Hide file tree
Showing 19 changed files with 241 additions and 91 deletions.
5 changes: 3 additions & 2 deletions Doc/library/stdtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1245,8 +1245,9 @@ accepts integers that meet the value restriction ``0 <= x <= 255``).
| ``s.pop()`` or ``s.pop(i)`` | retrieves the item at *i* and | \(2) |
| | also removes it from *s* | |
+------------------------------+--------------------------------+---------------------+
| ``s.remove(x)`` | remove the first item from *s* | \(3) |
| | where ``s[i]`` is equal to *x* | |
| ``s.remove(x)`` | removes the first item from | \(3) |
| | *s* where ``s[i]`` is equal to | |
| | *x* | |
+------------------------------+--------------------------------+---------------------+
| ``s.reverse()`` | reverses the items of *s* in | \(4) |
| | place | |
Expand Down
16 changes: 10 additions & 6 deletions Doc/reference/datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,16 @@ that mutable object is changed.
Types affect almost all aspects of object behavior. Even the importance of
object identity is affected in some sense: for immutable types, operations that
compute new values may actually return a reference to any existing object with
the same type and value, while for mutable objects this is not allowed. E.g.,
after ``a = 1; b = 1``, ``a`` and ``b`` may or may not refer to the same object
with the value one, depending on the implementation, but after ``c = []; d =
[]``, ``c`` and ``d`` are guaranteed to refer to two different, unique, newly
created empty lists. (Note that ``c = d = []`` assigns the same object to both
``c`` and ``d``.)
the same type and value, while for mutable objects this is not allowed.
For example, after ``a = 1; b = 1``, *a* and *b* may or may not refer to
the same object with the value one, depending on the implementation.
This is because :class:`int` is an immutable type, so the reference to ``1``
can be reused. This behaviour depends on the implementation used, so should
not be relied upon, but is something to be aware of when making use of object
identity tests.
However, after ``c = []; d = []``, *c* and *d* are guaranteed to refer to two
different, unique, newly created empty lists. (Note that ``e = f = []`` assigns
the *same* object to both *e* and *f*.)


.. _types:
Expand Down
2 changes: 1 addition & 1 deletion Doc/using/cmdline.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Command line

When invoking Python, you may specify any of these options::

python [-bBdEhiIOqsSuvVWx?] [-c command | -m module-name | script | - ] [args]
python [-bBdEhiIOPqRsSuvVWx?] [-c command | -m module-name | script | - ] [args]

The most common use case is, of course, a simple invocation of a script::

Expand Down
15 changes: 12 additions & 3 deletions Lib/argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,15 +447,24 @@ def _get_actions_usage_parts(self, actions, groups):
parts.append(part)

# group mutually exclusive actions
inserted_separators_indices = set()
for start, end in sorted(inserts, reverse=True):
group = inserts[start, end]
group_parts = [item for item in parts[start:end] if item is not None]
group_size = len(group_parts)
if group.required:
open, close = "()" if len(group_parts) > 1 else ("", "")
open, close = "()" if group_size > 1 else ("", "")
else:
open, close = "[]"
parts[start] = open + " | ".join(group_parts) + close
for i in range(start + 1, end):
group_parts[0] = open + group_parts[0]
group_parts[-1] = group_parts[-1] + close
for i, part in enumerate(group_parts[:-1], start=start):
# insert a separator if not already done in a nested group
if i not in inserted_separators_indices:
parts[i] = part + ' |'
inserted_separators_indices.add(i)
parts[start + group_size - 1] = group_parts[-1]
for i in range(start + group_size, end):
parts[i] = None

# return the usage parts
Expand Down
26 changes: 22 additions & 4 deletions Lib/test/test_argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -2959,12 +2959,12 @@ def get_parser(self, required=None):
]

usage_when_not_required = '''\
usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ]
[--klmno KLMNO | --pqrst PQRST]
usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ] [--klmno KLMNO |
--pqrst PQRST]
'''
usage_when_required = '''\
usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ]
(--klmno KLMNO | --pqrst PQRST)
usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ] (--klmno KLMNO |
--pqrst PQRST)
'''
help = '''\
Expand Down Expand Up @@ -4347,6 +4347,24 @@ def test_nested_mutex_groups(self):
''')
self.assertEqual(parser.format_usage(), usage)

def test_long_mutex_groups_wrap(self):
parser = argparse.ArgumentParser(prog='PROG')
g = parser.add_mutually_exclusive_group()
g.add_argument('--op1', metavar='MET', nargs='?')
g.add_argument('--op2', metavar=('MET1', 'MET2'), nargs='*')
g.add_argument('--op3', nargs='*')
g.add_argument('--op4', metavar=('MET1', 'MET2'), nargs='+')
g.add_argument('--op5', nargs='+')
g.add_argument('--op6', nargs=3)
g.add_argument('--op7', metavar=('MET1', 'MET2', 'MET3'), nargs=3)

usage = textwrap.dedent('''\
usage: PROG [-h] [--op1 [MET] | --op2 [MET1 [MET2 ...]] | --op3 [OP3 ...] |
--op4 MET1 [MET2 ...] | --op5 OP5 [OP5 ...] | --op6 OP6 OP6 OP6 |
--op7 MET1 MET2 MET3]
''')
self.assertEqual(parser.format_usage(), usage)


class TestHelpVariableExpansion(HelpTestCase):
"""Test that variables are expanded properly in help messages"""
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ Michael Ernst
Ben Escoto
Andy Eskilsson
André Espaze
Lucas Esposito
Stefan Esser
Nicolas Estibals
Jonathan Eunice
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix wrapping of long usage text of arguments inside a mutually exclusive
group in :mod:`argparse`.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:mod:`mimetypes` no longer fails when it encounters an inaccessible registry key.
2 changes: 1 addition & 1 deletion Modules/_winapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2803,7 +2803,7 @@ _winapi__mimetypes_read_windows_registry_impl(PyObject *module,
}

err = RegOpenKeyExW(hkcr, ext, 0, KEY_READ, &subkey);
if (err == ERROR_FILE_NOT_FOUND) {
if (err == ERROR_FILE_NOT_FOUND || err == ERROR_ACCESS_DENIED) {
err = ERROR_SUCCESS;
continue;
} else if (err != ERROR_SUCCESS) {
Expand Down
10 changes: 5 additions & 5 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -862,13 +862,14 @@ dummy_func(
PyStackRef_CLOSE(list_st);
}

inst(STORE_SUBSCR_DICT, (unused/1, value, dict_st, sub_st -- )) {
PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st);
inst(STORE_SUBSCR_DICT, (unused/1, value, dict_st, sub -- )) {
PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st);

DEOPT_IF(!PyDict_CheckExact(dict));
STAT_INC(STORE_SUBSCR, hit);
int err = _PyDict_SetItem_Take2((PyDictObject *)dict, sub, PyStackRef_AsPyObjectSteal(value));
int err = _PyDict_SetItem_Take2((PyDictObject *)dict,
PyStackRef_AsPyObjectSteal(sub),
PyStackRef_AsPyObjectSteal(value));
PyStackRef_CLOSE(dict_st);
ERROR_IF(err, error);
}
Expand Down Expand Up @@ -1182,7 +1183,6 @@ dummy_func(
assert(!_PyErr_Occurred(tstate));
}
else {
assert(PyLong_Check(lasti));
_PyErr_SetString(tstate, PyExc_SystemError, "lasti is not an int");
ERROR_NO_POP();
}
Expand Down Expand Up @@ -1424,7 +1424,7 @@ dummy_func(
"no locals found");
ERROR_IF(true, error);
}
locals = PyStackRef_FromPyObjectNew(l);;
locals = PyStackRef_FromPyObjectNew(l);
}

inst(LOAD_FROM_DICT_OR_GLOBALS, (mod_or_class_dict -- v)) {
Expand Down
43 changes: 22 additions & 21 deletions Python/executor_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 29f5b2b

Please sign in to comment.