| # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
| # For details: https://github.com/PyCQA/pylint/blob/master/LICENSE |
| |
| |
| import optparse # pylint: disable=deprecated-module |
| from typing import Any, Dict, Tuple |
| |
| from pylint.config.option import _validate |
| |
| |
| class UnsupportedAction(Exception): |
| """raised by set_option when it doesn't know what to do for an action""" |
| |
| |
| class OptionsProviderMixIn: |
| """Mixin to provide options to an OptionsManager""" |
| |
| # those attributes should be overridden |
| priority = -1 |
| name = "default" |
| options: Tuple[Tuple[str, Dict[str, Any]], ...] = () |
| level = 0 |
| |
| def __init__(self): |
| self.config = optparse.Values() |
| self.load_defaults() |
| |
| def load_defaults(self): |
| """initialize the provider using default values""" |
| for opt, optdict in self.options: |
| action = optdict.get("action") |
| if action != "callback": |
| # callback action have no default |
| if optdict is None: |
| optdict = self.get_option_def(opt) |
| default = optdict.get("default") |
| self.set_option(opt, default, action, optdict) |
| |
| def option_attrname(self, opt, optdict=None): |
| """get the config attribute corresponding to opt""" |
| if optdict is None: |
| optdict = self.get_option_def(opt) |
| return optdict.get("dest", opt.replace("-", "_")) |
| |
| def option_value(self, opt): |
| """get the current value for the given option""" |
| return getattr(self.config, self.option_attrname(opt), None) |
| |
| def set_option(self, optname, value, action=None, optdict=None): |
| """method called to set an option (registered in the options list)""" |
| if optdict is None: |
| optdict = self.get_option_def(optname) |
| if value is not None: |
| value = _validate(value, optdict, optname) |
| if action is None: |
| action = optdict.get("action", "store") |
| if action == "store": |
| setattr(self.config, self.option_attrname(optname, optdict), value) |
| elif action in ("store_true", "count"): |
| setattr(self.config, self.option_attrname(optname, optdict), 0) |
| elif action == "store_false": |
| setattr(self.config, self.option_attrname(optname, optdict), 1) |
| elif action == "append": |
| optname = self.option_attrname(optname, optdict) |
| _list = getattr(self.config, optname, None) |
| if _list is None: |
| if isinstance(value, (list, tuple)): |
| _list = value |
| elif value is not None: |
| _list = [] |
| _list.append(value) |
| setattr(self.config, optname, _list) |
| elif isinstance(_list, tuple): |
| setattr(self.config, optname, _list + (value,)) |
| else: |
| _list.append(value) |
| elif action == "callback": |
| optdict["callback"](None, optname, value, None) |
| else: |
| raise UnsupportedAction(action) |
| |
| def get_option_def(self, opt): |
| """return the dictionary defining an option given its name""" |
| assert self.options |
| for option in self.options: |
| if option[0] == opt: |
| return option[1] |
| raise optparse.OptionError( |
| f"no such option {opt} in section {self.name!r}", opt |
| ) |
| |
| def options_by_section(self): |
| """return an iterator on options grouped by section |
| |
| (section, [list of (optname, optdict, optvalue)]) |
| """ |
| sections = {} |
| for optname, optdict in self.options: |
| sections.setdefault(optdict.get("group"), []).append( |
| (optname, optdict, self.option_value(optname)) |
| ) |
| if None in sections: |
| yield None, sections.pop(None) |
| for section, options in sorted(sections.items()): |
| yield section.upper(), options |
| |
| def options_and_values(self, options=None): |
| if options is None: |
| options = self.options |
| for optname, optdict in options: |
| yield (optname, optdict, self.option_value(optname)) |