Skip to content

Commit fb9590f

Browse files
author
Pavel Minaev
authored
Merge pull request #46 from int19h/2079
Fix microsoft/ptvsd#2079: sys.argv sends in unicode instead of string
2 parents 9fe1be6 + 6feb7f9 commit fb9590f

2 files changed

Lines changed: 32 additions & 23 deletions

File tree

src/debugpy/server/cli.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,16 @@ def do(arg, it):
171171
# fmt: on
172172

173173

174-
def parse(args):
174+
def consume_argv():
175+
while len(sys.argv) >= 2:
176+
value = sys.argv[1]
177+
del sys.argv[1]
178+
yield value
179+
180+
181+
def parse_argv():
175182
seen = set()
176-
it = (compat.filename(arg) for arg in args)
183+
it = consume_argv()
177184

178185
while True:
179186
try:
@@ -215,14 +222,12 @@ def parse(args):
215222
assert options.target_kind is not None
216223
assert options.address is not None
217224

218-
return it
219-
220225

221226
def start_debugging(argv_0):
222227
# We need to set up sys.argv[0] before invoking either listen() or connect(),
223228
# because they use it to report the "process" event. Thus, we can't rely on
224229
# run_path() and run_module() doing that, even though they will eventually.
225-
sys.argv[0] = compat.filename(argv_0)
230+
sys.argv[0] = compat.filename_str(argv_0)
226231
log.debug("sys.argv after patching: {0!r}", sys.argv)
227232

228233
debugpy.configure(options.config)
@@ -392,7 +397,7 @@ def attach_to_pid():
392397
def main():
393398
original_argv = list(sys.argv)
394399
try:
395-
sys.argv[1:] = parse(sys.argv[1:])
400+
parse_argv()
396401
except Exception as ex:
397402
print(HELP + "\nError: " + str(ex), file=sys.stderr)
398403
sys.exit(2)

tests/debugpy/server/test_cli.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,30 @@ def cli_parser():
2323
from debugpy.server import cli
2424

2525
try:
26-
sys.argv[1:] = cli.parse(sys.argv[1:])
26+
cli.parse_argv()
2727
except Exception as exc:
2828
os.write(1, pickle.dumps(exc))
2929
sys.exit(1)
30-
else:
31-
# We only care about options that correspond to public switches.
32-
options = {
33-
name: getattr(cli.options, name)
34-
for name in [
35-
"address",
36-
"config",
37-
"log_to",
38-
"log_to_stderr",
39-
"mode",
40-
"target",
41-
"target_kind",
42-
"wait_for_client",
43-
]
44-
}
45-
os.write(1, pickle.dumps([sys.argv[1:], options]))
30+
31+
# Check that sys.argv has the correct type after parsing - there should be
32+
# no bytes on Python 3, nor unicode on Python 2.
33+
assert all(isinstance(s, str) for s in sys.argv)
34+
35+
# We only care about options that correspond to public switches.
36+
options = {
37+
name: getattr(cli.options, name)
38+
for name in [
39+
"address",
40+
"config",
41+
"log_to",
42+
"log_to_stderr",
43+
"mode",
44+
"target",
45+
"target_kind",
46+
"wait_for_client",
47+
]
48+
}
49+
os.write(1, pickle.dumps([sys.argv[1:], options]))
4650

4751
def parse(args):
4852
log.debug("Parsing argv: {0!r}", args)

0 commit comments

Comments
 (0)