deepeval 3.4.7__py3-none-any.whl → 3.4.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
deepeval/__init__.py CHANGED
@@ -7,9 +7,7 @@ from .env import autoload_dotenv as _autoload_dotenv
7
7
 
8
8
  _autoload_dotenv()
9
9
 
10
- # Optionally add telemetry
11
10
  from ._version import __version__
12
-
13
11
  from deepeval.evaluate import evaluate, assert_test
14
12
  from deepeval.evaluate.compare import compare
15
13
  from deepeval.test_run import on_test_run_end, log_hyperparameters
deepeval/_version.py CHANGED
@@ -1 +1 @@
1
- __version__: str = "3.4.7"
1
+ __version__: str = "3.4.8"
@@ -0,0 +1,71 @@
1
+ from __future__ import annotations
2
+ from pathlib import Path
3
+ import os
4
+ import re
5
+ import stat
6
+ from typing import Dict, Iterable
7
+
8
+ _LINE_RE = re.compile(r"^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)\s*$")
9
+
10
+
11
+ class DotenvHandler:
12
+ def __init__(self, path: str | Path = ".env.local"):
13
+ self.path = Path(path)
14
+
15
+ def _quote_if_needed(self, val: str) -> str:
16
+ # keep existing quoting if present; add quotes for spaces/#
17
+ if (val.startswith('"') and val.endswith('"')) or (
18
+ val.startswith("'") and val.endswith("'")
19
+ ):
20
+ return val
21
+ return f'"{val}"' if any(c in val for c in " #\t") else val
22
+
23
+ def upsert(self, updates: Dict[str, str]) -> None:
24
+ """
25
+ Idempotently set/replace keys in a dotenv file. Preserves comments/order.
26
+ Creates file if missing. Sets file mode to 0600 when possible.
27
+ """
28
+ lines = self.path.read_text().splitlines() if self.path.exists() else []
29
+ seen = set()
30
+
31
+ # replace existing keys in-place
32
+ for i, line in enumerate(lines):
33
+ m = _LINE_RE.match(line)
34
+ if not m:
35
+ continue
36
+ key = m.group(1)
37
+ if key in updates and key not in seen:
38
+ lines[i] = f"{key}={self._quote_if_needed(updates[key])}"
39
+ seen.add(key)
40
+
41
+ # append missing keys at end (after a blank line)
42
+ to_append = []
43
+ for k, v in updates.items():
44
+ if k in seen:
45
+ continue
46
+ to_append.append(f"{k}={self._quote_if_needed(v)}")
47
+ if to_append:
48
+ if lines and lines[-1].strip():
49
+ lines.append("")
50
+ lines.extend(to_append)
51
+
52
+ self.path.parent.mkdir(parents=True, exist_ok=True)
53
+ self.path.write_text("\n".join(lines) + ("\n" if lines else ""))
54
+ try:
55
+ self.path.chmod(stat.S_IRUSR | stat.S_IWUSR) # 0600
56
+ except Exception:
57
+ pass
58
+
59
+ def unset(self, keys: Iterable[str]) -> None:
60
+ """Remove keys from dotenv file, but leave comments and other lines untouched."""
61
+ if not self.path.exists():
62
+ return
63
+ lines = self.path.read_text().splitlines()
64
+ out = []
65
+ keys = set(keys)
66
+ for line in lines:
67
+ m = _LINE_RE.match(line)
68
+ if m and m.group(1) in keys:
69
+ continue
70
+ out.append(line)
71
+ self.path.write_text("\n".join(out) + ("\n" if out else ""))