Skip to content

Commit a330960

Browse files
VSCodeTools using td typings from interpreter if TD version available
1 parent 0de6080 commit a330960

File tree

11 files changed

+157
-10
lines changed

11 files changed

+157
-10
lines changed

Diff for: FunctionStore_tools_2023.code-workspace

+11-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,11 @@
1-
{"folders": [{"path": "."}]}
1+
{
2+
"folders": [
3+
{
4+
"path": "."
5+
}
6+
],
7+
"settings": {
8+
"python.defaultInterpreterPath": "C:\\Program Files\\Derivative\\TouchDesigner.2023.32139\\bin\\python.exe",
9+
"python.terminal.activateEnvironment": true
10+
}
11+
}

Diff for: modules/release/FunctionStore_tools_2023.tox

-27.3 KB
Binary file not shown.

Diff for: modules/release/OpenVSCode.tox

7.47 KB
Binary file not shown.

Diff for: modules/release/QuickExt.tox

208 Bytes
Binary file not shown.

Diff for: modules/release/VSCodeTools.tox

1.67 KB
Binary file not shown.

Diff for: modules/suspects/FunctionStore_tools_2023.tox

0 Bytes
Binary file not shown.
192 Bytes
Binary file not shown.
1.16 KB
Binary file not shown.
Binary file not shown.

Diff for: scripts/QuickExt/stubser/extStubser_.py

+32-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'''Info Header Start
22
Name : extStubser
33
Author : Dan@DAN-4090
4-
Saveorigin : FunctionStore_tools_2023.334.toe
4+
Saveorigin : FunctionStore_tools_2023.416.toe
55
Saveversion : 2023.11600
66
Info Header End'''
77
import ast
@@ -37,12 +37,37 @@ def _parse_td_version(self, path: Path) -> tuple[int, int] | None:
3737

3838
def _is_valid_td_version(self, version: tuple[int, int] | None) -> bool:
3939
"""Check if version meets minimum requirements (>= 2023.3000)."""
40-
return version is not None and version >= (2023, 3000)
40+
if version is None:
41+
return False
42+
major, minor = version
43+
if major > 2023:
44+
return True
45+
elif major == 2023:
46+
return minor >= 30000
47+
return False
4148

4249
def _find_td_builtins(self) -> Path | None:
4350
"""Search for valid __builtins__.pyi in the highest version TD installation."""
44-
# Start from current TD installation folder
45-
current_td = Path(app.binFolder).parent
51+
# First check current app version
52+
current_td = Path(app.installFolder)
53+
version = self._parse_td_version(current_td)
54+
debug(f"Current TD version: {version}")
55+
56+
# Always check if current builtins exists
57+
td_builtins = current_td / 'bin' / '__builtins__.pyi'
58+
if td_builtins.exists():
59+
if self._is_valid_td_version(version):
60+
debug(f"Using current TD builtins in {version[0]}.{version[1]}")
61+
return td_builtins
62+
else:
63+
debug("Current TD version is not valid, but builtins exists")
64+
# Store current builtins as fallback
65+
current_builtins = td_builtins
66+
else:
67+
current_builtins = None
68+
debug("Current TD builtins not found")
69+
70+
# If current version is not valid, search for highest version
4671
td_installations = current_td.parent
4772
highest_match = None
4873
highest_version = (0, 0)
@@ -59,7 +84,8 @@ def _find_td_builtins(self) -> Path | None:
5984
highest_match = td_builtins
6085
debug(f"Found builtins in TD {version[0]}.{version[1]}")
6186

62-
return highest_match
87+
# Return highest valid version if found, otherwise return current builtins
88+
return highest_match if highest_match else current_builtins
6389

6490
def _get_typing_paths(self, name: str) -> tuple[Path, Path]:
6591
"""Determine paths for builtins and stubs files."""
@@ -69,7 +95,7 @@ def _get_typing_paths(self, name: str) -> tuple[Path, Path]:
6995
if td_builtins:
7096
builtins_file = td_builtins
7197
else:
72-
debug("No valid TD installation (>= 2023.3000) found with __builtins__.pyi")
98+
debug("No valid TD installation (>= 2023.30000) found with __builtins__.pyi")
7399
# Fallback to local typings
74100
builtins_file = Path("typings", "__builtins__.pyi")
75101
else:

Diff for: scripts/VSCodeTools/OpenVSCode/ExtOpenVSCode.py

