python-reflexion/01-importers/dns_importer.py
2025-10-21 20:38:10 +02:00

53 lines
1.6 KiB
Python

from importlib import _bootstrap_external, _bootstrap
from urllib.parse import urlparse
import dns.resolver
import dns.exception
class DnsImporter(_bootstrap_external._LoaderBasics):
def __init__(self, path):
if not isinstance(path, str):
raise TypeError(f"expected str, not {type(path)!r}")
url = urlparse(path)
if not url.scheme in ('dns+pylib'):
raise ValueError(f'url scheme not supported: `{url.scheme}`')
self.base_domain = url.hostname
def find_spec(self, fullname, target=None):
module_domain = fullname.rpartition('.')[2] + '.' + self.base_domain
domains = (
(module_domain, False),
('__init__.' + module_domain, True)
)
for (domain, is_package) in domains:
try:
answer = dns.resolver.resolve(domain, 'TXT')
self.data = b''.join(
string
for rdata in answer
for string in rdata.strings
)
self.domain = domain
except dns.exception.DNSException as e:
continue
spec = _bootstrap.ModuleSpec(
fullname,
self, # loader
origin=f'dns+pylib://{self.domain}',
is_package=is_package
)
if is_package:
spec.submodule_search_locations.append(f'dns+pylib://{module_domain}')
return spec
return None
def get_code(self, fullname):
return compile(self.data, self.domain, 'exec', dont_inherit=True)