| Conditions | 18 |
| Total Lines | 82 |
| Code Lines | 51 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like exabgp.bgp.message.update.attribute.mprnlri.MPRNLRI.unpack() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | # encoding: utf-8 |
||
| 118 | @classmethod |
||
| 119 | def unpack (cls, data, negotiated): |
||
| 120 | nlris = [] |
||
| 121 | |||
| 122 | # -- Reading AFI/SAFI |
||
| 123 | _afi,_safi = unpack('!HB',data[:3]) |
||
| 124 | afi,safi = AFI.create(_afi),SAFI.create(_safi) |
||
| 125 | offset = 3 |
||
| 126 | nh_afi = afi |
||
| 127 | |||
| 128 | # we do not want to accept unknown families |
||
| 129 | if negotiated and (afi,safi) not in negotiated.families: |
||
| 130 | raise Notify(3,0,'presented a non-negotiated family %s/%s' % (afi,safi)) |
||
| 131 | |||
| 132 | # -- Reading length of next-hop |
||
| 133 | len_nh = ordinal(data[offset]) |
||
| 134 | offset += 1 |
||
| 135 | |||
| 136 | if (afi,safi) not in Family.size: |
||
| 137 | raise Notify(3,0,'unsupported %s %s' % (afi,safi)) |
||
| 138 | |||
| 139 | length, rd = Family.size[(afi, safi)] |
||
| 140 | |||
| 141 | if negotiated.nexthop: |
||
| 142 | if len_nh in (16, 32): |
||
| 143 | nh_afi = AFI.ipv6 |
||
| 144 | elif len_nh in (4,): |
||
| 145 | nh_afi = AFI.ipv4 |
||
| 146 | else: |
||
| 147 | raise Notify(3,0,'unsupported family %s %s with extended next-hop capability enabled' % (afi, safi)) |
||
| 148 | length, _ = Family.size[(nh_afi, safi)] |
||
| 149 | |||
| 150 | if len_nh not in length: |
||
| 151 | raise Notify(3,0,'invalid %s %s next-hop length %d expected %s' % (afi,safi,len_nh,' or '.join(str(_) for _ in length))) |
||
| 152 | |||
| 153 | size = len_nh - rd |
||
| 154 | |||
| 155 | # XXX: FIXME: GET IT FROM CACHE HERE ? |
||
| 156 | nhs = data[offset+rd:offset+rd+size] |
||
| 157 | nexthops = [nhs[pos:pos+16] for pos in range(0,len(nhs),16)] |
||
| 158 | |||
| 159 | # chech the RD is well zero |
||
| 160 | if rd and sum([int(ordinal(_)) for _ in data[offset:8]]) != 0: |
||
| 161 | raise Notify(3,0,"MP_REACH_NLRI next-hop's route-distinguisher must be zero") |
||
| 162 | |||
| 163 | offset += len_nh |
||
| 164 | |||
| 165 | # Skip a reserved bit as somone had to bug us ! |
||
| 166 | reserved = ordinal(data[offset]) |
||
| 167 | offset += 1 |
||
| 168 | |||
| 169 | if reserved != 0: |
||
| 170 | raise Notify(3,0,'the reserved bit of MP_REACH_NLRI is not zero') |
||
| 171 | |||
| 172 | # Is the peer going to send us some Path Information with the route (AddPath) |
||
| 173 | addpath = negotiated.addpath.receive(afi,safi) |
||
| 174 | |||
| 175 | # Reading the NLRIs |
||
| 176 | data = data[offset:] |
||
| 177 | |||
| 178 | if not data: |
||
| 179 | raise Notify(3,0,'No data to decode in an MPREACHNLRI but it is not an EOR %d/%d' % (afi,safi)) |
||
| 180 | |||
| 181 | while data: |
||
| 182 | if nexthops: |
||
| 183 | for nexthop in nexthops: |
||
| 184 | nlri,left = NLRI.unpack_nlri(afi,safi,data,IN.ANNOUNCED,addpath) |
||
| 185 | # allow unpack_nlri to return none for "treat as withdraw" controlled by NLRI.unpack_nlri |
||
| 186 | if nlri: |
||
| 187 | nlri.nexthop = NextHop.unpack(nexthop) |
||
| 188 | nlris.append(nlri) |
||
| 189 | else: |
||
| 190 | nlri,left = NLRI.unpack_nlri(afi,safi,data,IN.ANNOUNCED,addpath) |
||
| 191 | # allow unpack_nlri to return none for "treat as withdraw" controlled by NLRI.unpack_nlri |
||
| 192 | if nlri: |
||
| 193 | nlris.append(nlri) |
||
| 194 | |||
| 195 | if left == data: |
||
|
|
|||
| 196 | raise RuntimeError("sub-calls should consume data") |
||
| 197 | |||
| 198 | data = left |
||
| 199 | return cls(afi,safi,nlris) |
||
| 200 | |||
| 203 |