Skip to content

Commit c95af16

Browse files
authored
Merge branch 'main' into multi_inputs
2 parents 797990a + 3ae67ba commit c95af16

34 files changed

Lines changed: 260 additions & 218 deletions

Doc/library/cmdline.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The following modules have a command-line interface.
1212
* :ref:`compileall <compileall-cli>`
1313
* :mod:`cProfile`: see :ref:`profile <profile-cli>`
1414
* :ref:`dis <dis-cli>`
15-
* :mod:`doctest`
15+
* :ref:`doctest <doctest-cli>`
1616
* :mod:`!encodings.rot_13`
1717
* :mod:`ensurepip`
1818
* :mod:`filecmp`

Doc/library/doctest.rst

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,8 @@ prohibit it by passing ``verbose=False``. In either of those cases,
177177
``sys.argv`` is not examined by :func:`testmod` (so passing ``-v`` or not
178178
has no effect).
179179

180-
There is also a command line shortcut for running :func:`testmod`. You can
181-
instruct the Python interpreter to run the doctest module directly from the
182-
standard library and pass the module name(s) on the command line::
183-
184-
python -m doctest -v example.py
185-
186-
This will import :file:`example.py` as a standalone module and run
187-
:func:`testmod` on it. Note that this may not work correctly if the file is
188-
part of a package and imports other submodules from that package.
180+
There is also a command line shortcut for running :func:`testmod`, see section
181+
:ref:`doctest-cli`.
189182

190183
For more information on :func:`testmod`, see section :ref:`doctest-basic-api`.
191184

@@ -248,16 +241,53 @@ Like :func:`testmod`, :func:`testfile`'s verbosity can be set with the
248241
``-v`` command-line switch or with the optional keyword argument
249242
*verbose*.
250243

251-
There is also a command line shortcut for running :func:`testfile`. You can
252-
instruct the Python interpreter to run the doctest module directly from the
253-
standard library and pass the file name(s) on the command line::
244+
There is also a command line shortcut for running :func:`testfile`, see section
245+
:ref:`doctest-cli`.
254246

255-
python -m doctest -v example.txt
247+
For more information on :func:`testfile`, see section :ref:`doctest-basic-api`.
256248

257-
Because the file name does not end with :file:`.py`, :mod:`doctest` infers that
258-
it must be run with :func:`testfile`, not :func:`testmod`.
259249

260-
For more information on :func:`testfile`, see section :ref:`doctest-basic-api`.
250+
.. _doctest-cli:
251+
252+
Command-line Usage
253+
------------------
254+
255+
The :mod:`doctest` module can be invoked as a script from the command line:
256+
257+
.. code-block:: bash
258+
259+
python -m doctest [-v] [-o OPTION] [-f] file [file ...]
260+
261+
.. program:: doctest
262+
263+
.. option:: -v, --verbose
264+
265+
Detailed report of all examples tried is printed to standard output,
266+
along with assorted summaries at the end::
267+
268+
python -m doctest -v example.py
269+
270+
This will import :file:`example.py` as a standalone module and run
271+
:func:`testmod` on it. Note that this may not work correctly if the
272+
file is part of a package and imports other submodules from that package.
273+
274+
If the file name does not end with :file:`.py`, :mod:`!doctest` infers
275+
that it must be run with :func:`testfile` instead::
276+
277+
python -m doctest -v example.txt
278+
279+
.. option:: -o, --option <option>
280+
281+
Option flags control various aspects of doctest's behavior, see section
282+
:ref:`doctest-options`.
283+
284+
.. versionadded:: 3.4
285+
286+
.. option:: -f, --fail-fast
287+
288+
This is shorthand for ``-o FAIL_FAST``.
289+
290+
.. versionadded:: 3.4
261291

262292

263293
.. _doctest-how-it-works:
@@ -540,9 +570,6 @@ Symbolic names for the flags are supplied as module constants, which can be
540570
The names can also be used in :ref:`doctest directives <doctest-directives>`,
541571
and may be passed to the doctest command line interface via the ``-o`` option.
542572

543-
.. versionadded:: 3.4
544-
The ``-o`` command line option.
545-
546573
The first group of options define test semantics, controlling aspects of how
547574
doctest decides whether actual output matches an example's expected output:
548575

@@ -682,11 +709,6 @@ The second group of options controls how test failures are reported:
682709
1. This flag may be useful during debugging, since examples after the first
683710
failure won't even produce debugging output.
684711

