SettingsFrame.settings passes a Schema class where ListField expects a field instance, with the resulting type error silenced by a # type: ignore[arg-type].
The site
pcapkit/protocols/schema/application/httpv2.py:283-285:
#: Settings.
settings: 'list[SettingPair]' = ListField(
length=lambda pkt: pkt['__length__'],
item_type=SettingPair, # type: ignore[arg-type]
)
Every other ListField in the tree wraps its schema item in a SchemaField — for example pcapkit/protocols/schema/transport/tcp.py:393 is item_type=SchemaField(length=8, schema=SACKBlock), and internet/hip.py:260, internet/mh.py:535 and transport/sctp.py:702 follow the same shape.
Confirmed on e2d8ed6d1
SettingPair is a SchemaMeta -> Schema subclass: True
ListField._item_type is: SchemaMeta
So _item_type holds the metaclass-produced class object rather than a field, and the type: ignore is what let it through review — mypy had it right.
Consequence
ListField.unpack's schema branch calls self._item_type(packet) to build a configured per-item field (see #433, which corrected a related bug on that line). Calling a Schema class with a packet dict does not produce a field; it attempts to construct a schema instance from a dict positionally. Depending on the branch taken, this either raises or silently mis-parses.
Why this was unreachable until now
It sits behind the nested-packet fault in #445: the SETTINGS frame's pack path died earlier with KeyError: 'length'. PR #457 fixes #445, and this becomes reachable — the agent implementing it reported SETTINGS as one of five HTTP/2 frames that then fail on distinct, previously-unreachable defects.
Fix
Wrap it as the siblings do:
item_type=SchemaField(schema=SettingPair),
and remove the # type: ignore[arg-type], confirming with mypy rather than assuming — the baseline is 128 errors in 41 files. A regression test should exercise a real SETTINGS frame round trip rather than a fake, since a fake with a compatible __call__ would hide the distinction.
Provenance
Surfaced by the agent implementing #445 (PR #457) and verified independently before filing. Related: #433 (the same ListField schema branch), and #445 which currently masks this.
SettingsFrame.settingspasses aSchemaclass whereListFieldexpects a field instance, with the resulting type error silenced by a# type: ignore[arg-type].The site
pcapkit/protocols/schema/application/httpv2.py:283-285:Every other
ListFieldin the tree wraps its schema item in aSchemaField— for examplepcapkit/protocols/schema/transport/tcp.py:393isitem_type=SchemaField(length=8, schema=SACKBlock), andinternet/hip.py:260,internet/mh.py:535andtransport/sctp.py:702follow the same shape.Confirmed on
e2d8ed6d1So
_item_typeholds the metaclass-produced class object rather than a field, and thetype: ignoreis what let it through review — mypy had it right.Consequence
ListField.unpack's schema branch callsself._item_type(packet)to build a configured per-item field (see #433, which corrected a related bug on that line). Calling aSchemaclass with a packet dict does not produce a field; it attempts to construct a schema instance from a dict positionally. Depending on the branch taken, this either raises or silently mis-parses.Why this was unreachable until now
It sits behind the nested-packet fault in #445: the SETTINGS frame's pack path died earlier with
KeyError: 'length'. PR #457 fixes #445, and this becomes reachable — the agent implementing it reportedSETTINGSas one of five HTTP/2 frames that then fail on distinct, previously-unreachable defects.Fix
Wrap it as the siblings do:
and remove the
# type: ignore[arg-type], confirming with mypy rather than assuming — the baseline is 128 errors in 41 files. A regression test should exercise a real SETTINGS frame round trip rather than a fake, since a fake with a compatible__call__would hide the distinction.Provenance
Surfaced by the agent implementing #445 (PR #457) and verified independently before filing. Related: #433 (the same
ListFieldschema branch), and #445 which currently masks this.