Conditions | 33 |
Total Lines | 127 |
Code Lines | 92 |
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 sphinxarg.parser.parse_parser() 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 | import re |
||
49 | def parse_parser(parser, data=None, **kwargs): |
||
50 | if data is None: |
||
51 | data = { |
||
52 | 'name': '', |
||
53 | 'usage': parser.format_usage().strip(), |
||
54 | 'bare_usage': _format_usage_without_prefix(parser), |
||
55 | 'prog': parser.prog, |
||
56 | } |
||
57 | _try_add_parser_attribute(data, parser, 'description') |
||
58 | _try_add_parser_attribute(data, parser, 'epilog') |
||
59 | for action in parser._get_positional_actions(): |
||
60 | if not isinstance(action, _SubParsersAction): |
||
61 | continue |
||
62 | helps = {} |
||
63 | for item in action._choices_actions: |
||
64 | helps[item.dest] = item.help |
||
65 | |||
66 | # commands which share an existing parser are an alias, |
||
67 | # don't duplicate docs |
||
68 | subsection_alias = {} |
||
69 | subsection_alias_names = set() |
||
70 | for name, subaction in action._name_parser_map.items(): |
||
71 | if subaction not in subsection_alias: |
||
72 | subsection_alias[subaction] = [] |
||
73 | else: |
||
74 | subsection_alias[subaction].append(name) |
||
75 | subsection_alias_names.add(name) |
||
76 | |||
77 | for name, subaction in action._name_parser_map.items(): |
||
78 | if name in subsection_alias_names: |
||
79 | continue |
||
80 | subalias = subsection_alias[subaction] |
||
81 | subaction.prog = f'{parser.prog} {name}' |
||
82 | subdata = { |
||
83 | 'name': name if not subalias else f"{name} ({', '.join(subalias)})", |
||
84 | 'help': helps.get(name, ''), |
||
85 | 'usage': subaction.format_usage().strip(), |
||
86 | 'bare_usage': _format_usage_without_prefix(subaction), |
||
87 | } |
||
88 | if subalias: |
||
89 | subdata['identifier'] = name |
||
90 | parse_parser(subaction, subdata, **kwargs) |
||
91 | data.setdefault('children', []).append(subdata) |
||
92 | |||
93 | show_defaults = True |
||
94 | if kwargs.get('skip_default_values', False) is True: |
||
95 | show_defaults = False |
||
96 | show_defaults_const = show_defaults |
||
97 | if kwargs.get('skip_default_const_values', False) is True: |
||
98 | show_defaults_const = False |
||
99 | |||
100 | # argparse stores the different groups as a list in parser._action_groups |
||
101 | # the first element of the list holds the positional arguments, the |
||
102 | # second the option arguments not in groups, and subsequent elements |
||
103 | # argument groups with positional and optional parameters |
||
104 | action_groups = [] |
||
105 | for action_group in parser._action_groups: |
||
106 | options_list = [] |
||
107 | for action in action_group._group_actions: |
||
108 | if isinstance(action, _HelpAction): |
||
109 | continue |
||
110 | |||
111 | # Quote default values for string/None types |
||
112 | default = action.default |
||
113 | if action.default not in ['', None, True, False] and action.type in [None, str] and isinstance(action.default, str): |
||
114 | default = f'"{default}"' |
||
115 | |||
116 | # fill in any formatters, like %(default)s |
||
117 | format_dict = dict(vars(action), prog=data.get('prog', ''), default=default) |
||
118 | format_dict['default'] = default |
||
119 | help_str = action.help or '' # Ensure we don't print None |
||
120 | try: |
||
121 | help_str = help_str % format_dict |
||
122 | except Exception: |
||
123 | pass |
||
124 | |||
125 | # Options have the option_strings set, positional arguments don't |
||
126 | name = action.option_strings |
||
127 | if name == []: |
||
128 | if action.metavar is None: |
||
129 | name = [action.dest] |
||
130 | else: |
||
131 | name = [action.metavar] |
||
132 | # Skip lines for subcommands |
||
133 | if name == ['==SUPPRESS==']: |
||
134 | continue |
||
135 | |||
136 | if isinstance(action, _StoreConstAction): |
||
137 | option = { |
||
138 | 'name': name, |
||
139 | 'default': default if show_defaults_const else '==SUPPRESS==', |
||
140 | 'help': help_str, |
||
141 | } |
||
142 | else: |
||
143 | option = { |
||
144 | 'name': name, |
||
145 | 'default': default if show_defaults else '==SUPPRESS==', |
||
146 | 'help': help_str, |
||
147 | } |
||
148 | if action.choices: |
||
149 | option['choices'] = action.choices |
||
150 | if "==SUPPRESS==" not in option['help']: |
||
151 | options_list.append(option) |
||
152 | |||
153 | if len(options_list) == 0: |
||
154 | continue |
||
155 | |||
156 | # Upper case "Positional Arguments" and "Optional Arguments" titles |
||
157 | # Since python-3.10 'optional arguments' changed to 'options' |
||
158 | # more info: https://github.com/python/cpython/pull/23858 |
||
159 | if action_group.title == 'optional arguments' or action_group.title == 'options': |
||
160 | action_group.title = 'Named Arguments' |
||
161 | if action_group.title == 'positional arguments': |
||
162 | action_group.title = 'Positional Arguments' |
||
163 | |||
164 | group = { |
||
165 | 'title': action_group.title, |
||
166 | 'description': action_group.description, |
||
167 | 'options': options_list, |
||
168 | } |
||
169 | |||
170 | action_groups.append(group) |
||
171 | |||
172 | if len(action_groups) > 0: |
||
173 | data['action_groups'] = action_groups |
||
174 | |||
175 | return data |
||
176 |