685-
The doctest command line accepts the option ``-f`` as a shorthand for ``-o
686-
FAIL_FAST``.
687-
688-
.. versionadded:: 3.4
689-
690712

691713
.. data:: REPORTING_FLAGS
692714

Doc/library/test.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,9 +1435,12 @@ The :mod:`test.support.os_helper` module provides support for os tests.
14351435
``value``.
14361436

14371437

1438-
.. method:: EnvironmentVarGuard.unset(envvar)
1438+
.. method:: EnvironmentVarGuard.unset(envvar, *others)
14391439

1440-
Temporarily unset the environment variable ``envvar``.
1440+
Temporarily unset one or more environment variables.
1441+
1442+
.. versionchanged:: next
1443+
More than one environment variable can be unset.
14411444

14421445

14431446
.. function:: can_symlink()

Doc/library/winsound.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,13 @@ provided by Windows platforms. It includes functions and several constants.
135135
This flag is not supported on modern Windows platforms.
136136

137137

138+
.. data:: SND_APPLICATION
139+
140+
The *sound* parameter is an application-specific alias in the registry.
141+
This flag can be combined with the :const:`SND_ALIAS` flag
142+
to specify an application-defined sound alias.
143+
144+
138145
.. data:: MB_ICONASTERISK
139146

140147
Play the ``SystemDefault`` sound.

