Conditions | 18 |
Total Lines | 88 |
Code Lines | 55 |
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 |
||
109 | @classmethod |
||
110 | def unpack(cls, data, negotiated): |
||
111 | nlris = [] |
||
112 | |||
113 | # -- Reading AFI/SAFI |
||
114 | _afi, _safi = unpack('!HB', data[:3]) |
||
115 | afi, safi = AFI.create(_afi), SAFI.create(_safi) |
||
116 | offset = 3 |
||
117 | nh_afi = afi |
||
118 | |||
119 | # we do not want to accept unknown families |
||
120 | if negotiated and (afi, safi) not in negotiated.families: |
||
121 | raise Notify(3, 0, 'presented a non-negotiated family %s/%s' % (afi, safi)) |
||
122 | |||
123 | # -- Reading length of next-hop |
||
124 | len_nh = data[offset] |
||
125 | offset += 1 |
||
126 | |||
127 | if (afi, safi) not in Family.size: |
||
128 | raise Notify(3, 0, 'unsupported %s %s' % (afi, safi)) |
||
129 | |||
130 | length, rd = Family.size[(afi, safi)] |
||
131 | |||
132 | # Is the peer going to send us some Path Information with the route (AddPath) |
||
133 | # It need to be done before adapting the family for another possible next-hop |
||
134 | addpath = negotiated.addpath.receive(afi, safi) |
||
135 | |||
136 | if negotiated.nexthop: |
||
137 | if len_nh in (16, 32, 24): |
||
138 | nh_afi = AFI.ipv6 |
||
139 | elif len_nh in (4, 12): |
||
140 | nh_afi = AFI.ipv4 |
||
141 | else: |
||
142 | raise Notify(3, 0, 'unsupported family %s %s with extended next-hop capability enabled' % (afi, safi)) |
||
143 | length, _ = Family.size[(nh_afi, safi)] |
||
144 | |||
145 | if len_nh not in length: |
||
146 | raise Notify( |
||
147 | 3, |
||
148 | 0, |
||
149 | 'invalid %s %s next-hop length %d expected %s' |
||
150 | % (afi, safi, len_nh, ' or '.join(str(_) for _ in length)), |
||
151 | ) |
||
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(_) 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 = 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 | # Reading the NLRIs |
||
173 | data = data[offset:] |
||
174 | |||
175 | if not data: |
||
176 | raise Notify(3, 0, 'No data to decode in an MPREACHNLRI but it is not an EOR %d/%d' % (afi, safi)) |
||
177 | |||
178 | while data: |
||
179 | if nexthops: |
||
180 | for nexthop in nexthops: |
||
181 | nlri, left = NLRI.unpack_nlri(afi, safi, data, IN.ANNOUNCED, addpath) |
||
182 | # allow unpack_nlri to return none for "treat as withdraw" controlled by NLRI.unpack_nlri |
||
183 | if nlri: |
||
184 | nlri.nexthop = NextHop.unpack(nexthop) |
||
185 | nlris.append(nlri) |
||
186 | else: |
||
187 | nlri, left = NLRI.unpack_nlri(afi, safi, data, IN.ANNOUNCED, addpath) |
||
188 | # allow unpack_nlri to return none for "treat as withdraw" controlled by NLRI.unpack_nlri |
||
189 | if nlri: |
||
190 | nlris.append(nlri) |
||
191 | |||
192 | if left == data: |
||
|
|||
193 | raise RuntimeError("sub-calls should consume data") |
||
194 | |||
195 | data = left |
||
196 | return cls(afi, safi, nlris) |
||
197 | |||
200 |