Skip to content

Commit df77a64

Browse files
Merge branch 'atexit-c-callback' into per-interpreter-alloc
2 parents 593430b + 82b395c commit df77a64

Some content is hidden

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

50 files changed

+853
-448
lines changed

Doc/library/dis.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ the following command can be used to display the disassembly of
5959
3 2 LOAD_GLOBAL 1 (NULL + len)
6060
12 LOAD_FAST 0 (alist)
6161
14 CALL 1
62-
24 RETURN_VALUE
62+
22 RETURN_VALUE
6363

6464
(The "2" is a line number).
6565

Doc/library/functions.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,8 +1444,9 @@ are always available. They are listed here in alphabetical order.
14441444
arguments are converted to text strings, :func:`print` cannot be used with
14451445
binary mode file objects. For these, use ``file.write(...)`` instead.
14461446

1447-
Whether the output is buffered is usually determined by *file*, but if the
1448-
*flush* keyword argument is true, the stream is forcibly flushed.
1447+
Output buffering is usually determined by *file*.
1448+
However, if *flush* is true, the stream is forcibly flushed.
1449+
14491450

14501451
.. versionchanged:: 3.3
14511452
Added the *flush* keyword argument.

Doc/library/http.client.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,13 @@ HTTPConnection Objects
353353
The *headers* argument should be a mapping of extra HTTP headers to send with
354354
the CONNECT request.
355355

356+
As HTTP/1.1 is used for HTTP CONNECT tunnelling request, `as per the RFC
357+
<https://tools.ietf.org/html/rfc7231#section-4.3.6>`_, a HTTP ``Host:``
358+
header must be provided, matching the authority-form of the request target
359+
provided as the destination for the CONNECT request. If a HTTP ``Host:``
360+
header is not provided via the headers argument, one is generated and
361+
transmitted automatically.
362+
356363
For example, to tunnel through a HTTPS proxy server running locally on port
357364
8080, we would pass the address of the proxy to the :class:`HTTPSConnection`
358365
constructor, and the address of the host that we eventually want to reach to
@@ -365,6 +372,11 @@ HTTPConnection Objects
365372

366373
.. versionadded:: 3.2
367374

375+
.. versionchanged:: 3.12
376+
HTTP CONNECT tunnelling requests use protocol HTTP/1.1, upgraded from
377+
protocol HTTP/1.0. ``Host:`` HTTP headers are mandatory for HTTP/1.1, so
378+
one will be automatically generated and transmitted if not provided in
379+
the headers argument.
368380

369381
.. method:: HTTPConnection.connect()
370382

Doc/library/multiprocessing.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -460,16 +460,16 @@ process which created it.
460460
... return x*x
461461
...
462462
>>> with p:
463-
... p.map(f, [1,2,3])
463+
... p.map(f, [1,2,3])
464464
Process PoolWorker-1:
465465
Process PoolWorker-2:
466466
Process PoolWorker-3:
467467
Traceback (most recent call last):
468468
Traceback (most recent call last):
469469
Traceback (most recent call last):
470-
AttributeError: 'module' object has no attribute 'f'
471-
AttributeError: 'module' object has no attribute 'f'
472-
AttributeError: 'module' object has no attribute 'f'
470+
AttributeError: Can't get attribute 'f' on <module '__main__' (<class '_frozen_importlib.BuiltinImporter'>)>
471+
AttributeError: Can't get attribute 'f' on <module '__main__' (<class '_frozen_importlib.BuiltinImporter'>)>
472+
AttributeError: Can't get attribute 'f' on <module '__main__' (<class '_frozen_importlib.BuiltinImporter'>)>
473473

