Common Utilities¶
pcapkit.dumpkit.common holds the utilities shared by
pcapkit.dumpkit, chiefly customised hooks for dictdumper.dumper.Dumper
classes.
- pcapkit.dumpkit.common.make_dumper(output)[source]¶
Create a customised
Dumperclass.- Parameters:
output (
Type[dictdumper.dumper.Dumper]) – Output class to customise.- Return type:
- Returns:
Customised
Dumpersubclass ofoutput.
Changed in version 1.5.0: Several dumped shapes change. A nameless flag value renders its value as the name,
Flags::0 [0]rather thanFlags::None [0](#648). AnOrderedMultiDictdumps as a list of one-key mappings in wire order, not grouped by key (#1263). AnIPv4NetworkorIPv6Networkdumps as its string, a timezone as its offset in seconds, andNULLandNO_VALUEas'<NULL>'and'<NO_VALUE>'(#1258). Inplistoutput,Noneis kept (#1257), and a string carrying a character XML forbids is written as<data>(#1262).
- class pcapkit.dumpkit.common.Dumper(fname, **kwargs)[source]¶
Bases:
DumperBaseBase
Dumperobject.This class is a customised
Dumperfor thepcapkit.dumpkitimplementation, which is generally customised for opt-in registration to theExtractorandTraceFlowoutput dumper registries.Example
Registration is opt-in. Pass keyword argument
fmtat class definition to register the dumper under that output format:class MyDumper(Dumper, fmt='my_format', ext='.mine'): ...
Omit it and the subclass is not registered:
class MyMixin(Dumper): # not registered ...
Such a class can still be registered later, on demand. Note this hook writes every output registry, so the equivalent manual call is the module-level one that does the same, not any one class’ own method:
from pcapkit.foundation.registry.foundation import register_dumper register_dumper('my_mixin', MyMixin, ext='.mine')
Changed in version 1.5.0: Registration is opt-in, under the
fmtclass keyword; 1.4.x registered every subclass, under itskindwhen the keyword was omitted (#514).- classmethod __init_subclass__(fmt=None, ext=None, *args, **kwargs)[source]¶
Initialise subclass.
This method is used to register the subclass to the
ExtractorandTraceFlowoutput dumper registries.- Parameters:
fmt (
str|None) – Output format to register the subclass under, lowercased.None(the default) skips registration entirely.ext (
str|None) – Output file extension;Noneinfers it fromfmt. Only meaningful alongsidefmt.*args (
Any) – Arbitrary positional arguments.**kwargs (
Any) – Arbitrary keyword arguments.
- Raises:
UnsupportedCall – If
extis given withoutfmt, or if any unrecognised class keyword is given.- Return type:
Registration is opt-in: the subclass is registered if and only if
fmtis given. This is what lets a subclass decline registration rather than having to inheritDumperBaseto avoid it, and it matchesEnumSchema.__init_subclass__, which guards on its owncodekeyword the same way.Note
Inferring
fmtfrom the subclass’kindproperty would need an instance, hence atempfile.NamedTemporaryFile()created while theclassstatement is still executing. Guarding onfmtavoids that: a class definition does not touch the filesystem.
Internal Definitions¶
- pcapkit.dumpkit.common.render_enum(o)[source]¶
Render an enumeration member as
Type::name [value].This is the spelling every dumped enumeration carries in the
json,tree,text,txt,plistandxmloutput of bothExtractorandTraceFlow, so it lives in one function rather than being spelled out at each placemake_dumper()’s hook needs it.- Parameters:
o (
Enum|aenum.Enum) – Enumeration member to render.- Return type:
- Returns:
The member’s
Type::name [value]rendering.
Note
A
Flagvalue composed entirely of undeclared bits has no name at all –nameisNone, not a string – so interpolating it unguarded would put the literal four charactersNoneinto the name half and renderFlags(0)as'Flags::None [0]'(GitHub issue #648).That is worth a guard rather than a shrug.
'None'is a plausible member name, so a consumer splitting the rendering on::cannot tell it from a member genuinely so named – andNONEis a declared name elsewhere in the library. And the defect is not confined to zero:Flags(1),Flags(8)andFlags(65536)are every bit as nameless, so a guard written againstvalue == 0would fix one case and leave the rest.The fallback is the value’s own decimal spelling, which is what the enumeration libraries themselves already use for an undeclared residue:
Flags(2057).nameis'ACK|9', naming the declared bit and giving the leftovers as one number. A wholly-undeclared value is that same rendering with no declared bit to precede it, soFlags(9)becomes'Flags::9 [9]'andFlags(0)becomes'Flags::0 [0]'. It also cannot be mistaken for a member name, since a Python identifier may not begin with a digit.This is not an
aenumquirk. A stdlibenum.IntFlagbuilt from the same members answersname is Noneidentically on CPython 3.14.7, so the guard belongs here rather than in a choice of enumeration library.
- class pcapkit.dumpkit.common.DumperBase(fname, **kwargs)[source]¶
Bases:
dictdumper.dumper.DumperBase
Dumperobject.Note
This class is for internal use only. For customisation, please use
Dumperinstead.