Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/dns/_features.py: 54%
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
8def _tuple_from_text(version: str) -> tuple:
9 text_parts = version.split(".")
10 int_parts = []
11 for text_part in text_parts:
12 digit_prefix = "".join(
13 itertools.takewhile(lambda x: x in string.digits, text_part)
14 )
15 try:
16 int_parts.append(int(digit_prefix))
17 except Exception:
18 break
19 return tuple(int_parts)
22def _version_check(
23 requirement: str,
24) -> bool:
25 """Is the requirement fulfilled?
27 The requirement must be of the form
29 package>=version
30 """
31 package, minimum = requirement.split(">=")
32 try:
33 version = importlib.metadata.version(package)
34 # This shouldn't happen, but it apparently can.
35 if version is None:
36 return False
37 except Exception:
38 return False
39 t_version = _tuple_from_text(version)
40 t_minimum = _tuple_from_text(minimum)
41 if t_version < t_minimum:
42 return False
43 return True
46_cache: dict[str, bool] = {}
49def have(feature: str) -> bool:
50 """Is *feature* available?
52 This tests if all optional packages needed for the
53 feature are available and recent enough.
55 Returns ``True`` if the feature is available,
56 and ``False`` if it is not or if metadata is
57 missing.
58 """
59 value = _cache.get(feature)
60 if value is not None:
61 return value
62 requirements = _requirements.get(feature)
63 if requirements is None:
64 # we make a cache entry here for consistency not performance
65 _cache[feature] = False
66 return False
67 ok = True
68 for requirement in requirements:
69 if not _version_check(requirement):
70 ok = False
71 break
72 _cache[feature] = ok
73 return ok
76def force(feature: str, enabled: bool) -> None:
77 """Force the status of *feature* to be *enabled*.
79 This method is provided as a workaround for any cases
80 where importlib.metadata is ineffective, or for testing.
81 """
82 _cache[feature] = enabled
85_requirements: dict[str, list[str]] = {
86 ### BEGIN generated requirements
87 "dnssec": ["cryptography>=45"],
88 "doh": ["httpcore>=1.0.0", "httpx>=0.28.0", "h2>=4.2.0"],
89 "doq": ["aioquic>=1.2.0"],
90 "idna": ["idna>=3.10"],
91 "trio": ["trio>=0.30"],
92 "wmi": ["wmi>=1.5.1"],
93 ### END generated requirements
94}