474474
(If you try this it will actually output three full tracebacks
475475
interleaved in a semi-random fashion, and then you may have to

Doc/library/sys.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ always available.
697697
the encoding used with the :term:`filesystem error handler <filesystem
698698
encoding and error handler>` to convert between Unicode filenames and bytes
699699
filenames. The filesystem error handler is returned from
700-
:func:`getfilesystemencoding`.
700+
:func:`getfilesystemencodeerrors`.
701701

702702
For best compatibility, str should be used for filenames in all cases,
703703
although representing filenames as bytes is also supported. Functions

Doc/whatsnew/3.12.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ Optimizations
465465

466466
* Added experimental support for using the BOLT binary optimizer in the build
467467
process, which improves performance by 1-5%.
468-
(Contributed by Kevin Modzelewski in :gh:`90536`.)
468+
(Contributed by Kevin Modzelewski in :gh:`90536` and tuned by Dong-hee Na in :gh:`101525`)
469469

470470
* Speed up the regular expression substitution (functions :func:`re.sub` and
471471
:func:`re.subn` and corresponding :class:`!re.Pattern` methods) for

Include/cpython/pylifecycle.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,7 @@ PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category);
6565
PyAPI_FUNC(PyStatus) _Py_NewInterpreterFromConfig(
6666
PyThreadState **tstate_p,
6767
const _PyInterpreterConfig *config);
68+
69+
typedef void (*atexit_datacallbackfunc)(void *);
70+
PyAPI_FUNC(int) _Py_AtExit(
71+
PyInterpreterState *, atexit_datacallbackfunc, void *);

Include/internal/pycore_atexit.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#ifndef Py_INTERNAL_ATEXIT_H
2+
#define Py_INTERNAL_ATEXIT_H
3+
#ifdef __cplusplus
4+
extern "C" {
5+
#endif
6+
7+
#ifndef Py_BUILD_CORE
8+
# error "this header requires Py_BUILD_CORE define"
9+
#endif
10+
11+
12+
//###############
13+
// runtime atexit
14+
15+
typedef void (*atexit_callbackfunc)(void);
16+
17+
struct _atexit_runtime_state {
18+
#define NEXITFUNCS 32
19+
atexit_callbackfunc callbacks[NEXITFUNCS];
20+
int ncallbacks;
21+
};
22+
23+
24+
//###################
25+
// interpreter atexit
26+
27+
struct atexit_callback;
28+
typedef struct atexit_callback {
29+
atexit_datacallbackfunc func;
30+
void *data;
31+
struct atexit_callback *next;
32+
} atexit_callback;
33+
34+
typedef struct {
35+
PyObject *func;
36+
PyObject *args;
37+
PyObject *kwargs;
38+
} atexit_py_callback;
39+
40+
struct atexit_state {
41+
atexit_callback *ll_callbacks;
42+
atexit_callback *last_ll_callback;
43+
44+
// XXX The rest of the state could be moved to the atexit module state
45+
// and a low-level callback added for it during module exec.
46+
// For the moment we leave it here.
47+
atexit_py_callback **callbacks;
48+
int ncallbacks;
49+
int callback_len;
50+
};
51+
52+
53+
#ifdef __cplusplus
54+
}
55+
#endif
56+
#endif /* !Py_INTERNAL_ATEXIT_H */

