Skip to content

Commit baacf5f

Browse files
committed
Merge branch 'main' into inlinecomp2
* main: pythongh-99113: Add PyInterpreterConfig.own_gil (pythongh-104204) pythongh-104146: Remove unused var 'parser_body_declarations' from clinic.py (python#104214) pythongh-99113: Add Py_MOD_PER_INTERPRETER_GIL_SUPPORTED (pythongh-104205) pythongh-104108: Add the Py_mod_multiple_interpreters Module Def Slot (pythongh-104148) pythongh-99113: Share the GIL via PyInterpreterState.ceval.gil (pythongh-104203) pythonGH-100479: Add `pathlib.PurePath.with_segments()` (pythonGH-103975) pythongh-69152: Add _proxy_response_headers attribute to HTTPConnection (python#26152) pythongh-103533: Use PEP 669 APIs for cprofile (pythonGH-103534) pythonGH-96803: Add three C-API functions to make _PyInterpreterFrame less opaque for users of PEP 523. (pythonGH-96849)
2 parents fb9f89e + f3e7eb4 commit baacf5f

File tree

132 files changed

+791
-226
lines changed

Some content is hidden

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

132 files changed

+791
-226
lines changed

Doc/library/pathlib.rst

+26-2
Original file line numberDiff line numberDiff line change
@@ -530,10 +530,10 @@ Pure paths provide the following methods and properties:
530530
unintended effects.
531531

532532

533-
.. method:: PurePath.joinpath(*other)
533+
.. method:: PurePath.joinpath(*pathsegments)
534534

535535
Calling this method is equivalent to combining the path with each of
536-
the *other* arguments in turn::
536+
the given *pathsegments* in turn::
537537

538538
>>> PurePosixPath('/etc').joinpath('passwd')
539539
PurePosixPath('/etc/passwd')
@@ -680,6 +680,30 @@ Pure paths provide the following methods and properties:
680680
PureWindowsPath('README')
681681

682682

683+
.. method:: PurePath.with_segments(*pathsegments)
684+
685+
Create a new path object of the same type by combining the given
686+
*pathsegments*. This method is called whenever a derivative path is created,
687+
such as from :attr:`parent` and :meth:`relative_to`. Subclasses may
688+
override this method to pass information to derivative paths, for example::
689+
690+
from pathlib import PurePosixPath
691+
692+
class MyPath(PurePosixPath):
693+
def __init__(self, *pathsegments, session_id):
694+
super().__init__(*pathsegments)
695+
self.session_id = session_id
696+
697+
def with_segments(self, *pathsegments):
698+
return type(self)(*pathsegments, session_id=self.session_id)
699+
700+
etc = MyPath('/etc', session_id=42)
701+
hosts = etc / 'hosts'
702+
print(hosts.session_id) # 42
703+
704+
.. versionadded:: 3.12
705+
706+
683707
.. _concrete-paths:
684708

685709

Doc/whatsnew/3.12.rst

+5
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,11 @@ inspect
372372
pathlib
373373
-------
374374

375+
* Add support for subclassing :class:`pathlib.PurePath` and
376+
:class:`~pathlib.Path`, plus their Posix- and Windows-specific variants.
377+
Subclasses may override the :meth:`~pathlib.PurePath.with_segments` method
378+
to pass information between path instances.
379+
375380
* Add :meth:`~pathlib.Path.walk` for walking the directory trees and generating
376381
all file or directory names within them, similar to :func:`os.walk`.
377382
(Contributed by Stanislav Zmiev in :gh:`90385`.)

Include/cpython/frameobject.h

+17
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
# error "this header file must not be included directly"
55
#endif
66

7+
struct _PyInterpreterFrame;
8+
79
/* Standard object interface */
810

911
PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *,
@@ -27,3 +29,18 @@ PyAPI_FUNC(int) _PyFrame_IsEntryFrame(PyFrameObject *frame);
2729

2830
PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f);
2931
PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
32+
33+
/* The following functions are for use by debuggers and other tools
34+
* implementing custom frame evaluators with PEP 523. */
35+
36+
/* Returns the code object of the frame (strong reference).
37+
* Does not raise an exception. */
38+
PyAPI_FUNC(PyCodeObject *) PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame);
39+
40+
/* Returns a byte ofsset into the last executed instruction.
41+
* Does not raise an exception. */
42+
PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame);
43+
44+
/* Returns the currently executing line number, or -1 if there is no line number.
45+
* Does not raise an exception. */
46+
PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLine(struct _PyInterpreterFrame *frame);

Include/cpython/initconfig.h

