Skip to content

Commit 8a37e41

Browse files
authored
Merge branch 'main' into enable-debug-pytest
2 parents 66d75f8 + be9662f commit 8a37e41

File tree

5 files changed

+65
-72
lines changed

5 files changed

+65
-72
lines changed

pythonFiles/tests/pytestadapter/helpers.py

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,14 @@
1010
import socket
1111
import subprocess
1212
import sys
13+
import threading
1314
import uuid
1415
from typing import Any, Dict, List, Optional, Union
1516

1617
TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
1718
from typing_extensions import TypedDict
1819

1920

20-
@contextlib.contextmanager
21-
def test_output_file(root: pathlib.Path, ext: str = ".txt"):
22-
"""Creates a temporary python file with a random name."""
23-
basename = (
24-
"".join(random.choice("abcdefghijklmnopqrstuvwxyz") for _ in range(9)) + ext
25-
)
26-
fullpath = root / basename
27-
try:
28-
fullpath.write_text("", encoding="utf-8")
29-
yield fullpath
30-
finally:
31-
os.unlink(str(fullpath))
32-
33-
3421
def create_server(
3522
host: str = "127.0.0.1",
3623
port: int = 0,
@@ -116,31 +103,51 @@ def runner(args: List[str]) -> Optional[Dict[str, Any]]:
116103
"-p",
117104
"vscode_pytest",
118105
] + args
106+
listener: socket.socket = create_server()
107+
_, port = listener.getsockname()
108+
listener.listen()
109+
110+
env = os.environ.copy()
111+
env.update(
112+
{
113+
"TEST_UUID": str(uuid.uuid4()),
114+
"TEST_PORT": str(port),
115+
"PYTHONPATH": os.fspath(pathlib.Path(__file__).parent.parent.parent),
116+
}
117+
)
118+
119+
result: list = []
120+
t1: threading.Thread = threading.Thread(
121+
target=_listen_on_socket, args=(listener, result)
122+
)
123+
t1.start()
124+
125+
t2 = threading.Thread(
126+
target=lambda proc_args, proc_env, proc_cwd: subprocess.run(
127+
proc_args, env=proc_env, cwd=proc_cwd
128+
),
129+
args=(process_args, env, TEST_DATA_PATH),
130+
)
131+
t2.start()
132+
133+
t1.join()
134+
t2.join()
135+
136+
return process_rpc_json(result[0]) if result else None
137+
119138

120-
with test_output_file(TEST_DATA_PATH) as output_path:
121-
env = os.environ.copy()
122-
env.update(
123-
{
124-
"TEST_UUID": str(uuid.uuid4()),
125-
"TEST_PORT": str(12345), # port is not used for tests
126-
"PYTHONPATH": os.fspath(pathlib.Path(__file__).parent.parent.parent),
127-
"TEST_OUTPUT_FILE": os.fspath(output_path),
128-
}
129-
)
130-
131-
result = subprocess.run(
132-
process_args,
133-
env=env,
134-
cwd=os.fspath(TEST_DATA_PATH),
135-
stdout=subprocess.PIPE,
136-
stderr=subprocess.PIPE,
137-
)
138-
if result.returncode != 0:
139-
print("Subprocess Run failed with:")
140-
print(result.stdout.decode(encoding="utf-8"))
141-
print(result.stderr.decode(encoding="utf-8"))
142-
143-
return process_rpc_json(output_path.read_text(encoding="utf-8"))
139+
def _listen_on_socket(listener: socket.socket, result: List[str]):
140+
"""Listen on the socket for the JSON data from the server.
141+
Created as a seperate function for clarity in threading.
142+
"""
143+
sock, (other_host, other_port) = listener.accept()
144+
all_data: list = []
145+
while True:
146+
data: bytes = sock.recv(1024 * 1024)
147+
if not data:
148+
break
149+
all_data.append(data.decode("utf-8"))
150+
result.append("".join(all_data))
144151

145152

146153
def find_test_line_number(test_name: str, test_file_path) -> str:

