Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 9, 2026

Fix: Treat annotate functions as library code in Python 3.14+

Problem

In Python 3.14, debugpy incorrectly treats compiler-generated __annotate__ functions (PEP 649) as user code, causing false positive "User Uncaught Exceptions" when debugging code with:

  • Annotated pytest fixtures
  • Pydantic models with type annotations
  • Any code using PEP 649 annotations

Solution

Modified in_project_scope() in pydevd.py to treat frames with co_name == "__annotate__" as library code on Python 3.14+.

Changes

  • Add special handling for __annotate__ functions in in_project_scope()
  • Add Python 3.14+ version check to gate the fix
  • Import IS_PY314_OR_GREATER constant
  • Add comprehensive comments explaining the rationale
  • Create test case for Python 3.14+ validation
  • Address all code review feedback
  • Fix code formatting (trailing whitespace)
  • Run security scan (0 alerts found)
  • Fix ruff linting error (unused variable)

Testing

✓ Manual unit test confirms fix works correctly
✓ Version check ensures no impact on Python < 3.14
✓ CodeQL security scan: 0 alerts
✓ Ruff linting passes
✓ No existing tests affected

Impact

Users on Python 3.14+ will no longer see false positive exception stops when debugging code with type annotations.

Original prompt

This section details on the original issue you should resolve

<issue_title>Python 3.14: annotate NotImplementedError on annotated pytest fixtures, tests and pydantic models</issue_title>
<issue_description>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:

  1. Create py3.14 venv with pydantic and pytest packages
  2. Configure pytest as test runner in VS Code test explorer
  3. Create test_anything.py file containing pydantic model and/or annotated pytest fixture and test function
  4. Check User Uncaught Exceptions in Run and Debug panel
  5. Run Debug Tests from test explorer

I made example repo: https://github.com/pavel-slama/py3.14-annotate-test</issue_description>

<agent_instructions>Debugpy has to special case these annotate calls to actually be in system code. Please investigate.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@rchiodo 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 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:
def call_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.

    """
    if format == Format.VALUE_WITH_FAKE_GLOBALS:
        raise ValueError("The VALUE_WITH_FAKE_GLOBALS format is for internal use only")
    try:
        return annotate(format) <-- this line here
    except NotImplementedError:

I think it was caused by a change in 3.14 here:
python/cpython@7b7b90d</comment_new>

Addresses #1971


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 4 commits January 9, 2026 17:36
Co-authored-by: rchiodo <19672699+rchiodo@users.noreply.github.com>
Co-authored-by: rchiodo <19672699+rchiodo@users.noreply.github.com>
Co-authored-by: rchiodo <19672699+rchiodo@users.noreply.github.com>
Co-authored-by: rchiodo <19672699+rchiodo@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix NotImplementedError in annotated pytest fixtures and pydantic models Fix: Treat __annotate__ functions as library code in Python 3.14+ Jan 9, 2026
Copilot AI requested a review from rchiodo January 9, 2026 17:46
@rchiodo
Copy link
Contributor

rchiodo commented Jan 9, 2026

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@rchiodo
Copy link
Contributor

rchiodo commented Jan 9, 2026

@copilot there's a ruff failure:

line 435, col 9, Local variable stop is assigned to but never used

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

Copilot AI commented Jan 9, 2026

@copilot there's a ruff failure:

line 435, col 9, Local variable stop is assigned to but never used
...

Fixed in 4cce4a6. Removed the unused stop variable since we only need to verify that the breakpoint is reached without hitting an exception.

Copilot AI requested a review from rchiodo January 9, 2026 18:20
@rchiodo
Copy link
Contributor

rchiodo commented Jan 9, 2026

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@rchiodo rchiodo marked this pull request as ready for review January 9, 2026 21:19
@rchiodo rchiodo requested a review from a team as a code owner January 9, 2026 21:19
@rchiodo
Copy link
Contributor

rchiodo commented Jan 9, 2026

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@rchiodo rchiodo merged commit bb450fc into main Jan 9, 2026
25 of 28 checks passed
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.

3 participants