mirror of
https://github.com/microsoft/debugpy.git
synced 2025-12-23 08:48:12 +00:00
Blacken code.
This commit is contained in:
parent
cb25e2f106
commit
dd5196fbfc
36 changed files with 160 additions and 189 deletions
|
|
@ -95,7 +95,9 @@ def main(args):
|
|||
|
||||
listener_file = os.getenv("DEBUGPY_ADAPTER_ENDPOINTS")
|
||||
if listener_file is not None:
|
||||
log.info("Writing endpoints info to {0!r}:\n{1}", listener_file, json.repr(endpoints))
|
||||
log.info(
|
||||
"Writing endpoints info to {0!r}:\n{1}", listener_file, json.repr(endpoints)
|
||||
)
|
||||
|
||||
def delete_listener_file():
|
||||
log.info("Listener ports closed; deleting {0!r}", listener_file)
|
||||
|
|
|
|||
|
|
@ -12,9 +12,7 @@ ACCEPT_CONNECTIONS_TIMEOUT = 10
|
|||
|
||||
class ComponentNotAvailable(Exception):
|
||||
def __init__(self, type):
|
||||
super(ComponentNotAvailable, self).__init__(
|
||||
f"{type.__name__} is not available"
|
||||
)
|
||||
super(ComponentNotAvailable, self).__init__(f"{type.__name__} is not available")
|
||||
|
||||
|
||||
class Component(util.Observable):
|
||||
|
|
@ -167,7 +165,9 @@ class Capabilities(dict):
|
|||
except Exception as exc:
|
||||
raise message.isnt_valid("{0} {1}", json.repr(name), exc)
|
||||
|
||||
assert value != (), f"{validate} must provide a default value for missing properties."
|
||||
assert (
|
||||
value != ()
|
||||
), f"{validate} must provide a default value for missing properties."
|
||||
self[name] = value
|
||||
|
||||
log.debug("{0}", self)
|
||||
|
|
|
|||
|
|
@ -124,7 +124,9 @@ def spawn_debuggee(
|
|||
cmdline[i] = arg
|
||||
except UnicodeEncodeError as exc:
|
||||
raise start_request.cant_handle(
|
||||
"Invalid command line argument {0}: {1}", json.repr(arg), exc
|
||||
"Invalid command line argument {0}: {1}",
|
||||
json.repr(arg),
|
||||
exc,
|
||||
)
|
||||
|
||||
# If we are talking to the client over stdio, sys.stdin and sys.stdout
|
||||
|
|
|
|||
|
|
@ -110,9 +110,7 @@ if 'debugpy' not in sys.modules:
|
|||
return
|
||||
|
||||
if any(conn.pid == self.pid for conn in _connections):
|
||||
raise KeyError(
|
||||
f"{self} is already connected to this adapter"
|
||||
)
|
||||
raise KeyError(f"{self} is already connected to this adapter")
|
||||
|
||||
is_first_server = len(_connections) == 0
|
||||
_connections.append(self)
|
||||
|
|
@ -468,7 +466,9 @@ def inject(pid, debugpy_args):
|
|||
"Failed to inject debug server into process with PID={0}", pid
|
||||
)
|
||||
raise messaging.MessageHandlingError(
|
||||
"Failed to inject debug server into process with PID={0}: {1}".format(pid, exc)
|
||||
"Failed to inject debug server into process with PID={0}: {1}".format(
|
||||
pid, exc
|
||||
)
|
||||
)
|
||||
|
||||
# We need to capture the output of the injector - otherwise it can get blocked
|
||||
|
|
@ -483,7 +483,8 @@ def inject(pid, debugpy_args):
|
|||
log.info("Injector[PID={0}] exited.", pid)
|
||||
|
||||
thread = threading.Thread(
|
||||
target=capture_output, name=f"Injector[PID={pid}] output",
|
||||
target=capture_output,
|
||||
name=f"Injector[PID={pid}] output",
|
||||
)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
|
|
|||
|
|
@ -274,4 +274,4 @@ def repr(value):
|
|||
|
||||
|
||||
dumps = json.dumps
|
||||
loads = json.loads
|
||||
loads = json.loads
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class LogFile(object):
|
|||
platform.machine(),
|
||||
platform.python_implementation(),
|
||||
platform.python_version(),
|
||||
64 if sys.maxsize > 2 ** 32 else 32,
|
||||
64 if sys.maxsize > 2**32 else 32,
|
||||
debugpy.__version__,
|
||||
_to_files=[self],
|
||||
)
|
||||
|
|
@ -216,8 +216,7 @@ def swallow_exception(format_string="", *args, **kwargs):
|
|||
|
||||
|
||||
def reraise_exception(format_string="", *args, **kwargs):
|
||||
"""Like swallow_exception(), but re-raises the current exception after logging it.
|
||||
"""
|
||||
"""Like swallow_exception(), but re-raises the current exception after logging it."""
|
||||
|
||||
assert "exc_info" not in kwargs
|
||||
_exception(format_string, *args, **kwargs)
|
||||
|
|
@ -330,8 +329,7 @@ def describe_environment(header):
|
|||
site_packages = [
|
||||
p
|
||||
for p in sys.path
|
||||
if os.path.exists(p)
|
||||
and os.path.basename(p) == "site-packages"
|
||||
if os.path.exists(p) and os.path.basename(p) == "site-packages"
|
||||
]
|
||||
report_paths(lambda: site_packages, "sys.path (site-packages)")
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,7 @@ from debugpy.common import json, log, util
|
|||
|
||||
|
||||
class JsonIOError(IOError):
|
||||
"""Indicates that a read or write operation on JsonIOStream has failed.
|
||||
"""
|
||||
"""Indicates that a read or write operation on JsonIOStream has failed."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
stream = kwargs.pop("stream")
|
||||
|
|
@ -85,8 +84,7 @@ class JsonIOStream(object):
|
|||
|
||||
@classmethod
|
||||
def from_socket(cls, sock, name=None):
|
||||
"""Creates a new instance that sends and receives messages over a socket.
|
||||
"""
|
||||
"""Creates a new instance that sends and receives messages over a socket."""
|
||||
sock.settimeout(None) # make socket blocking
|
||||
if name is None:
|
||||
name = repr(sock)
|
||||
|
|
@ -133,8 +131,7 @@ class JsonIOStream(object):
|
|||
self._closed = False
|
||||
|
||||
def close(self):
|
||||
"""Closes the stream, the reader, and the writer.
|
||||
"""
|
||||
"""Closes the stream, the reader, and the writer."""
|
||||
|
||||
if self._closed:
|
||||
return
|
||||
|
|
@ -270,7 +267,7 @@ class JsonIOStream(object):
|
|||
|
||||
Value is written as encoded by encoder.encode().
|
||||
"""
|
||||
|
||||
|
||||
if self._closed:
|
||||
# Don't log this - it's a common pattern to write to a stream while
|
||||
# anticipating EOFError from it in case it got closed concurrently.
|
||||
|
|
@ -478,15 +475,13 @@ class Message(object):
|
|||
return key in self.payload
|
||||
|
||||
def is_event(self, *event):
|
||||
"""Returns True if this message is an Event of one of the specified types.
|
||||
"""
|
||||
"""Returns True if this message is an Event of one of the specified types."""
|
||||
if not isinstance(self, Event):
|
||||
return False
|
||||
return event == () or self.event in event
|
||||
|
||||
def is_request(self, *command):
|
||||
"""Returns True if this message is a Request of one of the specified types.
|
||||
"""
|
||||
"""Returns True if this message is a Request of one of the specified types."""
|
||||
if not isinstance(self, Request):
|
||||
return False
|
||||
return command == () or self.command in command
|
||||
|
|
@ -519,13 +514,11 @@ class Message(object):
|
|||
return exc
|
||||
|
||||
def isnt_valid(self, *args, **kwargs):
|
||||
"""Same as self.error(InvalidMessageError, ...).
|
||||
"""
|
||||
"""Same as self.error(InvalidMessageError, ...)."""
|
||||
return self.error(InvalidMessageError, *args, **kwargs)
|
||||
|
||||
def cant_handle(self, *args, **kwargs):
|
||||
"""Same as self.error(MessageHandlingError, ...).
|
||||
"""
|
||||
"""Same as self.error(MessageHandlingError, ...)."""
|
||||
return self.error(MessageHandlingError, *args, **kwargs)
|
||||
|
||||
|
||||
|
|
@ -584,8 +577,9 @@ class Event(Message):
|
|||
try:
|
||||
try:
|
||||
result = handler(self)
|
||||
assert result is None, \
|
||||
f"Handler {util.srcnameof(handler)} tried to respond to {self.describe()}."
|
||||
assert (
|
||||
result is None
|
||||
), f"Handler {util.srcnameof(handler)} tried to respond to {self.describe()}."
|
||||
except MessageHandlingError as exc:
|
||||
if not exc.applies_to(self):
|
||||
raise
|
||||
|
|
@ -717,24 +711,21 @@ class Request(Message):
|
|||
assert self.response is None, (
|
||||
"Handler {0} for {1} must not return NO_RESPONSE if it has already "
|
||||
"invoked request.respond().".format(
|
||||
util.srcnameof(handler),
|
||||
self.describe()
|
||||
util.srcnameof(handler), self.describe()
|
||||
)
|
||||
)
|
||||
elif self.response is not None:
|
||||
assert result is None or result is self.response.body, (
|
||||
"Handler {0} for {1} must not return a response body if it has "
|
||||
"already invoked request.respond().".format(
|
||||
util.srcnameof(handler),
|
||||
self.describe()
|
||||
util.srcnameof(handler), self.describe()
|
||||
)
|
||||
)
|
||||
else:
|
||||
assert result is not None, (
|
||||
"Handler {0} for {1} must either call request.respond() before it "
|
||||
"returns, or return the response body, or return NO_RESPONSE.".format(
|
||||
util.srcnameof(handler),
|
||||
self.describe()
|
||||
util.srcnameof(handler), self.describe()
|
||||
)
|
||||
)
|
||||
try:
|
||||
|
|
@ -900,8 +891,7 @@ class Response(Message):
|
|||
|
||||
@property
|
||||
def success(self):
|
||||
"""Whether the request succeeded or not.
|
||||
"""
|
||||
"""Whether the request succeeded or not."""
|
||||
return not isinstance(self.body, Exception)
|
||||
|
||||
@property
|
||||
|
|
@ -1194,8 +1184,7 @@ class JsonMessageChannel(object):
|
|||
)
|
||||
|
||||
def _prettify(self, message_dict):
|
||||
"""Reorders items in a MessageDict such that it is more readable.
|
||||
"""
|
||||
"""Reorders items in a MessageDict such that it is more readable."""
|
||||
for key in self._prettify_order:
|
||||
if key not in message_dict:
|
||||
continue
|
||||
|
|
@ -1270,8 +1259,7 @@ class JsonMessageChannel(object):
|
|||
pass
|
||||
|
||||
def request(self, *args, **kwargs):
|
||||
"""Same as send_request(...).wait_for_response()
|
||||
"""
|
||||
"""Same as send_request(...).wait_for_response()"""
|
||||
return self.send_request(*args, **kwargs).wait_for_response()
|
||||
|
||||
def propagate(self, message):
|
||||
|
|
@ -1387,7 +1375,9 @@ class JsonMessageChannel(object):
|
|||
if isinstance(exc, NoMoreMessages) and exc.stream is self.stream:
|
||||
raise
|
||||
log.swallow_exception(
|
||||
"Fatal error in channel {0} while parsing:\n{1}", self, json.repr(message_dict)
|
||||
"Fatal error in channel {0} while parsing:\n{1}",
|
||||
self,
|
||||
json.repr(message_dict),
|
||||
)
|
||||
os._exit(1)
|
||||
|
||||
|
|
@ -1414,7 +1404,8 @@ class JsonMessageChannel(object):
|
|||
# of handlers to run.
|
||||
if len(self._handler_queue) and self._handler_thread is None:
|
||||
self._handler_thread = threading.Thread(
|
||||
target=self._run_handlers, name=f"{self} message handler",
|
||||
target=self._run_handlers,
|
||||
name=f"{self} message handler",
|
||||
)
|
||||
self._handler_thread.pydev_do_not_trace = True
|
||||
self._handler_thread.is_pydev_daemon_thread = True
|
||||
|
|
@ -1469,8 +1460,7 @@ class JsonMessageChannel(object):
|
|||
os._exit(1)
|
||||
|
||||
def _get_handler_for(self, type, name):
|
||||
"""Returns the handler for a message of a given type.
|
||||
"""
|
||||
"""Returns the handler for a message of a given type."""
|
||||
|
||||
with self:
|
||||
handlers = self.handlers
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@ from debugpy.common import log
|
|||
|
||||
|
||||
def dump():
|
||||
"""Dump stacks of all threads in this process, except for the current thread.
|
||||
"""
|
||||
"""Dump stacks of all threads in this process, except for the current thread."""
|
||||
|
||||
tid = threading.current_thread().ident
|
||||
pid = os.getpid()
|
||||
|
|
@ -49,8 +48,7 @@ def dump():
|
|||
|
||||
|
||||
def dump_after(secs):
|
||||
"""Invokes dump() on a background thread after waiting for the specified time.
|
||||
"""
|
||||
"""Invokes dump() on a background thread after waiting for the specified time."""
|
||||
|
||||
def dumper():
|
||||
time.sleep(secs)
|
||||
|
|
|
|||
|
|
@ -33,13 +33,11 @@ class Observable(object):
|
|||
|
||||
|
||||
class Env(dict):
|
||||
"""A dict for environment variables.
|
||||
"""
|
||||
"""A dict for environment variables."""
|
||||
|
||||
@staticmethod
|
||||
def snapshot():
|
||||
"""Returns a snapshot of the current environment.
|
||||
"""
|
||||
"""Returns a snapshot of the current environment."""
|
||||
return Env(os.environ)
|
||||
|
||||
def copy(self, updated_from=None):
|
||||
|
|
@ -84,14 +82,12 @@ def force_bytes(s, encoding, errors="strict"):
|
|||
|
||||
|
||||
def force_ascii(s, errors="strict"):
|
||||
"""Same as force_bytes(s, "ascii", errors)
|
||||
"""
|
||||
"""Same as force_bytes(s, "ascii", errors)"""
|
||||
return force_bytes(s, "ascii", errors)
|
||||
|
||||
|
||||
def force_utf8(s, errors="strict"):
|
||||
"""Same as force_bytes(s, "utf8", errors)
|
||||
"""
|
||||
"""Same as force_bytes(s, "utf8", errors)"""
|
||||
return force_bytes(s, "utf8", errors)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ returns True, the launcher pauses and waits for user input before exiting.
|
|||
|
||||
|
||||
def describe():
|
||||
return f"Debuggee[PID={process.pid}]"
|
||||
return f"Debuggee[PID={process.pid}]"
|
||||
|
||||
|
||||
def spawn(process_name, cmdline, env, redirect_output):
|
||||
|
|
@ -91,7 +91,9 @@ def spawn(process_name, cmdline, env, redirect_output):
|
|||
process = subprocess.Popen(cmdline, env=env, bufsize=0, **kwargs)
|
||||
except Exception as exc:
|
||||
raise messaging.MessageHandlingError(
|
||||
"Couldn't spawn debuggee: {0}\n\nCommand line:{1!r}".format(exc, cmdline)
|
||||
"Couldn't spawn debuggee: {0}\n\nCommand line:{1!r}".format(
|
||||
exc, cmdline
|
||||
)
|
||||
)
|
||||
|
||||
log.info("Spawned {0}.", describe())
|
||||
|
|
@ -116,7 +118,8 @@ def spawn(process_name, cmdline, env, redirect_output):
|
|||
job_info.BasicLimitInformation.LimitFlags |= (
|
||||
# Ensure that the job will be terminated by the OS once the
|
||||
# launcher exits, even if it doesn't terminate the job explicitly.
|
||||
winapi.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE |
|
||||
winapi.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
|
||||
|
|
||||
# Allow the debuggee to create its own jobs unrelated to ours.
|
||||
winapi.JOB_OBJECT_LIMIT_BREAKAWAY_OK
|
||||
)
|
||||
|
|
|
|||
|
|
@ -88,7 +88,9 @@ def launch_request(request):
|
|||
if new_env_changes[k_upper] == v:
|
||||
continue
|
||||
else:
|
||||
raise request.isnt_valid('Found duplicate in "env": {0}.'.format(k_upper))
|
||||
raise request.isnt_valid(
|
||||
'Found duplicate in "env": {0}.'.format(k_upper)
|
||||
)
|
||||
new_env_changes[k_upper] = v
|
||||
env_changes = new_env_changes
|
||||
if "DEBUGPY_TEST" in env:
|
||||
|
|
|
|||
|
|
@ -102,8 +102,7 @@ class CaptureOutput(object):
|
|||
|
||||
|
||||
def wait_for_remaining_output():
|
||||
"""Waits for all remaining output to be captured and propagated.
|
||||
"""
|
||||
"""Waits for all remaining output to be captured and propagated."""
|
||||
for category, instance in CaptureOutput.instances.items():
|
||||
log.info("Waiting for remaining {0} of {1}.", category, instance._whose)
|
||||
instance._worker_thread.join()
|
||||
|
|
|
|||
|
|
@ -52,8 +52,7 @@ _settrace.called = False
|
|||
|
||||
|
||||
def ensure_logging():
|
||||
"""Starts logging to log.log_dir, if it hasn't already been done.
|
||||
"""
|
||||
"""Starts logging to log.log_dir, if it hasn't already been done."""
|
||||
if ensure_logging.ensured:
|
||||
return
|
||||
ensure_logging.ensured = True
|
||||
|
|
@ -114,7 +113,7 @@ def _starts_debugging(func):
|
|||
port.__index__() # ensure it's int-like
|
||||
except Exception:
|
||||
raise ValueError("expected port or (host, port)")
|
||||
if not (0 <= port < 2 ** 16):
|
||||
if not (0 <= port < 2**16):
|
||||
raise ValueError("invalid port number")
|
||||
|
||||
ensure_logging()
|
||||
|
|
@ -246,7 +245,9 @@ def listen(address, settrace_kwargs):
|
|||
client_port = int(endpoints["client"]["port"])
|
||||
except Exception as exc:
|
||||
log.swallow_exception(
|
||||
"Error parsing adapter endpoints:\n{0}\n", json.repr(endpoints), level="info"
|
||||
"Error parsing adapter endpoints:\n{0}\n",
|
||||
json.repr(endpoints),
|
||||
level="info",
|
||||
)
|
||||
raise RuntimeError("error parsing adapter endpoints: " + str(exc))
|
||||
log.info(
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ def set_address(mode):
|
|||
port = int(port)
|
||||
except Exception:
|
||||
port = -1
|
||||
if not (0 <= port < 2 ** 16):
|
||||
if not (0 <= port < 2**16):
|
||||
raise ValueError("invalid port number")
|
||||
|
||||
options.mode = mode
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ def get_marked_line_numbers(path):
|
|||
with open(path, "rb") as f:
|
||||
lines = {}
|
||||
for i, line in enumerate(f):
|
||||
match = re.search(br"#\s*@(.+?)\s*$", line)
|
||||
match = re.search(rb"#\s*@(.+?)\s*$", line)
|
||||
if match:
|
||||
markers = match.group(1).decode("ascii")
|
||||
for marker in markers.split(","):
|
||||
|
|
|
|||
|
|
@ -58,9 +58,7 @@ class BackChannel(object):
|
|||
self._socket = sock
|
||||
self._setup_stream()
|
||||
|
||||
accept_thread = threading.Thread(
|
||||
target=accept_worker, name=f"{self} listener"
|
||||
)
|
||||
accept_thread = threading.Thread(target=accept_worker, name=f"{self} listener")
|
||||
accept_thread.daemon = True
|
||||
accept_thread.start()
|
||||
|
||||
|
|
@ -115,8 +113,7 @@ class ScratchPad(object):
|
|||
raise NotImplementedError
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
"""Sets debuggee.scratchpad[key] = value inside the debugged process.
|
||||
"""
|
||||
"""Sets debuggee.scratchpad[key] = value inside the debugged process."""
|
||||
log.info("{0} debuggee.scratchpad[{1!r}] = {2!r}", self.session, key, value)
|
||||
expr = f"sys.modules['debuggee'].scratchpad[{key!r}] = {value!r}"
|
||||
self.session.request("evaluate", {"context": "repl", "expression": expr})
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ from debugpy.common import log
|
|||
|
||||
|
||||
class CapturedOutput(object):
|
||||
"""Captures stdout and stderr of the debugged process.
|
||||
"""
|
||||
"""Captures stdout and stderr of the debugged process."""
|
||||
|
||||
def __init__(self, session, **fds):
|
||||
self.session = session
|
||||
|
|
@ -59,8 +58,7 @@ class CapturedOutput(object):
|
|||
self._worker_threads.append(thread)
|
||||
|
||||
def wait(self, timeout=None):
|
||||
"""Wait for all remaining output to be captured.
|
||||
"""
|
||||
"""Wait for all remaining output to be captured."""
|
||||
if not self._worker_threads:
|
||||
return
|
||||
log.debug("Waiting for remaining {0} output...", self.session.debuggee_id)
|
||||
|
|
|
|||
|
|
@ -116,7 +116,12 @@ def _runner(f):
|
|||
|
||||
@_runner
|
||||
def launch(session, target, console=None, cwd=None):
|
||||
assert console in (None, "internalConsole", "integratedTerminal", "externalTerminal")
|
||||
assert console in (
|
||||
None,
|
||||
"internalConsole",
|
||||
"integratedTerminal",
|
||||
"externalTerminal",
|
||||
)
|
||||
|
||||
log.info("Launching {0} in {1} using {2}.", target, session, json.repr(console))
|
||||
|
||||
|
|
@ -144,9 +149,9 @@ def launch(session, target, console=None, cwd=None):
|
|||
|
||||
|
||||
def _attach_common_config(session, target, cwd):
|
||||
assert target.code is None or "debuggee.setup()" in target.code, (
|
||||
f"{target.filename} must invoke debuggee.setup()."
|
||||
)
|
||||
assert (
|
||||
target.code is None or "debuggee.setup()" in target.code
|
||||
), f"{target.filename} must invoke debuggee.setup()."
|
||||
|
||||
target.configure(session)
|
||||
config = session.config
|
||||
|
|
|
|||
|
|
@ -176,7 +176,9 @@ class Session(object):
|
|||
timeline.Event("output", some.dict.containing({"category": "stdout"})),
|
||||
timeline.Event("output", some.dict.containing({"category": "stderr"})),
|
||||
timeline.Event("output", some.dict.containing({"category": "console"})),
|
||||
timeline.Event("output", some.dict.containing({"category": "important"})),
|
||||
timeline.Event(
|
||||
"output", some.dict.containing({"category": "important"})
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
|
@ -342,8 +344,7 @@ class Session(object):
|
|||
assert not len(self.captured_output - {"stdout", "stderr"})
|
||||
|
||||
args = [exe] + [
|
||||
str(s.strpath if isinstance(s, py.path.local) else s)
|
||||
for s in args
|
||||
str(s.strpath if isinstance(s, py.path.local) else s) for s in args
|
||||
]
|
||||
|
||||
cwd = cwd.strpath if isinstance(cwd, py.path.local) else cwd
|
||||
|
|
@ -372,12 +373,7 @@ class Session(object):
|
|||
popen_fds[stream_name] = wfd
|
||||
capture_fds[stream_name] = rfd
|
||||
self.debuggee = psutil.Popen(
|
||||
args,
|
||||
cwd=cwd,
|
||||
env=env,
|
||||
bufsize=0,
|
||||
stdin=subprocess.PIPE,
|
||||
**popen_fds
|
||||
args, cwd=cwd, env=env, bufsize=0, stdin=subprocess.PIPE, **popen_fds
|
||||
)
|
||||
log.info("Spawned {0} with PID={1}", self.debuggee_id, self.debuggee.pid)
|
||||
watchdog.register_spawn(self.debuggee.pid, self.debuggee_id)
|
||||
|
|
@ -482,9 +478,7 @@ class Session(object):
|
|||
elif event.event == "debugpyAttach":
|
||||
self.observe(occ)
|
||||
pid = event("subProcessId", int)
|
||||
watchdog.register_spawn(
|
||||
pid, f"{self.debuggee_id}-subprocess-{pid}"
|
||||
)
|
||||
watchdog.register_spawn(pid, f"{self.debuggee_id}-subprocess-{pid}")
|
||||
|
||||
def run_in_terminal(self, args, cwd, env):
|
||||
exe = args.pop(0)
|
||||
|
|
@ -715,9 +709,7 @@ class Session(object):
|
|||
"variables", {"variablesReference": scopes[0]("variablesReference", int)}
|
||||
)("variables", json.array())
|
||||
|
||||
variables = collections.OrderedDict(
|
||||
((v("name", str), v) for v in variables)
|
||||
)
|
||||
variables = collections.OrderedDict(((v("name", str), v) for v in variables))
|
||||
if varnames:
|
||||
assert set(varnames) <= set(variables.keys())
|
||||
return tuple((variables[name] for name in varnames))
|
||||
|
|
@ -725,8 +717,7 @@ class Session(object):
|
|||
return variables
|
||||
|
||||
def get_variable(self, varname, frame_id=None):
|
||||
"""Same as get_variables(...)[0].
|
||||
"""
|
||||
"""Same as get_variables(...)[0]."""
|
||||
return self.get_variables(varname, frame_id=frame_id)[0]
|
||||
|
||||
def wait_for_next_event(self, event, body=some.object, freeze=True):
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ from tests.patterns import some
|
|||
|
||||
|
||||
class Target(object):
|
||||
"""Describes Python code that gets run by a Runner.
|
||||
"""
|
||||
"""Describes Python code that gets run by a Runner."""
|
||||
|
||||
def __init__(self, filename, args=()):
|
||||
if filename is not None and not isinstance(filename, py.path.local):
|
||||
|
|
@ -63,8 +62,7 @@ class Target(object):
|
|||
|
||||
@property
|
||||
def lines(self):
|
||||
"""Same as self.filename.lines, if it is valid - e.g. for @pyfile objects.
|
||||
"""
|
||||
"""Same as self.filename.lines, if it is valid - e.g. for @pyfile objects."""
|
||||
assert (
|
||||
self.filename is not None
|
||||
), "lines() requires Target created from filename"
|
||||
|
|
@ -74,13 +72,13 @@ class Target(object):
|
|||
class Program(Target):
|
||||
"""
|
||||
A Python script, executed directly.
|
||||
|
||||
|
||||
By default executes a program through its absolute path with:
|
||||
python /full/path/to/foo.py
|
||||
|
||||
|
||||
If made relative through make_relative(cwd), the cwd is set and the
|
||||
launch is made relative to it.
|
||||
|
||||
|
||||
i.e.:
|
||||
Given a path such as /full/path/to/foo.py
|
||||
if make_relative('/full/path') is called,
|
||||
|
|
|
|||
|
|
@ -348,7 +348,12 @@ def test_invalid_breakpoints(pyfile, target, run):
|
|||
expected_markers = []
|
||||
for r in requested_markers:
|
||||
e_generic = "e" + r[1:]
|
||||
e_versioned = e_generic + "-" + str(sys.version_info.major) + str(sys.version_info.minor)
|
||||
e_versioned = (
|
||||
e_generic
|
||||
+ "-"
|
||||
+ str(sys.version_info.major)
|
||||
+ str(sys.version_info.minor)
|
||||
)
|
||||
for e in e_versioned, e_generic, r:
|
||||
if e in code_to_debug.lines:
|
||||
expected_markers.append(e)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@ def test_env_replace_var(pyfile, target, run, case, new_value):
|
|||
|
||||
with debug.Session() as session:
|
||||
backchannel = session.open_backchannel()
|
||||
session.config.env[varname if case == "match_case" else varname.lower()] = new_value
|
||||
session.config.env[
|
||||
varname if case == "match_case" else varname.lower()
|
||||
] = new_value
|
||||
|
||||
os.environ[varname] = "1"
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -698,4 +698,3 @@ def test_evaluate_thread_locks(pyfile, target, run):
|
|||
assert evaluate == some.dict.containing({"result": "None"})
|
||||
|
||||
session.request_continue()
|
||||
|
||||
|
|
|
|||
|
|
@ -460,11 +460,13 @@ def test_subprocess_unobserved(pyfile, run, target, wait):
|
|||
if wait:
|
||||
# The child process should not have started running user code until
|
||||
# there was a client connection, so the breakpoint should be hit.
|
||||
child_session.wait_for_stop(expected_frames=[some.dap.frame(child, line="bp")])
|
||||
child_session.wait_for_stop(
|
||||
expected_frames=[some.dap.frame(child, line="bp")]
|
||||
)
|
||||
child_session.request_continue()
|
||||
else:
|
||||
# The breakpoint shouldn't be hit, since that line should have been
|
||||
# executed before we attached.
|
||||
# executed before we attached.
|
||||
pass
|
||||
|
||||
backchannel.send("proceed")
|
||||
|
|
@ -472,7 +474,9 @@ def test_subprocess_unobserved(pyfile, run, target, wait):
|
|||
|
||||
|
||||
@pytest.mark.parametrize("run", runners.all_launch)
|
||||
@pytest.mark.skipif(sys.platform != "win32", reason="job objects are specific to Windows")
|
||||
@pytest.mark.skipif(
|
||||
sys.platform != "win32", reason="job objects are specific to Windows"
|
||||
)
|
||||
def test_breakaway_job(pyfile, target, run):
|
||||
@pyfile
|
||||
def child():
|
||||
|
|
@ -509,10 +513,12 @@ def test_breakaway_job(pyfile, target, run):
|
|||
proc.wait()
|
||||
|
||||
with debug.Session() as parent_session:
|
||||
parent_session.config.update({
|
||||
"redirectOutput": False,
|
||||
"subProcess": False,
|
||||
})
|
||||
parent_session.config.update(
|
||||
{
|
||||
"redirectOutput": False,
|
||||
"subProcess": False,
|
||||
}
|
||||
)
|
||||
parent_session.expected_exit_code = some.int
|
||||
backchannel = parent_session.open_backchannel()
|
||||
|
||||
|
|
@ -530,4 +536,4 @@ def test_breakaway_job(pyfile, target, run):
|
|||
assert backchannel.receive() == "ok"
|
||||
|
||||
log.info("Waiting for child process...")
|
||||
child_process.wait()
|
||||
child_process.wait()
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ def expected_system_info():
|
|||
{
|
||||
"pid": some.int,
|
||||
"executable": sys.executable,
|
||||
"bitness": 64 if sys.maxsize > 2 ** 32 else 32,
|
||||
"bitness": 64 if sys.maxsize > 2**32 else 32,
|
||||
}
|
||||
),
|
||||
}
|
||||
|
|
|
|||
17
tests/net.py
17
tests/net.py
|
|
@ -34,7 +34,7 @@ def get_test_server_port(start, stop):
|
|||
n = 0
|
||||
else:
|
||||
assert worker_id == some.bytes.matching(
|
||||
br"gw(\d+)"
|
||||
rb"gw(\d+)"
|
||||
), "Unrecognized PYTEST_XDIST_WORKER format"
|
||||
n = int(worker_id[2:])
|
||||
|
||||
|
|
@ -75,8 +75,7 @@ def wait_until_port_is_listening(port, interval=1, max_attempts=1000):
|
|||
|
||||
|
||||
class WebRequest(object):
|
||||
"""An async wrapper around requests.
|
||||
"""
|
||||
"""An async wrapper around requests."""
|
||||
|
||||
@staticmethod
|
||||
def get(*args, **kwargs):
|
||||
|
|
@ -136,8 +135,7 @@ class WebRequest(object):
|
|||
)
|
||||
|
||||
def wait_for_response(self, timeout=None):
|
||||
"""Blocks until the request completes, and returns self.request.
|
||||
"""
|
||||
"""Blocks until the request completes, and returns self.request."""
|
||||
if self._worker_thread.is_alive():
|
||||
log.info("Waiting for response to {0} ...", self)
|
||||
self._worker_thread.join(timeout)
|
||||
|
|
@ -147,22 +145,19 @@ class WebRequest(object):
|
|||
return self.request
|
||||
|
||||
def response_text(self):
|
||||
"""Blocks until the request completes, and returns the response body.
|
||||
"""
|
||||
"""Blocks until the request completes, and returns the response body."""
|
||||
return self.wait_for_response().text
|
||||
|
||||
|
||||
class WebServer(object):
|
||||
"""Interacts with a web server listening on localhost on the specified port.
|
||||
"""
|
||||
"""Interacts with a web server listening on localhost on the specified port."""
|
||||
|
||||
def __init__(self, port):
|
||||
self.port = port
|
||||
self.url = f"http://localhost:{port}"
|
||||
|
||||
def __enter__(self):
|
||||
"""Blocks until the server starts listening on self.port.
|
||||
"""
|
||||
"""Blocks until the server starts listening on self.port."""
|
||||
log.info("Web server expected on {0}", self.url)
|
||||
wait_until_port_is_listening(self.port, interval=3)
|
||||
return self
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ import pydevd_file_utils
|
|||
|
||||
|
||||
class Some(object):
|
||||
"""A pattern that can be tested against a value with == to see if it matches.
|
||||
"""
|
||||
"""A pattern that can be tested against a value with == to see if it matches."""
|
||||
|
||||
def matches(self, value):
|
||||
raise NotImplementedError
|
||||
|
|
@ -36,23 +35,19 @@ class Some(object):
|
|||
return not self.matches(value)
|
||||
|
||||
def __invert__(self):
|
||||
"""The inverse pattern - matches everything that this one doesn't.
|
||||
"""
|
||||
"""The inverse pattern - matches everything that this one doesn't."""
|
||||
return Not(self)
|
||||
|
||||
def __or__(self, pattern):
|
||||
"""Union pattern - matches if either of the two patterns match.
|
||||
"""
|
||||
"""Union pattern - matches if either of the two patterns match."""
|
||||
return Either(self, pattern)
|
||||
|
||||
def such_that(self, condition):
|
||||
"""Same pattern, but it only matches if condition() is true.
|
||||
"""
|
||||
"""Same pattern, but it only matches if condition() is true."""
|
||||
return SuchThat(self, condition)
|
||||
|
||||
def in_range(self, start, stop):
|
||||
"""Same pattern, but it only matches if the start <= value < stop.
|
||||
"""
|
||||
"""Same pattern, but it only matches if the start <= value < stop."""
|
||||
return InRange(self, start, stop)
|
||||
|
||||
def equal_to(self, obj):
|
||||
|
|
@ -82,8 +77,7 @@ class Some(object):
|
|||
|
||||
|
||||
class Not(Some):
|
||||
"""Matches the inverse of the pattern.
|
||||
"""
|
||||
"""Matches the inverse of the pattern."""
|
||||
|
||||
def __init__(self, pattern):
|
||||
self.pattern = pattern
|
||||
|
|
@ -96,8 +90,7 @@ class Not(Some):
|
|||
|
||||
|
||||
class Either(Some):
|
||||
"""Matches either of the patterns.
|
||||
"""
|
||||
"""Matches either of the patterns."""
|
||||
|
||||
def __init__(self, *patterns):
|
||||
assert len(patterns) > 0
|
||||
|
|
@ -117,8 +110,7 @@ class Either(Some):
|
|||
|
||||
|
||||
class Object(Some):
|
||||
"""Matches anything.
|
||||
"""
|
||||
"""Matches anything."""
|
||||
|
||||
name = "<?>"
|
||||
|
||||
|
|
@ -127,8 +119,7 @@ class Object(Some):
|
|||
|
||||
|
||||
class Thing(Some):
|
||||
"""Matches anything that is not None.
|
||||
"""
|
||||
"""Matches anything that is not None."""
|
||||
|
||||
name = "<>"
|
||||
|
||||
|
|
@ -137,8 +128,7 @@ class Thing(Some):
|
|||
|
||||
|
||||
class InstanceOf(Some):
|
||||
"""Matches any object that is an instance of the specified type.
|
||||
"""
|
||||
"""Matches any object that is an instance of the specified type."""
|
||||
|
||||
def __init__(self, classinfo, name=None):
|
||||
if isinstance(classinfo, type):
|
||||
|
|
@ -199,8 +189,7 @@ class Path(Some):
|
|||
|
||||
|
||||
class ListContaining(Some):
|
||||
"""Matches any list that contains the specified subsequence of elements.
|
||||
"""
|
||||
"""Matches any list that contains the specified subsequence of elements."""
|
||||
|
||||
def __init__(self, *items):
|
||||
self.items = tuple(items)
|
||||
|
|
@ -241,10 +230,10 @@ class ListContaining(Some):
|
|||
class DictContaining(Some):
|
||||
"""Matches any dict that contains the specified key-value pairs::
|
||||
|
||||
d1 = {'a': 1, 'b': 2, 'c': 3}
|
||||
d2 = {'a': 1, 'b': 2}
|
||||
assert d1 == some.dict.containing(d2)
|
||||
assert d2 != some.dict.containing(d1)
|
||||
d1 = {'a': 1, 'b': 2, 'c': 3}
|
||||
d2 = {'a': 1, 'b': 2}
|
||||
assert d1 == some.dict.containing(d2)
|
||||
assert d2 != some.dict.containing(d1)
|
||||
"""
|
||||
|
||||
def __init__(self, items):
|
||||
|
|
@ -268,8 +257,7 @@ class DictContaining(Some):
|
|||
|
||||
|
||||
class Also(Some):
|
||||
"""Base class for patterns that narrow down another pattern.
|
||||
"""
|
||||
"""Base class for patterns that narrow down another pattern."""
|
||||
|
||||
def __init__(self, pattern):
|
||||
self.pattern = pattern
|
||||
|
|
@ -282,8 +270,7 @@ class Also(Some):
|
|||
|
||||
|
||||
class SuchThat(Also):
|
||||
"""Matches only if condition is true.
|
||||
"""
|
||||
"""Matches only if condition is true."""
|
||||
|
||||
def __init__(self, pattern, condition):
|
||||
super(SuchThat, self).__init__(pattern)
|
||||
|
|
@ -300,8 +287,7 @@ class SuchThat(Also):
|
|||
|
||||
|
||||
class InRange(Also):
|
||||
"""Matches only if the value is within the specified range.
|
||||
"""
|
||||
"""Matches only if the value is within the specified range."""
|
||||
|
||||
def __init__(self, pattern, start, stop):
|
||||
super(InRange, self).__init__(pattern)
|
||||
|
|
@ -319,8 +305,7 @@ class InRange(Also):
|
|||
|
||||
|
||||
class EqualTo(Also):
|
||||
"""Matches any object that is equal to the specified object.
|
||||
"""
|
||||
"""Matches any object that is equal to the specified object."""
|
||||
|
||||
def __init__(self, pattern, obj):
|
||||
super(EqualTo, self).__init__(pattern)
|
||||
|
|
@ -340,8 +325,7 @@ class EqualTo(Also):
|
|||
|
||||
|
||||
class NotEqualTo(Also):
|
||||
"""Matches any object that is not equal to the specified object.
|
||||
"""
|
||||
"""Matches any object that is not equal to the specified object."""
|
||||
|
||||
def __init__(self, pattern, obj):
|
||||
super(NotEqualTo, self).__init__(pattern)
|
||||
|
|
@ -355,8 +339,7 @@ class NotEqualTo(Also):
|
|||
|
||||
|
||||
class SameAs(Also):
|
||||
"""Matches one specific object only (i.e. makes '==' behave like 'is').
|
||||
"""
|
||||
"""Matches one specific object only (i.e. makes '==' behave like 'is')."""
|
||||
|
||||
def __init__(self, pattern, obj):
|
||||
super(SameAs, self).__init__(pattern)
|
||||
|
|
@ -370,8 +353,7 @@ class SameAs(Also):
|
|||
|
||||
|
||||
class Matching(Also):
|
||||
"""Matches any string that matches the specified regular expression.
|
||||
"""
|
||||
"""Matches any string that matches the specified regular expression."""
|
||||
|
||||
def __init__(self, pattern, regex, flags=0):
|
||||
assert isinstance(regex, bytes) or isinstance(regex, str)
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@ generates those ids sequentially.
|
|||
|
||||
|
||||
def source(path, **kwargs):
|
||||
"""Matches DAP Source objects.
|
||||
"""
|
||||
"""Matches DAP Source objects."""
|
||||
if isinstance(path, py.path.local):
|
||||
path = some.path(path)
|
||||
d = {"path": path}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,6 @@ if sys.platform != "win32":
|
|||
def long_tmpdir(request, tmpdir):
|
||||
return tmpdir
|
||||
|
||||
|
||||
else:
|
||||
import ctypes
|
||||
|
||||
|
|
@ -149,8 +148,7 @@ else:
|
|||
|
||||
@pytest.fixture
|
||||
def long_tmpdir(request, tmpdir):
|
||||
"""Like tmpdir, but ensures that it's a long rather than short filename on Win32.
|
||||
"""
|
||||
"""Like tmpdir, but ensures that it's a long rather than short filename on Win32."""
|
||||
path = tmpdir.strpath
|
||||
buffer = ctypes.create_unicode_buffer(512)
|
||||
if GetLongPathNameW(path, buffer, len(buffer)):
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ def pytest_configure(config):
|
|||
if config.option.debugpy_log_dir:
|
||||
log.log_dir = config.option.debugpy_log_dir
|
||||
else:
|
||||
bits = 64 if sys.maxsize > 2 ** 32 else 32
|
||||
bits = 64 if sys.maxsize > 2**32 else 32
|
||||
ver = "{0}.{1}-{bits}".format(*sys.version_info, bits=bits)
|
||||
log.log_dir = (tests.root / "_logs" / ver).strpath
|
||||
log.info("debugpy and pydevd logs will be under {0}", log.log_dir)
|
||||
|
|
|
|||
|
|
@ -15,10 +15,11 @@ from django.template import loader
|
|||
|
||||
exiting = False
|
||||
|
||||
|
||||
@receiver(request_finished)
|
||||
def on_request_finished(sender, **kwargs):
|
||||
if exiting:
|
||||
os._exit(0)
|
||||
os._exit(0)
|
||||
|
||||
|
||||
settings.configure(
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ def exit_app():
|
|||
exiting = True
|
||||
return "Done"
|
||||
|
||||
|
||||
@app.teardown_request
|
||||
def teardown(exception):
|
||||
if exiting:
|
||||
|
|
|
|||
|
|
@ -133,11 +133,11 @@ def test_matching():
|
|||
log_repr(pattern)
|
||||
assert pattern != "abbbc"
|
||||
|
||||
pattern = some.bytes.matching(br".(b+).")
|
||||
pattern = some.bytes.matching(rb".(b+).")
|
||||
log_repr(pattern)
|
||||
assert pattern == b"abbbc"
|
||||
|
||||
pattern = some.bytes.matching(br"bbb")
|
||||
pattern = some.bytes.matching(rb"bbb")
|
||||
log_repr(pattern)
|
||||
assert pattern != b"abbbc"
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@ from tests.timeline import Timeline, Mark, Event, Request, Response
|
|||
|
||||
|
||||
class MessageFactory(object):
|
||||
"""A factory for DAP messages that are not bound to a message channel.
|
||||
"""
|
||||
"""A factory for DAP messages that are not bound to a message channel."""
|
||||
|
||||
def __init__(self):
|
||||
self._seq_iter = itertools.count(1)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
# Licensed under the MIT License. See LICENSE in the project root
|
||||
# for license information.
|
||||
|
||||
|
||||
def test_vendoring(pyfile):
|
||||
@pyfile
|
||||
def import_debugpy():
|
||||
|
|
@ -12,15 +13,15 @@ def test_vendoring(pyfile):
|
|||
|
||||
class Dummy2(object):
|
||||
pass
|
||||
|
||||
|
||||
class Dummy3(object):
|
||||
def __getattribute__(self, *args, **kwargs):
|
||||
raise AssertionError('Error')
|
||||
raise AssertionError("Error")
|
||||
|
||||
sys.modules["pydev_dummy"] = Dummy()
|
||||
sys.modules["pydev_dummy2"] = Dummy2()
|
||||
sys.modules["pydev_dummy3"] = Dummy3()
|
||||
|
||||
|
||||
sys.modules["_pydev_dummy"] = Dummy()
|
||||
sys.modules["_pydev_dummy2"] = Dummy2()
|
||||
sys.modules["_pydev_dummy3"] = Dummy3()
|
||||
|
|
|
|||
|
|
@ -951,7 +951,9 @@ class Occurrence(Expectation):
|
|||
return hash(id(self))
|
||||
|
||||
def __repr__(self):
|
||||
return ("" if self.observed else "*") + f"{self.index}.{self.describe_circumstances()}"
|
||||
return (
|
||||
"" if self.observed else "*"
|
||||
) + f"{self.index}.{self.describe_circumstances()}"
|
||||
|
||||
def describe_circumstances(self):
|
||||
rest = repr(self.circumstances[1:])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue