examples/generators/options.py's TCP_BASE passes keyword arguments that TCP.make does not declare. They are silently dropped, with no warning, so every option fixture this generator produces is built with different field values than the dictionary states.
Measured
On origin/main (13a75dfcd), CPython 3.14.7:
TCP_BASE keys: ['ack', 'ack_flag', 'checksum', 'cwr', 'dstport', 'ece', 'fin',
'ns', 'payload', 'psh', 'rst', 'seq', 'srcport', 'syn', 'urg',
'urgent_pointer', 'window']
TCP(**TCP_BASE).info.seq = 0 while TCP_BASE says seq = 1
warnings captured: []
Nothing warns. warnings.simplefilter('always') around the construction captures nothing — no UnknownFieldWarning, no DeprecationWarning. The value is simply not applied.
Two distinct problems in one dictionary
seq is not a make parameter and is dropped. TCP_BASE declares seq = 1; the constructed object reports info.seq == 0.
ack and ack_flag are both present, and ack is not the acknowledgement number. ack binds to the ACK flag, so 'ack': 0 sets a flag rather than a sequence value, while ack_flag is not a declared parameter at all and is dropped.
So the dictionary reads as though it sets a sequence number of 1 and an explicit ACK flag, and does neither.
Why it matters beyond this file
options.py:403 and :417 both construct via TCP(options=…, **TCP_BASE), so this is the base for the generated option fixtures. Every fixture built through it carries seq = 0 regardless of what the generator says, and an ack that means something other than it appears to.
That makes the fixtures weaker evidence than they look: a test asserting round-trip fidelity over them is asserting it over a packet whose header fields were not what the generator specified.
Notes
examples/generators/options.py'sTCP_BASEpasses keyword arguments thatTCP.makedoes not declare. They are silently dropped, with no warning, so every option fixture this generator produces is built with different field values than the dictionary states.Measured
On
origin/main(13a75dfcd), CPython 3.14.7:Nothing warns.
warnings.simplefilter('always')around the construction captures nothing — noUnknownFieldWarning, noDeprecationWarning. The value is simply not applied.Two distinct problems in one dictionary
seqis not amakeparameter and is dropped.TCP_BASEdeclaresseq = 1; the constructed object reportsinfo.seq == 0.ackandack_flagare both present, andackis not the acknowledgement number.ackbinds to the ACK flag, so'ack': 0sets a flag rather than a sequence value, whileack_flagis not a declared parameter at all and is dropped.So the dictionary reads as though it sets a sequence number of 1 and an explicit ACK flag, and does neither.
Why it matters beyond this file
options.py:403and:417both construct viaTCP(options=…, **TCP_BASE), so this is the base for the generated option fixtures. Every fixture built through it carriesseq = 0regardless of what the generator says, and anackthat means something other than it appears to.That makes the fixtures weaker evidence than they look: a test asserting round-trip fidelity over them is asserting it over a packet whose header fields were not what the generator specified.
Notes
tcp.pyone.pcapkit/protocols/schema/schema.py:450warns about withUnknownFieldWarningfor schema construction. Whethermakeshould do the same for undeclared parameters is a design question this issue raises but does not answer — it is the reason the defect was invisible, and TCP._make_mptcp_addaddr cannot pack: kind/length rejected as fields, then the port predicate KeyErrors on length #541 and Two dropped-keyword/wrong-cast defects flagged in review and never filed (hip.py:3533, ipv6_route.py:207) #556 were about the same class of silence.