Python codec¶
This page describes how to encode, decode and manipulate prophy messages in Python.
Compilation¶
Prophy Compiler can be used to generate Python codec source code from .prophy files. This generated code together with Python prophy library forms a fully functional codec.
Example compiler invocation:
prophyc --python_out . test.prophy
will result in creating test.py
.
Generated code¶
File generated by Prophy Compiler defines classes representing enums, structs and unions.
Enumerators can be accessed:
enum Test1
{
Test1_1 = 1,
Test1_2 = 2,
Test1_3 = 3
};
>>> import test
>>> test.Test1_1
1
Structs can be instantiated, written or read and encoded or decoded:
struct Test2
{
u32 a;
};
>>> import test
>>> x = test.Test2()
>>> x.a = 42
>>> x.a
42
>>> print x
a: 42
>>> x.encode('>')
'\x00\x00\x00*'
>>> x.decode('\x00\x00\x00*', '>')
4
Struct enum field can be set by value or name, name can be extracted from it:
struct Test3
{
Test1 a;
};
>>> import test
>>> x = test.Test3()
>>> x.a = 2
>>> x.a = 'Test1_2'
>>> x.a
2L
>>> x.a.name
'Test1_2'
Arrays (all kinds) may be indexed, sliced and iterated:
struct Test4
{
i32 a[3];
};
>>> import test
>>> x = test.Test4()
>>> x.a[0] = 42
>>> x.a
[42, 0, 0]
>>> x.a[:] = [1, 2, 3]
>>> for value in x.a:
... print value
...
1
2
3
Arrays of structs or unions can add new elements or be extended by iterables of them:
struct Test5
{
Test2 a<>;
};
>>> import test
>>> x = test.Test5()
>>> y = x.a.add()
>>> y.a = 42
>>> print x
a {
a: 42
}
>>> x.a.extend([y])
>>> print x
a {
a: 42
}
a {
a: 42
}
Optional struct fields may be set or cleared by setting with True and None:
struct Test6
{
u32* a;
Test2* b;
};
>>> import test
>>> x = test.Test6()
>>> x.a = 42
>>> x.a
42
>>> x.a = None
>>> x.a
>>> x.b = True
>>> print x.b
a: 0
>>> x.b = None
>>> print x.b
None
Union arm is chosen by setting discriminator with arm number or name:
union Test7
{
0: u32 a;
1: Test2 b;
};
>>> import test
>>> x = test.Test7()
>>> x.discriminator = 0
>>> x.a = 42
>>> x.discriminator = 'b'
>>> x.b.a = 42
Packed mode¶
Python generated message descriptors may be altered
to inhibit padding by inheriting from struct_packed
instead of struct
.
Following message would be encoded as 6 bytes:
class PackedMessage(prophy.struct_packed):
__metaclass__ = prophy.struct_generator
_descriptor = [('x', prophy.u8),
('y', prophy.u32),
('z', prophy.u8)]
Warning
Mixing struct_packed
with nested struct
and otherwise yields undefined behavior.