Dtype#

Data types control how bits are converted into values, and how values are converted into bits.

They are often used implicitly when creating from or interpreting to integers, floats and other types, but can also be used explicitly in methods like Tibs.from_values(). Once created, a Dtype can also pack and unpack values itself:

>>> d = Dtype("u12")
>>> packed = d.pack_values([0, 103, 2048, 4095])
>>> packed.hex
'000067800fff'
>>> d.unpack_values(packed)
[0, 103, 2048, 4095]

The pack and pack_values methods return immutable Tibs instances. If mutable output is needed directly, use Mutibs.from_value() or Mutibs.from_values().

Dtype strings#

The compact dtype string usually starts with a kind and ends with the bit length of one value. The bool dtype is the exception: it is always exactly one bit long and has no length suffix.

Form

Meaning

Example

uN

Unsigned integer

u12

iN

Signed integer

i16

fN

IEEE floating-point value

f32

bool

Python bool using one bit

bool

bitsN

A bit sequence with exactly N bits, decoded as Tibs

bits5

binN

Binary string with exactly N bits

bin5

octN

Octal string with exactly N bits

oct12

hexN

Hex string with exactly N bits

hex16

bytesN

Bytes value using N bits

bytes32

bool values can be packed from True, False, 0 or 1, and are unpacked as Python bool objects. bitsN values use normal Tibs promotion, so they can be packed from Tibs, Mutibs, strings, bytes-like objects, or strict list/tuple bit patterns, and are unpacked as immutable Tibs objects.

Note

Lengths are consistently in bits throughout the tibs library. This can surprise in one place in particular — the bytesN dtype string is N bits long, so "bytes32" is 4 bytes, and not 32 bytes.

For integer and floating-point dtypes, append _le or _be to specify byte order for whole-byte values. The suffixes use the conventional endian abbreviations: _le means little-endian byte order, and _be means big-endian byte order:

>>> Dtype("u16_le")
Dtype('u16_le')
>>> Tibs.from_values("u16_le", [0x1234, 0xabcd]).hex
'3412cdab'

Byte order cannot be used with bool, bits, bin, oct, hex or bytes dtypes. Float values are encoded using the supported IEEE widths: 16, 32 and 64 bits. The selected bit range for Tibs.to_values() and Dtype.unpack_values() must be a whole number of dtype values.

Dtype instances are immutable. They compare and hash by kind, length and byte order, so they can be reused as dictionary keys or set members.

class Dtype(spec, /)#

A data type which determines how a value is encoded as a fixed-width bit sequence.

Dtype is used by Tibs.from_value(), Tibs.to_value(), Tibs.from_values() and related methods to describe the kind, length and optional byte order for encoded values.

>>> Dtype("u16_le")
Dtype('u16_le')
>>> Tibs.from_value("u8", 15)
Tibs('0x0f')
from_params(kind, length, byte_order=None)#

Create a dtype from explicit parameters.

Parameters:
  • kind (DtypeKind) – The kind of value to encode or decode.

  • length (int) – The number of bits used by one value.

  • byte_order (ByteOrder) – The byte order for integer and floating-point values. Defaults to ByteOrder.Unspecified.

Returns:

A new Dtype.

Raises:

ValueError – if length is not greater than zero, if DtypeKind.Bool is given a length other than 1, if byte order is used with a non-numeric kind, or if byte order is used with a non-byte length.

>>> Dtype.from_params(DtypeKind.Uint, 16, ByteOrder.Little)
Dtype('u16_le')
pack(value, /)#

Encode one Python value as a Tibs.

Parameters:

value (object) – The value to encode.

Returns:

A new Tibs.

>>> Dtype("u8").pack(15)
Tibs('0x0f')
pack_values(iterable, /)#

Encode and concatenate Python values as a Tibs.

Parameters:

iterable (Iterable) – The values to encode.

Returns:

A new Tibs.

>>> Dtype("u8").pack_values([1, 2, 3])
Tibs('0x010203')
unpack(bits, /, start=None, end=None)#

Decode one value from a bit sequence.

Parameters:
  • bits (object) – The bit sequence to decode. This can be anything promotable to Tibs.

  • start (int | None) – Start bit position. Defaults to 0.

  • end (int | None) – End bit position. Defaults to len(bits).

Returns:

The decoded Python value.

>>> Dtype("u8").unpack("0x0f")
15
unpack_values(bits, /, start=None, end=None)#

Decode a list of values from a bit sequence.

The selected range must be a whole number of dtype values.

Parameters:
  • bits (object) – The bit sequence to decode. This can be anything promotable to Tibs.

  • start (int | None) – Start bit position. Defaults to 0.

  • end (int | None) – End bit position. Defaults to len(bits).

Returns:

A list of decoded Python values.

>>> Dtype("u8").unpack_values("0x010203")
[1, 2, 3]
unpack_values_iter(bits, /, start=None, end=None)#

Return an iterator over values decoded from a bit sequence.

The selected range must be a whole number of dtype values.

Parameters:
  • bits (object) – The bit sequence to decode. This can be anything promotable to Tibs.

  • start (int | None) – Start bit position. Defaults to 0.

  • end (int | None) – End bit position. Defaults to len(bits).

Returns:

An iterator yielding decoded Python values.

>>> list(Dtype("u8").unpack_values_iter("0x010203"))
[1, 2, 3]
byte_order#

The byte order used by integer and floating-point values.

kind#

The value kind described by this dtype.

length#

The number of bits used by one value.