@@ -90,6 +90,79 @@ If you encounter :exc:`NameError`\s or pickling errors coming out of
90
90
New features
91
91
============
92
92
93
+ .. _whatsnew314-pep678 :
94
+
95
+ PEP 768: Safe external debugger interface for CPython
96
+ ----------------------------------------------------
97
+
98
+ :pep: `768 ` introduces a zero-overhead debugging interface that allows debuggers and profilers
99
+ to safely attach to running Python processes. This is a significant enhancement to Python's
100
+ debugging capabilities, bringing them in line with other major programming languages.
101
+
102
+ The new interface provides safe execution points for attaching debugger code without modifying
103
+ the interpreter's normal execution path or adding runtime overhead. This enables tools to
104
+ inspect and interact with Python applications in real-time without stopping or restarting
105
+ them — a crucial capability for high-availability systems and production environments.
106
+
107
+ For convenience, CPython implements this interface through the :mod: `sys ` module with a
108
+ :func: `sys.remote_exec ` function::
109
+
110
+ sys.remote_exec(pid, script_path)
111
+
112
+ This function allows sending Python code to be executed in a target process at the next safe
113
+ execution point. However, tool authors can also implement the protocol directly as described
114
+ in the PEP, which details the underlying mechanisms used to safely attach to running processes.
115
+
116
+ Here's a simple example that inspects object types in a running Python process:
117
+
118
+ .. code-block :: python
119
+
120
+ import sys
121
+ import tempfile
122
+ import os
123
+
124
+ # Create a temporary script
125
+ with tempfile.NamedTemporaryFile(mode = ' w' , suffix = ' .py' , delete = False ) as f:
126
+ script_path = f.name
127
+ f.write("""
128
+ import gc
129
+ import collections
130
+
131
+ # Collect all objects managed by the garbage collector
132
+ gc.collect()
133
+
134
+ # Count objects by type
135
+ type_counts = collections.Counter(type(obj).__name__
136
+ for obj in gc.get_objects())
137
+
138
+ # Print the most common types
139
+ print("Most common object types in process:")
140
+ for type_name, count in type_counts.most_common(10):
141
+ print(f" {type_name} : {count} ")
142
+ """ )
143
+
144
+ try :
145
+ # Execute in process with PID 1234
146
+ print (" Behold! An offering:" )
147
+ sys.remote_exec(1234 , script_path)
148
+ finally :
149
+ os.unlink(script_path)
150
+
151
+ The debugging interface has been carefully designed with security in mind and includes several
152
+ mechanisms to control access:
153
+
154
+ * A :envvar: `PYTHON_DISABLE_REMOTE_DEBUG ` environment variable.
155
+ * A :option: `-X disable-remote-debug ` command-line option.
156
+ * A ``--without-remote-debug `` configure flag to completely disable the feature at build time.
157
+
158
+ A key implementation detail is that the interface piggybacks on the interpreter's existing evaluation
159
+ loop and safe points, ensuring zero overhead during normal execution while providing a reliable way
160
+ for external processes to coordinate debugging operations.
161
+
162
+ See :pep: `768 ` for more details.
163
+
164
+ (Contributed by Pablo Galindo Salgado, Matt Wozniski, and Ivona Stojanovic in :gh: `131591 `.)
165
+
93
166
.. _whatsnew314-pep649 :
94
167
95
168
PEP 649: deferred evaluation of annotations
0 commit comments