Skip to content

Fix: ContinueRequest with specific threadId resumes all threads (in-process adapter fix)#2012

Merged
rchiodo merged 4 commits into
mainfrom
copilot/fix-thread-resume-issue
Mar 13, 2026
Merged

Fix: ContinueRequest with specific threadId resumes all threads (in-process adapter fix)#2012
rchiodo merged 4 commits into
mainfrom
copilot/fix-thread-resume-issue

Conversation

Copilot AI commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

With in_process_debug_adapter=True, pressing "continue" only resumed the breakpoint thread — other threads stayed paused despite VS Code showing them as running.

Root cause: The out-of-process adapter explicitly rewrites threadId to "*" before forwarding ContinueRequest to pydevd (clients.py:640). With the in-process adapter there is no such rewrite, so pydevd received a specific threadId and resumed only that thread. The existing guard in on_continue_request only set thread_id = "*" when multi_threads_single_notification=True, missing the in-process case.

Per the DAP spec: ContinueRequest resumes all threads unless singleThread is explicitly true.

Changes

  • pydevd_process_net_command_json.py — core fix:
    thread_id is now forced to "*" whenever singleThread is not explicitly True, regardless of multi_threads_single_notification:

    single_thread = arguments.singleThread
    if not single_thread or py_db.multi_threads_single_notification:
        thread_id = "*"
  • test_debugger_json.py — test helper update:
    write_continue gains a single_thread=False parameter. Default path now asserts allThreadsContinued=True in the response. single_thread=True preserves the existing per-thread assertions for explicit single-thread resumption.

  • test_case_json_suspend_notification — updated assertions to match the now-correct allThreadsContinued=True response when no singleThread flag is set.

  • New regression test test_case_json_continue_all_threads — runs with multi_threads_single_notification=False (the in-process adapter configuration) and verifies that a ContinueRequest carrying a specific threadId (no singleThread) resumes all threads and the process exits cleanly.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dns.google
    • Triggering command: /usr/bin/python3 /usr/bin/python3 -u /home/REDACTED/work/debugpy/debugpy/src/debugpy/_vendored/pydevd/pydevd.py --qt-support --client 127.0.0.1 --port 33219 --debug-mode debugpy-dap --json-dap-http --file /home/REDACTED/work/debugpy/debugpy/src/debugpy/_vendored/pydevd/tests_python/resources/_debugger_case_multi_threads_stepping.py MD_THREAD_RUN|CMD_THREAD_RESUME user.email urces/_debugger_case_change_breaks.py (dns block)
    • Triggering command: /usr/bin/python3 /usr/bin/python3 -u /home/REDACTED/work/debugpy/debugpy/src/debugpy/_vendored/pydevd/pydevd.py --qt-support --client 127.0.0.1 --port 41563 --debug-mode debugpy-dap --json-dap-http --file /home/REDACTED/work/debugpy/debugpy/src/debugpy/_vendored/pydevd/tests_python/resources/_debugger_case_multi_threads_stepping.py --local user.email urces/_debugger_case_change_breaks.py (dns block)
    • Triggering command: /usr/bin/python3 /usr/bin/python3 -u /home/REDACTED/work/debugpy/debugpy/src/debugpy/_vendored/pydevd/pydevd.py --qt-support --client 127.0.0.1 --port 45755 --debug-mode debugpy-dap --json-dap-http --file /home/REDACTED/work/debugpy/debugpy/src/debugpy/_vendored/pydevd/tests_python/resources/_debugger_case_multi_threads_stepping.py --local on_change_breaks urces/_debugger_case_change_breaks.py (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Problems resuming multiple threads if in_process_debug_adapter is True</issue_title>
<issue_description>## Environment data

  • debugpy version: 1.8.19 (from ms-python.debugpy-2025.18.0-win32-x64 extension)
  • OS and version: Windows 10 19045.6456
  • Python version (& distribution if applicable, e.g. Anaconda): Tested on Python 3.8.10, 3.12.10 and 3.14.0
  • Using VS Code or Visual Studio: VS Code 1.111

Actual behavior

When attaching to a debugpy instance with an in-process adapter, if there are multiple threads then only one thread gets resumed after pressing 'continue' instead of all of them, and it desyncs from the visual state in VS code as it thinks all threads are running.

Expected behavior

Attaching to a debugpy instance with an in-process adapter should behave the same as with a separate adapter process, if there is only one process being debugged.

For my real use case I'm trying to debug python embedded in an application, so using the out-of-process adapter would be difficult and much less convenient.

Steps to reproduce:

  1. Create repro.py which (if not already loaded) will load debugpy with an in-process adapter and run two threads to print in a loop:
import threading, time, sys

if 'debugpy' not in sys.modules.keys():
    import debugpy
    debugpy.configure(subProcess=False)
    debugpy.listen(5678, in_process_debug_adapter=True)

def f():
    for i in range(100):
        print(f"Thread {i}")
        time.sleep(0.3)

threading.Thread(target=f).start()

for i in range(100):
    print(f"Main {i}")
    time.sleep(0.3)
  1. Create a launch.json with 'Python Debugger: Remote Attach' to the default host+port (omitted for brevity, I remove the default pathMappings)
  2. Set PYTHONPATH so that debugpy can be found (for me e.g. C:\Users\baldurk\.vscode\extensions\ms-python.debugpy-2025.18.0-win32-x64\bundled\libs)
  3. Run first via the debugpy module (this creates an out-of-process adapter):
    $ python -m debugpy --listen localhost:5678 repro.py
  4. Attach from VS code, breakpoint on one of the print lines to stop debugging. VS Code shows both threads paused as expected.
  5. Remove the breakpoint and continue. Both threads are shown as running now in VS Code and both continue printing.
  6. Now run directly to let the script open an in-process adapter:
    $ python repro.py
  7. Attach from VS code and repeat the steps to breakpoint and continue. Only the thread that hit the breakpoint continues printing, the other remains paused even though both threads are shown as running in VS Code.

Logs

From running with DEBUGPY_LOG_DIR, here are some verbose logs from running with python 3.14:

Working case, out of process adapter:

debugpy.server-20952.log
debugpy.pydevd.20952.log
debugpy.adapter-30776.log

Broken case, in-process adapter:

debugpy.server-27444.log
debugpy.pydevd.27444.log

Thoughts/findings

I've separated out what I think is happening, since I'm not much of a python programmer, I'm unfamiliar with these codebases and the DAP. This may be misguided nonsense, please ignore if so 😄.

The key difference seems to be this (working):

0.83s - Process ContinueRequest: {
    "arguments": {
        "threadId": "*"
    },
    "command": "continue",
    "seq": 18,
    "type": "request"
}

vs this (broken):

2.17s - Process ContinueRequest: {
    "arguments": {
        "threadId": 1
    },
    "command": "continue",
    "seq": 15,
    "type": "request"
}

Tracing it through, VS Code always sends a threadId=X for the active thread with its ContinueRequest. The debugpy adapter process receives this, and forwards on with threadId forcibly set to * in Client.continue_request which causes pydevd to resume all threads.

When there's no separate adapter process, the threadId goes directly(?) to pydevd which then resumes only that one single thread. pydevd returns two responses - one from the requested single-notification mode which says allThreadsContinued=True and that arrives before a second from [on_continue_request](

def on_continue_request(self, py_db, request):
"""
:param ContinueRequest request:
"""
arguments = request.arguments # : :type arguments: ContinueArguments
thread_id = arguments.threadId
if py_db.multi_threads_single_notification:
thread_id = "*"
def on_resumed():
body = {"allThreadsContinued": thread_id == "*"}
response = pydevd_base_schema.build_response(request, kwargs={"body": body})
cmd = NetCommand(CMD_RETURN, 0, response, is_json=True)
py_db.writer.add_command(cmd)
if py_db.multi_threads_single_notification:
# Only send resumed notification when it has actually resumed!
# (otherwise the user could send a continue, receive the notification and then
# request a new pause which would be paused without sending any notification as
# it didn't really run in the first place).
py_db.threads_suspended_single_notification.add_on_resumed_callback(on_resumed)
self.api.request_resume_thread(thread_id)
else:
# Only send resumed notification when it has actually resumed!
# (otherwise the user could send a continue, receive the notification and then
# request a new pause which would be paused without sending any notification as
# it didn't really run in the first place).
self.api.request_resume_thread(thread_id)
on_resumed()
...


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Per the DAP spec, a ContinueRequest should resume all threads unless
singleThread=True is explicitly set. Previously, only the out-of-process
adapter path worked correctly (it transformed threadId to '*' before
forwarding to pydevd). With the in-process adapter, the specific threadId
reached pydevd directly but was only used to resume that one thread.

Fix on_continue_request to set thread_id='*' whenever singleThread is not
True, regardless of multi_threads_single_notification. Also update
write_continue test helper and add a regression test.

Fixes: #2009

Co-authored-by: rchiodo <19672699+rchiodo@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix issues resuming multiple threads in debugpy Fix: ContinueRequest with specific threadId resumes all threads (in-process adapter fix) Mar 11, 2026

# Per the DAP spec, the continue request resumes execution of all threads
# unless singleThread is explicitly true (and the capability
# supportsSingleThreadExecutionRequests is advertised). Only use the

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Verify singleThread attribute access is safe. The Skeptic identified that arguments.singleThread may raise AttributeError if ContinueArguments doesn't default this optional field. Consider using getattr(arguments, 'singleThread', False) or verify the schema class initializes it. Most DAP clients omit this field entirely.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The schema class does initialize self.singleThread = singleThread with a default of None in all paths, so direct access would be technically safe. That said, using getattr(arguments, 'singleThread', False) is the more defensive approach and guards against any non-standard arguments objects. Changed in 1553801.

stop_event.set() # Break here - breakpoint on this line

t.join()
print("TEST SUCEEDED!") # end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Typo: "TEST SUCEEDED!" should be "TEST SUCCEEDED!" (missing 'C'). While the test doesn't assert on this string, consistent spelling helps with log searching and debugging.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TEST SUCEEDED (the misspelled form) is an intentional convention throughout the pydevd test framework — debugger_unittest.py:722 explicitly checks stdout for this exact string to detect test success, and one plugin file even notes # incorrect spelling on purpose. Changing the spelling would break the framework's detection, as confirmed by a test failure. Left as-is to preserve the convention.

@@ -808,6 +817,33 @@ def test_case_json_suspend_notification(case_setup_dap):
writer.finished_ok = True

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot -847
Test coverage is good but relies on implicit timeout for failure detection. If the secondary thread stays blocked (the bug), the debuggee hangs on t.join() and the test times out. The Skeptic noted this works but is indirect. Consider adding a brief comment explaining that test failure manifests as timeout, so future maintainers understand the pass/fail mechanism.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment in 5afe4ad explaining that if the fix regresses, the secondary thread stays blocked and the debuggee hangs on t.join(), causing a test timeout rather than an explicit assertion failure.

…uest

Most DAP clients omit the optional singleThread field entirely. Using
getattr(arguments, 'singleThread', False) is more defensive than direct
attribute access, guarding against any non-standard arguments objects.

Co-authored-by: rchiodo <19672699+rchiodo@users.noreply.github.com>
…onvention

The 'TEST SUCEEDED' misspelling is an intentional convention in the pydevd
test framework (debugger_unittest.py checks stdout for this exact string).
Revert the resource file to preserve the convention while still adding the
explanatory comment requested in the test method.

Co-authored-by: rchiodo <19672699+rchiodo@users.noreply.github.com>

@rchiodo rchiodo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved via Review Center.

@rchiodo

rchiodo commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@rchiodo rchiodo marked this pull request as ready for review March 12, 2026 17:53
@rchiodo rchiodo requested a review from a team as a code owner March 12, 2026 17:53
@rchiodo rchiodo merged commit fb467d8 into main Mar 13, 2026
25 of 28 checks passed
736-c41-2c1-e464fc974 added a commit to Swiss-Armed-Forces/Loom that referenced this pull request Jun 29, 2026
This MR contains the following updates:

| Package | Type | Update | Change | OpenSSF |
|---|---|---|---|---|
| [debugpy](https://aka.ms/debugpy) ([source](https://github.com/microsoft/debugpy)) | dev | patch | `1.8.20` → `1.8.21` | [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/microsoft/debugpy/badge)](https://securityscorecards.dev/viewer/?uri=github.com/microsoft/debugpy) |
| [numpy](https://github.com/numpy/numpy) ([changelog](https://numpy.org/doc/stable/release)) | dependencies | patch | `2.4.4` → `2.4.6` | [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/numpy/numpy/badge)](https://securityscorecards.dev/viewer/?uri=github.com/numpy/numpy) |
| [pydantic-settings](https://github.com/pydantic/pydantic-settings) ([changelog](https://github.com/pydantic/pydantic-settings/releases)) | dependencies | patch | `2.14.0` → `2.14.2` | [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/pydantic/pydantic-settings/badge)](https://securityscorecards.dev/viewer/?uri=github.com/pydantic/pydantic-settings) |
| [python-multipart](https://github.com/Kludex/python-multipart) ([changelog](https://github.com/Kludex/python-multipart/blob/master/CHANGELOG.md)) | dependencies | patch | `^0.0.22` → `^0.0.32` | [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/Kludex/python-multipart/badge)](https://securityscorecards.dev/viewer/?uri=github.com/Kludex/python-multipart) |
| [types-requests](https://github.com/python/typeshed) ([changelog](https://github.com/typeshed-internal/stub_uploader/blob/main/data/changelogs/requests.md)) | dependencies | patch | `2.32.0.20240523` → `2.32.4.20260324` | [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/python/typeshed/badge)](https://securityscorecards.dev/viewer/?uri=github.com/python/typeshed) |

---

### Release Notes

<details>
<summary>microsoft/debugpy (debugpy)</summary>

### [`v1.8.21`](https://github.com/microsoft/debugpy/releases/tag/v1.8.21): debugpy v1.8.21

[Compare Source](microsoft/debugpy@v1.8.20...v1.8.21)

Fixes for:

- Return evaluate result in DAP response body instead of writing to stdout: [#&#8203;2027](microsoft/debugpy#2027)
- Prevent invalid `scopes` request from crashing debug session: [#&#8203;2026](microsoft/debugpy#2026)
- Skip uninitialized `__slots__` in variable resolver: [#&#8203;2024](microsoft/debugpy#2024)
- Handle `-c` arguments that are `bytes` instead of `str`: [#&#8203;2021](microsoft/debugpy#2021)
- Fix evaluation of variables from chained exception frames: [#&#8203;2018](microsoft/debugpy#2018)
- `ContinueRequest` with a specific `threadId` no longer resumes all threads (in-process adapter): [#&#8203;2012](microsoft/debugpy#2012)
- Avoid strong reference to exceptions during unwind: [#&#8203;2008](microsoft/debugpy#2008)
- Show error message on evaluate failures in the hover context: [#&#8203;2006](microsoft/debugpy#2006)
- Display `dlerror` output when `dlopen` fails: [#&#8203;2000](microsoft/debugpy#2000)
- Replace removed `pkgutil.get_loader` with `importlib.util.find_spec` in `get_fullname`: [#&#8203;1998](microsoft/debugpy#1998)

Enhancements:

- Add option to ignore all system exit codes: [#&#8203;2017](microsoft/debugpy#2017)
- Pull changes from pydevd up to March 2026: [#&#8203;2010](microsoft/debugpy#2010)

Infrastructure work:

- Suppress Flawfinder false positives on Cython memcpy / read-loop iterators (TSA [#&#8203;2816216](https://github.com/microsoft/debugpy/issues/2816216), [#&#8203;2816217](https://github.com/microsoft/debugpy/issues/2816217), [#&#8203;2816218](https://github.com/microsoft/debugpy/issues/2816218), [#&#8203;2816219](https://github.com/microsoft/debugpy/issues/2816219), [#&#8203;2816220](https://github.com/microsoft/debugpy/issues/2816220)): [#&#8203;2028](microsoft/debugpy#2028), [#&#8203;2029](microsoft/debugpy#2029), [#&#8203;2030](microsoft/debugpy#2030), [#&#8203;2031](microsoft/debugpy#2031), [#&#8203;2032](microsoft/debugpy#2032)

Thanks to [@&#8203;maxbachmann](https://github.com/maxbachmann), [@&#8203;mfussenegger](https://github.com/mfussenegger), and [@&#8203;sambrightman](https://github.com/sambrightman) for the commits.

</details>

<details>
<summary>numpy/numpy (numpy)</summary>

### [`v2.4.6`](https://github.com/numpy/numpy/releases/tag/v2.4.6): (May 18, 2026)

[Compare Source](numpy/numpy@v2.4.5...v2.4.6)

### NumPy 2.4.6 Release Notes

NumPy 2.4.6 is a quick release that fixes a regression discovered in the 2.4.5
release.

This release supports Python versions 3.11-3.14

#### Contributors

A total of 4 people contributed to this release. People with a "+" by their
names contributed a patch for the first time.

- !EarlMilktea
- Charles Harris
- Sebastian Berg
- Warren Weckesser

#### Pull requests merged

A total of 4 pull requests were merged for this release.

- [#&#8203;31444](numpy/numpy#31444): MAINT: Prepare 2.4.x for further development
- [#&#8203;31453](numpy/numpy#31453): BUG: Fix regression in `arr.conj()`
- [#&#8203;31459](numpy/numpy#31459): BUG: `np.linalg.svd(..., hermitian=True)` returns non-unitary...
- [#&#8203;31460](numpy/numpy#31460): BUG: Don't call INCREF/DECREF on descr in NpyStringAcquireAllocator...

### [`v2.4.5`](https://github.com/numpy/numpy/releases/tag/v2.4.5): (May 15, 2026)

[Compare Source](numpy/numpy@v2.4.4...v2.4.5)

### NumPy 2.4.5 Release Notes

NumPy 2.4.5 is a patch release that fixes bugs discovered after the 2.4.4
release, has some typing improvements, and maintains infrastructure.

This release supports Python versions 3.11-3.14

#### Contributors

A total of 17 people contributed to this release. People with a "+" by their
names contributed a patch for the first time.

- Aleksei Nikiforov
- Anarion Zuo +
- Ankit Ahlawat
- Breno Favaretto +
- Charles Harris
- Igor Krivenko +
- Ijtihed Kilani +
- Joren Hammudoglu
- Maarten Baert +
- Matti Picus
- Nathan Goldbaum
- Praneeth Kodumagulla +
- Ralf Gommers
- RoomWithOutRoof +
- Sebastian Berg
- Warren Weckesser
- div +

#### Pull requests merged

A total of 28 pull requests were merged for this release.

- [#&#8203;31093](numpy/numpy#31093): MAINT: Prepare 2.4.x for further development
- [#&#8203;31182](numpy/numpy#31182): TYP: fix `np.shape` assignability issue for python lists ([#&#8203;31171](numpy/numpy#31171))
- [#&#8203;31197](numpy/numpy#31197): ENH: Return rank 0 for empty matrices in matrix\_rank ([#&#8203;30422](numpy/numpy#30422))
- [#&#8203;31198](numpy/numpy#31198): CI/BUG: add native jobs for s390x, fix bug in `pack_inner`...
- [#&#8203;31199](numpy/numpy#31199): BUG: f2py map complex\_long\_double to NPY\_CLONGDOUBLE
- [#&#8203;31205](numpy/numpy#31205): MAINT: f2py: Stop setting re.\_MAXCACHE to 50.
- [#&#8203;31206](numpy/numpy#31206): BUG: fix heap buffer overflow in timedelta to string casts
- [#&#8203;31207](numpy/numpy#31207): MAINT: Rename ppc64le and s390x workflow ([#&#8203;31121](numpy/numpy#31121))
- [#&#8203;31208](numpy/numpy#31208): BUG: Fix matvec/vecmat in-place aliasing (out=input produces...
- [#&#8203;31209](numpy/numpy#31209): TYP: `tile`: accept numpy scalars and arrays as second argument...
- [#&#8203;31211](numpy/numpy#31211): DEP: Undo deprecation for np.dtype() signature used by old pickles...
- [#&#8203;31212](numpy/numpy#31212): REV: Manual revert of float16 svml use ([#&#8203;31178](numpy/numpy#31178))
- [#&#8203;31222](numpy/numpy#31222): TYP: `ix_` fix for boolean and non-1d input ([#&#8203;31218](numpy/numpy#31218))
- [#&#8203;31329](numpy/numpy#31329): BUG: incorrect temp elision for new-style (NEP 43) user-defined...
- [#&#8203;31330](numpy/numpy#31330): TYP: fix sliding\_window\_view axis parameter typing
- [#&#8203;31335](numpy/numpy#31335): BUG: Prevent deadlock due to downstream importing NumPy in dlopen...
- [#&#8203;31336](numpy/numpy#31336): BUG: Fix segfault in nditer.multi\_index when \_\_getitem\_\_ raises...
- [#&#8203;31338](numpy/numpy#31338): TYP: Fix ruff lint error
- [#&#8203;31357](numpy/numpy#31357): BUG: fix memory leak in np.zeros when fill-zero loop raises ([#&#8203;31320](numpy/numpy#31320))
- [#&#8203;31358](numpy/numpy#31358): BUG: np.einsum() fails with a 0-dimensional out argument and...
- [#&#8203;31379](numpy/numpy#31379): BUG: Fix signed overflow issue in npy\_gcd for INT\_MIN on s390x...
- [#&#8203;31383](numpy/numpy#31383): CI: remove Cirrus CI FreeBSD job ([#&#8203;31380](numpy/numpy#31380))
- [#&#8203;31390](numpy/numpy#31390): BUILD: newer MKL uses so.3
- [#&#8203;31391](numpy/numpy#31391): BLD/MAINT: improve support for Intel LLVM compilers
- [#&#8203;31401](numpy/numpy#31401): BUG: Avoid UB in [safe]()\[add,sub,mul] helpers ([#&#8203;31396](numpy/numpy#31396))
- [#&#8203;31402](numpy/numpy#31402): BUG: exclude \_\_pycache\_\_ directories from wheels ([#&#8203;31397](numpy/numpy#31397))
- [#&#8203;31404](numpy/numpy#31404): TYP: `_NestedSequence` type parameter default to work around...
- [#&#8203;31426](numpy/numpy#31426): TYP: Fix `DTypeLike` runtime type-checker support ([#&#8203;31425](numpy/numpy#31425))

</details>

<details>
<summary>pydantic/pydantic-settings (pydantic-settings)</summary>

### [`v2.14.2`](https://github.com/pydantic/pydantic-settings/releases/tag/v2.14.2)

[Compare Source](pydantic/pydantic-settings@v2.14.1...v2.14.2)

#### What's Changed

This is a security patch release.

- Prevent `NestedSecretsSettingsSource` from following symlinks outside `secrets_dir` by [@&#8203;hramezani](https://github.com/hramezani) in [#&#8203;889](pydantic/pydantic-settings#889)
- Prepare release 2.14.2 by [@&#8203;hramezani](https://github.com/hramezani) in [#&#8203;890](pydantic/pydantic-settings#890)

##### Security

Fixes [GHSA-4xgf-cpjx-pc3j](GHSA-4xgf-cpjx-pc3j): `NestedSecretsSettingsSource` with `secrets_nested_subdir=True` could follow a symbolic link inside `secrets_dir` pointing outside it, reading out-of-tree files into settings values and bypassing the `secrets_dir_max_size` cap. Affected versions: `>= 2.12.0, < 2.14.2`.

**Full Changelog**: <pydantic/pydantic-settings@v2.14.1...v2.14.2>

### [`v2.14.1`](https://github.com/pydantic/pydantic-settings/releases/tag/v2.14.1)

[Compare Source](pydantic/pydantic-settings@v2.14.0...v2.14.1)

#### What's Changed

- Bump the python-packages group with 4 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;850](pydantic/pydantic-settings#850)
- Bump the python-packages group with 5 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;854](pydantic/pydantic-settings#854)
- Bump the github-actions group with 3 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;853](pydantic/pydantic-settings#853)
- Bump the python-packages group with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;856](pydantic/pydantic-settings#856)
- Fix field named `cls` conflicting with classmethod parameter by [@&#8203;hramezani](https://github.com/hramezani) in [#&#8203;858](pydantic/pydantic-settings#858)
- Prepare release 2.14.1 by [@&#8203;hramezani](https://github.com/hramezani) in [#&#8203;859](pydantic/pydantic-settings#859)

**Full Changelog**: <pydantic/pydantic-settings@v2.14.0...v2.14.1>

</details>

<details>
<summary>Kludex/python-multipart (python-multipart)</summary>

### [`v0.0.32`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0032-2026-06-04)

[Compare Source](Kludex/python-multipart@0.0.31...0.0.32)

- Speed up partial-boundary scanning for CR/LF-dense part data [#&#8203;300](Kludex/python-multipart#300).

### [`v0.0.31`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0031-2026-06-04)

[Compare Source](Kludex/python-multipart@0.0.30...0.0.31)

- Speed up multipart header parsing and callback dispatch [#&#8203;295](Kludex/python-multipart#295).
- Bound header field name size before validating [#&#8203;296](Kludex/python-multipart#296).
- Validate `Content-Length` is non-negative in `parse_form` [#&#8203;297](Kludex/python-multipart#297).

### [`v0.0.30`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0030-2026-05-31)

[Compare Source](Kludex/python-multipart@0.0.29...0.0.30)

- Parse `application/x-www-form-urlencoded` bodies per the WHATWG URL standard, treating only `&` as a field separator [#&#8203;290](Kludex/python-multipart#290).
- Ignore RFC 2231/5987 extended parameters (`name*`, `filename*`) in `parse_options_header`, keeping the plain parameter authoritative per [RFC 7578 §4.2](https://datatracker.ietf.org/doc/html/rfc7578#section-4.2) [#&#8203;291](Kludex/python-multipart#291).

### [`v0.0.29`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0029-2026-05-17)

[Compare Source](Kludex/python-multipart@0.0.28...0.0.29)

- Handle malformed RFC 2231 continuations in `parse_options_header` [#&#8203;270](Kludex/python-multipart#270).

### [`v0.0.28`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0028-2026-05-10)

[Compare Source](Kludex/python-multipart@0.0.27...0.0.28)

- Speed up partial-boundary tail scan via `bytes.find` [#&#8203;281](Kludex/python-multipart#281).
- Cap multipart boundary length at 256 bytes [#&#8203;282](Kludex/python-multipart#282).

### [`v0.0.27`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0027-2026-04-27)

[Compare Source](Kludex/python-multipart@0.0.26...0.0.27)

- Add multipart header limits [#&#8203;267](Kludex/python-multipart#267).
- Pass parse offsets via constructors [#&#8203;268](Kludex/python-multipart#268).

### [`v0.0.26`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0026-2026-04-10)

[Compare Source](Kludex/python-multipart@0.0.25...0.0.26)

- Skip preamble before the first multipart boundary more efficiently [#&#8203;262](Kludex/python-multipart#262).
- Silently discard epilogue data after the closing multipart boundary [#&#8203;259](Kludex/python-multipart#259).

### [`v0.0.25`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0025-2026-04-10)

[Compare Source](Kludex/python-multipart@0.0.24...0.0.25)

- Add MIME content type info to `File` [#&#8203;143](Kludex/python-multipart#143).
- Handle CTE values case-insensitively [#&#8203;258](Kludex/python-multipart#258).
- Remove custom `FormParser` classes [#&#8203;257](Kludex/python-multipart#257).
- Add `UPLOAD_DELETE_TMP` to `FormParser` config [#&#8203;254](Kludex/python-multipart#254).
- Emit `field_end` for trailing bare field names on finalize [#&#8203;230](Kludex/python-multipart#230).
- Handle multipart headers case-insensitively [#&#8203;252](Kludex/python-multipart#252).
- Apply Apache-2.0 properly [#&#8203;247](Kludex/python-multipart#247).

### [`v0.0.24`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0024-2026-04-05)

[Compare Source](Kludex/python-multipart@0.0.23...0.0.24)

- Validate `chunk_size` in `parse_form()` [#&#8203;244](Kludex/python-multipart#244).

### [`v0.0.23`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0023-2026-04-05)

[Compare Source](Kludex/python-multipart@0.0.22...0.0.23)

- Remove unused `trust_x_headers` parameter and `X-File-Name` fallback [#&#8203;196](Kludex/python-multipart#196).
- Return processed length from `QuerystringParser._internal_write` [#&#8203;229](Kludex/python-multipart#229).
- Cleanup metadata dunders from `__init__.py` [#&#8203;227](Kludex/python-multipart#227).

</details>

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMTYiLCJ1cGRhdGVkSW5WZXIiOiI0My4yNDYuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIiwicmVub3ZhdGUiXX0=-->

See merge request swiss-armed-forces/cyber-command/cea/loom!460

Co-authored-by: Loom MR Pipeline Trigger <group_103951964_bot_9504bb8dead6d4e406ad817a607f24be@noreply.gitlab.com>
Co-authored-by: shrewd-laidback palace <shrewd-laidback-palace-736-c41-2c1-e464fc974@swiss-armed-forces-open-source.ch>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Problems resuming multiple threads if in_process_debug_adapter is True

3 participants