API
ConstructBase
- class strconstruct.ConstructBase
Bases:
object
ConstructBase forms the basis of all the StrConstruct class. All of them inherit from ConstructBase. ConstructBase provides two important public API that is exposed by all the StrConstruct objects;
build
andparse
. This class is intended for internal use only.The
build
method always returns a string. Theparse
method does the revers; it always gets a string. The input type ofbuild
and the return type ofparse
depend on the type of the StrConstruct. For example,StrInt
’s build method gets an int whileStrStruct
gets a dictionary.An StrConstruct can be also be named by the division operator. The return object of the division operation is the same StrConstruct object used in the operation, not a new object. So it has all attributes of the original object.
>>> d = StrInt("d") >>> d.name >>> id(d) 140492806992128 >>> d = "field" / d >>> d.name 'field' >>> id(d) 140492806992128
There are two motivations here; a clear syntax for declaring multi-field protocols and of course compatibility with Construct. See
StrStruct
for more information.Another important note is that _value_ is a reserved value when it comes to naming fields. Long story short, the reason behind it is support passing around contexts. More info on contexts can be found TODO.
- __rtruediv__(other: str) ConstructBase
Used for naming StrConstruct objects.
- Parameters:
other – The name of the construct.
_value_
is reserved for StrConstruct internal use.- Returns:
The same object with the new name
- __truediv__(other: str) ConstructBase
Used for naming StrConstruct objects.
- Parameters:
other – The name of the construct.
_value_
is reserved for StrConstruct internal use.- Returns:
The same object with the new name
- _build(_value_, **kwargs)
The build backed for different StrConstruct classes. Must be overridden by the child class.
- Parameters:
_value_ – The value to be built
**kwargs – The context
- Raises:
NotImplementedError if not overridden by the child class –
- _parse(string, **kwargs)
The parse backed for different StrConstruct classes. Must be overridden by the child class.
- Parameters:
string – The string to be parsed
**kwargs – The context
- Raises:
NotImplementedError if not overridden by the child class –
StrInt
- class strconstruct.StrInt(format_)
Bases:
ConstructBase
StrInt can be used for building and parsing numeric fields. An StrInt, needs a format to be constructed, similar to other str-construct classes. The constructed objects can be used to build and parse strings.
>>> from strconstruct import StrInt >>> StrInt("d").build(2) '2' >>> StrInt("d").build(-2) '-2' >>> StrInt("d").parse("3") 3 >>> StrInt("d").parse("-3") -3
StrInt accepts,
d
,x
, andX
formats. They work set decimal, lower-case hex and upper-case hex formats, respectively.>>> StrInt("x").build(15) 'f' >>> StrInt("X").build(15) 'F' >>> StrInt("X").parse("F") 15
Similar to other str-construct classes, StrInt is strict with parsing. The following line of code raises
StrConstructParseError
.>>> StrInt("x").parse("F")
Finally, all the formats accept lengths with an optional padding value of zero:
>>> StrInt("013X").build(10) '000000000000A' >>> StrInt("13X").parse("000000000000A") 10
If the expected number of characters is not received during parsing, a
StrConstructParseError
is raise. For example, the parsing for the following lines code will fail.>>> StrInt("3d").parse("12") >>> StrInt("13X").parse("00000000000A")
It’s also important to note that when no length is specified, the search continues until a non-parsable character is found. If there is a length, only that many of characters is processed by the parser method.
>>> StrInt("d").parse("12345>") 12345 >>> StrInt("2d").parse("12345>") 12 >>> StrInt("02d").parse("12345>") 12
- __init__(format_)
- Parameters:
format – The format of the StrInt. The supported values are
d
,x
, andX
. Length can also be specified with an optional padding value of zero.
- _build(_value_, **kwargs) str
Backend method for building numeric strings
- Parameters:
_value_ – The value to be built
**kwargs – Other values that might be provided to the build method as additional context. Ignore by StrInt.
- Returns:
The built string
- _parse(string, **kwargs) int
Backend method for parsing numeric strings
- Parameters:
string – The input string
**kwargs – Other values that might be provided to the build method as additional context. Will be ignored by StrFloat
- Returns:
The parsed content as an
int
object
StrFloat
- class strconstruct.StrFloat(format_)
Bases:
ConstructBase
StrFloat is a class for building and parsing strings that show floating-point numeric values. The number of decimal digits can also be specified.
>>> StrFloat(".1f").build(2) '2.0' >>> StrFloat(".1f").build(2.0) '2.0' >>> StrFloat(".1f").parse("2.1") 2.1 >>> StrFloat(".1f").parse("2.0") 2.0
The length makes the object more strict when it comes to parsing strings. The following raises an
StrConstructParseError
exception.>>> StrFloat(".4f").parse("2.018") ... strconstruct.str_construct_exceptions.StrConstructParseError: Insufficient characters found. At least 4 decimal numbers are needed
When a length is not specified, parsing becomes greedy, as far as there is parsable character.
>>> StrFloat("f").parse("19.98765@") 19.98765 >>> StrFloat(".2f").parse("19.18765@") 19.18
- __init__(format_)
- Parameters:
format – The format of the floating-point number. The only supported format is
f
. This module can receive the number of the decimal digits.- Raises:
ValueError – If the format is invalid
- _build(_value_, **kwargs) str
Backend method for building strings representing floating-point numbers
- Parameters:
_value_ – The value to be built
**kwargs – Other values that might be provided to the build method as additional context. Ignore by StrFloat.
- Returns:
The built string
- _parse(string, **kwargs) float
Backend method for parsing strings representing floating-point numbers
- Parameters:
string – The input string
**kwargs – Other values that might be provided to the build method as additional context. Will be ignored by StrFloat
- Returns:
The parsed content as a
float
object
StrConst
- class strconstruct.StrConst(const)
Bases:
ConstructBase
StrConst is helpful when there is constant fields and removes the need to specify them when building.
>>> packet = StrConst("MyString") >>> packet.build() 'MyString'
It can also build without a value, which becomes an important feature when using StrStruct (it can be defined only once).
>>> packet = StrStruct( ... StrConst(">"), ... "value" / StrInt("d"), ... StrConst("\n"), ... ) >>> packet.build({"value": 22}) '>22\n'
- __init__(const)
- Parameters:
const – The constant value use for both building and parsing
- _build(_value_, **ctx) str
Backend method for building constant strings
- Parameters:
_value_ – The value to be built
**ctx – Other values that might be provided to the build method as additional context. Ignore by StrConst.
- Returns:
The built string
- _parse(string: str, **ctx) str
Backend method for parsing constant strings
- Parameters:
string – The input string
**kwargs – Other values that might be provided to the build method as additional context. Will be ignored by StrConst
- Returns:
The parsed content as an
str
object
StrDefault
- class strconstruct.StrDefault(construct, default)
Bases:
ConstructBase
StrDefault provides a default value for the building procedure. Parsing is simply deferred to the sub-strConstruct object. Let’s take an example.
>>> d = StrDefault(StrInt("02X"), 17) >>> d.build() '11' >>> d.build(18) '12'
Parsing, in the example above, behaves exactly according to the sub-StrConstruct i.e. StrInt(). StrDefault does not make the parse method to work with no data (that would make no sense when seeing it in terms of communication and protocol)
>>> d.parse() ... TypeError: parse() missing 1 required positional argument: 'string' >>> d.parse("11") 17 >>> d.parse("12") 18
- __init__(construct, default)
- Parameters:
construct – The underlying StrConstruct object
default – The default value to be built when no data is give to the build method. Note that this value will be given to the StrConstruct object provided by construct and the output string depends on construct.
- _build(_value_, **ctx) str
Backend method for building default strings
- Parameters:
_value_ – The value to be built
**ctx – Other values that might be provided to the build method as additional context. Not used by StrDefault
- Returns:
The built string
- _parse(string, **ctx)
Backend method for parsing numeric strings
- Parameters:
string – The input string
**kwargs – Other values that might be provided to the build method as additional context. Not used by StrDefault
- Returns:
The parsed content. The type depends on the underlying StrConstruct object.
StrSwitch
- class strconstruct.StrSwitch(condition: Any, cases: dict, default: ConstructBase | None = None)
Bases:
ConstructBase
StrSwitch helps with running different build/parse paths depending on a set of conditions, similar to switch statement in languages like C.
>>> from strconstruct import StrSwitch, StrInt, StrFloat >>> d = StrSwitch( ... 1, ... { ... 1: StrFloat("0.3f"), ... 2: StrInt("02d") ... } ... ) >>> d.build(2) '2.000' >>> d = StrSwitch( ... 2, ... { ... 1: StrFloat("0.3f"), ... 2: StrInt("02d") ... } ... ) >>> d.build(2) '02'
Of course the above example is not very useful by itself. It just attempts to show how the first argument selects the build path. A more useful scenario, is to provide a callable as the condition:
>>> from strconstruct import StrFloat, StrConst, StrDefault, StrStruct, StrInt >>> d = StrSwitch( ... lambda this: this["n"], ... { ... 1: StrFloat("0.1f"), ... 2: StrConst("@"), ... 3: StrDefault(StrInt("03X"), 17), ... 4: StrStruct( ... "field1" / StrInt("d"), ... StrConst("-"), ... "field2" / StrFloat(".2f"), ... ) ... }, ... default=StrInt("d") ... ) >>> d.build(2, n=1) '2.0' >>> d.build(n=2) '@' >>> d.build(n=3) '011' >>> d.build(16, n=3) '010' >>> d.build(14, n=103) '14' >>> d.build( ... { ... "field1": 13, ... "field2": 17.29, ... }, ... n=4, ... ) '13-17.29'
The callable should receive an argument, which will be set to the context when called. (Construct also provides context and this)
Parsing provides a similar functionality
>>> d = StrSwitch( ... lambda ctx: 1, ... { ... 1: StrFloat("0.1f"), ... 2: StrConst("@") ... } ... ) >>> d.parse("2.0") 2.0 >>> d = StrSwitch( ... lambda ctx: 2, ... { ... 1: StrFloat("0.1f"), ... 2: StrConst("@") ... } ... ) >>> d.parse("@") '@'
- __init__(condition: Any, cases: dict, default: ConstructBase | None = None)
- Parameters:
condition – The condition for selecting cases. Can be a value or a callable. If a callable, it should be able to receive an argument and return a value for selecting a case (provided by
cases
). The context will be given to the callable.cases – The cases from which one will be selected based on
condition
. The keys will be compared tocondition
(or its return value when callable). The values should be strconstruct objects. The selected strconstruct object will be used for building.default – The default case for building - used when none of the cases is a match.
- _build(_value_, **kwargs) str
Backend method for building numeric strings
If the provide
condition
is callable, this method will call it to get a value and decide which build path should be take.- Parameters:
_value_ – The value to be built
**kwargs –
Other values that might be provided to the build method as additional context. Can be used for providing value to the condition
>>> d = StrSwitch( ... lambda this: this["n"], ... { ... 1: StrFloat("0.1f"), ... 2: StrInt("02d") ... } ... ) >>> d.build(2, n=1) '2.0' >>> d.build(2, n=2) '02'
- Returns:
The built string
- Raises:
StrConstructBuildError – If
condition
or its return value, when callable, does not have a match in the provided cases and no default case is provided.
- _parse(string, **ctx)
Backend method for parsing numeric strings
- Parameters:
string – The input string
**ctx – Other values that might be provided to the build method as additional context. Can be used for providing value to the condition. See
_build()
for more info.
- Returns:
The parsed content. The type depends on the selected case
StrIf
- class strconstruct.StrIf(condition: Callable | bool, subconstruct: ConstructBase)
Bases:
ConstructBase
StrIf helps with conditional statements in the protocol declaration. If it condition holds, it builds and parses using the sub-StrConstruct object. If the condition does not hold, the
build
method returns an empty string and theparse
method returns None. Note that StrStruct does not include None and empty strings.>>> d = StrIf(True, StrInt("d")) >>> d.build(2) '2' >>> d.parse("3") 3 >>> d = StrIf(False, StrInt("d")) >>> d.build(2) '' >>> d.parse("3") >>>
That’s just a simple example. The condition can of course be callables.
>>> d = StrIf(lambda this: this["n"], StrInt("d")) >>> d.build(3, n=True) '3' >>> d.build(3, n=False) '' >>> d.parse("5", n=True) 5 >>> d.parse("5", n=False) >>>
Even more useful in StrStruct
>>> d = StrStruct( ... "field1" / StrInt("d"), ... StrConst(","), ... "field2" / StrIf(lambda this: this["n"], StrFloat(".2f")), ... ) >>> d.build({"field1": 2, "field2": 2.34}, n=True) '2,2.34' >>> d.build({"field1": 2, "field2": 2.34}, n=False) '2,'
You see the comma at the end of the last build? StrStruct is smart when it comes to separators in StrConstruct objects that build nothing.
>>> d = StrStruct( ... "field1" / StrInt("d"), ... "field2" / StrIf(lambda this: this["n"], StrFloat(".2f")), ... separator="," ... ) >>> d.build({"field1": 2, "field2": 2.34}, n=True) '2,2.34' >>> d.build({"field1": 2, "field2": 2.34}, n=False) '2' >>> d.parse("2,2.34", n=True) {'field1': 2, 'field2': 2.34} >>> d.parse("2", n=False) {'field1': 2}
OK, that’s better.
- __init__(condition: Callable | bool, subconstruct: ConstructBase)
- Parameters:
condition – The condition to determine whether build/parse should be stopped.
subconstruct – The sub-StrConstruct object. If the condition holds, parsing and building will be deferred to this sub-StrConstruct object.
- _build(_value_, **ctx)
Backend method for building
- Parameters:
_value_ – The value to be built
**kwargs – Other values that might be provided to the build method as additional context. This value is passed on to the condition, if callable. It is also sent to the sub-StrConstruct when its
build
method is called.
- Returns:
The built string
StrStopIf
- class strconstruct.StrStopIf(condition: Callable | bool)
Bases:
ConstructBase
StrStopIf is condition str-construct object that signals StrStruct to stop building or parsing. It raises an StrStopFieldError exception for that purpose. Therefore if used by itself, it raises that exception, when the condition is met.
>>> from strconstruct import StrStopIf >>> d = StrStopIf(True) >>> d.build({}) ... strconstruct.str_construct_exceptions.StrStopFieldError: Found a boolean condition for StopIf. Stopping >>> d.parse("") ... strconstruct.str_construct_exceptions.StrStopFieldError: Found a boolean condition for StopIf. Stopping
The most useful application of StrStopIf is with StrStruct
>>> packet = StrStruct( ... "field1" / StrInt("d"), ... StrStopIf(lambda this: this["n"]), ... StrConst(","), ... "field2" / StrFloat(".2f"), ... ) >>> packet.build({"field1": 2}, n=True) '2' >>> packet.build({"field1": 2, "field2": 3.1}, n=True) '2' >>> packet.build({"field1": 2, "field2": 3.1}, n=False) '2,3.10' >>> packet.parse("2", n=True) {'field1': 2} >>> packet.parse("2,3.10", n=True) {'field1': 2} >>> packet.parse("2,3.10", n=False) {'field1': 2, 'field2': 3.1}
- __init__(condition: Callable | bool)
- Parameters:
condition – The condition to determine whether build/parse should be stopped. If it is a callable, it should accept one argument (for the context) and return a boolean value. If it returns True,
StrStopFieldError
will be raised by thebuild
andparse
methods.
- _build(_value_, **kwargs) str
Backend method for building. This class does not build anything. If the condition is not met, it simply returns an empty string.
- Parameters:
_value_ – The value to build. Will be ignored by this class
**kwargs – Other values that might be provided to the build method as additional context.
- Returns:
Always an empty string
- Raises:
StrStopFieldError – If the stopping condition is met.
- _parse(string, **kwargs) None
Backend method for parsing. This method does no parsing. If the stopping condition is met, it simply returns None.
- Parameters:
string – The input string. Will be ignored by this class
**kwargs – Other values that might be provided to the build method as additional context.
- Raises:
StrStopFieldError – If the stopping condition is met.
StrStruct
- class strconstruct.StrStruct(*args: ConstructBase, separator: str = '')
Bases:
ConstructBase
StrStruct is arguably one of the most important modules in this package when it comes to real-life protocols; they are usually a set of fields, rather than individual values.
StrStruct looks like a struct declaration in C. Here is an example
>>> d = StrStruct( ... "field1" / StrInt("d"), ... "field2" / StrConst(","), ... "field3" / StrFloat(".2f"), ... )
Every field can be renamed (using the division operator - see
ConstructBase
for more information). For building, since this is a multi-field StrConstruct, it receives a dictionary. Similarly, theparse
method returns a dictionary.>>> d.build({"field1": 12, "field3": 4.876}) '12,4.88' >>> d.parse("199,8.76") {'field1': 199, 'field2': ',', 'field3': 8.76}
The fields can be nameless as well. If they are, they need to be able to build without a given value (like
StrConst
,StrDefault
) as there will no way provide them with some value in the input dictionary. In the previous example, we can agree thatfield2
can become nameless; we’ll never need to give it a value.>>> d = StrStruct( ... "field1" / StrInt("d"), ... StrConst(","), ... "field3" / StrFloat(".2f"), ... ) >>> d.build({"field1": 12, "field3": 4.876}) '12,4.88' >>> d.parse("199,8.76") {'field1': 199, 'field3': 8.76}
It’s worth noting the difference that the nameless field made in the result of the
parse
method; it’s absent from the result. Importantly, the parser does parse all the fields; named, nameless or hidden (more on hidden later). This ensures that the parser is receiving a correct message. After all, this is designed for dealing with protocols.>>> d.parse("199-8.76") ... strconstruct.str_construct_exceptions.StrConstructParseError: Expected ',' but found '-8.76'
The fields can be hidden as well. In that case, they can receive values during build but they will be absent from the parse result.
>>> d = StrStruct( ... "field1" / StrInt("d"), ... StrConst(","), ... "_field3" / StrDefault(StrFloat(".2f"), 13.23), ... ) >>> d.build({"field1": 12}) '12,13.23' >>> d.build({"field1": 12, "_field3": 87.12}) '12,87.12' >>> d.parse("37,19.45") {'field1': 37}
StrStructs can be nested too. This is an important functionality when it comes to multi-level protocols.
>>> d = StrStruct( ... "field1" / StrInt("d"), ... StrConst(","), ... "field3" / StrSwitch( ... lambda this:this["field1"], ... { ... 1: StrStruct( ... "field4" / StrFloat(".2f"), ... StrConst("\n"), ... ), ... 2: StrStruct( ... "field4" / StrInt("d"), ... StrConst("\r"), ... ) ... } ... ) ... ) >>> d.build({"field1":2, "field3":{"field4":2}}) '2,2\r' >>> d.build({"field1":1, "field3":{"field4":2}}) '1,2.00\n'
As can be seen, each StrStruct needs its own dict when building.
A useful argument that StrStruct accepts is
separator
. When present, thebuild
method puts that separator between all the fields. Similarly, theparse
method expects the separator to be present in the input string>>> d = StrStruct( ... "field1" / StrInt("d"), ... "field2" / StrInt("02X"), ... "field3" / StrFloat(".2f"), ... separator=":" ... ) >>> output = d.build( ... { ... "field1": 2, ... "field2": 15, ... "field3": 3.1, ... } ... ) >>> output '2:0F:3.10'
- __init__(*args: ConstructBase, separator: str = '')
- Parameters:
*args – A set of StrConstructs objects. They can be named, nameless or have hidden names
separator – Sets a separator for all the fields
- _build(values, **ctx)
Backend method for building
- Parameters:
_value_ – The value to be built
**ctx – Other values that might be provided to the build method as additional context. StrStruct passes this to its child sub-StrConstruct objects. It also adds to this context every time an StrConstruct object is build. That’s how the child StrConstruct objects have access to the context, which includes both user-defined and build contexts.
- Returns:
The built string
- _parse(string, **ctx)
The parse backed for different StrConstruct classes. Must be overridden by the child class.
- Parameters:
string – The string to be parsed
**kwargs – The context
- Raises:
NotImplementedError if not overridden by the child class –
StrRebuild
- class strconstruct.StrRebuild(subconstruct: ConstructBase, callback: Callable)
Bases:
ConstructBase
StrRebuild is useful for calculating the input value of the
build
method during the build process. It only affects the build process. Parsing is simply deferred to the child StrConstruct object.>>> d = StrRebuild(StrInt("d"), lambda x: 2 * x["n"]) >>> d.build({}, n=5) '10'
My favorite use case of StrRebuild (and construct’s Rebuild) is calculating checksum. Here is an example.
>>> d = StrStruct( ... "stx" / StrDefault(StrInt("02X"), 12), ... "counter" / StrInt("d"), ... "payload" / StrInt("d"), ... "checksum" / StrRebuild( ... StrInt("d"), ... lambda ctx: sum([ctx["stx"], ctx["counter"], ctx["payload"]]) % 256 ... ), ... "etx" / StrConst("\n"), ... separator="," ... ) >>> >>> d.build({"counter": 3, "payload": 5}) '0C,3,5,20,\n'
As said before, parsing doesn’t recalculate the fields and checks the outcome against the received string.
>>> d.parse("0C,3,5,20,\n") {'stx': 12, 'counter': 3, 'payload': 5, 'checksum': 20, 'etx': '\n'} >>> d.parse("0C,3,5,21,\n") {'stx': 12, 'counter': 3, 'payload': 5, 'checksum': 21, 'etx': '\n'}
- __init__(subconstruct: ConstructBase, callback: Callable)
- Parameters:
subconstruct – The sub-StrConstruct object. Both build and parse will be deferred to this sub-StrConstruct object. But for build the value fed to the
build
method is collected from thecallback
.callback – The callback for rebuilding the build value. It should receive one argument (for the context) and return a value. The type of the return value should be suitable for
subconstruct
.
- _build(_value_, **ctx)
Backend method for building
- Parameters:
_value_ – Not used by this StrConstruct
**kwargs –
The main input for the callback function to extract the “value”. It is also sent to the sub-StrConstruct when its
build
method is called. This behavior is similar to construct’sRebuild
.>>> d = Rebuild(Int8ub, lambda x: 10) >>> d.build(2) b'\n' >>> d.build(20) b'\n'
- Returns:
The built string
- _parse(string, **ctx)
Backend method for parsing
- Parameters:
string – The input string
**ctx – Other values that might be provided to the build method as additional context. It’s also sent to the sub-StrConstruct object
- Returns:
The parsed content. The type depends on the child StrConstruct
StrCheck
- class strconstruct.StrCheck(condition: Callable)
Bases:
ConstructBase
StrCheck builds and parses nothing. It is useful only adding additional verification, for example, to an StrStruct.
>>> d = StrStruct( ... "f1" / StrInt("d"), ... StrCheck(lambda x: x["f1"] == 30) ... ) >>> d.build({"f1":30}) '30' >>> d.build({"f1":31}) ... strconstruct.str_construct_exceptions.StrCheckError: Check failed. Context was {'f1': 31} >>> d.parse("30") {'f1': 30} >>> d.parse("29") ... strconstruct.str_construct_exceptions.StrCheckError: Check failed. Context was {'f1': 29}
As can be seen in the example, the context is passed onto the StrCheck object and function pointer in StrCheck should return a boolean. If True, the check passes. The context is put together during both building and parsing. In both cases, it is a dictionary with “parsed” values (not strings).
It can be combined with other types of StrConstruct objects as well, of course.
>>> d = StrStruct( ... "f1" / StrInt("d"), ... StrConst(","), ... "f2" / StrRebuild(StrInt("d"), lambda x: x["f1"] * 2), ... StrCheck(lambda x: x["f2"] == 30), ... ) >>> d.build({"f1": 15}) '15,30' >>> d.parse("15,30") {'f1': 15, 'f2': 30} >>> >>> d.build({"f1": 14}) ... strconstruct.str_construct_exceptions.StrCheckError: Check failed. Context was {'f1': 14, 'f2': 28} >>> d.parse("14,31") ... strconstruct.str_construct_exceptions.StrCheckError: Check failed. Context was {'f1': 14, 'f2': 31}
It is mostly useful for parsing. An example is verifying checksum of received strings (during parsing).
- __init__(condition: Callable)
- Parameters:
condition – A function pointer that should get the context and return a boolean. The function will be evaluated during both
run
andbuild
. If it returns a False,build
andparse
StrCheckError.
- _build(_value_, **ctx) str
Backend method for building
- Parameters:
_value_ – The value to be built. Not used by this StrConstruct
**ctx – Other values that might be provided to the build method as additional context.
- Returns:
Always an empty string
- Raises:
StrCheckError, if the function pointer returns False –
- _parse(string, **ctx) int
Backend method for parsing
- Parameters:
string – The input string
**ctx – Other values that might be provided to the build method as additional context.
- Raises:
StrCheckError, if the function pointer returns False –
Exceptions
- class strconstruct.StrConstructError
StrConstruct base exception. All other exceptions in StrConstruct inherit from this exceptions.
- class strconstruct.StrConstructFormatError
Raised when building a StrConstruct object if a format is problematic.
- class strconstruct.StrConstructParseError
Raised when parsing fails. All StrConstruct objects can potentially raise this exception.
- class strconstruct.StrConstructBuildError
Raised when building fails. All StrConstruct objects can potentially raise this exception.
- class strconstruct.StrStopFieldError
Raised only by StrStopIf and when its condition is met.