Python interface for c-ares asynchronous DNS library
—
String encoding and domain name processing utilities for handling international domain names, proper ASCII encoding, and data conversion within pycares operations.
Convert various string and bytes types to appropriate formats for DNS operations.
def ascii_bytes(data):
"""
Convert string or bytes data to ASCII bytes.
Args:
data: Union[str, bytes] - Input data to convert
Returns:
bytes: ASCII-encoded bytes
Raises:
TypeError: If data is neither str nor bytes
"""
def maybe_str(data):
"""
Convert bytes to string if possible, otherwise return as-is.
Attempts to decode bytes data to ASCII string. If decoding fails,
returns the original bytes object.
Args:
data: Union[str, bytes] - Input data to convert
Returns:
Union[str, bytes]: String if decodable to ASCII, otherwise bytes
Raises:
TypeError: If data is neither str nor bytes
"""Usage Example:
import pycares
# Convert string to ASCII bytes
hostname_bytes = pycares.ascii_bytes("example.com")
print(hostname_bytes) # b'example.com'
# Convert bytes to string if possible
result = pycares.maybe_str(b"example.com")
print(result) # 'example.com'
# Binary data stays as bytes
binary_data = b'\x00\x01\x02'
result = pycares.maybe_str(binary_data)
print(type(result)) # <class 'bytes'>Process domain names for DNS queries, including support for internationalized domain names (IDNA).
def parse_name(name):
"""
Parse and encode domain name for DNS queries.
Handles both ASCII and internationalized domain names. For ASCII names,
performs direct encoding. For international domain names, uses IDNA 2008
encoding if the idna package is available, otherwise falls back to
built-in IDNA 2003 encoding.
Args:
name: Union[str, bytes] - Domain name to parse
Returns:
bytes: Properly encoded domain name for DNS queries
Raises:
TypeError: If name is neither str nor bytes
RuntimeError: If domain part exceeds 253 characters
"""Usage Example:
import pycares
# ASCII domain name
ascii_domain = pycares.parse_name("example.com")
print(ascii_domain) # b'example.com'
# International domain name (requires idna package for IDNA 2008)
try:
intl_domain = pycares.parse_name("例え.テスト")
print(intl_domain) # Encoded bytes representation
except RuntimeError as e:
print(f"Domain name too long: {e}")
# Bytes input passes through
bytes_domain = pycares.parse_name(b"example.org")
print(bytes_domain) # b'example.org'pycares provides enhanced internationalized domain name support when the optional idna package is installed:
# Install with IDNA 2008 support
# pip install pycares[idna]The parse_name function enforces DNS domain length limits:
Example with Error Handling:
import pycares
def safe_parse_name(domain):
"""Safely parse domain name with error handling."""
try:
return pycares.parse_name(domain)
except TypeError:
print(f"Invalid domain type: {type(domain)}")
return None
except RuntimeError as e:
print(f"Domain name error: {e}")
return None
# Test with various inputs
domains = [
"example.com", # ASCII domain
"例え.テスト", # International domain
b"binary.domain", # Bytes input
123, # Invalid type
"a" * 300 + ".com" # Too long
]
for domain in domains:
result = safe_parse_name(domain)
if result:
print(f"Parsed: {domain} -> {result}")
else:
print(f"Failed to parse: {domain}")These utility functions are used internally by pycares but can also be used directly when working with domain names and DNS data:
import pycares
def custom_dns_query(channel, raw_name, query_type, callback):
"""Example showing manual name processing."""
try:
# Process domain name using utility function
encoded_name = pycares.parse_name(raw_name)
# Use processed name in query
# (Note: pycares.Channel.query() handles this internally)
channel.query(encoded_name.decode('ascii'), query_type, callback)
except (TypeError, RuntimeError, UnicodeDecodeError) as e:
# Handle name processing errors
callback(None, pycares.errno.ARES_EBADNAME)
# Usage
channel = pycares.Channel()
custom_dns_query(channel, "example.com", pycares.QUERY_TYPE_A, lambda r, e: print(r, e))The utilities module exports the following functions in its __all__ list:
__all__ = ['ascii_bytes', 'maybe_str', 'parse_name']These functions are also available directly from the main pycares module after import.
Install with Tessl CLI
npx tessl i tessl/pypi-pycares