+3
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ typedef struct {
252252
int allow_threads;
253253
int allow_daemon_threads;
254254
int check_multi_interp_extensions;
255+
int own_gil;
255256
} PyInterpreterConfig;
256257

257258
#define _PyInterpreterConfig_INIT \
@@ -262,6 +263,7 @@ typedef struct {
262263
.allow_threads = 1, \
263264
.allow_daemon_threads = 0, \
264265
.check_multi_interp_extensions = 1, \
266+
.own_gil = 1, \
265267
}
266268

267269
#define _PyInterpreterConfig_LEGACY_INIT \
@@ -272,6 +274,7 @@ typedef struct {
272274
.allow_threads = 1, \
273275
.allow_daemon_threads = 1, \
274276
.check_multi_interp_extensions = 0, \
277+
.own_gil = 0, \
275278
}
276279

277280
/* --- Helper functions --------------------------------------- */

Include/internal/pycore_ceval.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ _PyEval_Vector(PyThreadState *tstate,
9696
PyObject* const* args, size_t argcount,
9797
PyObject *kwnames);
9898

99-
extern int _PyEval_ThreadsInitialized(struct pyruntimestate *runtime);
100-
extern PyStatus _PyEval_InitGIL(PyThreadState *tstate);
99+
extern int _PyEval_ThreadsInitialized(void);
100+
extern PyStatus _PyEval_InitGIL(PyThreadState *tstate, int own_gil);
101101
extern void _PyEval_FiniGIL(PyInterpreterState *interp);
102102

103103
extern void _PyEval_ReleaseLock(PyThreadState *tstate);

Include/internal/pycore_ceval_state.h

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ struct _ceval_runtime_state {
4949
the main thread of the main interpreter can handle signals: see
5050
_Py_ThreadCanHandleSignals(). */
5151
_Py_atomic_int signals_pending;
52+
53+
/* This is (only) used indirectly through PyInterpreterState.ceval.gil. */
5254
struct _gil_runtime_state gil;
5355
};
5456

@@ -83,6 +85,8 @@ struct _pending_calls {
8385

8486
struct _ceval_state {
8587
int recursion_limit;
88+
struct _gil_runtime_state *gil;
89+
int own_gil;
8690
/* This single variable consolidates all requests to break out of
8791
the fast path in the eval loop. */
8892
_Py_atomic_int eval_breaker;

Include/internal/pycore_frame.h

-2
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,6 @@ _PyFrame_PushUnchecked(PyThreadState *tstate, PyFunctionObject *func, int null_l
265265
return new_frame;
266266
}
267267

268-
int _PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame);
269-
270268
static inline
271269
PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame)
272270
{

Include/moduleobject.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,17 @@ struct PyModuleDef_Slot {
7878

7979
#define Py_mod_create 1
8080
#define Py_mod_exec 2
81+
#define Py_mod_multiple_interpreters 3
8182

8283
#ifndef Py_LIMITED_API
83-
#define _Py_mod_LAST_SLOT 2
84+
#define _Py_mod_LAST_SLOT 3
8485
#endif
8586

87+
/* for Py_mod_multiple_interpreters: */
88+
#define Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED ((void *)0)
89+
#define Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED ((void *)1)
90+
#define Py_MOD_PER_INTERPRETER_GIL_SUPPORTED ((void *)2)
91+
8692
#endif /* New in 3.5 */
8793

8894
struct PyModuleDef {

Lib/http/client.py

+7-11
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,7 @@ def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
858858
self._tunnel_host = None
859859
self._tunnel_port = None
860860
self._tunnel_headers = {}
861+
self._proxy_response_headers = None
861862

862863
(self.host, self.port) = self._get_hostport(host, port)
863864

@@ -944,21 +945,16 @@ def _tunnel(self):
944945
try:
945946
(version, code, message) = response._read_status()
946947

948+
self._proxy_response_headers = parse_headers(response.fp)
949+
950+
if self.debuglevel > 0:
951+
for hdr, val in self._proxy_response_headers.items():
952+
print("header:", hdr + ":", val)
953+
947954
if code != http.HTTPStatus.OK:
948955
self.close()
949956
raise OSError(f"Tunnel connection failed: {code} {message.strip()}")
950-
while True:
951-
line = response.fp.readline(_MAXLINE + 1)
952-
if len(line) > _MAXLINE:
953-
raise LineTooLong("header line")
954-
if not line:
955-
# for sites which EOF without sending a trailer
956-
break
957-
if line in (b'\r\n', b'\n', b''):
958-
break
959957

960-
if self.debuglevel > 0:
961-
print('header:', line.decode())
962958
finally:
963959
response.close()
964960

0 commit comments

Comments
 (0)