Skip to content

Return the endpoint from listen() with the in-process adapter - #2051

Open
Karan Dhaodiyal (karandhaodiyal28-hash) wants to merge 2 commits into
microsoft:mainfrom
karandhaodiyal28-hash:fix-listen-inprocess-return-1656
Open

Return the endpoint from listen() with the in-process adapter#2051
Karan Dhaodiyal (karandhaodiyal28-hash) wants to merge 2 commits into
microsoft:mainfrom
karandhaodiyal28-hash:fix-listen-inprocess-return-1656

Conversation

@karandhaodiyal28-hash

Copy link
Copy Markdown

debugpy.listen() is documented to return the (host, port) it ends up listening on, and it does — except when you pass in_process_debug_adapter=True, where it returns None:

host, port = debugpy.listen(5678, in_process_debug_adapter=True)
# TypeError: cannot unpack non-iterable NoneType object

The out-of-process path returns client_host, client_port at the end, but the in-process branch just did a bare return. This is especially annoying when you pass port 0, because there's then no way to find out which port was actually chosen.

This returns the endpoint from the in-process branch as well, and sets listen.called so both branches behave the same way with respect to the "listen already called" guard.

I added a small regression test that stubs out _settrace and checks the return value.

Fixes #1656.

debugpy.listen(..., in_process_debug_adapter=True) returned None, while the out-of-process path and the documented API both return the (host, port) tuple. That's a problem when you pass port 0, since there's then no way to find out which port was actually chosen. Return the endpoint and set listen.called so the in-process path matches the out-of-process one. Fixes microsoft#1656.

Signed-off-by: Karan Dhaodiyal <256503836+karandhaodiyal28-hash@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@rchiodo

Rich Chiodo (rchiodo) commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

🔒 Automated review in progress — Rich Chiodo (@rchiodo) is auto-reviewing this PR.

Comment thread src/debugpy/server/api.py Outdated
)
return
listen.called = True
return host, port

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.

Issue · Please address or respond

port is still the requested input value here, so listen(0, in_process_debug_adapter=True) now returns (host, 0) rather than the OS-assigned port. This does not meet the documented endpoint contract or the PR's stated port-0 motivation. Please obtain and return pydevd's bound port, or narrow the change and its description to explicitly document this limitation.

[verified]

Comment thread tests/debugpy/test_api.py
# Regression test for #1656: listen(..., in_process_debug_adapter=True) used
# to return None, unlike the out-of-process path which returns (host, port).
endpoint = _api.listen(("127.0.0.1", 5678), in_process_debug_adapter=True)
assert endpoint == ("127.0.0.1", 5678)

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.

Warning · Non-blocking recommendation

The fixed-port, no-op _settrace test only verifies that the input endpoint is echoed back; it cannot catch the port=0 contract gap. Add coverage that establishes whether the in-process path returns the resolved bound port for port 0.

[verified]

@rchiodo Rich Chiodo (rchiodo) added the review-auto:changes-requested Automated review: posted blocking findings to address. label Jul 31, 2026
Copilot AI lite review requested due to automatic review settings August 7, 2026 17:08

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@karandhaodiyal28-hash

Copy link
Copy Markdown
Author

Updated! Retrieved the actual bound port from pydevd for the in-process adapter path, and added regression test coverage for port 0.

@rchiodo

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

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

Comment thread src/debugpy/server/api.py
pydb.wait_for_server_socket_ready()
actual_host, actual_port = pydb._server_socket_name
else:
actual_host, actual_port = host, port

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.

Warning · Non-blocking recommendation

If _settrace() succeeds without installing a global debugger, this fallback returns the requested endpoint and can silently return port 0, violating the documented actual-endpoint contract. Treat the missing debugger as an invariant failure rather than returning a success-shaped value.

[verified]

Comment thread tests/debugpy/test_api.py
def no_settrace(monkeypatch):
# Avoid actually starting pydevd; we only care about listen()'s return value.
monkeypatch.setattr(_api, "_settrace", lambda **kwargs: None)
monkeypatch.setattr(_api.listen, "called", False)

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.

Info · Optional note

The fixture stubs _settrace but not ensure_logging(), which the @_starts_debugging wrapper still calls and can leave process-global logging state behind for other tests. Stub or restore that state so this unit test remains isolated.

[verified]

@rchiodo Rich Chiodo (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 Rich Chiodo (rchiodo) added review-auto:approved Automated review: no blocking findings (approval posted). and removed review-auto:changes-requested Automated review: posted blocking findings to address. labels Aug 7, 2026

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review-auto:approved Automated review: no blocking findings (approval posted).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

debugpy.listen() doesn't return endpoint if "in_process_debug_adapter=True" is passed

4 participants