Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Doc/library/urllib.request.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,10 @@ AbstractBasicAuthHandler Objects
authenticate for, *req* should be the (failed) :class:`Request` object, and
*headers* should be the error headers.

*headers* must be a mapping-like object with case-insensitive lookup
that implements the ``get_all()`` method,
such as :class:`email.message.Message` or :class:`wsgiref.headers.Headers`.

*host* is either an authority (e.g. ``"python.org"``) or a URL containing an
authority component (e.g. ``"https://python.org/"``). In either case, the
authority must not contain a userinfo component (so, ``"python.org"`` and
Expand Down Expand Up @@ -1097,6 +1101,9 @@ AbstractDigestAuthHandler Objects
should be the (failed) :class:`Request` object, and *headers* should be the
error headers.

*headers* must be a mapping-like object with case-insensitive lookup,
such as :class:`email.message.Message` or :class:`wsgiref.headers.Headers`.


.. _http-digest-auth-handler:

Expand Down
2 changes: 1 addition & 1 deletion Include/internal/pycore_interpframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ _PyFrame_GetFrameObject(_PyInterpreterFrame *frame)
{

assert(!_PyFrame_IsIncomplete(frame));
PyFrameObject *res = FT_ATOMIC_LOAD_PTR_ACQUIRE(frame->frame_obj);
PyFrameObject *res = (PyFrameObject*)FT_ATOMIC_LOAD_PTR_ACQUIRE(frame->frame_obj);
if (res != NULL) {
return res;
}
Expand Down
5 changes: 3 additions & 2 deletions Lib/concurrent/futures/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,11 @@ def _python_exit():


# On Windows, WaitForMultipleObjects is used to wait for processes to finish.
# It can wait on, at most, 63 objects. There is an overhead of two objects:
# It can wait on, at most, 64 objects. There is an overhead of three objects:
# - the result queue reader
# - the thread wakeup reader
_MAX_WINDOWS_WORKERS = 63 - 2
# - the SIGINT handler
_MAX_WINDOWS_WORKERS = 64 - 3

# Hack to embed stringification of remote traceback in local traceback

Expand Down
24 changes: 24 additions & 0 deletions Lib/test/test_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,30 @@ def test_argument_handling(self):
self.assertRaises(SyntaxError, exec, 'def f(a = 0, a = 1): pass')
self.assertRaises(SyntaxError, exec, 'def f(a): global a; a = 1')

def test_call_opcode_stack_use_limit(self):
def get_call_opcode(positional_count, keyword_count):
args = ["0"] * positional_count
args.extend(f"a{i}=0" for i in range(keyword_count))
code = compile(f"f({', '.join(args)})", "<test>", "exec")
return next(
instr.opname for instr in dis.get_instructions(code)
if instr.opname.startswith("CALL")
)

for positional_count, keyword_count, expected_opcode in [
(0, 16, "CALL_KW"),
(15, 14, "CALL_KW"),
(15, 15, "CALL_FUNCTION_EX"),
]:
with self.subTest(
positional_count=positional_count,
keyword_count=keyword_count,
):
self.assertEqual(
get_call_opcode(positional_count, keyword_count),
expected_opcode,
)

def test_syntax_error(self):
self.assertRaises(SyntaxError, compile, "1+*3", "filename", "exec")

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Compile pure-keyword calls with 16 to 29 keyword arguments using the faster
``CALL_KW`` instruction. This includes common cases such as dataclass
constructors with many fields.
7 changes: 5 additions & 2 deletions Python/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ typedef _PyCompile_FBlockInfo fblockinfo;

#define LOC(x) SRC_LOCATION_FROM_AST(x)

#define CALL_STACK_USE(nargs, nkwds) \
((nargs) + (nkwds) + ((nkwds) != 0))

#define NEW_JUMP_TARGET_LABEL(C, NAME) \
jump_target_label NAME = _PyInstructionSequence_NewLabel(INSTR_SEQUENCE(C)); \
if (!IS_JUMP_TARGET_LABEL(NAME)) { \
Expand Down Expand Up @@ -4147,7 +4150,7 @@ maybe_optimize_method_call(compiler *c, expr_ty e)
/* Check that there aren't too many arguments */
argsl = asdl_seq_LEN(args);
kwdsl = asdl_seq_LEN(kwds);
if (argsl + kwdsl + (kwdsl != 0) >= _PY_STACK_USE_GUIDELINE) {
if (CALL_STACK_USE(argsl, kwdsl) >= _PY_STACK_USE_GUIDELINE) {
return 0;
}
/* Check that there are no *varargs types of arguments. */
Expand Down Expand Up @@ -4440,7 +4443,7 @@ codegen_call_helper_impl(compiler *c, location loc,
nelts = asdl_seq_LEN(args);
nkwelts = asdl_seq_LEN(keywords);

if (nelts + nkwelts*2 > _PY_STACK_USE_GUIDELINE) {
if (CALL_STACK_USE(nelts, nkwelts) > _PY_STACK_USE_GUIDELINE) {
goto ex_call;
}
for (i = 0; i < nelts; i++) {
Expand Down
Loading