Conditions | 17 |
Total Lines | 115 |
Code Lines | 83 |
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.configuration.check.check_generation() 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 |
||
51 | def check_generation(neighbors): |
||
52 | option.enabled['parser'] = True |
||
53 | |||
54 | for name in neighbors.keys(): |
||
55 | neighbor = copy.deepcopy(neighbors[name]) |
||
56 | neighbor.local_as = neighbor.peer_as |
||
57 | |||
58 | path = {} |
||
59 | for f in NLRI.known_families(): |
||
60 | if neighbor.add_path: |
||
61 | path[f] = neighbor.add_path |
||
62 | |||
63 | capa = Capabilities().new(neighbor, False) |
||
64 | if path: |
||
65 | capa[Capability.CODE.ADD_PATH] = path |
||
66 | capa[Capability.CODE.MULTIPROTOCOL] = neighbor.families() |
||
67 | |||
68 | routerid_1 = str(neighbor.router_id) |
||
69 | routerid_2 = '.'.join(str((int(_) + 1) % 250) for _ in str(neighbor.router_id).split('.', -1)) |
||
70 | |||
71 | o1 = Open(Version(4), ASN(neighbor.local_as), HoldTime(180), RouterID(routerid_1), capa) |
||
72 | o2 = Open(Version(4), ASN(neighbor.peer_as), HoldTime(180), RouterID(routerid_2), capa) |
||
73 | negotiated = Negotiated(neighbor) |
||
74 | negotiated.sent(o1) |
||
75 | negotiated.received(o2) |
||
76 | # grouped = False |
||
77 | |||
78 | for _ in neighbor.rib.outgoing.updates(False): |
||
79 | pass |
||
80 | |||
81 | for change1 in neighbor.rib.outgoing.cached_changes(): |
||
82 | str1 = change1.extensive() |
||
83 | packed = list(Update([change1.nlri], change1.attributes).messages(negotiated)) |
||
84 | pack1 = packed[0] |
||
85 | |||
86 | log.debug('parsed route requires %d updates' % len(packed), 'parser') |
||
87 | log.debug('update size is %d' % len(pack1), 'parser') |
||
88 | |||
89 | log.debug('parsed route %s' % str1, 'parser') |
||
90 | log.debug('parsed hex %s' % od(pack1), 'parser') |
||
91 | |||
92 | # This does not take the BGP header - let's assume we will not break that :) |
||
93 | try: |
||
94 | log.debug('') # new line |
||
95 | |||
96 | pack1s = pack1[19:] if pack1.startswith(b'\xFF' * 16) else pack1 |
||
97 | update = Update.unpack_message(pack1s, negotiated) |
||
98 | |||
99 | change2 = Change(update.nlris[0], update.attributes) |
||
100 | str2 = change2.extensive() |
||
101 | pack2 = list(Update([update.nlris[0]], update.attributes).messages(negotiated))[0] |
||
102 | |||
103 | log.debug('recoded route %s' % str2, 'parser') |
||
104 | log.debug('recoded hex %s' % od(pack2), 'parser') |
||
105 | |||
106 | str1 = str1.replace('attribute [ 0x04 0x80 0x00000064 ]', 'med 100') |
||
107 | str1r = ( |
||
108 | str1.lower().replace(' med 100', '').replace(' local-preference 100', '').replace(' origin igp', '') |
||
109 | ) |
||
110 | str2r = ( |
||
111 | str2.lower().replace(' med 100', '').replace(' local-preference 100', '').replace(' origin igp', '') |
||
112 | ) |
||
113 | str2r = str2r.replace( |
||
114 | 'large-community [ 1:2:3 10:11:12 ]', |
||
115 | 'attribute [ 0x20 0xc0 0x0000000100000002000000030000000a0000000b0000000c ]', |
||
116 | ) |
||
117 | |||
118 | if 'next-hop self' in str1r: |
||
119 | if ':' in str1r: |
||
120 | str1r = str1r.replace('next-hop self', 'next-hop ::1') |
||
121 | else: |
||
122 | str1r = str1r.replace('next-hop self', 'next-hop %s' % neighbor.local_address) |
||
123 | |||
124 | if ' name ' in str1r: |
||
125 | parts = str1r.split(' ') |
||
126 | pos = parts.index('name') |
||
127 | str1r = ' '.join(parts[:pos] + parts[pos + 2 :]) |
||
128 | |||
129 | skip = False |
||
130 | |||
131 | if str1r != str2r: |
||
132 | if 'attribute [' in str1r and ' 0x00 ' in str1r: |
||
133 | # we do not decode non-transitive attributes |
||
134 | log.debug('skipping string check on update with non-transitive attribute(s)', 'parser') |
||
135 | skip = True |
||
136 | else: |
||
137 | log.debug('strings are different:', 'parser') |
||
138 | log.debug('[%s]' % (str1r), 'parser') |
||
139 | log.debug('[%s]' % (str2r), 'parser') |
||
140 | return False |
||
141 | else: |
||
142 | log.debug('strings are fine', 'parser') |
||
143 | |||
144 | if skip: |
||
145 | log.debug('skipping encoding for update with non-transitive attribute(s)', 'parser') |
||
146 | elif pack1 != pack2: |
||
147 | log.debug('encoding are different', 'parser') |
||
148 | log.debug('[%s]' % (od(pack1)), 'parser') |
||
149 | log.debug('[%s]' % (od(pack2)), 'parser') |
||
150 | return False |
||
151 | else: |
||
152 | log.debug('encoding is fine', 'parser') |
||
153 | log.debug('----------------------------------------', 'parser') |
||
154 | |||
155 | log.debug('JSON nlri %s' % change1.nlri.json(), 'parser') |
||
156 | log.debug('JSON attr %s' % change1.attributes.json(), 'parser') |
||
157 | |||
158 | except Notify as exc: |
||
159 | log.debug('----------------------------------------', 'parser') |
||
160 | log.debug(str(exc), 'parser') |
||
161 | log.debug('----------------------------------------', 'parser') |
||
162 | return False |
||
163 | neighbor.rib.clear() |
||
164 | |||
165 | return True |
||
166 | |||
281 |