def update_type(self, tpe, bases): """ Change the bases of the given ``tpe`` """ if not isinstance(tpe, PersistableType): raise UnsupportedTypeError("Object is not a PersistableType") if self.type_registry.is_static_type(tpe): raise CannotUpdateType("Type '{}' is defined in code and cannot" "be updated.".format(get_type_id(tpe))) descriptor = self.type_registry.get_descriptor(tpe) existing_attrs = dict_difference(descriptor.attributes, descriptor.declared_attributes) base_attrs = {} for base in bases: desc = self.type_registry.get_descriptor(base) base_attrs.update(desc.attributes) base_attrs = dict_difference(base_attrs, descriptor.declared_attributes) if existing_attrs != base_attrs: raise CannotUpdateType("Inherited attributes are not identical") match_clauses = [get_match_clause(tpe, 'type', self.type_registry)] create_clauses = [] query_args = {} for index, base in enumerate(bases): name = 'base_{}'.format(index) match = get_match_clause(base, name, self.type_registry) create = "type -[:ISA {%s_props}]-> %s" % (name, name) query_args["{}_props".format(name)] = {'base_index': index} match_clauses.append(match) create_clauses.append(create) query = join_lines( "MATCH", (match_clauses, ','), ", type -[r:ISA]-> ()", "DELETE r", "CREATE", (create_clauses, ','), "RETURN type") try: next(self._execute(query, **query_args)) self.invalidate_type_system() except StopIteration: raise CannotUpdateType("Type or bases not found in the database.") self.reload_types()