Skip to content

Commit fddf0de

Browse files
committed
Fix debug output and put wait back the way it was
1 parent 4d609d2 commit fddf0de

10 files changed

Lines changed: 50 additions & 30 deletions

File tree

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ On Linux or macOS:
6565
```
6666
.../debugpy$ python3 -m tox
6767
```
68-
This will perform a full run with the default settings. A full run will run tests on Python 2.7 and 3.5-3.8, and requires all of those to be installed. If some versions are missing, or it is desired to skip them for a particular run, tox can be directed to only run tests on specific versions with `-e`. In addition, the `--developer` option can be used to skip the packaging step, running tests directly against the source code in `src/debugpy`. This should only be used when iterating on the code, and a proper run should be performed before submitting a PR. On Windows:
68+
This will perform a full run with the default settings. A full run will run tests on Python 2.7 and 3.5-3.8, and requires all of those to be installed. If some versions are missing, or it is desired to skip them for a particular run, tox can be directed to only run tests on specific versions with `-e`. In addition, the `--develop` option can be used to skip the packaging step, running tests directly against the source code in `src/debugpy`. This should only be used when iterating on the code, and a proper run should be performed before submitting a PR. On Windows:
6969
```
7070
...\debugpy> py -m tox -e py27,py37 --develop
7171
```

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ executionEnvironments = [
2222
{ root = "src" }, { root = "." }
2323
]
2424
typeCheckingMode = "standard"
25+
enableTypeIgnoreComments = false
2526

2627
[tool.ruff]
2728
# Enable the pycodestyle (`E`) and Pyflakes (`F`) rules by default.

src/debugpy/adapter/servers.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
import traceback
2020
import io
2121

22-
from debugpy.common.util import WaitForTimeout
23-
2422
access_token = None
2523
"""Access token used to authenticate with the servers."""
2624

