Skip to content

Commit 41eec20

Browse files
refactor(tidy3d): FXC-4436-move-typing-only-imports-behind-if-type-checking
1 parent 3e3526a commit 41eec20

File tree

6 files changed

+46
-21
lines changed

6 files changed

+46
-21
lines changed

tests/config/test_legacy_env.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ def test_env_pending_overrides_apply_on_activation(mock_config_dir, config_manag
4343
assert current_manager.profile == "dev"
4444
dev_web = current_manager.get_section("web")
4545
assert dev_web.enable_caching is False
46-
assert dev_web.ssl_version == ssl.TLSVersion.TLSv1_2
46+
assert dev_web.ssl_version == "TLSv1_2"
4747
assert Env.current.enable_caching is False
48-
assert Env.current.ssl_version == ssl.TLSVersion.TLSv1_2
48+
assert Env.current.ssl_version == "TLSv1_2"
4949
finally:
5050
reload_config(profile="default")
5151

tests/test_web/test_env.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ def test_tidy3d_env():
1414

1515

1616
def test_set_ssl_version():
17-
Env.set_ssl_version(ssl.TLSVersion.TLSv1_3)
18-
assert Env.current.ssl_version == ssl.TLSVersion.TLSv1_3
17+
Env.set_ssl_version("TLSv1_3")
18+
assert Env.current.ssl_version == "TLSv1_3"
1919

2020
Env.set_ssl_version(ssl.TLSVersion.TLSv1_2)
21-
assert Env.current.ssl_version == ssl.TLSVersion.TLSv1_2
21+
assert Env.current.ssl_version == "TLSv1_2"
2222

2323
Env.set_ssl_version(ssl.TLSVersion.TLSv1_1)
24-
assert Env.current.ssl_version == ssl.TLSVersion.TLSv1_1
24+
assert Env.current.ssl_version == "TLSv1_1"
2525

2626
Env.set_ssl_version(None)
2727
assert Env.current.ssl_version is None

tidy3d/config/legacy.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from __future__ import annotations
88

99
import os
10-
import ssl
1110
import warnings
1211
from pathlib import Path
1312
from typing import Any, Optional
@@ -160,7 +159,7 @@ def __init__(
160159
s3_region: Optional[str] = None,
161160
ssl_verify: Optional[bool] = None,
162161
enable_caching: Optional[bool] = None,
163-
ssl_version: Optional[ssl.TLSVersion] = None,
162+
ssl_version: Optional[str] = None,
164163
env_vars: Optional[dict[str, str]] = None,
165164
environment: Optional[LegacyEnvironment] = None,
166165
) -> None:
@@ -239,11 +238,11 @@ def enable_caching(self, value: Optional[bool]) -> None:
239238
self._set_pending("enable_caching", value)
240239

241240
@property
242-
def ssl_version(self) -> Optional[ssl.TLSVersion]:
241+
def ssl_version(self) -> Optional[str]:
243242
return self._value("ssl_version")
244243

245244
@ssl_version.setter
246-
def ssl_version(self, value: Optional[ssl.TLSVersion]) -> None:
245+
def ssl_version(self, value: Optional[str]) -> None:
247246
self._set_pending("ssl_version", value)
248247

249248
@property
@@ -363,7 +362,7 @@ def enable_caching(self, enable_caching: Optional[bool] = True) -> None:
363362
config.enable_caching = enable_caching
364363
self._sync_to_manager()
365364

366-
def set_ssl_version(self, ssl_version: Optional[ssl.TLSVersion]) -> None:
365+
def set_ssl_version(self, ssl_version: Optional[str]) -> None:
367366
config = self.current
368367
config.ssl_version = ssl_version
369368
self._sync_to_manager()

tidy3d/config/sections.py

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from __future__ import annotations
44

55
import os
6-
import ssl
76
from os import PathLike
87
from pathlib import Path
98
from typing import Any, Literal, Optional
@@ -28,6 +27,28 @@
2827
from .registry import get_manager as _get_attached_manager
2928
from .registry import register_handler, register_section
3029

30+
TLS_VERSION_CHOICES = {"TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"}
31+
32+
33+
def _normalize_tls_version(value: Any) -> str:
34+
"""Normalize TLS version-like inputs to the canonical ``TLSvX_Y`` form."""
35+
36+
if hasattr(value, "name") and isinstance(value.name, str):
37+
candidate = value.name
38+
else:
39+
candidate = str(value).strip()
40+
if not candidate:
41+
raise ValueError("TLS version cannot be empty")
42+
normalized = candidate.replace("-", "_").replace(" ", "")
43+
normalized = normalized.replace(".", "_").upper()
44+
if not normalized.startswith("TLSV"):
45+
raise ValueError("TLS version must start with 'TLSv'")
46+
canonical = "TLSv" + normalized[4:]
47+
if canonical not in TLS_VERSION_CHOICES:
48+
allowed = ", ".join(sorted(TLS_VERSION_CHOICES))
49+
raise ValueError(f"TLS version must be one of: {allowed}")
50+
return canonical
51+
3152

3253
class ConfigSection(BaseModel):
3354
"""Base class for configuration sections."""
@@ -328,10 +349,13 @@ class WebConfig(ConfigSection):
328349
le=300,
329350
)
330351

