def load_string(self, string, **kwargs): '''Insert a string into the Language Builder and return the root widget (if defined) of the kv string. :Parameters: `rulesonly`: bool, defaults to False If True, the Builder will raise an exception if you have a root widget inside the definition. ''' kwargs.setdefault('rulesonly', False) self._current_filename = fn = kwargs.get('filename', None) # put a warning if a file is loaded multiple times if fn in self.files: Logger.warning('Lang: The file {} is loaded multiples times, ' 'you might have unwanted behaviors.'.format(fn)) try: # parse the string parser = Parser(content=string, filename=fn) # merge rules with our rules self.rules.extend(parser.rules) self._clear_matchcache() # add the template found by the parser into ours for name, cls, template in parser.templates: self.templates[name] = (cls, template, fn) Factory.register(name, cls=partial(self.template, name), is_template=True, warn=True) # register all the dynamic classes for name, baseclasses in iteritems(parser.dynamic_classes): Factory.register(name, baseclasses=baseclasses, filename=fn, warn=True) # create root object is exist if kwargs['rulesonly'] and parser.root: filename = kwargs.get('rulesonly', '<string>') raise Exception('The file <%s> contain also non-rules ' 'directives' % filename) # save the loaded files only if there is a root without # template/dynamic classes if fn and (parser.templates or parser.dynamic_classes or parser.rules): self.files.append(fn) if parser.root: widget = Factory.get(parser.root.name)() self._apply_rule(widget, parser.root, parser.root) return widget finally: self._current_filename = None
def load_string(self, string, **kwargs): '''Insert a string into the Language Builder and return the root widget (if defined) of the kv string. :Parameters: `rulesonly`: bool, defaults to False If True, the Builder will raise an exception if you have a root widget inside the definition. `filename`: str, defaults to None If specified, the filename used to index the kv rules. The filename parameter can be used to unload kv strings in the same way as you unload kv files. This can be achieved using pseudo file names e.g.:: Build.load_string(""" <MyRule>: Label: text="Hello" """, filename="myrule.kv") can be unloaded via:: Build.unload_file("myrule.kv") ''' kwargs.setdefault('rulesonly', False) self._current_filename = fn = kwargs.get('filename', None) # put a warning if a file is loaded multiple times if fn in self.files: Logger.warning('Lang: The file {} is loaded multiples times, ' 'you might have unwanted behaviors.'.format(fn)) try: # parse the string parser = Parser(content=string, filename=fn) # merge rules with our rules self.rules.extend(parser.rules) self._clear_matchcache() # add the template found by the parser into ours for name, cls, template in parser.templates: self.templates[name] = (cls, template, fn) Factory.register(name, cls=partial(self.template, name), is_template=True, warn=True) # register all the dynamic classes for name, baseclasses in parser.dynamic_classes.items(): Factory.register(name, baseclasses=baseclasses, filename=fn, warn=True) # create root object is exist if kwargs['rulesonly'] and parser.root: filename = kwargs.get('rulesonly', '<string>') raise Exception('The file <%s> contain also non-rules ' 'directives' % filename) # save the loaded files only if there is a root without # template/dynamic classes if fn and (parser.templates or parser.dynamic_classes or parser.rules): self.files.append(fn) if parser.root: widget = Factory.get(parser.root.name)(__no_builder=True) rule_children = [] widget.apply_class_lang_rules(root=widget, rule_children=rule_children) self._apply_rule(widget, parser.root, parser.root, rule_children=rule_children) for child in rule_children: child.dispatch('on_kv_post', widget) widget.dispatch('on_kv_post', widget) return widget finally: self._current_filename = None