def update_config_main_options(self, vals): """Set the main options. This means setting the used classes for every class :attr:`BASECLASSES`. :param dict[str,str] vals: The dictionary of the mapping ``baseclass:subclass``. :raises ValueError: If the key you want to set is present in :attr:`FIXED_OPTIONS` or if the value is not a subclass of the provided key according to :func:`helpers.get_all_subclasses`. :returns: Nothing of value """ for key, value in vals.items(): if key in self.FIXED_OPTIONS: raise ValueError("This item cannot be set!") for basecls in self.BASECLASSES: if basecls.__name__ != key: continue for subcls in helpers.get_all_subclasses(basecls): if subcls.__name__ == value: self.user_config['main'][key] = value break else: continue break # if we did break break out of this loop as well. else: raise ValueError("Wrong value encountered!")
def set_default_options(self): """Set the default options of all subclasses as the only config. This overrides any special config that was present in the `self.user_config` variable. The main section of `self.user_config` is the only key that is preserved. :returns: Nothing of value. """ main_cfg = self.user_config['main'] self.user_config = {cls.__name__: dict() for cls in self.BASECLASSES} self.user_config['main'] = main_cfg for basecls in self.BASECLASSES: for cls in helpers.get_all_subclasses(basecls): if cls.__name__ not in self.user_config[basecls.__name__]: self.user_config[basecls.__name__][cls.__name__] = dict() defaults = cls.__init__.__defaults__ if defaults is None: continue # zip the default arguments with its default value and set this # in user_config for arg, val in zip( get_args(cls.__init__)[-len(defaults):], defaults): self.user_config[basecls.__name__][cls.__name__][arg] = val
def get_all_options(baseclasses=None): """Get all options for all classes. :param baseclasses: The classes to use, defaults to :attr:`BASECLASSES`. :type baseclasses: list(type) or None :returns: The dictionary with all options. For the format see the :ref:`#sdaas protocol<sdaas-protocol>`. :rtype: dict """ configs = dict() if baseclasses is None: baseclasses = Config.BASECLASSES for basecls in baseclasses: configs[basecls.__name__] = dict() for subcls in helpers.get_all_subclasses(basecls): configs[basecls.__name__][subcls.__name__] = dict() configs[basecls.__name__][subcls.__name__]['parts'] = dict() configs[basecls.__name__][subcls.__name__]['doc'] = dict() cls_doc = helpers.parse_docstring(subcls.__doc__) init_doc = helpers.parse_docstring(subcls.__init__.__doc__) param_doc = init_doc['params'] configs[basecls.__name__][ subcls.__name__]['doc']['short'] = cls_doc['short'] configs[basecls.__name__][ subcls.__name__]['doc']['long'] = cls_doc['long'] defaults = subcls.__init__.__defaults__ default_amount = 0 if isinstance(defaults, tuple): default_amount = len(defaults) var_amount = subcls.__init__.__code__.co_argcount for idx, arg in enumerate(get_args(subcls.__init__)): if arg == "self": continue part = { 'doc': param_doc[arg] if arg in param_doc else "", 'fixed': arg in Config.FIXED_OPTIONS, 'required': idx < var_amount - default_amount } configs[basecls.__name__][ subcls.__name__]['parts'][arg] = part return configs
def get_class(self, basecls, cls_name): """Get a class for the given category with the given name. .. note:: this does not return an instance, only the class. :param type basecls: The base class, this should be a member of :attr:`BASECLASSES`. :param cls_name: The name of the subclass to find. This class should be a subclass of basecls. If `cls_name` is none the name from ``user_config['main'][basecls]`` is used. :type cls_name: str or None :return: The class object with the given `cls_name` :rtype: type """ if cls_name is None: cls_name = self.user_config["main"][basecls.__name__] for cls in helpers.get_all_subclasses(basecls): if cls.__name__ == cls_name: return cls raise KeyError( "Class {} could not be found as a subclass of {}".format( cls_name, basecls.__name__))
def test_get_all_subclasses(baseclass, expected): assert helpers.get_all_subclasses(baseclass) == expected