@@ -431,11 +429,14 @@ def wait_for_connection(session, predicate, timeout: Union[float, None]=None):
431429
If there is more than one server connection already available, returns the oldest
432430
one.
433431
"""
434-
def after_wait():
432+
def wait_for_timeout():
433+
if timeout is not None:
434+
time.sleep(timeout)
435+
wait_for_timeout.timed_out = True # pyright: ignore[reportFunctionMemberAccess]
435436
with _lock:
436437
_connections_changed.set()
437-
wait_for_timeout = WaitForTimeout(timeout, after_wait)
438438

439+
wait_for_timeout.timed_out = timeout == 0 # pyright: ignore[reportFunctionMemberAccess]
439440
if timeout:
440441
thread = threading.Thread(
441442
target=wait_for_timeout, name="servers.wait_for_connection() timeout"
@@ -450,7 +451,7 @@ def after_wait():
450451
_connections_changed.clear()
451452
conns = (conn for conn in _connections if predicate(conn))
452453
conn = next(conns, None)
453-
if conn is not None or wait_for_timeout.timed_out:
454+
if conn is not None or wait_for_timeout.timed_out: # pyright: ignore[reportFunctionMemberAccess]
454455
return conn
455456
_connections_changed.wait()
456457

src/debugpy/adapter/sessions.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import os
77
import signal
88
import threading
9+
import time
910
from typing import Union
1011

1112
from debugpy import common
@@ -112,8 +113,14 @@ def wait_for(self, predicate, timeout: Union[float, None]=None):
112113
seconds regardless of whether the predicate was satisfied. The method returns
113114
False if it timed out, and True otherwise.
114115
"""
115-
wait_for_timeout = util.WaitForTimeout(timeout, lambda: self.notify_changed())
116-
116+
def wait_for_timeout():
117+
if timeout is not None:
118+
time.sleep(timeout)
119+
wait_for_timeout.timed_out = True # pyright: ignore[reportFunctionMemberAccess]
120+
self.notify_changed()
121+
122+
wait_for_timeout.timed_out = False # pyright: ignore[reportFunctionMemberAccess]
123+
117124
if timeout is not None:
118125
thread = threading.Thread(
119126
target=wait_for_timeout, name="Session.wait_for() timeout"
@@ -123,7 +130,7 @@ def wait_for(self, predicate, timeout: Union[float, None]=None):
123130

124131
with self:
125132
while not predicate():
126-
if wait_for_timeout.timed_out:
133+
if wait_for_timeout.timed_out: # pyright: ignore[reportFunctionMemberAccess]
127134
return False
128135
self._changed_condition.wait()
129136
return True

src/debugpy/common/log.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@
1212
import sys
1313
import threading
1414
import traceback
15-
from typing import Any, NoReturn, Protocol, Union
16-
from typing_extensions import TypeIs
15+
from typing import TYPE_CHECKING, Any, NoReturn, Protocol, Union
16+
17+
if TYPE_CHECKING:
18+
# Careful not force this import in production code, as it's not available in all
19+
# code that we run.
20+
from typing_extensions import TypeIs
1721

1822
import debugpy
1923
from debugpy.common import json, timestamp, util
@@ -283,7 +287,7 @@ def prefixed(format_string, *args, **kwargs):
283287
class HasName(Protocol):
284288
name: str
285289

286-
def has_name(obj: Any) -> TypeIs[HasName]:
290+
def has_name(obj: Any) -> "TypeIs[HasName]":
287291
try:
288292
return hasattr(obj, "name")
289293
except NameError:

src/debugpy/common/messaging.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@
2020
import socket
2121
import sys
2222
import threading
23-
from typing import BinaryIO, Callable, Union, cast, Any
24-
from typing_extensions import TypeIs
23+
from typing import TYPE_CHECKING, BinaryIO, Callable, Union, cast, Any
24+
if TYPE_CHECKING:
25+
# Careful not force this import in production code, as it's not available in all
26+
# code that we run.
27+
from typing_extensions import TypeIs
2528

2629
from debugpy.common import json, log, util
2730
from debugpy.common.util import hide_thread_from_debugger
@@ -429,7 +432,7 @@ class AssociableMessageDict(MessageDict):
429432
def associate_with(self, message: Message):
430433
self.message = message
431434

432-
def is_associable(obj) -> TypeIs[AssociableMessageDict]:
435+
def is_associable(obj) -> "TypeIs[AssociableMessageDict]":
433436
return isinstance(obj, MessageDict) and hasattr(obj, "associate_with")
434437

435438
def _payload(value):

src/debugpy/common/util.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,3 @@ def hide_thread_from_debugger(thread):
165165
thread.pydev_do_not_trace = True
166166
thread.is_pydev_daemon_thread = True
167167

168-
class WaitForTimeout():
169-
def __init__(self, timeout: Union[float, None], func: Callable[[], None]):
170-
self._func = func
171-
self._timeout = timeout
172-
self.timed_out = False
173-
174-
def __call__(self):
175-
if self._timeout is not None:
176-
time.sleep(self._timeout)
177-
self.timed_out = True
178-
self._func()

tests/logs.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,27 @@
44

55
import io
66
import os
7+
import shutil
78
import pytest_timeout
89
import sys
910

1011
from debugpy.common import json, log
1112

1213

14+
def write_title(title, stream=None, sep="~"):
15+
"""Write a section title.
16+
If *stream* is None sys.stderr will be used, *sep* is used to
17+
draw the line.
18+
"""
19+
if stream is None:
20+
stream = sys.stderr
21+
width, height = shutil.get_terminal_size()
22+
fill = int((width - len(title) - 2) / 2)
23+
line = " ".join([sep * fill, title, sep * fill])
24+
if len(line) < width:
25+
line += sep * (width - len(line))
26+
stream.write("\n" + line + "\n")
27+
1328
def dump():
1429
if log.log_dir is None:
1530
return
@@ -27,5 +42,5 @@ def dump():
2742
pass
2843
else:
2944
path = os.path.relpath(path, log.log_dir)
30-
pytest_timeout.write_title(path)
45+
write_title(path)
3146
print(s, file=sys.stderr)

tests/pytest_hooks.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import pytest_timeout
88
import sys
99

10-
from debugpy.common import log
10+
from debugpy.common import log # pyright: ignore[reportAttributeAccessIssue]
1111
import tests
1212
from tests import logs
1313

@@ -56,9 +56,8 @@ def pytest_runtest_makereport(item, call):
5656
def pytest_make_parametrize_id(config, val):
5757
return getattr(val, "pytest_id", None)
5858

59-
6059
# If a test times out and pytest tries to print the stacks of where it was hanging,
6160
# we want to print the pydevd log as well. This is not a normal pytest hook - we
6261
# just detour pytest_timeout.dump_stacks directly.
6362
_dump_stacks = pytest_timeout.dump_stacks
64-
pytest_timeout.dump_stacks = lambda: (_dump_stacks(), logs.dump())
63+
pytest_timeout.dump_stacks = lambda terminal: (_dump_stacks(terminal), logs.dump())

tests/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ flask
1919
gevent
2020
numpy
2121
requests
22+
typing_extensions

0 commit comments

Comments
 (0)