pythonFiles/vscode_pytest/__init__.py

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -442,19 +442,13 @@ def execution_post(
442442
Request-uuid: {testuuid}
443443
444444
{data}"""
445-
test_output_file: Optional[str] = os.getenv("TEST_OUTPUT_FILE", None)
446-
if test_output_file == "stdout":
447-
print(request)
448-
elif test_output_file:
449-
pathlib.Path(test_output_file).write_text(request, encoding="utf-8")
450-
else:
451-
try:
452-
with socket_manager.SocketManager(addr) as s:
453-
if s.socket is not None:
454-
s.socket.sendall(request.encode("utf-8"))
455-
except Exception as e:
456-
print(f"Plugin error connection error[vscode-pytest]: {e}")
457-
print(f"[vscode-pytest] data: {request}")
445+
try:
446+
with socket_manager.SocketManager(addr) as s:
447+
if s.socket is not None:
448+
s.socket.sendall(request.encode("utf-8"))
449+
except Exception as e:
450+
print(f"Plugin error connection error[vscode-pytest]: {e}")
451+
print(f"[vscode-pytest] data: {request}")
458452

459453

460454
def post_response(cwd: str, session_node: TestNode) -> None:
@@ -482,18 +476,10 @@ def post_response(cwd: str, session_node: TestNode) -> None:
482476
Request-uuid: {testuuid}
483477
484478
{data}"""
485-
test_output_file: Optional[str] = os.getenv("TEST_OUTPUT_FILE", None)
486-
if test_output_file == "stdout":
487-
print(request)
488-
elif test_output_file:
489-
pathlib.Path(test_output_file).write_text(request, encoding="utf-8")
490-
else:
491-
try:
492-
with socket_manager.SocketManager(addr) as s:
493-
if s.socket is not None:
494-
s.socket.sendall(request.encode("utf-8"))
495-
except Exception as e:
496-
print(
497-
f"Plugin!! error connection error[vscode-pytest]: {e}, port: {testPort}"
498-
)
499-
print(f"[vscode-pytest] data: {request}")
479+
try:
480+
with socket_manager.SocketManager(addr) as s:
481+
if s.socket is not None:
482+
s.socket.sendall(request.encode("utf-8"))
483+
except Exception as e:
484+
print(f"Plugin error connection error[vscode-pytest]: {e}")
485+
print(f"[vscode-pytest] data: {request}")

src/client/debugger/extension/configuration/dynamicdebugConfigurationService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export class DynamicPythonDebugConfigurationService implements IDynamicDebugConf
6969
type: DebuggerTypeName,
7070
request: 'launch',
7171
module: 'uvicorn',
72-
args: [`${fastApiPath}:app`],
72+
args: [`${fastApiPath}:app`, '--reload'],
7373
jinja: true,
7474
justMyCode: true,
7575
});

src/client/debugger/extension/configuration/providers/fastapiLaunch.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ export async function buildFastAPILaunchDebugConfiguration(
2525
type: DebuggerTypeName,
2626
request: 'launch',
2727
module: 'uvicorn',
28-
args: ['main:app'],
28+
args: ['main:app', '--reload'],
2929
jinja: true,
3030
justMyCode: true,
3131
};
3232

33-
if (!application) {
33+
if (!application && config.args) {
3434
const selectedPath = await input.showInputBox({
3535
title: DebugConfigStrings.fastapi.enterAppPathOrNamePath.title,
3636
value: 'main.py',
@@ -44,7 +44,7 @@ export async function buildFastAPILaunchDebugConfiguration(
4444
});
4545
if (selectedPath) {
4646
manuallyEnteredAValue = true;
47-
config.args = [`${path.basename(selectedPath, '.py').replace('/', '.')}:app`];
47+
config.args[0] = `${path.basename(selectedPath, '.py').replace('/', '.')}:app`;
4848
}
4949
}
5050

src/test/debugger/extension/configuration/providers/fastapiLaunch.unit.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ suite('Debugging - Configuration Provider FastAPI', () => {
5353
type: DebuggerTypeName,
5454
request: 'launch',
5555
module: 'uvicorn',
56-
args: ['main:app'],
56+
args: ['main:app', '--reload'],
5757
jinja: true,
5858
justMyCode: true,
5959
};
@@ -73,7 +73,7 @@ suite('Debugging - Configuration Provider FastAPI', () => {
7373
type: DebuggerTypeName,
7474
request: 'launch',
7575
module: 'uvicorn',
76-
args: ['main:app'],
76+
args: ['main:app', '--reload'],
7777
jinja: true,
7878
justMyCode: true,
7979
};

0 commit comments

Comments
 (0)