Skip to content

Commit 0d7b200

Browse files
committed
refactor: remove two unreachable branches, commented-out raises and unused test helpers (#2318)
Problem: two guards could never run, because something earlier had already raised -- Header.read's FileError on an unknown magic number, which the schema's magic_number_callback beats to it; and _read_opt_calipso's two length guards, which calipso_pad_len beats to it while the option is unpacked. Beside them sat commented-out raise lines next to the warn that replaced them, a repeated pylint: disable=unused-argument, and three names nothing read: dispatch.py's _internet_enum, a FAKE_GH query no caller sends, and GATING. A third candidate, _read_opt_qs's unknown QS function arm, looked unreachable the same way but is not: the unassigned-option dispatch it depends on is by schema class, decided from the func a parse's own registry resolves it against, not from the func held in a directly-constructed schema's flags. A QuickStartRequestOption or QuickStartReportOption built directly with an unassigned func reaches this method's own check regardless, and a parse reaches it too once a caller registers a schema against that func, so it stays, with a Note on each of the three readers explaining why. Fix: the two genuinely unreachable guards are deleted, with the prose that described them corrected -- Header.read documents ProtocolError, and _read_opt_calipso documents what checked the length instead. The three fabricated-schema stanzas that reached the deleted guards by calling a private reader directly are replaced by the real parse paths, which raise as before. Test: tests/protocols/test_dead_branches_2318_unit.py parses what was supposed to reach each deleted branch and pins what happens instead, pins the restored QS guard against both schema kinds across all three protocols through the public construction path and through a parse once a schema is registered against the func, and pins the source as holding no such deleted branch, no commented-out raise beside a warn, and no repeated pragma; tests/project/test_dead_helpers_2318_unit.py pins the rule that made each helper dead. 8 of the 17 test methods across the two files fail on the parent commit; the other 9 pin unchanged behaviour by design.
1 parent 7886d9f commit 0d7b200

17 files changed

Lines changed: 667 additions & 94 deletions

File tree

‎examples/generators/dispatch.py‎

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,16 @@ def _resolve(entry: 'Any') -> 'Any':
135135
def code_name(code: 'Any', enum: 'Optional[Any]' = None) -> 'str':
136136
"""Render a registry key as a name usable in a test id.
137137
138-
Most ``__proto__`` tables are keyed entirely by enumeration members, whose
139-
own ``.name`` is used directly. ``Link.__proto__`` holds an entry keyed by
140-
a bare :class:`int` instead (0x8137 for IPX) -- :func:`_resolve` does not
141-
care, since dict lookup does not distinguish an :class:`~enum.IntEnum`
142-
member from the plain :class:`int` it equals, but a case label needs a
143-
name. ``enum`` is consulted for that one, so the label reads
144-
``Novell_Inc_0x8137`` rather than the opaque ``33079``.
138+
Many ``__proto__`` tables are keyed entirely by enumeration members, whose
139+
own ``.name`` is used directly. ``Link.__proto__`` and the port tables hold
140+
bare :class:`int` keys as well -- :func:`_resolve` does not care, since
141+
dict lookup does not distinguish an :class:`~enum.IntEnum` member from the
142+
plain :class:`int` it equals, but a case label needs a name. ``enum`` is
143+
consulted where an enumeration member equals such a key, which is
144+
``Link.__proto__``'s 0x8137 for IPX, so that label reads
145+
``Novell_Inc_0x8137`` rather than the opaque ``33079``. A port number has
146+
no enumeration to consult, so it keeps its plain string form and its family
147+
is given no ``enum``.
145148
146149
Args:
147150
code: Registry key.
@@ -580,16 +583,11 @@ def _link_enum() -> 'Any':
580583
return EtherType
581584

582585

583-
def _internet_enum() -> 'Any':
584-
from pcapkit.const.reg.transtype import TransType
585-
return TransType
586-
587-
588586
#: Every family this module exercises, one per ``__proto__`` table named in
589587
#: GitHub issue #496, and the loopback table #1574 added.
590588
FAMILIES = (
591589
Family('link', _link_registry, _link_build, _link_enum),
592-
Family('internet', _internet_registry, _internet_build, _internet_enum),
590+
Family('internet', _internet_registry, _internet_build),
593591
Family('tcp', _tcp_registry, _tcp_build),
594592
Family('udp', _udp_registry, _udp_build),
595593
Family('sctp', _sctp_registry, _sctp_build),

‎pcapkit/protocols/application/httpv2.py‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,6 @@ def _read_http_none(self, schema: 'Schema_UnassignedFrame', *,
575575
576576
"""
577577
if any(header.flags.values()):
578-
#raise ProtocolError(f'HTTP/2: [Type {frame}] invalid format')
579578
warn(f'HTTP/2: [Type {header.type}] invalid format', ProtocolWarning)
580579

581580
data = Data_UnassignedFrame(

‎pcapkit/protocols/internet/hip.py‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1508,7 +1508,6 @@ def _read_param_hip_cipher(self, schema: 'Schema_HIPCipherParameter', *, version
15081508
ciphers = schema.ciphers
15091509
if len(ciphers) > 6:
15101510
warn(f'HIPv{version}: [ParamNo {schema.type}] invalid format', ProtocolWarning)
1511-
# raise ProtocolError(f'HIPv{version}: [ParamNo {schema.type}] invalid format')
15121511
ciphers = ciphers[:6]
15131512

15141513
hip_cipher = Data_HIPCipherParameter(

‎pcapkit/protocols/internet/hopopt.py‎

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -769,17 +769,14 @@ def _read_opt_calipso(self, schema: 'Schema_CALIPSOOption', *, options: 'Option'
769769
Returns:
770770
Parsed option data.
771771
772-
Raises:
773-
ProtocolError: If the option is malformed.
772+
Note:
773+
``Cmpt Length`` counts 32-bit words and may be odd
774+
[:rfc:`5570#section-5.2`]; it only has to fit inside ``Opt Data
775+
Len``, which
776+
:func:`~pcapkit.protocols.schema.internet.ipv6_option.calipso_pad_len`
777+
has already checked while the option was unpacked.
774778
775779
"""
776-
if schema.len < 8 and schema.len % 8 != 0:
777-
raise ProtocolError(f'{self.alias}: [OptNo {schema.type}] invalid format')
778-
# ``Cmpt Length`` counts 32-bit words and may be odd [:rfc:`5570#section-5.2`];
779-
# it only has to fit inside ``Opt Data Len``
780-
if schema.len < 8 + schema.cmpt_len * 4:
781-
raise ProtocolError(f'{self.alias}: [OptNo {schema.type}] invalid format')
782-
783780
opt = Data_CALIPSOOption(
784781
type=schema.type,
785782
action=Enum_OptionAction.get(schema.type >> 6),
@@ -930,7 +927,7 @@ def _read_opt_pdm(self, schema: 'Schema_PDMOption', *, options: 'Option') -> 'Da
930927
)
931928
return opt
932929

933-
def _read_opt_qs(self, schema: 'Schema_QuickStartOption', *, options: 'Option') -> 'Data_QuickStartOption': # pylint: disable=unused-argument # pylint: disable=unused-argument
930+
def _read_opt_qs(self, schema: 'Schema_QuickStartOption', *, options: 'Option') -> 'Data_QuickStartOption': # pylint: disable=unused-argument
934931
"""Read HOPOPT Quick Start option.
935932
936933
Structure of HOPOPT Quick-Start option [:rfc:`4782`]:
@@ -974,7 +971,13 @@ def _read_opt_qs(self, schema: 'Schema_QuickStartOption', *, options: 'Option')
974971
Note:
975972
An option whose QS function is neither of the two above has no
976973
defined layout, so the schema keeps it as an unassigned option and
977-
it is parsed as one, see :meth:`_read_opt_none`.
974+
it is parsed as one, see :meth:`_read_opt_none`. That dispatch is
975+
by the schema's own class, decided from the octets a file read
976+
hands it; a :class:`~pcapkit.protocols.schema.internet.hopopt.QuickStartRequestOption`
977+
or :class:`~pcapkit.protocols.schema.internet.hopopt.QuickStartReportOption`
978+
built directly with an unassigned ``func`` reaches this method
979+
regardless, which is why it still raises below rather than
980+
returning early.
978981
979982
"""
980983
if isinstance(schema, Schema_UnassignedOption):
@@ -1533,7 +1536,6 @@ def _make_opt_pad(self, code: 'Enum_Option', opt: 'Optional[Data_PadOption]' = N
15331536
pad = getattr(opt, 'pad', b'')
15341537

15351538
if code == Enum_Option.Pad1 and length != 0:
1536-
#raise ProtocolError(f'{self.alias}: [OptNo {code}] invalid format')
15371539
warn(f'{self.alias}: [OptNo {code}] invalid format', ProtocolWarning)
15381540
code = Enum_Option.PadN # type: ignore[assignment]
15391541

‎pcapkit/protocols/internet/ipv4.py‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,6 @@ def _read_opt_sec(self, schema: 'Schema_SECOption', *, options: 'Option') -> 'Da
883883
flags.append(authority)
884884

885885
if byte & 0x01 == 0 and base < schema.length - 4:
886-
#raise ProtocolError(f'{self.alias}: [OptNo {kind}] invalid format: remaining data')
887886
warn(f'{self.alias}: [OptNo {schema.type}] invalid format: remaining data', ProtocolWarning)
888887

889888
if schema.data[-1] & 0x01 == 1:
@@ -1319,7 +1318,14 @@ def _read_opt_qs(self, schema: 'Schema_QSOption', *, options: 'Option') -> 'Data
13191318
Note:
13201319
An option whose QS function is neither of the two above has no
13211320
defined layout, so the schema keeps it as an unassigned option and
1322-
it is parsed as one, see :meth:`_read_opt_unassigned`.
1321+
it is parsed as one, see :meth:`_read_opt_unassigned`. That
1322+
dispatch is by the schema's own class, decided from the octets a
1323+
file read hands it; a
1324+
:class:`~pcapkit.protocols.schema.internet.ipv4.QuickStartRequestOption`
1325+
or :class:`~pcapkit.protocols.schema.internet.ipv4.QuickStartReportOption`
1326+
built directly with an unassigned ``func`` reaches this method
1327+
regardless, which is why it still raises below rather than
1328+
returning early.
13231329
13241330
"""
13251331
if isinstance(schema, Schema_UnassignedOption):

‎pcapkit/protocols/internet/ipv6_opts.py‎

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -757,17 +757,14 @@ def _read_opt_calipso(self, schema: 'Schema_CALIPSOOption', *, options: 'Option'
757757
Returns:
758758
Parsed option data.
759759
760-
Raises:
761-
ProtocolError: If the option is malformed.
760+
Note:
761+
``Cmpt Length`` counts 32-bit words and may be odd
762+
[:rfc:`5570#section-5.2`]; it only has to fit inside ``Opt Data
763+
Len``, which
764+
:func:`~pcapkit.protocols.schema.internet.ipv6_option.calipso_pad_len`
765+
has already checked while the option was unpacked.
762766
763767
"""
764-
if schema.len < 8 and schema.len % 8 != 0:
765-
raise ProtocolError(f'{self.alias}: [OptNo {schema.type}] invalid format')
766-
# ``Cmpt Length`` counts 32-bit words and may be odd [:rfc:`5570#section-5.2`];
767-
# it only has to fit inside ``Opt Data Len``
768-
if schema.len < 8 + schema.cmpt_len * 4:
769-
raise ProtocolError(f'{self.alias}: [OptNo {schema.type}] invalid format')
770-
771768
opt = Data_CALIPSOOption(
772769
type=schema.type,
773770
action=Enum_OptionAction.get(schema.type >> 6),
@@ -918,7 +915,7 @@ def _read_opt_pdm(self, schema: 'Schema_PDMOption', *, options: 'Option') -> 'Da
918915
)
919916
return opt
920917

921-
def _read_opt_qs(self, schema: 'Schema_QuickStartOption', *, options: 'Option') -> 'Data_QuickStartOption': # pylint: disable=unused-argument # pylint: disable=unused-argument
918+
def _read_opt_qs(self, schema: 'Schema_QuickStartOption', *, options: 'Option') -> 'Data_QuickStartOption': # pylint: disable=unused-argument
922919
"""Read IPv6-Opts Quick Start option.
923920
924921
Structure of IPv6-Opts Quick-Start option [:rfc:`4782`]:
@@ -962,7 +959,13 @@ def _read_opt_qs(self, schema: 'Schema_QuickStartOption', *, options: 'Option')
962959
Note:
963960
An option whose QS function is neither of the two above has no
964961
defined layout, so the schema keeps it as an unassigned option and
965-
it is parsed as one, see :meth:`_read_opt_none`.
962+
it is parsed as one, see :meth:`_read_opt_none`. That dispatch is
963+
by the schema's own class, decided from the octets a file read
964+
hands it; a :class:`~pcapkit.protocols.schema.internet.ipv6_opts.QuickStartRequestOption`
965+
or :class:`~pcapkit.protocols.schema.internet.ipv6_opts.QuickStartReportOption`
966+
built directly with an unassigned ``func`` reaches this method
967+
regardless, which is why it still raises below rather than
968+
returning early.
966969
967970
"""
968971
if isinstance(schema, Schema_UnassignedOption):
@@ -1521,7 +1524,6 @@ def _make_opt_pad(self, code: 'Enum_Option', opt: 'Optional[Data_PadOption]' = N
15211524
pad = getattr(opt, 'pad', b'')
15221525

15231526
if code == Enum_Option.Pad1 and length != 0:
1524-
#raise ProtocolError(f'{self.alias}: [OptNo {code}] invalid format')
15251527
warn(f'{self.alias}: [OptNo {code}] invalid format', ProtocolWarning)
15261528
code = Enum_Option.PadN # type: ignore[assignment]
15271529

‎pcapkit/protocols/internet/mh.py‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7921,7 +7921,6 @@ def _make_opt_pad(self, type: 'Enum_Option', option: 'Optional[Data_PadOption]'
79217921
data = getattr(option, 'data', b'')
79227922

79237923
if type == Enum_Option.Pad1 and length != 0:
7924-
# raise ProtocolError(f'{self.alias}: [OptNo {type}] invalid format')
79257924
warn(f'{self.alias}: [OptNo {type}] invalid format', ProtocolWarning)
79267925
type = Enum_Option.PadN # type: ignore[assignment]
79277926

‎pcapkit/protocols/misc/pcap/header.py‎

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
from pcapkit.protocols.schema.misc.pcap.header import GLOBAL_HEADER_LEN, MAGIC_NUMBER
4343
from pcapkit.protocols.schema.misc.pcap.header import Header as Schema_Header
4444
from pcapkit.protocols.schema.schema import keep_short_read, replay_short_read
45-
from pcapkit.utilities.exceptions import EndianError, FileError, UnsupportedCall
45+
from pcapkit.utilities.exceptions import EndianError, UnsupportedCall
4646

4747
if TYPE_CHECKING:
4848
from enum import IntEnum as StdlibEnum
@@ -141,11 +141,10 @@ def read(self, length: 'Optional[int]' = None, **kwargs: 'Any') -> 'Data_Header'
141141
Parsed packet data.
142142
143143
Raises:
144-
FileError: If the magic number is invalid. Parsing does not get
144+
ProtocolError: If the magic number is invalid. Parsing does not get
145145
this far with one: the schema's
146146
:func:`~pcapkit.protocols.schema.misc.pcap.header.magic_number_callback`
147-
raises :exc:`~pcapkit.utilities.exceptions.ProtocolError` for it
148-
while the header is unpacked.
147+
raises it while the header is unpacked.
149148
150149
"""
151150
if TYPE_CHECKING:
@@ -154,12 +153,10 @@ def read(self, length: 'Optional[int]' = None, **kwargs: 'Any') -> 'Data_Header'
154153

155154
_magn = schema.magic_number
156155
# NOTE: looked up as :obj:`bytes`, so that a :obj:`bytearray` magic
157-
# number is matched rather than rejected as unhashable.
158-
_decl = (MAGIC_NUMBER.get(bytes(_magn))
159-
if isinstance(_magn, (bytes, bytearray, memoryview)) else None)
160-
if _decl is None:
161-
raise FileError(5, 'Unknown file format', self._file.name) # pylint: disable=no-member
162-
self._byte, self._nsec = _decl
156+
# number is matched rather than rejected as unhashable. The lookup
157+
# cannot miss: ``magic_number_callback`` has already raised for a magic
158+
# number this mapping does not hold.
159+
self._byte, self._nsec = MAGIC_NUMBER[bytes(_magn)]
163160

164161
header = Data_Header(
165162
magic_number=Data_MagicNumber(

‎pcapkit/protocols/misc/pcapng.py‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,6 @@ def nanosecond(self) -> 'bool':
989989
def ts_resolution(self) -> 'int':
990990
"""Timestamp resolution of the current block, in units per second."""
991991
if self._ctx is None:
992-
#raise UnsupportedCall(f"'{self.__class__.__name__}' object has no attribute 'ts_resolution'")
993992
warn(f"'{self.__class__.__name__}' object has no attribute 'ts_resolution'",
994993
AttributeWarning, stacklevel=stacklevel())
995994
return DEFAULT_RESOLUTION
@@ -1001,7 +1000,6 @@ def ts_resolution(self) -> 'int':
10011000
def ts_offset(self) -> 'int':
10021001
"""Timestamp offset of the current block, in seconds."""
10031002
if self._ctx is None:
1004-
#raise UnsupportedCall(f"'{self.__class__.__name__}' object has no attribute 'ts_offset'")
10051003
warn(f"'{self.__class__.__name__}' object has no attribute 'ts_offset'",
10061004
AttributeWarning, stacklevel=stacklevel())
10071005
return 0
@@ -1018,7 +1016,6 @@ def ts_timezone(self) -> 'timezone':
10181016
10191017
"""
10201018
if self._ctx is None:
1021-
#raise UnsupportedCall(f"'{self.__class__.__name__}' object has no attribute 'ts_timezone'")
10221019
warn(f"'{self.__class__.__name__}' object has no attribute 'ts_timezone'",
10231020
AttributeWarning, stacklevel=stacklevel())
10241021
return datetime.timezone.utc
@@ -1786,7 +1783,6 @@ def _get_resolution(self, interface_id: 'int' = 0) -> 'int':
17861783
17871784
"""
17881785
if self._ctx is None:
1789-
# raise UnsupportedCall(f"'{self.__class__.__name__}' object has no attribute '_get_resolution'")
17901786
warn(f"'{self.__class__.__name__}' object has no attribute '_get_resolution'",
17911787
AttributeWarning, stacklevel=stacklevel())
17921788
return DEFAULT_RESOLUTION
@@ -1809,7 +1805,6 @@ def _get_offset(self, interface_id: 'int' = 0) -> 'int':
18091805
18101806
"""
18111807
if self._ctx is None:
1812-
# raise UnsupportedCall(f"'{self.__class__.__name__}' object has no attribute '_get_offset'")
18131808
warn(f"'{self.__class__.__name__}' object has no attribute '_get_offset'",
18141809
AttributeWarning, stacklevel=stacklevel())
18151810
return 0
@@ -1841,7 +1836,6 @@ def _get_timezone(self, interface_id: 'int' = 0) -> 'timezone':
18411836
# and ``_get_offset`` fall back to the format's own defaults in this
18421837
# situation; this is the matching one.
18431838
if self._ctx is None:
1844-
# raise UnsupportedCall(f"'{self.__class__.__name__}' object has no attribute '_get_timezone'")
18451839
warn(f"'{self.__class__.__name__}' object has no attribute '_get_timezone'",
18461840
AttributeWarning, stacklevel=stacklevel())
18471841
return datetime.timezone.utc

‎pcapkit/protocols/schema/internet/hip.py‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -918,8 +918,6 @@ def pre_unpack(cls, packet: 'dict[str, Any]') -> 'None':
918918
if not cipher_list:
919919
warn(f'HIP: [ParamNo {Enum_Parameter.ENCRYPTED}] '
920920
'missing HIP_CIPHER parameter', ProtocolWarning)
921-
# raise ProtocolError(f'HIPv{version}: [ParamNo {schema.type}] invalid format')
922-
923921
cipher_id = Enum_Cipher(0xffff)
924922
else:
925923
cipher_ids = [] # type: list[Enum_Cipher]
@@ -933,8 +931,6 @@ def pre_unpack(cls, packet: 'dict[str, Any]') -> 'None':
933931
if encrypted_index >= len(cipher_ids):
934932
warn(f'HIP: [ParamNo {Enum_Parameter.ENCRYPTED}] '
935933
'too many ENCRYPTED parameters', ProtocolWarning)
936-
# raise ProtocolError(f'HIPv{version}: [ParamNo {schema.type}] invalid format')
937-
938934
cipher_id = Enum_Cipher(0xfffe)
939935
else:
940936
cipher_id = cipher_ids[encrypted_index]

0 commit comments

Comments
 (0)