Conditions | 11 |
Total Lines | 66 |
Lines | 0 |
Ratio | 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 st2common.models.utils.ActionAliasFormatParser.get_extracted_param_value() 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 | # Licensed to the StackStorm, Inc ('StackStorm') under one or more |
||
30 | def get_extracted_param_value(self): |
||
31 | |||
32 | result = {} |
||
33 | |||
34 | # As there's a lot of questions about using regular expressions, |
||
35 | # I'll try to be thorough when documenting this code. |
||
36 | |||
37 | # We're parsing the arbitrary key-value pairs at the end of the stream |
||
38 | # to support passing of parameters not specified in the format string, |
||
39 | # and cutting them from the stream as they're no longer needed. |
||
40 | # Possible values are quoted strings, a word, or anything inside "{}". |
||
41 | pairs_match = r'(?:^|\s+)(\S+)=("(.*?)"|\'(.*?)\'|({.*?})|(\S+))' |
||
42 | extra = re.match(r'.*?((' + pairs_match + r'\s*)*)$', |
||
43 | self._param_stream, re.DOTALL) |
||
44 | if extra: |
||
45 | kv_pairs = re.findall(pairs_match, |
||
46 | extra.group(1), re.DOTALL) |
||
47 | self._param_stream = self._param_stream.replace(extra.group(1), '') |
||
48 | self._param_stream = " %s " % self._param_stream |
||
49 | |||
50 | # Now we'll match parameters with default values in form of |
||
51 | # {{ value = parameter }} (and all possible permutations of spaces), |
||
52 | # compiling them into a list. |
||
53 | # "test {{ url = http://google.com }} {{ extra = Test }}" will become |
||
54 | # [ ["url", "http://google.com"], ["extra", "Test"] ] |
||
55 | params = re.findall(r'{{\s*(.+?)\s*(?:=\s*[\'"]?({.+?}|.+?)[\'"]?)?\s*}}', |
||
56 | self._format, re.DOTALL) |
||
57 | |||
58 | # Now we're transforming our format string into a regular expression, |
||
59 | # substituting {{ ... }} with regex named groups, so that param_stream |
||
60 | # matched against this expression yields a dict of params with values. |
||
61 | param_match = r'["\']?(?P<\2>(?:(?<=\').+?(?=\')|(?<=").+?(?=")|{.+?}|.+?))["\']?' |
||
62 | reg = re.sub(r'(\s*){{\s*([^=}]+?)\s*}}(?![\'"]?\s+}})', |
||
63 | r'\1' + param_match, |
||
64 | self._format) |
||
65 | reg = re.sub(r'(\s*){{\s*(\S+)\s*=\s*(?:{.+?}|.+?)\s*}}', |
||
66 | r'(?:\1' + param_match + r')?', |
||
67 | reg) |
||
68 | reg = re.sub(r'(\s*){{\s*(.+?)\s*}}', |
||
69 | r'\1' + param_match, |
||
70 | reg) |
||
71 | reg = '^\s*' + reg + r'\s*$' |
||
|
|||
72 | |||
73 | # Now we're matching param_stream against our format string regex, |
||
74 | # getting a dict of values. We'll also get default values from |
||
75 | # "params" list if something is not present. |
||
76 | # Priority, from lowest to highest: |
||
77 | # 1. Default parameters |
||
78 | # 2. Matched parameters |
||
79 | # 3. Extra parameters |
||
80 | matched_stream = re.match(reg, self._param_stream, re.DOTALL) |
||
81 | if matched_stream: |
||
82 | values = matched_stream.groupdict() |
||
83 | for param in params: |
||
84 | matched_value = values[param[0]] if matched_stream else None |
||
85 | matched_result = matched_value or param[1] |
||
86 | if matched_result: |
||
87 | result[param[0]] = matched_result |
||
88 | if extra: |
||
89 | for pair in kv_pairs: |
||
90 | result[pair[0]] = ''.join(pair[2:]) |
||
91 | |||
92 | if self._format and not (self._param_stream.strip() or any(result.values())): |
||
93 | raise content.ParseException('No value supplied and no default value found.') |
||
94 | |||
95 | return result |
||
96 |
Escape sequences in Python are generally interpreted according to rules similar to standard C. Only if strings are prefixed with
r
orR
are they interpreted as regular expressions.The escape sequence that was used indicates that you might have intended to write a regular expression.
Learn more about the available escape sequences. in the Python documentation.