Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/dns/_features.py: 55%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
3import importlib.metadata
4import itertools
5import string
6from typing import Dict, List, Tuple
9def _tuple_from_text(version: str) -> Tuple:
10 text_parts = version.split(".")
11 int_parts = []
12 for text_part in text_parts:
13 digit_prefix = "".join(
14 itertools.takewhile(lambda x: x in string.digits, text_part)
15 )
16 try:
17 int_parts.append(int(digit_prefix))
18 except Exception:
19 break
20 return tuple(int_parts)
23def _version_check(
24 requirement: str,
25) -> bool:
26 """Is the requirement fulfilled?
28 The requirement must be of the form
30 package>=version
31 """
32 package, minimum = requirement.split(">=")
33 try:
34 version = importlib.metadata.version(package)
35 # This shouldn't happen, but it apparently can.
36 if version is None:
37 return False
38 except Exception:
39 return False
40 t_version = _tuple_from_text(version)
41 t_minimum = _tuple_from_text(minimum)
42 if t_version < t_minimum:
43 return False
44 return True
47_cache: Dict[str, bool] = {}
50def have(feature: str) -> bool:
51 """Is *feature* available?
53 This tests if all optional packages needed for the
54 feature are available and recent enough.
56 Returns ``True`` if the feature is available,
57 and ``False`` if it is not or if metadata is
58 missing.
59 """
60 value = _cache.get(feature)
61 if value is not None:
62 return value
63 requirements = _requirements.get(feature)
64 if requirements is None:
65 # we make a cache entry here for consistency not performance
66 _cache[feature] = False
67 return False
68 ok = True
69 for requirement in requirements:
70 if not _version_check(requirement):
71 ok = False
72 break
73 _cache[feature] = ok
74 return ok
77def force(feature: str, enabled: bool) -> None:
78 """Force the status of *feature* to be *enabled*.
80 This method is provided as a workaround for any cases
81 where importlib.metadata is ineffective, or for testing.
82 """
83 _cache[feature] = enabled
86_requirements: Dict[str, List[str]] = {
87 ### BEGIN generated requirements
88 "dnssec": ["cryptography>=43"],
89 "doh": ["httpcore>=1.0.0", "httpx>=0.26.0", "h2>=4.1.0"],
90 "doq": ["aioquic>=1.0.0"],
91 "idna": ["idna>=3.7"],
92 "trio": ["trio>=0.23"],
93 "wmi": ["wmi>=1.5.1"],
94 ### END generated requirements
95}