Didn't find this reported specifically, hence filing a new bug.
Not sure if it's debugger problem or pydantic / pytest / possibly others.
Environment data
debugpy version: 1.8.16 baked in ms-python.debugpy-2025.15.2025110302-linux-x64
OS and version: Fedora 42 kernel 6.17.5-200.fc42.x86_64
Python version (& distribution if applicable, e.g. Anaconda): Python 3.14.0 (main, Oct 7 2025, 00:00:00) [GCC 15.2.1 20250808 (Red Hat 15.2.1-1)] on linux
Using VS Code or Visual Studio:
VS Code
Version: 1.105.1
Commit: 7d842fb85a0275a4a8e4d7e040d2625abbf7f084
Date: 2025-10-14T22:33:36.618Z
Electron: 37.6.0
ElectronBuildId: 12502201
Chromium: 138.0.7204.251
Node.js: 22.19.0
V8: 13.8.258.32-electron.0
OS: Linux x64 6.17.5-200.fc42.x86_64
Actual behavior
Debugger raises "User Uncaught Exceptions" on every annotated pytest fixture and pydantic model on python 3.14 when they're imported (I guess it tries to inspect annotations in wrong way or these libraries are somehow mangling the new annotations).
On python 3.13 - it works fine (no exceptions).
Exception has occurred: NotImplementedError (note: full exception trace is shown but execution is paused at: __annotate__)
exception: no description
File "/home/pslama/wrkspaces/test/test_annotations.py", line 25, in __annotate__ (Current frame)
class AnnotatedTest(BaseModel):
File "/home/pslama/wrkspaces/test/test_annotations.py", line 25, in <module>
class AnnotatedTest(BaseModel):
NotImplementedError:
Expected behavior
No such exceptions.
Steps to reproduce:
Create py3.14 venv with pydantic and pytest packages
Configure pytest as test runner in VS Code test explorer
Create test_anything.py file containing pydantic model and/or annotated pytest fixture and test function
Check User Uncaught Exceptions in Run and Debug panel
I believe this is caused by justMyCode not working entirely in 3.14. If you turn off 'User Uncaught Exceptions' or you ignore the exception, the test passes. pytest is throwing an exception and debugpy is marking that exception as being thrown from user code (which is where the bug is). But the exception is harmless.
Looking at the __annotate__ stack, it looks like debugpy would have to special case this. This is where 3.14 is calling the annotate function:
defcall_annotate_function(annotate, format, *, owner=None, _is_evaluate=False):
"""Call an __annotate__ function. __annotate__ functions are normally generated by the compiler to defer the evaluation of annotations. They can be called with any of the format arguments in the Format enum, but compiler-generated __annotate__ functions only support the VALUE format. This function provides additional functionality to call __annotate__ functions with the FORWARDREF and STRING formats. *annotate* must be an __annotate__ function, which takes a single argument and returns a dict of annotations. *format* must be a member of the Format enum or one of the corresponding integer values. *owner* can be the object that owns the annotations (i.e., the module, class, or function that the __annotate__ function derives from). With the FORWARDREF format, it is used to provide better evaluation capabilities on the generated ForwardRef objects. """ifformat==Format.VALUE_WITH_FAKE_GLOBALS:
raiseValueError("The VALUE_WITH_FAKE_GLOBALS format is for internal use only")
try:
returnannotate(format) <--thislinehereexceptNotImplementedError:
I believe this is caused by justMyCode not working entirely in 3.14. If you turn off 'User Uncaught Exceptions' or you ignore the exception, the test passes. pytest is throwing an exception and debugpy is marking that exception as being thrown from user code (which is where the bug is). But the exception is harmless.
I know the exceptions can be ignored and the test passes, but so many exceptions (one for each annotated model, fixture, test) despite being harmless render whole "User Uncaught Exceptions" unusable in 3.14.
But without it the debugger won't stop even on geniune exceptions raised in user code during pytest run - and that's a problem during test debugging.
Reacted by Philipp A., Isaac, João Moreno, Jojain and kennethd-decathlon
changed the title [-]Python 3.14: __annotate__ NotImplementedError on annotated pytest fixtures / pydantic models[/-][+]Python 3.14: __annotate__ NotImplementedError on annotated pytest fixtures, tests and pydantic models[/+]on Nov 4, 2025
In 3.14 the way annotations work by default changed. They are now effectively closures/thunks to make the evaluation of the annotations lazy. As such, when you try to read them they need to be resolved (typically with annotationslib), which then means executing the closure. I think debugpy just needs to be taught that those closures are a Python thing and not a user thing.
Tibor (@tiborrr) I know, but it means adding the ignore to every pydantic model, every pytest fixture and every test! That's a lot of clutter for a workaround.
Rich Chiodo (@rchiodo) I'm not sure who best to ask but is it possible to accelerate the next release to get this out? It is making debugging in Cursor and Vscode almost unusable
This is going to be a while. There are bugs in our build pipeline that depend upon another team fixing their output. Debugpy binaries have to run through a bunch of security checks and we're stalled waiting on the C++ compiler to fix a warning in a lib.
Philipp A. (@flying-sheep) maybe I am missing something but it's a pain to keep deleting and reinstalling my environment when swapping from 3.14 for production and 3.13 for debugging as writing code in 3.13 and then pushing to 3.14 seems like a recipe for disaster. Rich Chiodo (@rchiodo) I appreciate you trying, hopefully these other pipeline issues and patches get sorted soon.
@flying-sheep maybe I am missing something but it's a pain to keep deleting and reinstalling my environment when swapping from 3.14 for production and 3.13 for debugging as writing code in 3.13 and then pushing to 3.14 seems like a recipe for disaster.
Rollo Kennedy-Dyson (@rollokd) I don't know your setup but you can create 2 environments (like .venv3.13 and .venv3.14) and switch in python environments extension (+deactivate and reactivate environment in open terminals - there's a button to do that). And then keep them both up to date whenever dependecies change. Somewhat cumbersome but at least locally works. With containers it's worse - those you'd have to keep rebuilding..
We’re getting far off-topic here, but this is exactly why I use Hatch instead of uv’s CLI. With Hatch one declares multiple environments for multiple test scenarios, and you can easily run stuff in them like e.g. hatch run hatch-test.py3.14:uv pip list. In our projects, we usually use three test environments: “default resolution with all extras with newest Python” (should give what users installing the package get), “minimal specified version with all extras and minimum supported Python”, and “default, but no extras active” (to check if no misplaced imports introduce accidental dependencies).
Activity
rchiodo commented on Nov 4, 2025
I believe this is caused by justMyCode not working entirely in 3.14. If you turn off 'User Uncaught Exceptions' or you ignore the exception, the test passes. pytest is throwing an exception and debugpy is marking that exception as being thrown from user code (which is where the bug is). But the exception is harmless.
rchiodo commented on Nov 4, 2025
Looking at the __annotate__ stack, it looks like debugpy would have to special case this. This is where 3.14 is calling the annotate function:
I think it was caused by a change in 3.14 here:
python/cpython@7b7b90d
pavel-slama commented on Nov 4, 2025
I know the exceptions can be ignored and the test passes, but so many exceptions (one for each annotated model, fixture, test) despite being harmless render whole "User Uncaught Exceptions" unusable in 3.14.
But without it the debugger won't stop even on geniune exceptions raised in user code during pytest run - and that's a problem during test debugging.
brettcannon commented on Nov 4, 2025
In 3.14 the way annotations work by default changed. They are now effectively closures/thunks to make the evaluation of the annotations lazy. As such, when you try to read them they need to be resolved (typically with annotationslib), which then means executing the closure. I think debugpy just needs to be taught that those closures are a Python thing and not a user thing.
tiborrr commented on Dec 15, 2025
Pavel Slama (@pavel-slama) as a workaround you can add the #@IgnoreException to your code:
for example:
pavel-slama commented on Dec 16, 2025
Tibor (@tiborrr) I know, but it means adding the ignore to every pydantic model, every pytest fixture and every test! That's a lot of clutter for a workaround.
I'm sticking to py3.13 until it's fixed.
rollokd commented on Jan 9, 2026
+1
I found the same issue using pydantic and pytest in our codebase, installed with uv and running in cursor.
rollokd commented on Jan 19, 2026
Rich Chiodo (@rchiodo) I'm not sure who best to ask but is it possible to accelerate the next release to get this out? It is making debugging in Cursor and Vscode almost unusable
flying-sheep commented on Jan 19, 2026
Rollo Kennedy-Dyson (@rollokd) I’m all for it but can’t you just debug on Python 3.13?
rchiodo commented on Jan 20, 2026
I usually wait until there's a least 2 or 3 fixes before releasing. Maybe this one is important enough to warrant its own fix though.
rchiodo commented on Jan 21, 2026
This is going to be a while. There are bugs in our build pipeline that depend upon another team fixing their output. Debugpy binaries have to run through a bunch of security checks and we're stalled waiting on the C++ compiler to fix a warning in a lib.
rollokd commented on Jan 21, 2026
Philipp A. (@flying-sheep) maybe I am missing something but it's a pain to keep deleting and reinstalling my environment when swapping from 3.14 for production and 3.13 for debugging as writing code in 3.13 and then pushing to 3.14 seems like a recipe for disaster.
Rich Chiodo (@rchiodo) I appreciate you trying, hopefully these other pipeline issues and patches get sorted soon.
pavel-slama commented on Jan 21, 2026
Rollo Kennedy-Dyson (@rollokd) I don't know your setup but you can create 2 environments (like .venv3.13 and .venv3.14) and switch in python environments extension (+deactivate and reactivate environment in open terminals - there's a button to do that). And then keep them both up to date whenever dependecies change. Somewhat cumbersome but at least locally works. With containers it's worse - those you'd have to keep rebuilding..
flying-sheep commented on Jan 21, 2026
We’re getting far off-topic here, but this is exactly why I use Hatch instead of uv’s CLI. With Hatch one declares multiple environments for multiple test scenarios, and you can easily run stuff in them like e.g. hatch run hatch-test.py3.14:uv pip list. In our projects, we usually use three test environments: “default resolution with all extras with newest Python” (should give what users installing the package get), “minimal specified version with all extras and minimum supported Python”, and “default, but no extras active” (to check if no misplaced imports introduce accidental dependencies).
rchiodo commented on Jan 29, 2026
Version https://github.com/microsoft/debugpy/releases/tag/v1.8.20 has the fix for this issue. It should show up in a future version of the vscode-python-debugger extension or you can install it through pypi.
fix(deps): update backend dependencies (patch) (patch)
Merge branch 'renovate/patch-backend-dependencies' into 'main'