-
-
Notifications
You must be signed in to change notification settings - Fork 31.8k
completion for remote pdb is not ideal #133351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I put it under the bug label for now, but maybe it's a feature. It's very close to beta freeze now, I think we should at least update the protocol so we can try to keep the protocol version and solve the issue for 3.14. I don't think the code is too complicated. |
Hm. I see two alternative fixes that wouldn't require changing the protocol schema:
PDB can't currently complete the local variable name, but wouldn't it be nice if it could? It could heuristically do that by parsing the written-but-not-yet-executed text looking for assignment statements and adding the names on the LHS to its list of possible completions. But for that to work, the server would need to get the full context of what's buffered, not just the last line of it. (Admittedly though this is a slippery slope, you'll never get something perfect without being able to actually execute the code and introspect its objects, so it's reasonable to decide that you don't want to implement this feature at all because of the fact that there would always be requests to do more - like recognize that it's a list and complete list methods for it, or the like.) |
I don't like sending with PyREPL does not even handle the local variable names defined in the previous lines for now. I think that is rather complicated because that requires constantly compile code that might not be compilable. Even if you passed the whole multi-line string, you probably will need some logic to figure out whether that's a Python command or not (checking If you think it's easier to deal with this case with a full context, we can try that. |
Huh. It seems like this is something that regular PDB gets wrong, actually. If I do:
I would expect it to complete the two variable names, since the If we fix that, so that
and
show the same completions, then my quick fix will work. |
There's a Lines 275 to 280 in 2bc8365
After fixing that, |
Ah right my brain went somewhere else. Do you want to make a PR to fix that? I can do it too. Either change line 276 to |
After #133364 is applied I think this patch makes completion do what you want: diff --git a/Lib/pdb.py b/Lib/pdb.py
index 343cf4404d7..eaea762e2db 100644
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -2933,6 +2933,7 @@ def __init__(self, pid, sockfile, interrupt_script):
self.completion_matches = []
self.state = "dumb"
self.write_failed = False
+ self.multiline_block = False
def _ensure_valid_message(self, msg):
# Ensure the message conforms to our protocol.
@@ -2979,6 +2980,7 @@ def _send(self, **kwargs):
self.write_failed = True
def read_command(self, prompt):
+ self.multiline_block = False
reply = input(prompt)
if self.state == "dumb":
@@ -3003,6 +3005,7 @@ def read_command(self, prompt):
return prefix + reply
# Otherwise, valid first line of a multi-line statement
+ self.multiline_block = True
continue_prompt = "...".ljust(len(prompt))
while codeop.compile_command(reply, "<stdin>", "single") is None:
reply += "\n" + input(continue_prompt)
@@ -3105,9 +3108,13 @@ def complete(self, text, state):
origline = readline.get_line_buffer()
line = origline.lstrip()
- stripped = len(origline) - len(line)
- begidx = readline.get_begidx() - stripped
- endidx = readline.get_endidx() - stripped
+ if self.multiline_block:
+ # We're completing a line contained in a multi-line block.
+ # Force the remote to treat it as a Python expression.
+ line = "! "
+ offset = len(origline) - len(line)
+ begidx = readline.get_begidx() - offset
+ endidx = readline.get_endidx() - offset
msg = {
"complete": { Can you try that out and see if you spot any other problems? |
Is this correct? Shouldn't it be |
Hah! Yes it should. Believe it or not it actually works even with that bug! 😆 |
It does also work with that bug fixed, so we should definitely do what you suggest, heh |
I guess |
* origin/main: (111 commits) pythongh-91048: Add filename and line number to external inspection routines (pythonGH-133385) pythongh-131178: Add tests for `ast` command-line interface (python#133329) Regenerate pcbuild.sln in Visual Studio 2022 (python#133394) pythongh-133042: disable HACL* HMAC on Emscripten (python#133064) pythongh-133351: Fix remote PDB's multi-line block tab completion (python#133387) pythongh-109700: Improve stress tests for interpreter creation (pythonGH-109946) pythongh-81793: Skip tests for os.link() to symlink on Android (pythonGH-133388) pythongh-126835: Rename `ast_opt.c` to `ast_preprocess.c` and related stuff after moving const folding to the peephole optimizier (python#131830) pythongh-91048: Relax test_async_global_awaited_by to fix flakyness (python#133368) pythongh-132457: make staticmethod and classmethod generic (python#132460) pythongh-132805: annotationlib: Fix handling of non-constant values in FORWARDREF (python#132812) pythongh-132426: Add get_annotate_from_class_namespace replacing get_annotate_function (python#132490) pythongh-81793: Always call linkat() from os.link(), if available (pythonGH-132517) pythongh-122559: Synchronize C and Python implementation of the io module about pickling (pythonGH-122628) pythongh-69605: Add PyREPL import autocomplete feature to 'What's New' (python#133358) bpo-44172: Keep reference to original window in curses subwindow objects (pythonGH-26226) pythonGH-133231: Changes to executor management to support proposed `sys._jit` module (pythonGH-133287) pythongh-133363: Fix Cmd completion for lines beginning with `! ` (python#133364) pythongh-132983: Introduce `_zstd` bindings module (pythonGH-133027) pythonGH-91048: Add utils for printing the call stack for asyncio tasks (python#133284) ...
I think this can be closed now |
Bug report
Bug description:
Due to various reasons, remote pdb client does not sync with the server entirely. For example, for multi-line inputs, it will read the full content on the client then send it to the server.
However, this introduced the issue for completion - the server doesn't know it. When user requests a completion for the multi-line code, server pdb doesn't know what completion should be provided (more specifically, whether pdb commands should be provided).
The simplest way to deal with it is to add an extra field
"mode"
in completion protocol - unless we sync the client and server perfectly, we will need it because the server knows nothing about the client.CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
!
#133362The text was updated successfully, but these errors were encountered: