Skip to content

Commit

Permalink
Add some more typing for the public api (#1619)
Browse files Browse the repository at this point in the history
* Add some more typing for the public api

* Review feedback
  • Loading branch information
rchiodo authored Jul 3, 2024
1 parent cfe3fef commit 1d7c662
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 27 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ exclude = '''
[tool.pyright]
pythonVersion = "3.8"
include = ["src/**", "tests/**" ]
extraPaths = ["src/debugpy/_vendored/pydevd"]
extraPaths = ["src/debugpy/_vendored/pydevd", "src/debugpy/_vendored/pydevd/pydevd_attach_to_process"]
ignore = ["src/debugpy/_vendored/pydevd", "src/debugpy/_version.py"]
executionEnvironments = [
{ root = "src" }, { root = "." }
Expand Down
9 changes: 5 additions & 4 deletions src/debugpy/public_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ def cancel(*args, **kwargs):
wrapped = getattr(api, f.__name__)
return wrapped.cancel(*args, **kwargs)

wrapper.cancel = cancel
wrapper.cancel = cancel # pyright: ignore

return wrapper

return apply


@_api()
def log_to(__path: str) -> None:
def log_to(__path: str | typing.TextIO) -> None:
"""Generate detailed debugpy logs in the specified directory.
The directory must already exist. Several log files are generated,
Expand Down Expand Up @@ -117,7 +117,7 @@ def listen(
adapter that it starts. Use `wait_for_client` to block execution
until the client connects.
"""

...

@_api()
def connect(__endpoint: Endpoint | int, *, access_token: str | None = None) -> Endpoint:
Expand All @@ -135,7 +135,7 @@ def connect(__endpoint: Endpoint | int, *, access_token: str | None = None) -> E
adapter that it connects to. Use `wait_for_client` to block
execution until the client connects.
"""

...

@_api(cancelable=True)
def wait_for_client() -> None:
Expand All @@ -153,6 +153,7 @@ def is_client_connected() -> bool:
"""True if a client is connected to the debug adapter that is
debugging this process.
"""
...


@_api()
Expand Down
51 changes: 29 additions & 22 deletions src/debugpy/server/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import re
import sys
from importlib.util import find_spec
from typing import Any

# debugpy.__main__ should have preloaded pydevd properly before importing this module.
# Otherwise, some stdlib modules above might have had imported threading before pydevd
Expand All @@ -18,6 +19,7 @@
from _pydevd_bundle import pydevd_runpy as runpy

import debugpy
import debugpy.server
from debugpy.common import log
from debugpy.server import api

Expand All @@ -41,13 +43,14 @@

class Options(object):
mode = None
address = None
address: "tuple[str, int] | None" = None
log_to = None
log_to_stderr = False
target = None
target_kind = None
target: str | None = None
target_kind: str | None = None
wait_for_client = False
adapter_access_token = None
config: "dict[str, Any]" = {}


options = Options()
Expand Down Expand Up @@ -139,7 +142,7 @@ def set_config(arg, it):
options.config[name] = value


def set_target(kind, parser=(lambda x: x), positional=False):
def set_target(kind: str, parser=(lambda x: x), positional=False):
def do(arg, it):
options.target_kind = kind
target = parser(arg if positional else next(it))
Expand Down Expand Up @@ -252,9 +255,9 @@ def start_debugging(argv_0):

debugpy.configure(options.config)

if options.mode == "listen":
if options.mode == "listen" and options.address is not None:
debugpy.listen(options.address)
elif options.mode == "connect":
elif options.mode == "connect" and options.address is not None:
debugpy.connect(options.address, access_token=options.adapter_access_token)
else:
raise AssertionError(repr(options.mode))
Expand All @@ -272,7 +275,7 @@ def run_file():
# parent directory to sys.path. Thus, importing other modules from the
# same directory is broken unless sys.path is patched here.

if os.path.isfile(target):
if target is not None and os.path.isfile(target):
dir = os.path.dirname(target)
sys.path.insert(0, dir)
else:
Expand All @@ -293,7 +296,7 @@ def run_module():
# actually invoking it.
argv_0 = sys.argv[0]
try:
spec = find_spec(options.target)
spec = None if options.target is None else find_spec(options.target)
if spec is not None:
argv_0 = spec.origin
except Exception:
Expand All @@ -318,16 +321,19 @@ def run_module():


def run_code():
# Add current directory to path, like Python itself does for -c.
sys.path.insert(0, str(""))
code = compile(options.target, str("<string>"), str("exec"))
if options.target is not None:
# Add current directory to path, like Python itself does for -c.
sys.path.insert(0, str(""))
code = compile(options.target, str("<string>"), str("exec"))

start_debugging(str("-c"))
start_debugging(str("-c"))

log.describe_environment("Pre-launch environment:")
log.info("Running code:\n\n{0}", options.target)
log.describe_environment("Pre-launch environment:")
log.info("Running code:\n\n{0}", options.target)

eval(code, {})
eval(code, {})
else:
log.error("No target to run.")


def attach_to_pid():
Expand Down Expand Up @@ -421,13 +427,14 @@ def main():
)

try:
run = {
"file": run_file,
"module": run_module,
"code": run_code,
"pid": attach_to_pid,
}[options.target_kind]
run()
if options.target_kind is not None:
run = {
"file": run_file,
"module": run_module,
"code": run_code,
"pid": attach_to_pid,
}[options.target_kind]
run()
except SystemExit as exc:
log.reraise_exception(
"Debuggee exited via SystemExit: {0!r}", exc.code, level="debug"
Expand Down

0 comments on commit 1d7c662

Please sign in to comment.