Navegador

fix: lazy-import yaml in Ansible parser for CI compatibility CI installs core deps only (no [iac] extras), so top-level `import yaml` broke test collection. Now imported at call sites.

lmata 2026-03-30 02:42 trunk
Commit 66c638480837fc1a18b9221ca30131e6a0e9a5aea3535496f278882047b6ae94
--- navegador/ingestion/ansible.py
+++ navegador/ingestion/ansible.py
@@ -12,12 +12,10 @@
1212
1313
import logging
1414
import re
1515
from pathlib import Path
1616
17
-import yaml
18
-
1917
from navegador.graph.schema import EdgeType, NodeLabel
2018
from navegador.graph.store import GraphStore
2119
from navegador.ingestion.parser import LanguageParser
2220
2321
logger = logging.getLogger(__name__)
@@ -178,12 +176,14 @@
178176
179177
if not text.lstrip().startswith("---"):
180178
return False
181179
182180
try:
181
+ import yaml
182
+
183183
data = yaml.safe_load(text)
184
- except yaml.YAMLError:
184
+ except Exception:
185185
return False
186186
187187
if isinstance(data, list) and data:
188188
if any(isinstance(item, dict) and "hosts" in item for item in data):
189189
return True
@@ -195,13 +195,15 @@
195195
def parse_file(self, path: Path, repo_root: Path, store: GraphStore) -> dict[str, int]:
196196
rel_path = str(path.relative_to(repo_root))
197197
stats = {"functions": 0, "classes": 0, "edges": 0}
198198
199199
try:
200
+ import yaml
201
+
200202
text = path.read_text(encoding="utf-8", errors="replace")
201203
data = yaml.safe_load(text)
202
- except (OSError, yaml.YAMLError) as exc:
204
+ except Exception as exc:
203205
logger.warning("Could not parse Ansible file %s: %s", rel_path, exc)
204206
return stats
205207
206208
if data is None:
207209
return stats
208210
--- navegador/ingestion/ansible.py
+++ navegador/ingestion/ansible.py
@@ -12,12 +12,10 @@
12
13 import logging
14 import re
15 from pathlib import Path
16
17 import yaml
18
19 from navegador.graph.schema import EdgeType, NodeLabel
20 from navegador.graph.store import GraphStore
21 from navegador.ingestion.parser import LanguageParser
22
23 logger = logging.getLogger(__name__)
@@ -178,12 +176,14 @@
178
179 if not text.lstrip().startswith("---"):
180 return False
181
182 try:
 
 
183 data = yaml.safe_load(text)
184 except yaml.YAMLError:
185 return False
186
187 if isinstance(data, list) and data:
188 if any(isinstance(item, dict) and "hosts" in item for item in data):
189 return True
@@ -195,13 +195,15 @@
195 def parse_file(self, path: Path, repo_root: Path, store: GraphStore) -> dict[str, int]:
196 rel_path = str(path.relative_to(repo_root))
197 stats = {"functions": 0, "classes": 0, "edges": 0}
198
199 try:
 
 
200 text = path.read_text(encoding="utf-8", errors="replace")
201 data = yaml.safe_load(text)
202 except (OSError, yaml.YAMLError) as exc:
203 logger.warning("Could not parse Ansible file %s: %s", rel_path, exc)
204 return stats
205
206 if data is None:
207 return stats
208
--- navegador/ingestion/ansible.py
+++ navegador/ingestion/ansible.py
@@ -12,12 +12,10 @@
12
13 import logging
14 import re
15 from pathlib import Path
16
 
 
17 from navegador.graph.schema import EdgeType, NodeLabel
18 from navegador.graph.store import GraphStore
19 from navegador.ingestion.parser import LanguageParser
20
21 logger = logging.getLogger(__name__)
@@ -178,12 +176,14 @@
176
177 if not text.lstrip().startswith("---"):
178 return False
179
180 try:
181 import yaml
182
183 data = yaml.safe_load(text)
184 except Exception:
185 return False
186
187 if isinstance(data, list) and data:
188 if any(isinstance(item, dict) and "hosts" in item for item in data):
189 return True
@@ -195,13 +195,15 @@
195 def parse_file(self, path: Path, repo_root: Path, store: GraphStore) -> dict[str, int]:
196 rel_path = str(path.relative_to(repo_root))
197 stats = {"functions": 0, "classes": 0, "edges": 0}
198
199 try:
200 import yaml
201
202 text = path.read_text(encoding="utf-8", errors="replace")
203 data = yaml.safe_load(text)
204 except Exception as exc:
205 logger.warning("Could not parse Ansible file %s: %s", rel_path, exc)
206 return stats
207
208 if data is None:
209 return stats
210
--- tests/test_ansible_parser.py
+++ tests/test_ansible_parser.py
@@ -2,12 +2,16 @@
22
33
import tempfile
44
from pathlib import Path
55
from unittest.mock import MagicMock
66
7
-from navegador.graph.schema import EdgeType, NodeLabel
8
-from navegador.ingestion.ansible import AnsibleParser
7
+import pytest
8
+
9
+yaml = pytest.importorskip("yaml", reason="pyyaml not installed")
10
+
11
+from navegador.graph.schema import EdgeType, NodeLabel # noqa: E402
12
+from navegador.ingestion.ansible import AnsibleParser # noqa: E402
913
1014
1115
def _make_store():
1216
store = MagicMock()
1317
store.query.return_value = MagicMock(result_set=[])
1418
--- tests/test_ansible_parser.py
+++ tests/test_ansible_parser.py
@@ -2,12 +2,16 @@
2
3 import tempfile
4 from pathlib import Path
5 from unittest.mock import MagicMock
6
7 from navegador.graph.schema import EdgeType, NodeLabel
8 from navegador.ingestion.ansible import AnsibleParser
 
 
 
 
9
10
11 def _make_store():
12 store = MagicMock()
13 store.query.return_value = MagicMock(result_set=[])
14
--- tests/test_ansible_parser.py
+++ tests/test_ansible_parser.py
@@ -2,12 +2,16 @@
2
3 import tempfile
4 from pathlib import Path
5 from unittest.mock import MagicMock
6
7 import pytest
8
9 yaml = pytest.importorskip("yaml", reason="pyyaml not installed")
10
11 from navegador.graph.schema import EdgeType, NodeLabel # noqa: E402
12 from navegador.ingestion.ansible import AnsibleParser # noqa: E402
13
14
15 def _make_store():
16 store = MagicMock()
17 store.query.return_value = MagicMock(result_set=[])
18

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button