331-
ssl_version: Optional[ssl.TLSVersion] = Field(
352+
ssl_version: Optional[str] = Field(
332353
None,
333354
title="SSL/TLS version",
334-
description="Optional SSL/TLS version to enforce for requests.",
355+
description=(
356+
"Optional TLS version override to enforce for requests. Accepts values such as "
357+
"'TLSv1_2'."
358+
),
335359
)
336360

337361
env_vars: dict[str, str] = Field(
@@ -349,14 +373,18 @@ def to_dict(self, *, mask_secrets: bool = True) -> dict[str, Any]:
349373
secret = data.get("apikey")
350374
if isinstance(secret, SecretStr):
351375
data["apikey"] = secret.get_secret_value()
352-
ssl_version = data.get("ssl_version")
353-
if isinstance(ssl_version, ssl.TLSVersion):
354-
data["ssl_version"] = ssl_version.value
355376
for field in ("api_endpoint", "website_endpoint"):
356377
if field in data and data[field] is not None:
357378
data[field] = str(data[field])
358379
return data
359380

381+
@field_validator("ssl_version", mode="before")
382+
@classmethod
383+
def _validate_ssl_version(cls, value: Any) -> Optional[str]:
384+
if value is None:
385+
return None
386+
return _normalize_tls_version(value)
387+
360388
@field_validator("api_endpoint", "website_endpoint", mode="before")
361389
@classmethod
362390
def _validate_http_url(cls, value: Any) -> str:

tidy3d/plugins/dispersion/web.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from __future__ import annotations
44

5-
import ssl
65
from enum import Enum
76
from typing import Literal, Optional
87

@@ -247,7 +246,7 @@ def _setup_server(url_server: str) -> tuple[dict[str, str], bool]:
247246
# test connection
248247
resp = requests.get(f"{url_server}/health", verify=ssl_verify)
249248
resp.raise_for_status()
250-
except (requests.exceptions.SSLError, ssl.SSLError):
249+
except requests.exceptions.SSLError:
251250
log.info("Retrying with SSL verification disabled.")
252251
ssl_verify = False
253252
resp = requests.get(f"{url_server}/health", verify=ssl_verify)

tidy3d/web/cli/app.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import os
88
import shutil
9-
import ssl
109
from typing import Any
1110

1211
import click
@@ -99,7 +98,7 @@ def auth(req: requests.Request) -> requests.Request:
9998

10099
try:
101100
resp = requests.get(target_url, auth=auth, verify=config.web.ssl_verify)
102-
except (requests.exceptions.SSLError, ssl.SSLError):
101+
except requests.exceptions.SSLError:
103102
resp = requests.get(target_url, auth=auth, verify=False)
104103

105104
if resp.status_code == 200:

0 commit comments

Comments
 (0)