Common Utilities

pcapkit.dumpkit.common is the collection of common utility functions for pcapkit.dumpkit implementation, which is generally the customised hooks for dictdumper.Dumper classes.

pcapkit.dumpkit.common.make_dumper(output)[source]

Create a customised Dumper object.

Parameters:

output (Type[Dumper]) – Output class to customise.

Return type:

Type[Dumper]

Returns:

Customised Dumper object.

class pcapkit.dumpkit.common.Dumper(fname, **kwargs)[source]

Bases: DumperBase

Base Dumper object.

This class is a customised Dumper for the pcapkit.dumpkit implementation, which is generally customised for opt-in registration to the Extractor and TraceFlow output dumper registries.

Example

Registration is opt-in. Pass keyword argument fmt at 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 both output registries, so the equivalent manual call is the module-level one that does the same, not either class’ own method:

from pcapkit.foundation.registry.foundation import register_dumper

register_dumper('my_mixin', MyMixin, '.mine')
classmethod __init_subclass__(fmt=None, ext=None, *args, **kwargs)[source]

Initialise subclass.

This method is used to register the subclass to the Extractor and TraceFlow output 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; None infers it from fmt. Only meaningful alongside fmt.

  • *args (Any) – Arbitrary positional arguments.

  • **kwargs (Any) – Arbitrary keyword arguments.

Raises:

UnsupportedCall – If ext is given without fmt, or if any unrecognised class keyword is given.

Registration is opt-in: the subclass is registered if and only if fmt is given. This is what lets a subclass decline registration rather than having to inherit DumperBase to avoid it, and it matches EnumSchema.__init_subclass__, which has guarded on its own code keyword all along.

Note

The previous behaviour inferred fmt from the subclass’ kind property, which it could only read off an instance – so it constructed one against a tempfile.NamedTemporaryFile() while the class statement was still executing. Guarding on fmt removes that: a class definition no longer touches 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, plist and xml output of both Extractor and TraceFlow, so it lives in one function rather than being spelled out at each of the three places make_dumper()’s hook needs it.

Parameters:

o (Enum | Enum) – Enumeration member to render.

Return type:

str

Returns:

The member’s Type::name [value] rendering.

Note

A Flag value composed entirely of undeclared bits has no name at all – name is None, not a string – so interpolating it unguarded put the literal four characters None into the name half and rendered Flags (0) as 'Flags::None [0]' (GitHub issue #648).

Two things make that 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 – and NONE is a declared name elsewhere in the library. And the defect is not confined to zero: Flags(1), Flags(8) and Flags(65536) are every bit as nameless, so a guard written against value == 0 would 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).name is '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, so Flags(9) becomes 'Flags::9 [9]' and Flags(0) becomes 'Flags::0 [0]'. It also cannot be mistaken for a member name, since a Python identifier may not begin with a digit – none of the 1867 identifiers declared under pcapkit.const is a bare decimal, and none ever can be.

This is not an aenum quirk. A stdlib enum.IntFlag built from the same members answers name is None identically 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: Dumper

Base Dumper object.

Note

This class is for internal use only. For customisation, please use Dumper instead.