multiformats.varint
Implementation of the unsigned-varint spec.
Suggested usage:
>>> from multiformats import varint
BytesLike
- BytesLike
Type alias for bytes-like objects.
alias of
bytes
|bytearray
|memoryview
byteslike
- byteslike = (<class 'bytes'>, <class 'bytearray'>, <class 'memoryview'>)
Tuple of bytes-like objects types (for use with
isinstance
checks).
decode
- decode(b)[source]
Decodes an unsigned varint from a bytes-like object or a buffered binary stream.
if a stream is passed, only the bytes encoding the varint are read from it
if a bytes-like object is passed, the varint encoding must use all bytes
Example usage with bytes:
>>> from multiformats import varint >>> varint.decode(b'\x80\x01') 128
Example usage with streams, for the (typical) situation where the varint is only part of the data:
>>> from io import BytesIO >>> stream = BytesIO(b"\x80\x01\x12\xff\x01") >>> varint.decode(stream) 128 >>> stream.read() # what's left in the stream b'\x12\xff\x01'
- Parameters:
b (
BytesLike
,BufferedIOBase
orBinaryIO
) – the bytes-like object or stream from which to decode a varint- Raises:
ValueError – if the input contains no bytes (from specs, the number 0 is encoded as
0b00000000
)ValueError – if the 9th byte of the input is a continuation byte (from specs, no number >= 2**63 is allowed)
ValueError – if the last byte of the input is a continuation byte (invalid format)
ValueError – if the decoded integer could be encoded in fewer bytes than were read (from specs, encoding must be minimal)
ValueError – if the input is a bytes-like object and the number of bytes used by the encoding is fewer than its length
The last point is a designed choice aimed to reduce errors when decoding fixed-length bytestrings (rather than streams). If this behaviour is undesirable, consider using decode_head instead.
- Return type:
decode_raw
- decode_raw(b)[source]
Specialised version of
decode
for partial decoding, returning a pair(x, n)
of the decoded varintx
and the numbern
of bytes read from the start and/or consumed from the stream. Unlikedecode
, this function doesn’t raise ValueError in case not all bytes are read in the process.Example usage with bytes:
>>> bs = b"\x80\x01\x12\xff\x01" >>> x, n, m = varint.decode_raw(bs) >>> x 128 >>> n 2 # read first 2 bytes: b"\x80\x01" >>> m <memory at 0x000001A6E55DDA00> >>> bytes(m) b'\x12\xff\x01' # memoryview on remaining bytes # note: bytes(m) did not consume the bytes
Example usage with streams, for the (typical) situation where the varint is only part of the data:
>>> from io import BytesIO >>> stream = BytesIO(b"\x80\x01\x12\xff\x01") >>> x, n = varint.decode_head(stream) >>> x 128 >>> n 2 # read first 2 bytes: b"\x80\x01" >>> m <_io.BytesIO object at 0x000001A6E554BBD0> >>> m == stream True # original stream returned, containing remaining bytes >>> stream.read() b'\x12\xff\x01' # 2 bytes were consumed decoding the varint, so 3 bytes were left in the stream # note: stream.read() consumed the bytes
- Parameters:
b (
BytesLike
,BufferedIOBase
orBinaryIO
) – the bytes-like object or stream from which to decode a varint- Raises:
ValueError – same reasons as
decode
, except for the last (where no error is raised)- Return type:
Tuple
[int
,int
,Union
[memoryview
,BufferedIOBase
,BinaryIO
]]
encode
- encode(x)[source]
Encodes a non-negative integer as an unsigned varint, returning the encoded bytes.
Example usage:
>>> from multiformats import varint >>> varint.encode(128) b'\x80\x01'
- Parameters:
x (
int
) – the non-negative integer to encode- Raises:
ValueError – if x < 0 (varints encode unsigned integers)
ValueError – if x >= 2**63 (from specs, varints are limited to 9 bytes)
- Return type: