Deferred Packet¶
pcapkit.corekit.packet contains
DeferredPacket, the mixin that lets an
Info subclass hold its packet field as
a placeholder and resolve it on first read. It is shared by the reassembled
datagrams of pcapkit.foundation.reassembly and the traced flows of
pcapkit.foundation.traceflow, whose packet is a second parse of the
payload and a reassembly of the stream respectively.
A subclass is declared class X(DeferredPacket, Info), lists packet in
its __additional__, and names its placeholder class in
__deferred__;
__init_subclass__() refuses one
that does not. Listing packet in __additional__ is what makes the field
lazy: Info then stores it under a mangled
key, so reading it reaches __getattr__, while dict(x),
to_dict() and iteration still
report it as packet.
Resolution happens at most once: the placeholder is called with no arguments, and its result replaces it, so every later read returns that same object.
- class pcapkit.corekit.packet.DeferredPacket[source]¶
Bases:
objectResolves a deferred
packetfield on first read.A mixin for
Infosubclasses; seepcapkit.corekit.packetfor the contract a subclass keeps. Readingpacket– as an attribute, asx['packet'], or throughto_dict(),str()orrepr()– resolves a placeholder once and keeps the result.'packet' in x,len()and iteration report the field by name without resolving it.It is shared by
pcapkit.foundation.reassembly.data.ip.Datagram,pcapkit.foundation.reassembly.data.tcp.Datagramandpcapkit.foundation.traceflow.data.tcp.Index, which differ only in the placeholder class each names in__deferred__(#1516).- __deferred__¶
Placeholder class the
packetfield may hold, set by each subclass. A value of this class is resolved by calling it with no arguments; an instance of any other class,Noneincluded, is not.
- classmethod __init_subclass__(*args, **kwargs)[source]¶
Refuse a subclass that does not keep the contract.
Either omission would otherwise fail silently, and only on a read. Without
packetin__additional__the field lands in__dict__under its own name,__getattr__()is never reached, and the placeholder itself comes back. Without__deferred__,__analyse__()raisesAttributeErrorfrom inside__getattr__(), whichgetattr(x, 'packet', None)takes for a missing attribute and answers withNone.- Parameters:
- Raises:
InfoError – If
clsdoes not listpacketin its__additional__, or does not name a class in its__deferred__.
- __analyse__()[source]¶
Resolve the
packetfield, at most once.A placeholder, i.e. an instance of
__deferred__, is called with no arguments and its result replaces it in__dict__. Any other value is returned as it is.