Source code for multicodec.code

"""
Multicodec Code type and core functionality.

This module provides:
- Code class for type-safe codec handling
- ReservedStart and ReservedEnd constants
- KnownCodes() function to list all registered codes
"""

from __future__ import annotations

from .constants import CODE_TABLE, NAME_TABLE

# ReservedStart is the (inclusive) start of the reserved range of codes that
# are safe to use for internal purposes.
RESERVED_START: int = 0x300000

# ReservedEnd is the (inclusive) end of the reserved range of codes that are
# safe to use for internal purposes.
RESERVED_END: int = 0x3FFFFF


[docs] class Code: """ Code describes an integer reserved in the multicodec table. This class provides: - Type-safe codec handling - String conversion (name lookup) - Set from string (name or hex number) - Tag lookup Example: >>> code = Code(0x12) >>> str(code) 'sha2-256' >>> code = Code.from_string("sha2-256") >>> int(code) 18 """ __slots__ = ("_value",) def __init__(self, value: int) -> None: """Initialize a Code with an integer value.""" if not isinstance(value, int): raise TypeError(f"Code value must be an integer, got {type(value).__name__}") if value < 0: raise ValueError("Code value must be non-negative") self._value = value
[docs] @classmethod def from_string(cls, text: str) -> Code: """ Create a Code from a string, interpreting it as a multicodec name or number. The input string can be the name or number for a known code. A number can be in decimal or hexadecimal format (with 0x prefix). Numbers in the reserved range 0x300000-0x3FFFFF are also accepted. :param str text: The codec name or number :return: A Code instance :rtype: Code :raises ValueError: If the text is not a valid codec """ # Try parsing as a number first (cheap operation) try: n = int(text, 0) # base 0 allows decimal, hex (0x), octal (0o), binary (0b) code = cls(n) # Accept if in reserved range if RESERVED_START <= n <= RESERVED_END: return code # Accept if known code if n in CODE_TABLE: return code except ValueError: pass # Try matching by name if text in NAME_TABLE: return cls(NAME_TABLE[text]) raise ValueError(f'unknown multicodec: "{text}"')
[docs] def set(self, text: str) -> None: """ Set the code from a string. :param str text: The codec name or number :raises ValueError: If the text is not a valid codec """ new_code = Code.from_string(text) self._value = new_code._value
def __int__(self) -> int: """Return the integer value of the code.""" return self._value def __index__(self) -> int: """Support using Code in contexts that require an integer index.""" return self._value def __str__(self) -> str: """ Return the string name of the code. Returns the codec name if known, otherwise returns the hex representation. """ if self._value in CODE_TABLE: return CODE_TABLE[self._value] return f"Code(0x{self._value:x})" def __repr__(self) -> str: """Return a detailed representation of the code.""" if self._value in CODE_TABLE: return f"Code({CODE_TABLE[self._value]!r}, 0x{self._value:x})" return f"Code(0x{self._value:x})" def __eq__(self, other: object) -> bool: """Check equality with another Code or integer.""" if isinstance(other, Code): return self._value == other._value if isinstance(other, int): return self._value == other return NotImplemented def __hash__(self) -> int: """Return hash of the code value.""" return hash(self._value) def __lt__(self, other: Code | int) -> bool: """Compare less than.""" if isinstance(other, Code): return self._value < other._value if isinstance(other, int): return self._value < other return NotImplemented def __le__(self, other: Code | int) -> bool: """Compare less than or equal.""" if isinstance(other, Code): return self._value <= other._value if isinstance(other, int): return self._value <= other return NotImplemented def __gt__(self, other: Code | int) -> bool: """Compare greater than.""" if isinstance(other, Code): return self._value > other._value if isinstance(other, int): return self._value > other return NotImplemented def __ge__(self, other: Code | int) -> bool: """Compare greater than or equal.""" if isinstance(other, Code): return self._value >= other._value if isinstance(other, int): return self._value >= other return NotImplemented @property def name(self) -> str: """Return the codec name, or '<unknown>' if not found.""" return CODE_TABLE.get(self._value, "<unknown>")
[docs] def tag(self) -> str: """ Return the tag for this codec. Tags categorize codecs (e.g., "multihash", "multiaddr", "ipld", etc.) """ return _get_tag(self._value)
def _get_tag(code: int) -> str: """Get the tag for a codec code (mirrors go-multicodec's Tag() method).""" name = CODE_TABLE.get(code, "") # CID if name in ("cidv1", "cidv2", "cidv3"): return "cid" # Encryption if name in ("aes-gcm-256",): return "encryption" # Filecoin if name in ("fil-commitment-unsealed", "fil-commitment-sealed"): return "filecoin" # Hash (non-multihash) if name in ( "murmur3-x64-64", "murmur3-32", "murmur3-128", "crc32", "crc64-ecma", "crc64-nvme", "murmur3-x64-128", "sha256a", "xxh-32", "xxh-64", "xxh3-64", "xxh3-128", ): return "hash" # Holochain if "holochain" in name: return "holochain" # IPLD if name in ( "cbor", "raw", "dag-pb", "dag-cbor", "libp2p-key", "git-raw", "torrent-info", "torrent-file", "blake3-hashseq", "leofcoin-block", "leofcoin-tx", "leofcoin-pr", "dag-jose", "dag-cose", "eth-block", "eth-block-list", "eth-tx-trie", "eth-tx", "eth-tx-receipt-trie", "eth-tx-receipt", "eth-state-trie", "eth-account-snapshot", "eth-storage-trie", "eth-receipt-log-trie", "eth-receipt-log", "bitcoin-block", "bitcoin-tx", "bitcoin-witness-commitment", "zcash-block", "zcash-tx", "stellar-block", "stellar-tx", "decred-block", "decred-tx", "dash-block", "dash-tx", "swarm-manifest", "swarm-feed", "beeson", "dag-json", "swhid-1-snp", "json", "rdfc-1", "json-jcs", ): return "ipld" # Key if any( k in name for k in ( "-pub", "-priv", "secp256k1", "bls12_381", "x25519", "ed25519", "p256", "p384", "p521", "ed448", "x448", "sr25519", "rsa", "sm2", "mlkem", "jwk", ) ): return "key" # Libp2p if name in ("libp2p-peer-record", "libp2p-relay-rsvp"): return "libp2p" # Multiaddr if name in ( "ip4", "tcp", "dccp", "ip6", "ip6zone", "ipcidr", "dns", "dns4", "dns6", "dnsaddr", "sctp", "udp", "p2p-webrtc-star", "p2p-webrtc-direct", "p2p-stardust", "p2p-circuit", "udt", "utp", "unix", "thread", "p2p", "https", "onion", "onion3", "garlic64", "garlic32", "tls", "sni", "noise", "shs", "quic", "quic-v1", "webtransport", "certhash", "ws", "wss", "p2p-websocket-star", "http", "http-path", "webrtc-direct", "webrtc", "plaintextv2", "scion", "memory", ): return "multiaddr" # Multiformat if name in ("multicodec", "multihash", "multiaddr", "multibase", "varsig"): return "multiformat" # Multihash if any( h in name for h in ( "identity", "sha1", "sha2-", "sha3-", "shake-", "keccak-", "blake2b-", "blake2s-", "blake3", "dbl-sha2-", "md4", "md5", "bmt", "ripemd-", "x11", "kangarootwelve", "sm3-", "poseidon-", "skein", ) ): return "multihash" # Namespace if name in ( "path", "lbry", "streamid", "ipld-ns", "ipfs-ns", "swarm-ns", "ipns-ns", "zeronet", "dnslink", "skynet-ns", "arweave-ns", "subspace-ns", "kumandra-ns", ): return "namespace" # Serialization if name in ( "protobuf", "rlp", "bencode", "messagepack", "car", "car-index-sorted", "car-multihash-index-sorted", "ipns-record", "x509-certificate", "ssz", ): return "serialization" # Transport if name in ( "transport-bitswap", "transport-graphsync-filecoinv1", "transport-ipfs-gateway-http", ): return "transport" # Varsig if name in ( "nonstandard-sig", "es256k", "bls12_381-g1-sig", "bls12_381-g2-sig", "eddsa", "eip-191", "es256", "es384", "es512", "rs256", ): return "varsig" # Zeroxcert if name in ("zeroxcert-imprint-256",): return "zeroxcert" return "<unknown>" # Cache for known codes list _known_codes: list[Code] | None = None
[docs] def known_codes() -> list[Code]: """ Return a list of all codes registered in the multicodec table. The returned list should be treated as read-only. :return: List of all known Code objects :rtype: list[Code] """ global _known_codes if _known_codes is None: _known_codes = [Code(code) for code in sorted(CODE_TABLE.keys())] return _known_codes
[docs] def is_reserved(code: int | Code) -> bool: """ Check if a code falls within the reserved range. The reserved range (0x300000-0x3FFFFF) is designated for internal and experimental use. :param code: The codec code to check :return: True if the code is in the reserved range :rtype: bool """ if isinstance(code, Code): code = int(code) return RESERVED_START <= code <= RESERVED_END