+114-3
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,49 @@ def OpenVSCode(self):
111111
# Ensure workspace file exists, create if necessary
112112
project_folder = Path(project.folder)
113113
workspace_path = project_folder / self.workspace
114+
115+
# Get the interpreter path
116+
interpreter_path = self._get_interpreter_path()
117+
118+
# Load existing workspace config or create new one
119+
if workspace_path.exists():
120+
with workspace_path.open('r') as file:
121+
workspace_config = json.load(file)
122+
else:
123+
workspace_config = {"folders": [{"path": "."}]}
124+
125+
# Initialize settings if it doesn't exist
126+
if "settings" not in workspace_config:
127+
workspace_config["settings"] = {}
128+
129+
# Update Python settings to force workspace interpreter
130+
python_settings = {
131+
"python.defaultInterpreterPath": str(interpreter_path),
132+
"python.terminal.activateEnvironment": True
133+
}
134+
135+
# Update workspace settings
136+
workspace_config["settings"].update(python_settings)
137+
138+
# Save the workspace config
139+
with workspace_path.open('w') as file:
140+
json.dump(workspace_config, file, indent=4)
141+
114142
if not workspace_path.exists():
115-
with workspace_path.open('w') as file:
116-
json.dump({"folders": [{"path": "."}]}, file)
117143
self.logger.Log(f"Created workspace file: {workspace_path}")
118-
if TDTypings := getattr(op, FNS_TDTYPINGS, None):
144+
else:
145+
self.logger.Log(f"Updated interpreter path in workspace file: {workspace_path}")
146+
147+
# Check if we're using a valid TD interpreter or falling back to local typings
148+
interpreter_parent = interpreter_path.parent
149+
version = self._parse_td_version(interpreter_parent.parent)
150+
151+
# Only deploy stubs if we're not using a valid TD interpreter
152+
if not self._is_valid_td_version(version):
153+
if TDTypings := getattr(op, 'FNS_TDTYPINGS', None):
154+
self.logger.Log("Deploying stubs because no valid TD interpreter found")
119155
TDTypings.DeployStubs()
156+
120157
missing_workspace = not self.workspace or not Path(self.workspace).exists()
121158

122159
if missing_exe or missing_workspace:
@@ -144,3 +181,77 @@ def _popErrorMessage(self, missing_exe=False, missing_workspace=False):
144181
ui.messageBox("Error", message, buttons=["OK"])
145182
self.ownerComp.openParameters()
146183
pass
184+
185+
def _parse_td_version(self, path: Path) -> tuple[int, int] | None:
186+
"""Extract TouchDesigner version from path."""
187+
td_pattern = re.compile(r'TouchDesigner\.(\d+)\.(\d+)')
188+
# Check folder name for version
189+
match = td_pattern.match(path.name)
190+
if match:
191+
return (int(match.group(1)), int(match.group(2)))
192+
return None
193+
194+
def _is_valid_td_version(self, version: tuple[int, int] | None) -> bool:
195+
"""Check if version meets minimum requirements (>= 2023.3000)."""
196+
if version is None:
197+
return False
198+
major, minor = version
199+
if major > 2023:
200+
return True
201+
elif major == 2023:
202+
return minor >= 30000
203+
return False
204+
205+
def _find_td_interpreter(self) -> Path | None:
206+
"""Search for valid python.exe in the highest version TD installation."""
207+
# First check current app version
208+
current_td = Path(app.installFolder)
209+
version = self._parse_td_version(current_td)
210+
self.logger.Log(f"Current TD version: {version}")
211+
212+
# Always check if current interpreter exists
213+
td_interpreter = current_td / 'bin' / 'python.exe'
214+
if td_interpreter.exists():
215+
if self._is_valid_td_version(version):
216+
self.logger.Log(f"Using current TD interpreter in {version[0]}.{version[1]}")
217+
return td_interpreter
218+
else:
219+
self.logger.Log("Current TD version is not valid, but interpreter exists")
220+
# Store current interpreter as fallback
221+
current_interpreter = td_interpreter
222+
else:
223+
current_interpreter = None
224+
self.logger.Log("Current TD interpreter not found")
225+
226+
# If current version is not valid, search for highest version
227+
td_installations = current_td.parent
228+
highest_match = None
229+
highest_version = (0, 0)
230+
231+
for td_folder in td_installations.iterdir():
232+
if not td_folder.is_dir():
233+
continue
234+
235+
version = self._parse_td_version(td_folder)
236+
if self._is_valid_td_version(version) and version > highest_version:
237+
td_interpreter = td_folder / 'bin' / 'python.exe'
238+
if td_interpreter.exists():
239+
highest_version = version
240+
highest_match = td_interpreter
241+
self.logger.Log(f"Found interpreter in TD {version[0]}.{version[1]}")
242+
243+
# Return highest valid version if found, otherwise return current interpreter
244+
return highest_match if highest_match else current_interpreter
245+
246+
def _get_interpreter_path(self) -> Path:
247+
"""Determine paths for builtins and stubs files."""
248+
# Try to find builtins in highest version TD installation
249+
td_interpreter = self._find_td_interpreter()
250+
if td_interpreter:
251+
interpreter_file = td_interpreter
252+
else:
253+
self.logger.Log("No valid TD installation (>= 2023.3000) found with python.exe")
254+
# Fallback to local typings
255+
interpreter_file = Path("typings", "python.exe")
256+
257+
return interpreter_file

0 commit comments

Comments
 (0)