Three declarations in pcapkit/foundation/extraction.py on main (dd64913df) describe a type the attribute never holds:
:183 — _exeng: 'Engine[_P]'
:354 — def engine(self) -> 'Engine':
:738 — def record_header(self) -> 'Engine':
Both built-in engines subclass the base directly, so neither is an Engine:
PCAP bases=['EngineBase'] issubclass(PCAP, Engine)=False
PCAPNG bases=['EngineBase'] issubclass(PCAPNG, Engine)=False
Two cast calls at :609 and :612 already launder it:
self._exeng = cast('Engine[_P]', PCAP_Engine(self))
self._exeng = cast('Engine[_P]', PCAPNG_Engine(self))
Nothing is lost by telling the truth, because Engine adds no instance API over EngineBase — measured, the only member it adds is __init_subclass__, the registration hook. So no call site can be reading an Engine-only attribute off _exeng.
The fix is to declare all three as EngineBase and delete both casts. warn_redundant_casts does not catch them today because base-to-public is a genuine narrowing, not a redundant cast.
Worth doing deliberately rather than as drive-by: Extractor.engine is public API, so narrowing its declared return type from Engine to EngineBase is a visible signature change even though it is strictly more accurate. Anyone annotating against it already holds a base-only object at run time.
Surfaced by the cross-review on #1020; out of that PR's scope. Related: #513, #1016.
Three declarations in
pcapkit/foundation/extraction.pyonmain(dd64913df) describe a type the attribute never holds::183—_exeng: 'Engine[_P]':354—def engine(self) -> 'Engine'::738—def record_header(self) -> 'Engine':Both built-in engines subclass the base directly, so neither is an
Engine:Two
castcalls at:609and:612already launder it:Nothing is lost by telling the truth, because
Engineadds no instance API overEngineBase— measured, the only member it adds is__init_subclass__, the registration hook. So no call site can be reading anEngine-only attribute off_exeng.The fix is to declare all three as
EngineBaseand delete both casts.warn_redundant_castsdoes not catch them today because base-to-public is a genuine narrowing, not a redundant cast.Worth doing deliberately rather than as drive-by:
Extractor.engineis public API, so narrowing its declared return type fromEnginetoEngineBaseis a visible signature change even though it is strictly more accurate. Anyone annotating against it already holds a base-only object at run time.Surfaced by the cross-review on #1020; out of that PR's scope. Related: #513, #1016.