def __getattr__(self, attr): if attr in self.__dict__: return self.__dict__[attr] data = self.__dict__['_data'] from rez.plugin_managers import plugin_manager if attr in plugin_manager.get_plugin_types(): # get plugin config data, and apply overrides plugin_type = attr config_data = plugin_manager.get_plugin_config_data(plugin_type) d = copy.deepcopy(config_data) deep_update(d, data.get(plugin_type, {})) # validate schema = plugin_manager.get_plugin_config_schema(plugin_type) try: d = schema.validate(d) except SchemaError as e: raise ConfigurationError( "Error in Rez configuration under plugins.%s: %s" % (plugin_type, str(e))) elif attr in data: d = data[attr] else: raise AttributeError( "No such configuration setting: 'plugins.%s'" % attr) d_ = convert_dicts(d, RO_AttrDictWrapper) self.__dict__[attr] = d_ return d_
def load_plugins(self): import pkgutil from rez.backport.importlib import import_module type_module_name = 'rezplugins.' + self.type_name package = import_module(type_module_name) # on import, the `__path__` variable of the imported package is extended # to include existing directories on the plugin search path (via # extend_path, above). this means that `walk_packages` will walk over all # modules on the search path at the same level (.e.g in a # 'rezplugins/type_name' sub-directory). paths = [package.__path__] if isinstance(package.__path__, basestring) \ else package.__path__ for path in paths: for loader, modname, ispkg in pkgutil.walk_packages( [path], package.__name__ + '.'): if loader is not None: plugin_name = modname.split('.')[-1] if plugin_name.startswith('_'): continue if config.debug("plugins"): print_debug("loading %s plugin at %s: %s..." % (self.type_name, path, modname)) try: # load_module will force reload the module if it's # already loaded, so check for that module = sys.modules.get(modname) if module is None: module = loader.find_module(modname).load_module(modname) if hasattr(module, 'register_plugin') and \ hasattr(module.register_plugin, '__call__'): plugin_class = module.register_plugin() if plugin_class != None: self.register_plugin(plugin_name, plugin_class, module) else: if config.debug("plugins"): print_warning( "'register_plugin' function at %s: %s did not return a class." % (path, modname)) else: if config.debug("plugins"): print_warning( "no 'register_plugin' function at %s: %s" % (path, modname)) # delete from sys.modules? except Exception as e: nameish = modname.split('.')[-1] self.failed_plugins[nameish] = str(e) if config.debug("plugins"): import traceback from StringIO import StringIO out = StringIO() traceback.print_exc(file=out) print_debug(out.getvalue()) # load config data, _ = _load_config_from_filepaths([os.path.join(path, "rezconfig")]) deep_update(self.config_data, data)
def __getattr__(self, attr): if attr in self.__dict__: return self.__dict__[attr] data = self.__dict__['_data'] from rez.plugin_managers import plugin_manager if attr in plugin_manager.get_plugin_types(): # get plugin config data, and apply overrides plugin_type = attr config_data = plugin_manager.get_plugin_config_data(plugin_type) d = copy.deepcopy(config_data) deep_update(d, data.get(plugin_type, {})) # validate schema = plugin_manager.get_plugin_config_schema(plugin_type) try: d = schema.validate(d) except SchemaError as e: raise ConfigurationError( "Error in Rez configuration under plugins.%s: %s" % (plugin_type, str(e))) elif attr in data: d = data[attr] else: raise AttributeError("No such configuration setting: 'plugins.%s'" % attr) d_ = convert_dicts(d, RO_AttrDictWrapper) self.__dict__[attr] = d_ return d_
def override(self, key, value): def _nosuch(): raise AttributeError("no such setting: %r" % ".".join(key)) if len(key) < 2: _nosuch() from rez.plugin_managers import plugin_manager if key[0] not in plugin_manager.get_plugin_types(): _nosuch() plugin_type = key[0] key = key[1:] data = {} new_overrides = {plugin_type: data} while len(key) > 1: data_ = {} data[key[0]] = data_ data = data_ key = key[1:] data[key[0]] = value deep_update(self.__dict__["_data"], new_overrides) if plugin_type in self.__dict__: del self.__dict__[plugin_type] # uncache
def update_settings(self, new_settings, override=False): """Can be called within test methods to modify settings on a per-test basis (as opposed cls.settings, which modifies it for all tests on the class) Note that multiple calls will not "accumulate" updates, but will instead patch the class's settings with the new_settings each time. new_settings : dict the updated settings to override the config with override : bool normally, the resulting config will be the result of merging the base cls.settings with the new_settings - ie, like doing cls.settings.update(new_settings). If this is True, however, then the cls.settings will be ignored entirely, and the new_settings will be the only configuration settings applied """ # restore the "normal" config... from rez.util import deep_update self.teardown_config() # ...then copy the class settings dict to instance, so we can # modify... if override: self.settings = dict(new_settings) else: self.settings = dict(type(self).settings) deep_update(self.settings, new_settings) # now swap the config back in... self.setup_config()
def config_schema(self): """Returns the merged configuration data schema for this plugin type.""" from rez.config import _plugin_config_dict d = _plugin_config_dict.get(self.type_name, {}) for name, plugin_class in self.plugin_classes.iteritems(): if hasattr(plugin_class, "schema_dict") \ and plugin_class.schema_dict: d_ = {name: plugin_class.schema_dict} deep_update(d, d_) return dict_to_schema(d, required=True, modifier=expand_system_vars)
def _load_config_from_filepaths(filepaths): data = {} sourced_filepaths = [] loaders = ((".py", _load_config_py), ("", _load_config_yaml)) for filepath in filepaths: for extension, loader in loaders: if extension: no_ext = os.path.splitext(filepath)[0] filepath_with_ext = no_ext + extension else: filepath_with_ext = filepath if not os.path.isfile(filepath_with_ext): continue data_ = loader(filepath_with_ext) deep_update(data, data_) sourced_filepaths.append(filepath_with_ext) break return data, sourced_filepaths
def override(self, key, value): def _nosuch(): raise AttributeError("no such setting: %r" % '.'.join(key)) if len(key) < 2: _nosuch() from rez.plugin_managers import plugin_manager if key[0] not in plugin_manager.get_plugin_types(): _nosuch() plugin_type = key[0] key = key[1:] data = {} new_overrides = {plugin_type: data} while len(key) > 1: data_ = {} data[key[0]] = data_ data = data_ key = key[1:] data[key[0]] = value deep_update(self.__dict__['_data'], new_overrides) if plugin_type in self.__dict__: del self.__dict__[plugin_type] # uncache
def _data(self): data, self._sourced_filepaths = _load_config_from_filepaths(self.filepaths) deep_update(data, self.overrides) return data
def _data(self): data, self._sourced_filepaths = _load_config_from_filepaths( self.filepaths) deep_update(data, self.overrides) return data