Skip to content

Commit

Permalink
Merge branch 'main' into inlinecomp2
Browse files Browse the repository at this point in the history
* 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)
  • Loading branch information
carljm committed May 5, 2023
2 parents fb9f89e + f3e7eb4 commit baacf5f
Show file tree
Hide file tree
Showing 132 changed files with 791 additions and 226 deletions.
28 changes: 26 additions & 2 deletions Doc/library/pathlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -530,10 +530,10 @@ Pure paths provide the following methods and properties:
unintended effects.


.. method:: PurePath.joinpath(*other)
.. method:: PurePath.joinpath(*pathsegments)

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

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


.. method:: PurePath.with_segments(*pathsegments)

Create a new path object of the same type by combining the given
*pathsegments*. This method is called whenever a derivative path is created,
such as from :attr:`parent` and :meth:`relative_to`. Subclasses may
override this method to pass information to derivative paths, for example::

from pathlib import PurePosixPath

class MyPath(PurePosixPath):
def __init__(self, *pathsegments, session_id):
super().__init__(*pathsegments)
self.session_id = session_id

def with_segments(self, *pathsegments):
return type(self)(*pathsegments, session_id=self.session_id)

etc = MyPath('/etc', session_id=42)
hosts = etc / 'hosts'
print(hosts.session_id) # 42

.. versionadded:: 3.12


.. _concrete-paths:


Expand Down
5 changes: 5 additions & 0 deletions Doc/whatsnew/3.12.rst
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,11 @@ inspect
pathlib
-------

* Add support for subclassing :class:`pathlib.PurePath` and
:class:`~pathlib.Path`, plus their Posix- and Windows-specific variants.
Subclasses may override the :meth:`~pathlib.PurePath.with_segments` method
to pass information between path instances.

* Add :meth:`~pathlib.Path.walk` for walking the directory trees and generating
all file or directory names within them, similar to :func:`os.walk`.
(Contributed by Stanislav Zmiev in :gh:`90385`.)
Expand Down
17 changes: 17 additions & 0 deletions Include/cpython/frameobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
# error "this header file must not be included directly"
#endif

struct _PyInterpreterFrame;

/* Standard object interface */

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

PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f);
PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);

/* The following functions are for use by debuggers and other tools
* implementing custom frame evaluators with PEP 523. */

/* Returns the code object of the frame (strong reference).
* Does not raise an exception. */
PyAPI_FUNC(PyCodeObject *) PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame);

/* Returns a byte ofsset into the last executed instruction.
* Does not raise an exception. */
PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame);

/* Returns the currently executing line number, or -1 if there is no line number.
* Does not raise an exception. */
PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLine(struct _PyInterpreterFrame *frame);
3 changes: 3 additions & 0 deletions Include/cpython/initconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ typedef struct {
int allow_threads;
int allow_daemon_threads;
int check_multi_interp_extensions;
int own_gil;
} PyInterpreterConfig;

#define _PyInterpreterConfig_INIT \
Expand All @@ -262,6 +263,7 @@ typedef struct {
.allow_threads = 1, \
.allow_daemon_threads = 0, \
.check_multi_interp_extensions = 1, \
.own_gil = 1, \
}

#define _PyInterpreterConfig_LEGACY_INIT \
Expand All @@ -272,6 +274,7 @@ typedef struct {
.allow_threads = 1, \
.allow_daemon_threads = 1, \
.check_multi_interp_extensions = 0, \
.own_gil = 0, \
}

/* --- Helper functions --------------------------------------- */
Expand Down
4 changes: 2 additions & 2 deletions Include/internal/pycore_ceval.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ _PyEval_Vector(PyThreadState *tstate,
PyObject* const* args, size_t argcount,
PyObject *kwnames);

extern int _PyEval_ThreadsInitialized(struct pyruntimestate *runtime);
extern PyStatus _PyEval_InitGIL(PyThreadState *tstate);
extern int _PyEval_ThreadsInitialized(void);
extern PyStatus _PyEval_InitGIL(PyThreadState *tstate, int own_gil);
extern void _PyEval_FiniGIL(PyInterpreterState *interp);

extern void _PyEval_ReleaseLock(PyThreadState *tstate);
Expand Down
4 changes: 4 additions & 0 deletions Include/internal/pycore_ceval_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ struct _ceval_runtime_state {
the main thread of the main interpreter can handle signals: see
_Py_ThreadCanHandleSignals(). */
_Py_atomic_int signals_pending;

/* This is (only) used indirectly through PyInterpreterState.ceval.gil. */
struct _gil_runtime_state gil;
};

Expand Down Expand Up @@ -83,6 +85,8 @@ struct _pending_calls {

struct _ceval_state {
int recursion_limit;
struct _gil_runtime_state *gil;
int own_gil;
/* This single variable consolidates all requests to break out of
the fast path in the eval loop. */
_Py_atomic_int eval_breaker;
Expand Down
2 changes: 0 additions & 2 deletions Include/internal/pycore_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,6 @@ _PyFrame_PushUnchecked(PyThreadState *tstate, PyFunctionObject *func, int null_l
return new_frame;
}

int _PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame);

static inline
PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame)
{
Expand Down
8 changes: 7 additions & 1 deletion Include/moduleobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,17 @@ struct PyModuleDef_Slot {

#define Py_mod_create 1
#define Py_mod_exec 2
#define Py_mod_multiple_interpreters 3

#ifndef Py_LIMITED_API
#define _Py_mod_LAST_SLOT 2
#define _Py_mod_LAST_SLOT 3
#endif

/* for Py_mod_multiple_interpreters: */
#define Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED ((void *)0)
#define Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED ((void *)1)
#define Py_MOD_PER_INTERPRETER_GIL_SUPPORTED ((void *)2)

#endif /* New in 3.5 */

struct PyModuleDef {
Expand Down
18 changes: 7 additions & 11 deletions Lib/http/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,7 @@ def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
self._tunnel_host = None
self._tunnel_port = None
self._tunnel_headers = {}
self._proxy_response_headers = None

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

Expand Down Expand Up @@ -944,21 +945,16 @@ def _tunnel(self):
try:
(version, code, message) = response._read_status()

self._proxy_response_headers = parse_headers(response.fp)

if self.debuglevel > 0:
for hdr, val in self._proxy_response_headers.items():
print("header:", hdr + ":", val)

if code != http.HTTPStatus.OK:
self.close()
raise OSError(f"Tunnel connection failed: {code} {message.strip()}")
while True:
line = response.fp.readline(_MAXLINE + 1)
if len(line) > _MAXLINE:
raise LineTooLong("header line")
if not line:
# for sites which EOF without sending a trailer
break
if line in (b'\r\n', b'\n', b''):
break

if self.debuglevel > 0:
print('header:', line.decode())
finally:
response.close()

Expand Down
Loading

0 comments on commit baacf5f

Please sign in to comment.