[plum.nil] Tutorial: Using Nil Type

The Nil type consumes no bytes when unpacked and produces no bytes when packed. Seldom needed, but important when a dynamic structure needs a placeholder. This tutorial shows a sample usage and the Nil type’s properties.

Sample Usage

One application where Nil may become necessary is when a structure member’s datatype depends on another structure member. The variable type member as shown in the following example demonstrates a use case. The data member’s type depends on the value of the datatype member as defined by the type mapping. When datatype equals 0, no bytes are expected for the data member. When datatype equals 1 or 2, bytes for a UInt8 or UInt16 (respectively) are expected for the data member:

>>> from plum import unpack
>>> from plum.int.little import UInt8, UInt16
>>> from plum.nil import Nil
>>> from plum.structure import Structure, TypeMember, VariableTypeMember
>>>
>>> class Struct1(Structure):
...     datatype: int = TypeMember(cls=UInt8, mapping={0: Nil, 1: UInt8, 2: UInt16})
...     data: object = VariableTypeMember(type_member=datatype)
...
>>> unpack(Struct1, b'\x00').dump()
+--------+-----------------+-------+-------+---------+
| Offset | Access          | Value | Bytes | Type    |
+--------+-----------------+-------+-------+---------+
|        |                 |       |       | Struct1 |
| 0      | [0] (.datatype) | 0     | 00    | UInt8   |
|        | [1] (.data)     | nil   |       | Nil     |
+--------+-----------------+-------+-------+---------+
>>>
>>> unpack(Struct1, b'\x01\x02').dump()
+--------+-----------------+-------+-------+---------+
| Offset | Access          | Value | Bytes | Type    |
+--------+-----------------+-------+-------+---------+
|        |                 |       |       | Struct1 |
| 0      | [0] (.datatype) | 1     | 01    | UInt8   |
| 1      | [1] (.data)     | 2     | 02    | UInt8   |
+--------+-----------------+-------+-------+---------+

Properties

During instantiation or packing, the Nil type accepts either None, the singleton nil object, or nothing:

>>> from plum.nil import Nil, nil
>>>
>>> Nil(None)
nil
>>> Nil(nil)
nil
>>> Nil()
nil

Instantiation of Nil always yields the singleton nil object:

>>> x = Nil()
>>> y = Nil()
>>> x is y
True
>>> x is nil
True
>>> y is nil
True

Instances of Nil compare equally against either None or nil:

>>> Nil() == nil
True
>>> Nil() == None
True