Include/cpython/object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ struct _specialization_cache {
256256
// - If getitem is NULL, then getitem_version is meaningless.
257257
// - If getitem->func_version == getitem_version, then getitem can be called
258258
// with two positional arguments and no keyword arguments, and has neither
259-
// *args nor **kwargs (as required by BINARY_SUBSCR_GETITEM):
259+
// *args nor **kwargs (as required by BINARY_OP_SUBSCR_GETITEM):
260260
PyObject *getitem;
261261
uint32_t getitem_version;
262262
PyObject *init;

Include/internal/pycore_code.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,6 @@ typedef struct {
118118

119119
#define INLINE_CACHE_ENTRIES_COMPARE_OP CACHE_ENTRIES(_PyCompareOpCache)
120120

121-
typedef struct {
122-
_Py_BackoffCounter counter;
123-
} _PyBinarySubscrCache;
124-
125-
#define INLINE_CACHE_ENTRIES_BINARY_SUBSCR CACHE_ENTRIES(_PyBinarySubscrCache)
126-
127121
typedef struct {
128122
_Py_BackoffCounter counter;
129123
} _PySuperAttrCache;

InternalDocs/frames.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ to see in an exception traceback.
126126
The `return_offset` field determines where a `RETURN` should go in the caller,
127127
relative to `instr_ptr`. It is only meaningful to the callee, so it needs to
128128
be set in any instruction that implements a call (to a Python function),
129-
including CALL, SEND and BINARY_SUBSCR_GETITEM, among others. If there is no
129+
including CALL, SEND and BINARY_OP_SUBSCR_GETITEM, among others. If there is no
130130
callee, then return_offset is meaningless. It is necessary to have a separate
131131
field for the return offset because (1) if we apply this offset to `instr_ptr`
132132
while executing the `RETURN`, this is too early and would lose us information

InternalDocs/interpreter.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ already points to the next instruction.
112112
Thus, jump instructions can be implemented by manipulating `next_instr`:
113113

114114
- A jump forward (`JUMP_FORWARD`) sets `next_instr += oparg`.
115-
- A jump backward sets `next_instr -= oparg`.
115+
- A jump backward (`JUMP_BACKWARD`) sets `next_instr -= oparg`.
116116

117117
## Inline cache entries
118118

Lib/opcode.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@
6363
"CONTAINS_OP": {
6464
"counter": 1,
6565
},
66-
"BINARY_SUBSCR": {
67-
"counter": 1,
68-
},
6966
"FOR_ITER": {
7067
"counter": 1,
7168
},

Lib/pathlib/__init__.py

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from pathlib._os import (
3030
PathInfo, DirEntryInfo,
3131
ensure_different_files, ensure_distinct_paths,
32-
copy_file, copy_info,
32+
copyfile2, copyfileobj, magic_open, copy_info,
3333
)
3434

3535

@@ -810,12 +810,6 @@ def write_text(self, data, encoding=None, errors=None, newline=None):
810810
with self.open(mode='w', encoding=encoding, errors=errors, newline=newline) as f:
811811
return f.write(data)
812812

813-
def _write_info(self, info, follow_symlinks=True):
814-
"""
815-
Write the given PathInfo to this path.
816-
"""
817-
copy_info(info, self, follow_symlinks=follow_symlinks)
818-
819813
_remove_leading_dot = operator.itemgetter(slice(2, None))
820814
_remove_trailing_slash = operator.itemgetter(slice(-1))
821815

@@ -1100,18 +1094,21 @@ def replace(self, target):
11001094
target = self.with_segments(target)
11011095
return target
11021096

1103-
def copy(self, target, follow_symlinks=True, preserve_metadata=False):
1097+
def copy(self, target, **kwargs):
11041098
"""
11051099
Recursively copy this file or directory tree to the given destination.
11061100
"""
11071101
if not hasattr(target, 'with_segments'):
11081102
target = self.with_segments(target)
11091103
ensure_distinct_paths(self, target)
1110-
copy_file(self, target, follow_symlinks, preserve_metadata)
1104+
try:
1105+
copy_to_target = target._copy_from
1106+
except AttributeError:
1107+
raise TypeError(f"Target path is not writable: {target!r}") from None
1108+
copy_to_target(self, **kwargs)
11111109
return target.joinpath() # Empty join to ensure fresh metadata.
11121110

1113-
def copy_into(self, target_dir, *, follow_symlinks=True,
1114-
preserve_metadata=False):
1111+
def copy_into(self, target_dir, **kwargs):
11151112
"""
11161113
Copy this file or directory tree into the given existing directory.
11171114
"""
@@ -1122,8 +1119,59 @@ def copy_into(self, target_dir, *, follow_symlinks=True,
11221119
target = target_dir / name
11231120
else:
11241121
target = self.with_segments(target_dir, name)
1125-
return self.copy(target, follow_symlinks=follow_symlinks,
1126-
preserve_metadata=preserve_metadata)
1122+
return self.copy(target, **kwargs)
1123+
1124+
def _copy_from(self, source, follow_symlinks=True, preserve_metadata=False):
1125+
"""
1126+
Recursively copy the given path to this path.
1127+
"""
1128+
if not follow_symlinks and source.info.is_symlink():
1129+
self._copy_from_symlink(source, preserve_metadata)
1130+
elif source.info.is_dir():
1131+
children = source.iterdir()
1132+
os.mkdir(self)
1133+
for child in children:
1134+
self.joinpath(child.name)._copy_from(
1135+
child, follow_symlinks, preserve_metadata)
1136+
if preserve_metadata:
1137+
copy_info(source.info, self)
1138+
else:
1139+
self._copy_from_file(source, preserve_metadata)
1140+
1141+
def _copy_from_file(self, source, preserve_metadata=False):
1142+
ensure_different_files(source, self)
1143+
with magic_open(source, 'rb') as source_f:
1144+
with open(self, 'wb') as target_f:
1145+
copyfileobj(source_f, target_f)
1146+
if preserve_metadata:
1147+
copy_info(source.info, self)
1148+
1149+
if copyfile2:
1150+
# Use fast OS routine for local file copying where available.
1151+
_copy_from_file_fallback = _copy_from_file
1152+
def _copy_from_file(self, source, preserve_metadata=False):
1153+
try:
1154+
source = os.fspath(source)
1155+
except TypeError:
1156+
pass
1157+
else:
1158+
copyfile2(source, str(self))
1159+
return
1160+
self._copy_from_file_fallback(source, preserve_metadata)
1161+
1162+
if os.name == 'nt':
1163+
# If a directory-symlink is copied *before* its target, then
1164+
# os.symlink() incorrectly creates a file-symlink on Windows. Avoid
1165+
# this by passing *target_is_dir* to os.symlink() on Windows.
1166+
def _copy_from_symlink(self, source, preserve_metadata=False):
1167+
os.symlink(str(source.readlink()), self, source.info.is_dir())
1168+
if preserve_metadata:
1169+
copy_info(source.info, self, follow_symlinks=False)
1170+
else:
1171+
def _copy_from_symlink(self, source, preserve_metadata=False):
1172+
os.symlink(str(source.readlink()), self)
1173+
if preserve_metadata:
1174+
copy_info(source.info, self, follow_symlinks=False)
11271175

11281176
def move(self, target):
11291177
"""

0 commit comments

Comments
 (0)