Coverage for archdocs/features/http_clients/parser.py: 100%
14 statements
« prev ^ index » next coverage.py v7.15.3, created at 2026-08-03 00:00 +0000
« prev ^ index » next coverage.py v7.15.3, created at 2026-08-03 00:00 +0000
1import re as py_re
2import types
3import typing
5from archdocs import prefilter, settings
6from archdocs.features.http_clients.const import HttpClientEnum, HttpClientFeatures
9_CLIENT_PATTERNS: typing.Final = types.MappingProxyType(
10 {
11 one_client: py_re.compile(rf"\b(?:from|import)\s+{one_client.value}\b", flags=settings.TYPICAL_RE_FLAGS)
12 for one_client in HttpClientEnum
13 },
14)
15_ASYNC_DETECTION_PATTERNS: typing.Final = py_re.compile(
16 r"\b(?:httpx\.AsyncClient|aiohttp\.ClientSession)\b",
17 flags=settings.TYPICAL_RE_FLAGS,
18)
19_EMPTY_FEATURES: typing.Final = HttpClientFeatures(
20 clients_used=frozenset(),
21 async_used=False,
22 has_external_calls=False,
23)
26def find_http_client_features(raw_source: str) -> HttpClientFeatures:
27 lowered_source: typing.Final = raw_source.lower()
28 clients_found: typing.Final = {
29 one_client.value
30 for one_client, one_pattern in _CLIENT_PATTERNS.items()
31 if prefilter.contains_any_literal(lowered_source, (one_client.value,)) and one_pattern.search(raw_source)
32 }
33 if not clients_found:
34 return _EMPTY_FEATURES
35 return HttpClientFeatures(
36 clients_used=frozenset(clients_found),
37 async_used=bool(_ASYNC_DETECTION_PATTERNS.search(raw_source)),
38 has_external_calls=True,
39 )