Skip to content

Commit d022f22

Browse files
Fix TRY003 violations and remove from suppression list
Agent-Logs-Url: https://github.com/GitHubSecurityLab/seclab-taskflow-agent/sessions/93ebfeff-7922-41fa-b6a6-fe1abafe4e1c Co-authored-by: kevinbackhouse <4358136+kevinbackhouse@users.noreply.github.com>
1 parent 44ae901 commit d022f22

15 files changed

Lines changed: 95 additions & 68 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@ ignore = [
174174
"EM102", # Exception f-strings
175175
"G004", # Logging f-strings
176176
"T201", # print() used for user output
177-
"TRY003", # Raise with inline message strings
178177

179178
# Backwards-compatibility suppressions for existing code
180179
"A001", # Variable shadows built-in
@@ -253,3 +252,4 @@ ignore = [
253252

254253
[tool.ruff.lint.per-file-ignores]
255254
"tests/*" = ["S101", "PLR2004"]
255+
"src/seclab_taskflow_agent/mcp_servers/codeql/jsonrpyc/*" = ["TRY003"]

src/seclab_taskflow_agent/agent.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@ def __init__(
172172
if token:
173173
resolved_token = os.getenv(token, "")
174174
if not resolved_token:
175-
raise RuntimeError(f"Token env var {token!r} is not set")
175+
msg = f"Token env var {token!r} is not set"
176+
raise RuntimeError(msg)
176177
else:
177178
resolved_token = get_AI_token()
178179

src/seclab_taskflow_agent/available_tools.py

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -108,18 +108,15 @@ def _load(self, tooltype: AvailableToolType, toolname: str) -> DocumentModel:
108108
# Resolve package and filename from dotted path
109109
components = toolname.rsplit(".", 1)
110110
if len(components) != 2:
111-
raise BadToolNameError(
112-
f'Not a valid toolname: "{toolname}". '
113-
f'Expected format: "packagename.filename"'
114-
)
111+
msg = f'Not a valid toolname: "{toolname}". Expected format: "packagename.filename"'
112+
raise BadToolNameError(msg)
115113
package, filename = components
116114

117115
try:
118116
pkg_dir = importlib.resources.files(package)
119117
if not pkg_dir.is_dir():
120-
raise BadToolNameError(
121-
f"Cannot load {toolname} because {pkg_dir} is not a valid directory."
122-
)
118+
msg = f"Cannot load {toolname} because {pkg_dir} is not a valid directory."
119+
raise BadToolNameError(msg)
123120
filepath = pkg_dir.joinpath(filename + ".yaml")
124121
with filepath.open() as fh:
125122
raw = yaml.safe_load(fh)
@@ -128,17 +125,14 @@ def _load(self, tooltype: AvailableToolType, toolname: str) -> DocumentModel:
128125
header = raw.get("seclab-taskflow-agent", {})
129126
filetype = header.get("filetype", "")
130127
if filetype != tooltype.value:
131-
raise FileTypeException(
132-
f"Error in {filepath}: expected filetype {tooltype.value!r}, "
133-
f"got {filetype!r}."
134-
)
128+
msg = f"Error in {filepath}: expected filetype {tooltype.value!r}, got {filetype!r}."
129+
raise FileTypeException(msg)
135130

136131
# Parse into the appropriate Pydantic model
137132
model_cls = DOCUMENT_MODELS.get(filetype)
138133
if model_cls is None:
139-
raise BadToolNameError(
140-
f"Unknown filetype {filetype!r} in {toolname}"
141-
)
134+
msg = f"Unknown filetype {filetype!r} in {toolname}"
135+
raise BadToolNameError(msg)
142136

143137
try:
144138
doc = model_cls(**raw)
@@ -147,21 +141,19 @@ def _load(self, tooltype: AvailableToolType, toolname: str) -> DocumentModel:
147141
for err in exc.errors():
148142
if "Unsupported version" in str(err.get("msg", "")):
149143
raise VersionException(str(err["msg"])) from exc
150-
raise BadToolNameError(
151-
f"Validation error loading {toolname}: {exc}"
152-
) from exc
153-
154-
# Cache and return
144+
msg = f"Validation error loading {toolname}: {exc}"
145+
raise BadToolNameError(msg) from exc
155146
if tooltype not in self._cache:
156147
self._cache[tooltype] = {}
157148
self._cache[tooltype][toolname] = doc
158149
return doc
159150

160151
except ModuleNotFoundError as exc:
161-
raise BadToolNameError(f"Cannot load {toolname}: {exc}") from exc
152+
msg = f"Cannot load {toolname}: {exc}"
153+
raise BadToolNameError(msg) from exc
162154
except FileNotFoundError:
163-
raise BadToolNameError(
164-
f"Cannot load {toolname} because {filepath} is not a valid file."
165-
)
155+
msg = f"Cannot load {toolname} because {filepath} is not a valid file."
156+
raise BadToolNameError(msg)
166157
except ValueError as exc:
167-
raise BadToolNameError(f"Cannot load {toolname}: {exc}") from exc
158+
msg = f"Cannot load {toolname}: {exc}"
159+
raise BadToolNameError(msg) from exc

src/seclab_taskflow_agent/capi.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ def get_AI_token() -> str:
167167
token = os.getenv("COPILOT_TOKEN")
168168
if token:
169169
return token
170-
raise RuntimeError("AI_API_TOKEN environment variable is not set.")
170+
msg = "AI_API_TOKEN environment variable is not set."
171+
raise RuntimeError(msg)
171172

172173

173174
# ---------------------------------------------------------------------------

src/seclab_taskflow_agent/cli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
def _parse_global(value: str) -> tuple[str, str]:
3737
"""Parse a ``KEY=VALUE`` string into a (key, value) pair."""
3838
if "=" not in value:
39-
raise typer.BadParameter(f"Invalid global variable format: {value!r}. Expected KEY=VALUE.")
39+
msg = f"Invalid global variable format: {value!r}. Expected KEY=VALUE."
40+
raise typer.BadParameter(msg)
4041
key, _, val = value.partition("=")
4142
return key.strip(), val.strip()
4243

src/seclab_taskflow_agent/mcp_lifecycle.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ def _print_err(line: str) -> None:
116116
client_session_timeout_seconds=client_session_timeout,
117117
)
118118
case _:
119-
raise ValueError(f"Unsupported MCP transport: {params['kind']}")
119+
msg = f"Unsupported MCP transport: {params['kind']}"
120+
raise ValueError(msg)
120121

121122
entries.append(MCPServerEntry(MCPNamespaceWrap(confirms, mcp_server), server_proc, name=tb))
122123

src/seclab_taskflow_agent/mcp_servers/codeql/client.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,12 @@ def _server_request_run(
194194
template_values: dict | None = None,
195195
):
196196
if not self.active_database:
197-
raise RuntimeError("No Active Database")
197+
msg = "No Active Database"
198+
raise RuntimeError(msg)
198199

199200
if not self.active_connection:
200-
raise RuntimeError("No Active Connection")
201+
msg = "No Active Connection"
202+
raise RuntimeError(msg)
201203

202204
if isinstance(quick_eval_pos, dict):
203205
# A quick eval position contains:
@@ -302,7 +304,8 @@ def _format(self, query):
302304
def _resolve_query_server(self):
303305
help_msg = shell_command_to_string(self.codeql_cli + ["excute", "--help"])
304306
if not re.search("query-server2", help_msg):
305-
raise RuntimeError("Legacy server not supported!")
307+
msg = "Legacy server not supported!"
308+
raise RuntimeError(msg)
306309
return "query-server2"
307310

308311
def _resolve_library_paths(self, query_path):
@@ -463,11 +466,13 @@ def _file_uri_to_path(uri):
463466
# internally the codeql client will resolve both relative and full paths
464467
# regardless of root directory differences
465468
if not uri.startswith("file:///"):
466-
raise ValueError("URI path should be formatted as absolute")
469+
msg = "URI path should be formatted as absolute"
470+
raise ValueError(msg)
467471
# note: don't try to parse paths like "file://a/b" because that returns "/b", should be "file:///a/b"
468472
parsed = urlparse(uri)
469473
if parsed.scheme != "file":
470-
raise ValueError(f"Not a file:// uri: {uri}")
474+
msg = f"Not a file:// uri: {uri}"
475+
raise ValueError(msg)
471476
path = unquote(parsed.path)
472477
region = None
473478
if ":" in path:
@@ -605,7 +610,8 @@ def run_query(
605610
if target:
606611
target_pos = get_query_position(query_path, target)
607612
if not target_pos:
608-
raise ValueError(f"Could not resolve quick eval target for {target}")
613+
msg = f"Could not resolve quick eval target for {target}"
614+
raise ValueError(msg)
609615
try:
610616
with (
611617
QueryServer(database, keep_alive=keep_alive, log_stderr=log_stderr) as server,
@@ -633,7 +639,9 @@ def run_query(
633639
case "sarif":
634640
result = server._bqrs_to_sarif(bqrs_path, server._query_info(query_path))
635641
case _:
636-
raise ValueError("Unsupported output format {fmt}")
642+
msg = f"Unsupported output format {fmt}"
643+
raise ValueError(msg)
637644
except Exception as e:
638-
raise RuntimeError(f"Error in run_query: {e}") from e
645+
msg = f"Error in run_query: {e}"
646+
raise RuntimeError(msg) from e
639647
return result

src/seclab_taskflow_agent/mcp_servers/codeql/mcp_server.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,12 @@
5353
def _resolve_query_path(language: str, query: str) -> Path:
5454
global TEMPLATED_QUERY_PATHS
5555
if language not in TEMPLATED_QUERY_PATHS:
56-
raise RuntimeError(f"Error: Language `{language}` not supported!")
56+
msg = f"Error: Language `{language}` not supported!"
57+
raise RuntimeError(msg)
5758
query_path = TEMPLATED_QUERY_PATHS[language].get(query)
5859
if not query_path:
59-
raise RuntimeError(f"Error: query `{query}` not supported for `{language}`!")
60+
msg = f"Error: query `{query}` not supported for `{language}`!"
61+
raise RuntimeError(msg)
6062
return Path(query_path)
6163

6264

@@ -69,7 +71,8 @@ def _resolve_db_path(relative_db_path: str | Path):
6971
absolute_path = CODEQL_DBS_BASE_PATH / relative_db_path
7072
if not absolute_path.is_dir():
7173
_debug_log(f"Database path not found: {absolute_path}")
72-
raise RuntimeError(f"Error: Database not found at {absolute_path}!")
74+
msg = f"Error: Database not found at {absolute_path}!"
75+
raise RuntimeError(msg)
7376
return absolute_path
7477

7578

src/seclab_taskflow_agent/mcp_transport.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ async def async_wait_for_connection(
109109
host = parsed.hostname
110110
port = parsed.port
111111
if host is None or port is None:
112-
raise ValueError(f"URL must include a host and port: {self.url}")
112+
msg = f"URL must include a host and port: {self.url}"
113+
raise ValueError(msg)
113114
deadline = asyncio.get_event_loop().time() + timeout
114115
while True:
115116
try:
@@ -119,7 +120,8 @@ async def async_wait_for_connection(
119120
return
120121
except (OSError, ConnectionRefusedError):
121122
if asyncio.get_event_loop().time() > deadline:
122-
raise TimeoutError(f"Could not connect to {host}:{port} after {timeout} seconds")
123+
msg = f"Could not connect to {host}:{port} after {timeout} seconds"
124+
raise TimeoutError(msg)
123125
await asyncio.sleep(poll_interval)
124126

125127
def wait_for_connection(
@@ -139,15 +141,17 @@ def wait_for_connection(
139141
host = parsed.hostname
140142
port = parsed.port
141143
if host is None or port is None:
142-
raise ValueError(f"URL must include a host and port: {self.url}")
144+
msg = f"URL must include a host and port: {self.url}"
145+
raise ValueError(msg)
143146
deadline = time.time() + timeout
144147
while True:
145148
try:
146149
with socket.create_connection((host, port), timeout=2):
147150
return
148151
except OSError:
149152
if time.time() > deadline:
150-
raise TimeoutError(f"Could not connect to {host}:{port} after {timeout} seconds")
153+
msg = f"Could not connect to {host}:{port} after {timeout} seconds"
154+
raise TimeoutError(msg)
151155
time.sleep(poll_interval)
152156

153157
def run(self) -> None:
@@ -216,7 +220,8 @@ def join_and_raise(self, timeout: float | None = None) -> None:
216220
"""
217221
self.join(timeout)
218222
if self.is_alive():
219-
raise RuntimeError("Process thread did not exit within timeout.")
223+
msg = "Process thread did not exit within timeout."
224+
raise RuntimeError(msg)
220225
if self.exception is not None:
221226
raise self.exception
222227

src/seclab_taskflow_agent/mcp_utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ def mcp_client_params(
202202
logging.debug(f"Initializing streamable toolbox: {tb}\nargs:\n{args}\nenv:\n{env}\n")
203203
exe = shutil.which(sp.command)
204204
if exe is None:
205-
raise FileNotFoundError(f"Could not resolve path to {sp.command}")
205+
msg = f"Could not resolve path to {sp.command}"
206+
raise FileNotFoundError(msg)
206207
start_cmd = [exe]
207208
if args:
208209
for i, v in enumerate(args):
@@ -220,7 +221,8 @@ def mcp_client_params(
220221
server_params["env"] = env
221222

222223
case _:
223-
raise ValueError(f"Unsupported MCP transport {kind}")
224+
msg = f"Unsupported MCP transport {kind}"
225+
raise ValueError(msg)
224226

225227
client_params[tb] = (
226228
server_params,

0 commit comments

Comments
 (0)