Include/internal/pycore_code.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ typedef struct {
7373
typedef struct {
7474
uint16_t counter;
7575
uint16_t func_version[2];
76-
uint16_t min_args;
7776
} _PyCallCache;
7877

7978
#define INLINE_CACHE_ENTRIES_CALL CACHE_ENTRIES(_PyCallCache)

Include/internal/pycore_interp.h

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ extern "C" {
1010

1111
#include <stdbool.h>
1212

13-
#include "pycore_atomic.h" // _Py_atomic_address
1413
#include "pycore_ast_state.h" // struct ast_state
14+
#include "pycore_atexit.h" // struct atexit_state
15+
#include "pycore_atomic.h" // _Py_atomic_address
1516
#include "pycore_ceval_state.h" // struct _ceval_state
1617
#include "pycore_code.h" // struct callable_cache
1718
#include "pycore_context.h" // struct _Py_context_state
@@ -33,20 +34,6 @@ extern "C" {
3334
#include "pycore_warnings.h" // struct _warnings_runtime_state
3435

3536

36-
// atexit state
37-
typedef struct {
38-
PyObject *func;
39-
PyObject *args;
40-
PyObject *kwargs;
41-
} atexit_callback;
42-
43-
struct atexit_state {
44-
atexit_callback **callbacks;
45-
int ncallbacks;
46-
int callback_len;
47-
};
48-
49-
5037
struct _Py_long_state {
5138
int max_str_digits;
5239
};

Include/internal/pycore_opcode.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_runtime.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ extern "C" {
88
# error "this header requires Py_BUILD_CORE define"
99
#endif
1010

11+
#include "pycore_atexit.h" // struct atexit_runtime_state
1112
#include "pycore_atomic.h" /* _Py_atomic_address */
1213
#include "pycore_ceval_state.h" // struct _ceval_runtime_state
1314
#include "pycore_floatobject.h" // struct _Py_float_runtime_state
@@ -130,9 +131,7 @@ typedef struct pyruntimestate {
130131

131132
struct _parser_runtime_state parser;
132133

133-
#define NEXITFUNCS 32
134-
void (*exitfuncs[NEXITFUNCS])(void);
135-
int nexitfuncs;
134+
struct _atexit_runtime_state atexit;
136135

137136
struct _import_runtime_state imports;
138137
struct _ceval_runtime_state ceval;

Include/pymacro.h

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,23 @@
33

44
// gh-91782: On FreeBSD 12, if the _POSIX_C_SOURCE and _XOPEN_SOURCE macros are
55
// defined, <sys/cdefs.h> disables C11 support and <assert.h> does not define
6-
// the static_assert() macro. Define the static_assert() macro in Python until
7-
// <sys/cdefs.h> suports C11:
6+
// the static_assert() macro.
87
// https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=255290
9-
#if defined(__FreeBSD__) && !defined(static_assert)
10-
# define static_assert _Static_assert
11-
#endif
12-
13-
// static_assert is defined in glibc from version 2.16. Before it requires
14-
// compiler support (gcc >= 4.6) and is called _Static_assert.
15-
// In C++ 11 static_assert is a keyword, redefining is undefined behaviour.
16-
#if (defined(__GLIBC__) \
17-
&& (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 16)) \
18-
&& !(defined(__cplusplus) && __cplusplus >= 201103L) \
19-
&& !defined(static_assert))
8+
//
9+
// macOS <= 10.10 doesn't define static_assert in assert.h at all despite
10+
// having C11 compiler support.
11+
//
12+
// static_assert is defined in glibc from version 2.16. Compiler support for
13+
// the C11 _Static_assert keyword is in gcc >= 4.6.
14+
//
15+
// MSVC makes static_assert a keyword in C11-17, contrary to the standards.
16+
//
17+
// In C++11 and C2x, static_assert is a keyword, redefining is undefined
18+
// behaviour. So only define if building as C (if __STDC_VERSION__ is defined),
19+
// not C++, and only for C11-17.
20+
#if !defined(static_assert) && (defined(__GNUC__) || defined(__clang__)) \
21+
&& defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L \
22+
&& __STDC_VERSION__ <= 201710L
2023
# define static_assert _Static_assert
2124
#endif
2225

Lib/http/client.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -870,27 +870,39 @@ def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
870870
def set_tunnel(self, host, port=None, headers=None):
871871
"""Set up host and port for HTTP CONNECT tunnelling.
872872
873-
In a connection that uses HTTP CONNECT tunneling, the host passed to the
874-
constructor is used as a proxy server that relays all communication to
875-
the endpoint passed to `set_tunnel`. This done by sending an HTTP
873+
In a connection that uses HTTP CONNECT tunnelling, the host passed to
874+
the constructor is used as a proxy server that relays all communication
875+
to the endpoint passed to `set_tunnel`. This done by sending an HTTP
876876
CONNECT request to the proxy server when the connection is established.
877877
878878
This method must be called before the HTTP connection has been
879879
established.
880880
881881
The headers argument should be a mapping of extra HTTP headers to send
882882
with the CONNECT request.
883+
884+
As HTTP/1.1 is used for HTTP CONNECT tunnelling request, as per the RFC
885+
(https://tools.ietf.org/html/rfc7231#section-4.3.6), a HTTP Host:
886+
header must be provided, matching the authority-form of the request
887+
target provided as the destination for the CONNECT request. If a
888+
HTTP Host: header is not provided via the headers argument, one
889+
is generated and transmitted automatically.
883890
"""
884891

885892
if self.sock:
886893
raise RuntimeError("Can't set up tunnel for established connection")
887894

888895
self._tunnel_host, self._tunnel_port = self._get_hostport(host, port)
889896
if headers:
890-
self._tunnel_headers = headers
897+
self._tunnel_headers = headers.copy()
891898
else:
892899
self._tunnel_headers.clear()
893900

901+
if not any(header.lower() == "host" for header in self._tunnel_headers):
902+
encoded_host = self._tunnel_host.encode("idna").decode("ascii")
903+
self._tunnel_headers["Host"] = "%s:%d" % (
904+
encoded_host, self._tunnel_port)
905+
894906
def _get_hostport(self, host, port):
895907
if port is None:
896908
i = host.rfind(':')
@@ -915,8 +927,9 @@ def set_debuglevel(self, level):
915927
self.debuglevel = level
916928

917929
def _tunnel(self):
918-
connect = b"CONNECT %s:%d HTTP/1.0\r\n" % (
919-
self._tunnel_host.encode("ascii"), self._tunnel_port)
930+
connect = b"CONNECT %s:%d %s\r\n" % (
931+
self._tunnel_host.encode("idna"), self._tunnel_port,
932+
self._http_vsn_str.encode("ascii"))
920933
headers = [connect]
921934
for header, value in self._tunnel_headers.items():
922935
headers.append(f"{header}: {value}\r\n".encode("latin-1"))

Lib/importlib/_bootstrap_external.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ def _write_atomic(path, data, mode=0o666):
438438
# Python 3.12a7 3522 (Removed JUMP_IF_FALSE_OR_POP/JUMP_IF_TRUE_OR_POP)
439439
# Python 3.12a7 3523 (Convert COMPARE_AND_BRANCH back to COMPARE_OP)
440440
# Python 3.12a7 3524 (Shrink the BINARY_SUBSCR caches)
441+
# Python 3.12b1 3525 (Shrink the CALL caches)
441442

442443
# Python 3.13 will start with 3550
443444

@@ -454,7 +455,7 @@ def _write_atomic(path, data, mode=0o666):
454455
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
455456
# in PC/launcher.c must also be updated.
456457

457-
MAGIC_NUMBER = (3524).to_bytes(2, 'little') + b'\r\n'
458+
MAGIC_NUMBER = (3525).to_bytes(2, 'little') + b'\r\n'
458459

459460
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
460461

Lib/inspect.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1772,9 +1772,9 @@ def trace(context=1):
17721772
# ------------------------------------------------ static version of getattr
17731773

17741774
_sentinel = object()
1775+
_static_getmro = type.__dict__['__mro__'].__get__
1776+
_get_dunder_dict_of_class = type.__dict__["__dict__"].__get__
17751777

1776-
def _static_getmro(klass):
1777-
return type.__dict__['__mro__'].__get__(klass)
17781778

17791779
def _check_instance(obj, attr):
17801780
instance_dict = {}
@@ -1802,10 +1802,9 @@ def _is_type(obj):
18021802
return True
18031803

18041804
def _shadowed_dict(klass):
1805-
dict_attr = type.__dict__["__dict__"]
18061805
for entry in _static_getmro(klass):
18071806
try:
1808-
class_dict = dict_attr.__get__(entry)["__dict__"]
1807+
class_dict = _get_dunder_dict_of_class(entry)["__dict__"]
18091808
except KeyError:
18101809
pass
18111810
else:

Lib/opcode.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,6 @@ def pseudo_op(name, op, real_ops):
410410
"CALL": {
411411
"counter": 1,
412412
"func_version": 2,
413-
"min_args": 1,
414413
},
415414
"STORE_SUBSCR": {
416415
"counter": 1,

0 commit comments

Comments
 (0)