follow yams 0.25 api changes to improve performance stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 15 Oct 2009 20:29:21 +0200
branchstable
changeset 3689 deb13e88e037
parent 3688 421fb447ecb2
child 3690 a5ef45850d23
follow yams 0.25 api changes to improve performance
devtools/devctl.py
devtools/fill.py
devtools/testlib.py
entities/__init__.py
entity.py
goa/__init__.py
goa/appobjects/components.py
goa/appobjects/dbmgmt.py
goa/db.py
goa/dbinit.py
goa/overrides/rqlannotation.py
goa/rqlinterpreter.py
rqlrewrite.py
rset.py
schema.py
schemaviewer.py
selectors.py
server/checkintegrity.py
server/hooks.py
server/hooksmanager.py
server/migractions.py
server/msplanner.py
server/querier.py
server/repository.py
server/rqlannotation.py
server/schemahooks.py
server/schemaserial.py
server/securityhooks.py
server/sources/__init__.py
server/sources/ldapuser.py
server/sources/native.py
server/sources/pyrorql.py
server/sources/rql2sql.py
server/sqlutils.py
server/ssplanner.py
server/test/unittest_migractions.py
server/test/unittest_msplanner.py
server/test/unittest_rql2sql.py
sobjects/notification.py
test/unittest_entity.py
test/unittest_schema.py
view.py
web/facet.py
web/formfields.py
web/formwidgets.py
web/uicfg.py
web/views/__init__.py
web/views/actions.py
web/views/autoform.py
web/views/csvexport.py
web/views/editcontroller.py
web/views/editforms.py
web/views/forms.py
web/views/magicsearch.py
web/views/navigation.py
web/views/owl.py
web/views/plots.py
web/views/primary.py
web/views/schema.py
web/views/sparql.py
web/views/startup.py
web/views/tableview.py
web/views/urlpublishing.py
web/views/xmlrss.py
web/widgets.py
--- a/devtools/devctl.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/devtools/devctl.py	Thu Oct 15 20:29:21 2009 +0200
@@ -144,13 +144,13 @@
         if etype not in libschema:
             add_msg(w, etype)
             add_msg(w, '%s_plural' % etype)
-            if not eschema.is_final():
+            if not eschema.final:
                 add_msg(w, 'This %s' % etype)
                 add_msg(w, 'New %s' % etype)
             if eschema.description and not eschema.description in done:
                 done.add(eschema.description)
                 add_msg(w, eschema.description)
-        if eschema.is_final():
+        if eschema.final:
             continue
         for rschema, targetschemas, role in eschema.relation_definitions(True):
             for tschema in targetschemas:
@@ -199,7 +199,7 @@
             for subjschema in rschema.subjects():
                 if not subjschema in libsubjects:
                     add_msg(w, rtype, subjschema.type)
-        if not (schema.rschema(rtype).is_final() or rschema.symetric):
+        if not (schema.rschema(rtype).final or rschema.symetric):
             if rschema not in no_context_rtypes:
                 libobjects = librschema and librschema.objects() or ()
                 for objschema in rschema.objects():
--- a/devtools/fill.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/devtools/fill.py	Thu Oct 15 20:29:21 2009 +0200
@@ -347,7 +347,7 @@
         queries = []
         #   1/ skip final relations and explictly ignored relations
         rels = [rschema for rschema in self.schema.relations()
-                if not (rschema.is_final() or rschema in ignored_relations)]
+                if not (rschema.final or rschema in ignored_relations)]
         # for each relation
         #   2/ take each possible couple (subj, obj)
         #   3/ analyze cardinality of relation
--- a/devtools/testlib.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/devtools/testlib.py	Thu Oct 15 20:29:21 2009 +0200
@@ -44,7 +44,7 @@
     # compute how many entities by type we need to be able to satisfy relation constraint
     relmap = {}
     for rschema in schema.relations():
-        if rschema.is_final():
+        if rschema.final:
             continue
         for subj, obj in rschema.iter_rdefs():
             card = rschema.rproperty(subj, obj, 'cardinality')
@@ -143,7 +143,7 @@
         existingrels = {}
         ignored_relations = SYSTEM_RELATIONS + self.ignored_relations
         for rschema in self.schema.relations():
-            if rschema.is_final() or rschema in ignored_relations:
+            if rschema.final or rschema in ignored_relations:
                 continue
             rset = cu.execute('DISTINCT Any X,Y WHERE X %s Y' % rschema)
             existingrels.setdefault(rschema.type, set()).update((x, y) for x, y in rset)
--- a/entities/__init__.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/entities/__init__.py	Thu Oct 15 20:29:21 2009 +0200
@@ -63,7 +63,7 @@
 
     def dc_description(self, format='text/plain'):
         """return a suitable description for this entity"""
-        if self.e_schema.has_subject_relation('description'):
+        if 'description' in self.e_schema.subjrels:
             return self.printable_value('description', format=format)
         return u''
 
--- a/entity.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/entity.py	Thu Oct 15 20:29:21 2009 +0200
@@ -238,7 +238,7 @@
         _fetchattrs = []
         for attr in fetchattrs:
             try:
-                rschema = eschema.subject_relation(attr)
+                rschema = eschema.subjrels[attr]
             except KeyError:
                 cls.warning('skipping fetch_attr %s defined in %s (not found in schema)',
                             attr, cls.id)
@@ -249,7 +249,7 @@
             selection.append(var)
             restriction = '%s %s %s' % (mainvar, attr, var)
             restrictions.append(restriction)
-            if not rschema.is_final():
+            if not rschema.final:
                 # XXX this does not handle several destination types
                 desttype = rschema.objects(eschema.type)[0]
                 card = rschema.rproperty(eschema, desttype, 'cardinality')[0]
@@ -290,7 +290,7 @@
             needcheck = not cls.e_schema.has_unique_values(mainattr)
         else:
             for rschema in cls.e_schema.subject_relations():
-                if rschema.is_final() and rschema != 'eid' and cls.e_schema.has_unique_values(rschema):
+                if rschema.final and rschema != 'eid' and cls.e_schema.has_unique_values(rschema):
                     mainattr = str(rschema)
                     needcheck = False
                     break
@@ -487,7 +487,7 @@
         assert self.has_eid()
         execute = self.req.execute
         for rschema in self.e_schema.subject_relations():
-            if rschema.is_final() or rschema.meta:
+            if rschema.final or rschema.meta:
                 continue
             # skip already defined relations
             if getattr(self, rschema.type):
@@ -535,7 +535,7 @@
     def to_complete_relations(self):
         """by default complete final relations to when calling .complete()"""
         for rschema in self.e_schema.subject_relations():
-            if rschema.is_final():
+            if rschema.final:
                 continue
             if len(rschema.objects(self.e_schema)) > 1:
                 # ambigous relations, the querier doesn't handle
--- a/goa/__init__.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/goa/__init__.py	Thu Oct 15 20:29:21 2009 +0200
@@ -65,7 +65,7 @@
             edef.name = edef.name.encode()
             assert re.match(r'[A-Z][A-Za-z0-9]*[a-z]+[0-9]*$', edef.name), repr(edef.name)
             eschema = super(CubicWebSchema, self).add_entity_type(edef)
-            if not eschema.is_final():
+            if not eschema.final:
                 # automatically add the eid relation to non final entity types
                 rdef = ybo.RelationDefinition(eschema.type, 'eid', 'Bytes',
                                               cardinality='?1', uid=True)
--- a/goa/appobjects/components.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/goa/appobjects/components.py	Thu Oct 15 20:29:21 2009 +0200
@@ -67,7 +67,7 @@
     """
     req = self.req
     for eschema in eschemas:
-        if eschema.is_final() or not (eschema.has_perm(req, 'read') or
+        if eschema.final or not (eschema.has_perm(req, 'read') or
                                       eschema.has_local_role('read')):
             continue
         etype = eschema.type
--- a/goa/appobjects/dbmgmt.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/goa/appobjects/dbmgmt.py	Thu Oct 15 20:29:21 2009 +0200
@@ -175,7 +175,7 @@
         # XXX should use unsafe_execute with all hooks deactivated
         # XXX step by catching datastore errors?
         for eschema in self.schema.entities():
-            if eschema.is_final() or eschema in self.skip_etypes:
+            if eschema.final or eschema in self.skip_etypes:
                 continue
             self.req.execute('DELETE %s X' % eschema)
             self.w(u'deleted all %s entities<br/>' % eschema)
--- a/goa/db.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/goa/db.py	Thu Oct 15 20:29:21 2009 +0200
@@ -147,7 +147,7 @@
     def __initialize__(cls):
         super(Model, cls).__initialize__()
         cls._attributes = frozenset(rschema for rschema in cls.e_schema.subject_relations()
-                                    if rschema.is_final())
+                                    if rschema.final)
 
     def __init__(self, *args, **kwargs):
         # db.Model prototype:
@@ -162,7 +162,7 @@
             super(Model, self).__init__(None, None)
             # if Model instances are given in kwargs, turn them into db model
             for key, val in kwargs.iteritems():
-                if key in self.e_schema.subject_relations() and not self.e_schema.schema[key].is_final():
+                if key in self.e_schema.subject_relations() and not self.e_schema.schema[key].final:
                     if isinstance(kwargs, (list, tuple)):
                         val = [isinstance(x, Model) and x._dbmodel or x for x in val]
                     elif isinstance(val, Model):
--- a/goa/dbinit.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/goa/dbinit.py	Thu Oct 15 20:29:21 2009 +0200
@@ -90,7 +90,7 @@
     eschema = schema.eschema('CWEType')
     execute(rql, {'name': u'CWEType', 'descr': unicode(eschema.description)})
     for eschema in schema.entities():
-        if eschema.is_final() or eschema == 'CWEType':
+        if eschema.final or eschema == 'CWEType':
             continue
         execute(rql, {'name': unicode(eschema),
                       'descr': unicode(eschema.description)})
--- a/goa/overrides/rqlannotation.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/goa/overrides/rqlannotation.py	Thu Oct 15 20:29:21 2009 +0200
@@ -13,7 +13,7 @@
     def __init__(self, schema):
         self.schema = schema
         self.nfdomain = frozenset(eschema.type for eschema in schema.entities()
-                                  if not eschema.is_final())
+                                  if not eschema.final)
     def annotate(self, rqlst):
         rqlst.has_text_query = False
         rqlst.need_distinct = False
--- a/goa/rqlinterpreter.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/goa/rqlinterpreter.py	Thu Oct 15 20:29:21 2009 +0200
@@ -156,7 +156,7 @@
         myvar = self.rhs.name
         ovar = self.var.name
         rtype = self.rtype
-        if self.schema.rschema(rtype).is_final():
+        if self.schema.rschema(rtype).final:
             # should be detected by rql.stcheck: "Any C WHERE NOT X attr C" doesn't make sense
             #if self._not:
             #    raise NotImplementedError()
@@ -595,7 +595,7 @@
             # ok, we *may* process this Not node (not implemented error will be
             # raised later if we can't)
             extra[node.parent] = True
-        if rschema.is_final():
+        if rschema.final:
             self._visit_final_relation(rschema, node, constraints, extra)
         elif neged:
             self._visit_non_final_neged_relation(rschema, node, constraints)
--- a/rqlrewrite.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/rqlrewrite.py	Thu Oct 15 20:29:21 2009 +0200
@@ -32,7 +32,7 @@
     allpossibletypes = {}
     for solution in solutions:
         for varname, etype in solution.iteritems():
-            if not varname in newroot.defined_vars or eschema(etype).is_final():
+            if not varname in newroot.defined_vars or eschema(etype).final:
                 continue
             allpossibletypes.setdefault(varname, set()).add(etype)
     for varname in sorted(allpossibletypes):
@@ -289,7 +289,7 @@
         stinfo = self.varinfo['stinfo']
         for rel in stinfo['relations']:
             rschema = self.schema.rschema(rel.r_type)
-            if rschema.is_final() or (rschema.inlined and
+            if rschema.final or (rschema.inlined and
                                       not rel in stinfo['rhsrelations']):
                 self.select.remove_node(rel)
                 rel.children[0].name = selectvar
--- a/rset.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/rset.py	Thu Oct 15 20:29:21 2009 +0200
@@ -345,7 +345,7 @@
         etype = self.description[row][col]
         try:
             eschema = self.vreg.schema.eschema(etype)
-            if eschema.is_final():
+            if eschema.final:
                 raise NotAnEntity(etype)
         except KeyError:
             raise NotAnEntity(etype)
@@ -409,14 +409,14 @@
                 if outerselidx is None:
                     continue
                 if x == 'subject':
-                    rschema = eschema.subject_relation(attr)
-                    if rschema.is_final():
+                    rschema = eschema.subjrels[attr]
+                    if rschema.final:
                         entity[attr] = rowvalues[outerselidx]
                         continue
                     tetype = rschema.objects(etype)[0]
                     card = rschema.rproperty(etype, tetype, 'cardinality')[0]
                 else:
-                    rschema = eschema.object_relation(attr)
+                    rschema = eschema.objrels[attr]
                     tetype = rschema.subjects(etype)[0]
                     card = rschema.rproperty(tetype, etype, 'cardinality')[1]
                 # only keep value if it can't be multivalued
@@ -489,7 +489,7 @@
         locate_query_col = col
         rqlst = self.syntax_tree()
         etype = self.description[row][col]
-        if self.vreg.schema.eschema(etype).is_final():
+        if self.vreg.schema.eschema(etype).final:
             # final type, find a better one to locate the correct subquery
             # (ambiguous if possible)
             for i in xrange(len(rqlst.children[0].selection)):
@@ -498,7 +498,7 @@
                 coletype = self.description[row][i]
                 if coletype is None:
                     continue
-                if not self.vreg.schema.eschema(coletype).is_final():
+                if not self.vreg.schema.eschema(coletype).final:
                     etype = coletype
                     locate_query_col = i
                     if len(self.column_types(i)) > 1:
--- a/schema.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/schema.py	Thu Oct 15 20:29:21 2009 +0200
@@ -239,7 +239,7 @@
     """return system entity types only: skip final, schema and application entities
     """
     for eschema in schema.entities():
-        if eschema.is_final() or eschema.schema_entity():
+        if eschema.final or eschema.schema_entity():
             continue
         yield eschema.type
 
@@ -301,7 +301,7 @@
         may_need_has_text, has_has_text = False, False
         need_has_text = None
         for rschema in self.subject_relations():
-            if rschema.is_final():
+            if rschema.final:
                 if rschema == 'has_text':
                     has_has_text = True
                 elif self.rproperty(rschema, 'fulltextindexed'):
@@ -433,7 +433,7 @@
 
     def rql_expression(self, expression, mainvars=None, eid=None):
         """rql expression factory"""
-        if self.is_final():
+        if self.final:
             return ERQLExpression(expression, mainvars, eid)
         return RRQLExpression(expression, mainvars, eid)
 
@@ -473,7 +473,7 @@
         edef.name = bw_normalize_etype(edef.name)
         assert re.match(r'[A-Z][A-Za-z0-9]*[a-z]+[0-9]*$', edef.name), repr(edef.name)
         eschema = super(CubicWebSchema, self).add_entity_type(edef)
-        if not eschema.is_final():
+        if not eschema.final:
             # automatically add the eid relation to non final entity types
             rdef = ybo.RelationDefinition(eschema.type, 'eid', 'Int',
                                           cardinality='11', uid=True)
--- a/schemaviewer.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/schemaviewer.py	Thu Oct 15 20:29:21 2009 +0200
@@ -47,7 +47,7 @@
                                            klass='titleUnderline'),))
         layout.append(esection)
         eschemas = [eschema for eschema in schema.entities()
-                    if not (eschema.is_final() or eschema in skiptypes)]
+                    if not (eschema.final or eschema in skiptypes)]
         for eschema in sorted(eschemas):
             esection.append(self.visit_entityschema(eschema, skiptypes))
         if display_relations:
@@ -55,7 +55,7 @@
             rsection = Section(children=(title,))
             layout.append(rsection)
             relations = [rschema for rschema in schema.relations()
-                         if not (rschema.is_final() or rschema.type in skiptypes)]
+                         if not (rschema.final or rschema.type in skiptypes)]
             keys = [(rschema.type, rschema) for rschema in relations]
             for key, rschema in sorted(keys):
                 relstr = self.visit_relationschema(rschema)
@@ -143,7 +143,7 @@
         data.append(Section(children=rels, klass='rels'))
         data.append(Section(children=t_vars, klass='vars'))
         layout.append(Section(children=data, klass='entityAttributes'))
-        if eschema.is_final(): # stop here for final entities
+        if eschema.final: # stop here for final entities
             return layout
         _ = self.req._
         if self.req.user.matching_groups('managers'):
--- a/selectors.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/selectors.py	Thu Oct 15 20:29:21 2009 +0200
@@ -682,9 +682,9 @@
         eschema = eclass.e_schema
         try:
             if self.role == 'object':
-                rschema = eschema.object_relation(self.rtype)
+                rschema = eschema.objrels[self.rtype]
             else:
-                rschema = eschema.subject_relation(self.rtype)
+                rschema = eschema.subjrels[self.rtype]
         except KeyError:
             return 0
         if self.target_etype is not None:
@@ -899,7 +899,7 @@
     """
     def score(self, cls, req, etype):
         eschema = cls.schema.eschema(etype)
-        if not (eschema.is_final() or eschema.is_subobject(strict=True)) \
+        if not (eschema.final or eschema.is_subobject(strict=True)) \
                and eschema.has_perm(req, 'add'):
             return 1
         return 0
--- a/server/checkintegrity.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/checkintegrity.py	Thu Oct 15 20:29:21 2009 +0200
@@ -87,7 +87,7 @@
     repo.do_fti = True  # ensure full-text indexation is activated
     etypes = set()
     for eschema in schema.entities():
-        if eschema.is_final():
+        if eschema.final:
             continue
         indexable_attrs = tuple(eschema.indexable_attributes()) # generator
         if not indexable_attrs:
@@ -165,7 +165,7 @@
                 print >> sys.stderr
     print 'Checking entities tables'
     for eschema in schema.entities():
-        if eschema.is_final():
+        if eschema.final:
             continue
         table = SQL_PREFIX + eschema.type
         column = SQL_PREFIX +  'eid'
@@ -197,7 +197,7 @@
     """check all relations registered in the repo system table"""
     print 'Checking relations'
     for rschema in schema.relations():
-        if rschema.is_final() or rschema in PURE_VIRTUAL_RTYPES:
+        if rschema.final or rschema in PURE_VIRTUAL_RTYPES:
             continue
         if rschema.inlined:
             for subjtype in rschema.subjects():
--- a/server/hooks.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/hooks.py	Thu Oct 15 20:29:21 2009 +0200
@@ -244,7 +244,7 @@
     for attr, val in entity.items():
         if val is None:
             continue
-        if eschema.subject_relation(attr).is_final() and \
+        if eschema.subjrels[attr].final and \
                eschema.has_unique_values(attr):
             rql = '%s X WHERE X %s %%(val)s' % (entity.e_schema, attr)
             rset = session.unsafe_execute(rql, {'val': val})
@@ -257,7 +257,7 @@
         return
     schema = session.vreg.schema
     for attr in entity.edited_attributes:
-        if schema.rschema(attr).is_final():
+        if schema.rschema(attr).final:
             constraints = [c for c in entity.e_schema.constraints(attr)
                            if isinstance(c, RQLVocabularyConstraint)]
             if constraints:
--- a/server/hooksmanager.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/hooksmanager.py	Thu Oct 15 20:29:21 2009 +0200
@@ -286,7 +286,7 @@
     def call(self, session, fromeid, rtype, toeid):
         for eid in (fromeid, toeid):
             etype = session.describe(eid)[0]
-            if not self.schema.eschema(etype).has_subject_relation(self.rtype):
+            if self.rtype not in self.schema.eschema(etype).subjrels:
                 return
         if rtype in self.subject_relations:
             meid, seid = fromeid, toeid
@@ -312,12 +312,12 @@
         eschema = self.schema.eschema(session.describe(fromeid)[0])
         execute = session.unsafe_execute
         for rel in self.subject_relations:
-            if eschema.has_subject_relation(rel):
+            if rel in eschema.subjrels:
                 execute('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
                         'X %s R, NOT R %s P' % (rtype, rel, rtype),
                         {'x': fromeid, 'p': toeid}, 'x')
         for rel in self.object_relations:
-            if eschema.has_object_relation(rel):
+            if rel in eschema.objrels:
                 execute('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
                         'R %s X, NOT R %s P' % (rtype, rel, rtype),
                         {'x': fromeid, 'p': toeid}, 'x')
@@ -336,12 +336,12 @@
         eschema = self.schema.eschema(session.describe(fromeid)[0])
         execute = session.unsafe_execute
         for rel in self.subject_relations:
-            if eschema.has_subject_relation(rel):
+            if rel in eschema.subjrels:
                 execute('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
                         'X %s R' % (rtype, rel),
                         {'x': fromeid, 'p': toeid}, 'x')
         for rel in self.object_relations:
-            if eschema.has_object_relation(rel):
+            if rel in eschema.objrels:
                 execute('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
                         'R %s X' % (rtype, rel),
                         {'x': fromeid, 'p': toeid}, 'x')
--- a/server/migractions.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/migractions.py	Thu Oct 15 20:29:21 2009 +0200
@@ -306,7 +306,7 @@
             return
         newrschema = self.fs_schema[ertype]
         teid = self.repo.schema[ertype].eid
-        if 'update' in newrschema.ACTIONS or newrschema.is_final():
+        if 'update' in newrschema.ACTIONS or newrschema.final:
             # entity type
             exprtype = u'ERQLExpression'
         else:
@@ -643,7 +643,7 @@
             # XXX (syt) plz explain: if we're adding an entity type, it should
             # not be there...
             eschema = instschema[etype]
-            if eschema.is_final():
+            if eschema.final:
                 instschema.del_entity_type(etype)
         else:
             eschema = self.fs_schema.eschema(etype)
@@ -686,7 +686,7 @@
                         if role == 'subject':
                             subjschema = spschema
                             objschema = tschema
-                            if rschema.final and instspschema.has_subject_relation(rschema):
+                            if rschema.final and rschema in instspschema.subjrels:
                                 # attribute already set, has_rdef would check if
                                 # it's of the same type, we don't want this so
                                 # simply skip here
@@ -852,7 +852,7 @@
         """unregister an existing relation definition"""
         rschema = self.repo.schema.rschema(rtype)
         # unregister the definition from CWAttribute or CWRelation
-        if rschema.is_final():
+        if rschema.final:
             etype = 'CWAttribute'
         else:
             etype = 'CWRelation'
--- a/server/msplanner.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/msplanner.py	Thu Oct 15 20:29:21 2009 +0200
@@ -334,7 +334,7 @@
             for i, sol in enumerate(self._solutions):
                 vartype = sol[varname]
                 # skip final variable
-                if eschema(vartype).is_final():
+                if eschema(vartype).final:
                     break
                 for source in repo.sources:
                     if source.support_entity(vartype):
@@ -381,7 +381,7 @@
             # process non final relations only
             # note: don't try to get schema for 'is' relation (not available
             # during bootstrap)
-            if not rel.is_types_restriction() and not rschema(rel.r_type).is_final():
+            if not rel.is_types_restriction() and not rschema(rel.r_type).final:
                 # nothing to do if relation is not supported by multiple sources
                 # or if some source has it listed in its cross_relations
                 # attribute
@@ -457,7 +457,7 @@
             repo = self._repo
             rschema = self._schema.rschema
             for rel in self.plan.rqlst.main_relations:
-                if not rschema(rel.r_type).is_final():
+                if not rschema(rel.r_type).final:
                     # nothing to do if relation is not supported by multiple sources
                     if len(repo.rel_type_sources(rel.r_type)) < 2:
                         continue
@@ -730,7 +730,7 @@
                             # its lhs/rhs variable isn't in "terms", and the
                             # other end *is* in "terms", mark it have to be
                             # selected
-                            if source.uri != 'system' and not rschema(rel.r_type).is_final():
+                            if source.uri != 'system' and not rschema(rel.r_type).final:
                                 lhs, rhs = rel.get_variable_parts()
                                 try:
                                     lhsvar = lhs.variable
@@ -1003,7 +1003,7 @@
         for varname, mapping in step.outputmap.iteritems():
             if varname in inputmap and \
                    not (mapping == inputmap[varname] or
-                        self._schema.eschema(solutions[0][varname]).is_final()):
+                        self._schema.eschema(solutions[0][varname]).final):
                 self._conflicts.append((varname, inputmap[varname]))
         inputmap.update(step.outputmap)
         self.plan.add_step(step)
@@ -1359,7 +1359,7 @@
                 return False
         if not self.final and not relation in self.terms:
             rschema = self.schema.rschema(relation.r_type)
-            if not rschema.is_final():
+            if not rschema.final:
                 for term in relation.get_nodes((VariableRef, Constant)):
                     term = getattr(term, 'variable', term)
                     termsources = sorted(set(x[0] for x in self.ppi._term_sources(term)))
@@ -1370,7 +1370,7 @@
     def visit_relation(self, node, newroot, terms):
         if not node.is_types_restriction():
             if node in self.skip and self.solindices.issubset(self.skip[node]):
-                if not self.schema.rschema(node.r_type).is_final():
+                if not self.schema.rschema(node.r_type).final:
                     # can't really skip the relation if one variable is selected and only
                     # referenced by this relation
                     for vref in node.iget_nodes(VariableRef):
@@ -1403,7 +1403,7 @@
                 vref.unregister_reference()
             raise
         ored = node.ored()
-        if rschema.is_final() or rschema.inlined:
+        if rschema.final or rschema.inlined:
             vrefs = node.children[1].get_nodes(VariableRef)
             if not vrefs:
                 if not ored:
--- a/server/querier.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/querier.py	Thu Oct 15 20:29:21 2009 +0200
@@ -389,7 +389,7 @@
                     # add constant values to entity def
                     value = rhs.eval(self.args)
                     eschema = edef.e_schema
-                    attrtype = eschema.subject_relation(rtype).objects(eschema)[0]
+                    attrtype = eschema.subjrels[rtype].objects(eschema)[0]
                     if attrtype == 'Password' and isinstance(value, unicode):
                         value = value.encode('UTF8')
                     edef[rtype] = value
--- a/server/repository.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/repository.py	Thu Oct 15 20:29:21 2009 +0200
@@ -1022,8 +1022,8 @@
         # XXX use entity.keys here since edited_attributes is not updated for
         # inline relations
         for attr in entity.keys():
-            rschema = eschema.subject_relation(attr)
-            if not rschema.is_final(): # inlined relation
+            rschema = eschema.subjrels[attr]
+            if not rschema.final: # inlined relation
                 relations.append((attr, entity[attr]))
         entity.set_defaults()
         entity.check(creation=True)
@@ -1041,7 +1041,7 @@
             rtype = str(rschema)
             if rtype in VIRTUAL_RTYPES:
                 continue
-            if rschema.is_final():
+            if rschema.final:
                 entity.setdefault(rtype, None)
             else:
                 entity.set_related_cache(rtype, 'subject', session.empty_rset())
@@ -1081,8 +1081,8 @@
         for attr in edited_attributes:
             if attr == 'eid':
                 continue
-            rschema = eschema.subject_relation(attr)
-            if rschema.is_final():
+            rschema = eschema.subjrels[attr]
+            if rschema.final:
                 if eschema.rproperty(attr, 'fulltextindexed'):
                     need_fti_update = True
                 only_inline_rels = False
--- a/server/rqlannotation.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/rqlannotation.py	Thu Oct 15 20:29:21 2009 +0200
@@ -201,7 +201,7 @@
         for rel in select.iget_nodes(Relation):
             if rel.neged(strict=True) and not rel.is_types_restriction():
                 rschema = getrschema(rel.r_type)
-                if not rschema.is_final():
+                if not rschema.final:
                     # if one of the relation's variable is ambiguous but not
                     # invariant, an intersection will be necessary
                     for vref in rel.get_nodes(VariableRef):
@@ -221,7 +221,7 @@
     def __init__(self, schema):
         self.schema = schema
         self.nfdomain = frozenset(eschema.type for eschema in schema.entities()
-                                  if not eschema.is_final())
+                                  if not eschema.final)
 
     def annotate(self, rqlst):
         """add information to the rql syntax tree to help sources to do their
@@ -288,7 +288,7 @@
         # set domains for each variable
         for varname, var in rqlst.defined_vars.iteritems():
             if var.stinfo['uidrels'] or \
-                   self.eschema(rqlst.solutions[0][varname]).is_final():
+                   self.eschema(rqlst.solutions[0][varname]).final:
                 ptypes = var.stinfo['possibletypes']
             else:
                 ptypes = set(self.nfdomain)
@@ -304,7 +304,7 @@
             lhs, rhs = rel.get_variable_parts()
             if isinstance(lhs, VariableRef) or isinstance(rhs, VariableRef):
                 rschema = self.rschema(rel.r_type)
-                if rschema.inlined or rschema.is_final():
+                if rschema.inlined or rschema.final:
                     self.not_invariants.add(lhs.variable)
                 self.set_rel_constraint(lhs, rel, rschema.subjects)
                 self.set_rel_constraint(rhs, rel, rschema.objects)
--- a/server/schemahooks.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/schemahooks.py	Thu Oct 15 20:29:21 2009 +0200
@@ -206,7 +206,7 @@
     def precommit_event(self):
         session = self.session
         rschema = self.rschema
-        if rschema.is_final() or not 'inlined' in self.values:
+        if rschema.final or not 'inlined' in self.values:
             return # nothing to do
         inlined = self.values['inlined']
         entity = self.entity
@@ -444,7 +444,7 @@
                 sysource.create_index(self.session, table, column)
             else:
                 sysource.drop_index(self.session, table, column)
-        if 'cardinality' in self.values and self.rschema.is_final():
+        if 'cardinality' in self.values and self.rschema.final:
             adbh = self.session.pool.source('system').dbhelper
             if not adbh.alter_column_support:
                 # not supported (and NOT NULL not set by yams in that case, so
@@ -818,7 +818,7 @@
     pendings = session.transaction_data.get('pendingeids', ())
     pendingrdefs = session.transaction_data.setdefault('pendingrdefs', set())
     # first delete existing relation if necessary
-    if rschema.is_final():
+    if rschema.final:
         rdeftype = 'CWAttribute'
         pendingrdefs.add((subjschema, rschema))
     else:
@@ -835,7 +835,7 @@
     # relations, but only if it's the last instance for this relation type
     # for other relations
 
-    if (rschema.is_final() or rschema.inlined):
+    if (rschema.final or rschema.inlined):
         rset = execute('Any COUNT(X) WHERE X is %s, X relation_type R, '
                        'R eid %%(x)s, X from_entity E, E name %%(name)s'
                        % rdeftype, {'x': rteid, 'name': str(subjschema)})
--- a/server/schemaserial.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/schemaserial.py	Thu Oct 15 20:29:21 2009 +0200
@@ -64,7 +64,7 @@
     entity type tables and columns
     """
     for etype in schema.entities():
-        if etype.is_final():
+        if etype.final:
             continue
         try:
             sql = 'ALTER TABLE %s RENAME TO cw_%s' % (
@@ -76,7 +76,7 @@
         for rschema in etype.subject_relations():
             if rschema == 'has_text':
                 continue
-            if rschema.is_final() or rschema.inlined:
+            if rschema.final or rschema.inlined:
                 sql = 'ALTER TABLE cw_%s RENAME %s TO cw_%s' % (
                     etype, rschema, rschema)
                 print sql
@@ -326,7 +326,7 @@
         raise Exception("can't decode %s [was %s]" % (erschema.description, e))
     return {
         'name': type_,
-        'final': erschema.is_final(),
+        'final': erschema.final,
         'description': desc,
         }
 
@@ -340,7 +340,7 @@
 
 def rschema_relations_values(rschema):
     values = _ervalues(rschema)
-    values['final'] = rschema.is_final()
+    values['final'] = rschema.final
     values['symetric'] = rschema.symetric
     values['inlined'] = rschema.inlined
     if HAS_FULLTEXT_CONTAINER:
@@ -402,7 +402,7 @@
         # don't serialize infered relations
         if _props.get('infered'):
             continue
-        gen = genmap[rschema.is_final()]
+        gen = genmap[rschema.final]
         for rql, values in gen(rschema, subjtype, objtype, _props):
             yield rql, values
 
--- a/server/securityhooks.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/securityhooks.py	Thu Oct 15 20:29:21 2009 +0200
@@ -25,8 +25,8 @@
     for attr in editedattrs:
         if attr in defaults:
             continue
-        rschema = eschema.subject_relation(attr)
-        if rschema.is_final(): # non final relation are checked by other hooks
+        rschema = eschema.subjrels[attr]
+        if rschema.final: # non final relation are checked by other hooks
             # add/delete should be equivalent (XXX: unify them into 'update' ?)
             rschema.check_perm(session, 'add', eid)
 
--- a/server/sources/__init__.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/sources/__init__.py	Thu Oct 15 20:29:21 2009 +0200
@@ -168,7 +168,7 @@
             wsupport = self.support_relations[rtype]
         except KeyError:
             rschema = self.schema.rschema(rtype)
-            if not rschema.is_final() or rschema == 'has_text':
+            if not rschema.final or rschema == 'has_text':
                 return False
             for etype in rschema.subjects():
                 try:
@@ -225,7 +225,7 @@
         # delete relations referencing one of those eids
         eidcolum = SQL_PREFIX + 'eid'
         for rschema in self.schema.relations():
-            if rschema.is_final() or rschema.type in VIRTUAL_RTYPES:
+            if rschema.final or rschema.type in VIRTUAL_RTYPES:
                 continue
             if rschema.inlined:
                 column = SQL_PREFIX + rschema.type
--- a/server/sources/ldapuser.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/sources/ldapuser.py	Thu Oct 15 20:29:21 2009 +0200
@@ -631,7 +631,7 @@
             return ''
         lhs, rhs = relation.get_parts()
         # attribute relation
-        if self.source.schema.rschema(rtype).is_final():
+        if self.source.schema.rschema(rtype).final:
             # dunno what to do here, don't pretend anything else
             if lhs.name != self._mainvarname:
                 if lhs.name in self.mainvars:
--- a/server/sources/native.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/sources/native.py	Thu Oct 15 20:29:21 2009 +0200
@@ -71,7 +71,7 @@
         try:
             sql.append('%s %s' % (name, typemap[ttype]))
         except KeyError:
-            # assert not schema(ttype).is_final()
+            # assert not schema(ttype).final
             sql.append('%s %s' % (name, typemap['Int']))
     return ','.join(sql), varmap
 
--- a/server/sources/pyrorql.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/sources/pyrorql.py	Thu Oct 15 20:29:21 2009 +0200
@@ -303,7 +303,7 @@
             needtranslation = []
             rows = rset.rows
             for i, etype in enumerate(descr[0]):
-                if (etype is None or not self.schema.eschema(etype).is_final()
+                if (etype is None or not self.schema.eschema(etype).final
                     or uidtype(union, i, etype, args)):
                     needtranslation.append(i)
             if needtranslation:
@@ -487,7 +487,7 @@
             raise
         if node.optional in ('left', 'both'):
             lhs += '?'
-        if node.r_type == 'eid' or not self.source.schema.rschema(node.r_type).is_final():
+        if node.r_type == 'eid' or not self.source.schema.rschema(node.r_type).final:
             self.need_translation = True
             self.current_operator = node.operator()
             if isinstance(node.children[0], Constant):
--- a/server/sources/rql2sql.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/sources/rql2sql.py	Thu Oct 15 20:29:21 2009 +0200
@@ -60,7 +60,7 @@
                 newivar = _new_var(newselect, vref.name)
                 newselect.selection.append(VariableRef(newivar))
                 _fill_to_wrap_rel(vref.variable, newselect, towrap, schema)
-        elif rschema.is_final():
+        elif rschema.final:
             towrap.add( (var, rel) )
 
 def rewrite_unstable_outer_join(select, solutions, unstable, schema):
@@ -616,7 +616,7 @@
             return ''
         lhs, rhs = relation.get_parts()
         rschema = self.schema.rschema(rtype)
-        if rschema.is_final():
+        if rschema.final:
             if rtype == 'eid' and lhs.variable._q_invariant and \
                    lhs.variable.stinfo['constnode']:
                 # special case where this restriction is already generated by
@@ -1096,7 +1096,7 @@
         except KeyError:
             etype = self._state.solution[var.name]
             # XXX this check should be moved in rql.stcheck
-            if self.schema.eschema(etype).is_final():
+            if self.schema.eschema(etype).final:
                 raise BadRQLQuery(var.stmt.root)
             table = var.name
             sql = '%s.%seid' % (table, SQL_PREFIX)
@@ -1211,7 +1211,7 @@
         """return the table alias used by the given relation"""
         if relation in self._state.done:
             return relation._q_sqltable
-        assert not self.schema.rschema(relation.r_type).is_final(), relation.r_type
+        assert not self.schema.rschema(relation.r_type).final, relation.r_type
         rid = 'rel_%s%s' % (relation.r_type, self._state.count)
         # relation's table is belonging to the root scope if it is the principal
         # table of one of it's variable and if that variable belong's to parent
--- a/server/sqlutils.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/sqlutils.py	Thu Oct 15 20:29:21 2009 +0200
@@ -229,8 +229,8 @@
         attrs = {}
         eschema = entity.e_schema
         for attr, value in entity.items():
-            rschema = eschema.subject_relation(attr)
-            if rschema.is_final():
+            rschema = eschema.subjrels[attr]
+            if rschema.final:
                 atype = str(entity.e_schema.destination(attr))
                 if atype == 'Boolean':
                     value = self.dbhelper.boolean_value(value)
--- a/server/ssplanner.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/ssplanner.py	Thu Oct 15 20:29:21 2009 +0200
@@ -75,8 +75,8 @@
                 if reverse:
                     rdefs[i] = rtype, RelationsStep.REVERSE_RELATION
                 else:
-                    rschema = eschema.subject_relation(rtype)
-                    if rschema.is_final() or rschema.inlined:
+                    rschema = eschema.subjrels[rtype]
+                    if rschema.final or rschema.inlined:
                         rdefs[i] = rtype, RelationsStep.FINAL
                     else:
                         rdefs[i] = rtype, RelationsStep.RELATION
@@ -147,7 +147,7 @@
                 selected_index[rhs.as_string('utf-8')] = index
                 index += 1
             rschema = getrschema(relation.r_type)
-            if rschema.is_final() or rschema.inlined:
+            if rschema.final or rschema.inlined:
                 attrrelations.append(relation)
             else:
                 relations.append(relation)
--- a/server/test/unittest_migractions.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/test/unittest_migractions.py	Thu Oct 15 20:29:21 2009 +0200
@@ -147,7 +147,7 @@
         self.assertEquals([str(rs) for rs in self.schema['Folder2'].object_relations()],
                           ['filed_under2', 'identity'])
         self.assertEquals(sorted(str(e) for e in self.schema['filed_under2'].subjects()),
-                          sorted(str(e) for e in self.schema.entities() if not e.is_final()))
+                          sorted(str(e) for e in self.schema.entities() if not e.final))
         self.assertEquals(self.schema['filed_under2'].objects(), ('Folder2',))
         eschema = self.schema.eschema('Folder2')
         for cstr in eschema.constraints('name'):
@@ -176,7 +176,7 @@
         self.schema.rebuild_infered_relations()
         self.failUnless('filed_under2' in self.schema)
         self.assertEquals(sorted(str(e) for e in self.schema['filed_under2'].subjects()),
-                          sorted(str(e) for e in self.schema.entities() if not e.is_final()))
+                          sorted(str(e) for e in self.schema.entities() if not e.final))
         self.assertEquals(self.schema['filed_under2'].objects(), ('Folder2',))
         self.mh.cmd_drop_relation_type('filed_under2')
         self.failIf('filed_under2' in self.schema)
--- a/server/test/unittest_msplanner.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/test/unittest_msplanner.py	Thu Oct 15 20:29:21 2009 +0200
@@ -226,7 +226,7 @@
                     self.ldap: {'Y': s[0], 'X': s[0]}}, True)
 
     def test_complex_aggregat(self):
-        solindexes = set(range(len([e for e in self.schema.entities() if not e.is_final()])))
+        solindexes = set(range(len([e for e in self.schema.entities() if not e.final])))
         self._test('Any MAX(X)',
                    {self.system: {'X': solindexes}}, False)
 
--- a/server/test/unittest_rql2sql.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/server/test/unittest_rql2sql.py	Thu Oct 15 20:29:21 2009 +0200
@@ -1081,7 +1081,7 @@
         self.assertEquals(var_sols('FROM_ENTITYOBJECT'), set(('CWAttribute', 'CWRelation')))
         self.assertEquals(var_sols('FROM_ENTITYOBJECT'), delete.defined_vars['FROM_ENTITYOBJECT'].stinfo['possibletypes'])
         self.assertEquals(var_sols('ISOBJECT'),
-                          set(x.type for x in self.schema.entities() if not x.is_final()))
+                          set(x.type for x in self.schema.entities() if not x.final))
         self.assertEquals(var_sols('ISOBJECT'), delete.defined_vars['ISOBJECT'].stinfo['possibletypes'])
 
 
--- a/sobjects/notification.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/sobjects/notification.py	Thu Oct 15 20:29:21 2009 +0200
@@ -272,7 +272,7 @@
         for attr, oldvalue, newvalue in sorted(changes):
             # check current user has permission to see the attribute
             rschema = self.vreg.schema[attr]
-            if rschema.is_final():
+            if rschema.final:
                 if not rschema.has_perm(self.req, 'read', eid=self.rset[0][0]):
                     continue
             # XXX suppose it's a subject relation...
--- a/test/unittest_entity.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/test/unittest_entity.py	Thu Oct 15 20:29:21 2009 +0200
@@ -127,10 +127,10 @@
         Note = self.vreg['etypes'].etype_class('Note')
         peschema = Personne.e_schema
         seschema = Societe.e_schema
-        peschema.subject_relation('travaille').set_rproperty(peschema, seschema, 'cardinality', '1*')
-        peschema.subject_relation('connait').set_rproperty(peschema, peschema, 'cardinality', '11')
-        peschema.subject_relation('evaluee').set_rproperty(peschema, Note.e_schema, 'cardinality', '1*')
-        seschema.subject_relation('evaluee').set_rproperty(seschema, Note.e_schema, 'cardinality', '1*')
+        peschema.subjrels['travaille'].set_rproperty(peschema, seschema, 'cardinality', '1*')
+        peschema.subjrels['connait'].set_rproperty(peschema, peschema, 'cardinality', '11')
+        peschema.subjrels['evaluee'].set_rproperty(peschema, Note.e_schema, 'cardinality', '1*')
+        seschema.subjrels['evaluee'].set_rproperty(seschema, Note.e_schema, 'cardinality', '1*')
         # testing basic fetch_attrs attribute
         self.assertEquals(Personne.fetch_rql(user),
                           'Any X,AA,AB,AC ORDERBY AA ASC '
@@ -165,13 +165,13 @@
             self.assertEquals(Personne.fetch_rql(user), 'Any X,AA,AB ORDERBY AA ASC '
                               'WHERE X is Personne, X nom AA, X connait AB?')
             # testing optional relation
-            peschema.subject_relation('travaille').set_rproperty(peschema, seschema, 'cardinality', '?*')
+            peschema.subjrels['travaille'].set_rproperty(peschema, seschema, 'cardinality', '?*')
             Personne.fetch_attrs = ('nom', 'prenom', 'travaille')
             Societe.fetch_attrs = ('nom',)
             self.assertEquals(Personne.fetch_rql(user),
                               'Any X,AA,AB,AC,AD ORDERBY AA ASC WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD')
             # testing relation with cardinality > 1
-            peschema.subject_relation('travaille').set_rproperty(peschema, seschema, 'cardinality', '**')
+            peschema.subjrels['travaille'].set_rproperty(peschema, seschema, 'cardinality', '**')
             self.assertEquals(Personne.fetch_rql(user),
                               'Any X,AA,AB ORDERBY AA ASC WHERE X is Personne, X nom AA, X prenom AB')
             # XXX test unauthorized attribute
--- a/test/unittest_schema.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/test/unittest_schema.py	Thu Oct 15 20:29:21 2009 +0200
@@ -88,7 +88,7 @@
         self.assertEqual(esociete.type, 'Societe')
         self.assertEqual(schema.has_relation('TEST'), 0)
         self.assertEqual(schema.has_relation('test'), 1)
-        self.assertEqual(eperson.subject_relation('test').type, 'test')
+        self.assertEqual(eperson.subjrels['test'].type, 'test')
         self.assertEqual(schema.has_relation('Concerne'), 0)
         self.assertEqual(schema.has_relation('concerne'), 1)
         self.assertEqual(schema.rschema('concerne').type, 'concerne')
--- a/view.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/view.py	Thu Oct 15 20:29:21 2009 +0200
@@ -202,7 +202,7 @@
         coltypes = rset.column_types(0)
         if len(coltypes) == 1:
             etype = iter(coltypes).next()
-            if not self.schema.eschema(etype).is_final():
+            if not self.schema.eschema(etype).final:
                 if len(rset) == 1:
                     entity = rset.get_entity(0, 0)
                     return entity.absolute_url(vid=self.id)
--- a/web/facet.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/facet.py	Thu Oct 15 20:29:21 2009 +0200
@@ -92,7 +92,7 @@
             # constant restriction
             # XXX: X title LOWER(T) if it makes sense?
             return None
-        if rschema.is_final():
+        if rschema.final:
             if len(ovar.stinfo['relations']) == 1:
                 # attribute selection
                 return ovar
--- a/web/formfields.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/formfields.py	Thu Oct 15 20:29:21 2009 +0200
@@ -524,7 +524,7 @@
     if role == 'subject':
         targetschema = rschema.objects(eschema)[0]
         help = rschema.rproperty(eschema, targetschema, 'description')
-        if rschema.is_final():
+        if rschema.final:
             if rschema.rproperty(eschema, targetschema, 'internationalizable'):
                 kwargs.setdefault('internationalizable', True)
             def get_default(form, es=eschema, rs=rschema):
@@ -540,7 +540,7 @@
     else:
         kwargs.setdefault('label', (eschema.type, rschema.type))
     kwargs.setdefault('help', help)
-    if rschema.is_final():
+    if rschema.final:
         if skip_meta_attr and rschema in eschema.meta_attributes():
             return None
         fieldclass = FIELDS[targetschema]
--- a/web/formwidgets.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/formwidgets.py	Thu Oct 15 20:29:21 2009 +0200
@@ -430,7 +430,7 @@
         # XXX entity form specific
         entity = form.edited_entity
         attrs['cubicweb:etype_to'] = entity.e_schema
-        etype_from = entity.e_schema.subject_relation(field.name).objects(entity.e_schema)[0]
+        etype_from = entity.e_schema.subjrels[field.name].objects(entity.e_schema)[0]
         attrs['cubicweb:etype_from'] = etype_from
         return name, values, attrs
 
--- a/web/uicfg.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/uicfg.py	Thu Oct 15 20:29:21 2009 +0200
@@ -85,7 +85,7 @@
     if rtag.get(sschema, rschema, oschema, role) is None:
         card = card_from_role(rschema.rproperty(sschema, oschema, 'cardinality'), role)
         composed = rschema.rproperty(sschema, oschema, 'composite') == neg_role(role)
-        if rschema.is_final():
+        if rschema.final:
             if rschema.meta or sschema.is_metadata(rschema) \
                     or oschema.type in ('Password', 'Bytes'):
                 section = 'hidden'
@@ -185,7 +185,7 @@
                 composed = rschema.rproperty(sschema, oschema, 'composite') == 'subject'
             if card in '1+':
                 section = 'primary'
-            elif rschema.is_final():
+            elif rschema.final:
                 section = 'secondary'
             else:
                 section = 'generic'
--- a/web/views/__init__.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/__init__.py	Thu Oct 15 20:29:21 2009 +0200
@@ -39,7 +39,7 @@
         if not isinstance(selected[i+1], nodes.VariableRef):
             return True
         # if this is not a final entity
-        if not schema.eschema(etype).is_final():
+        if not schema.eschema(etype).final:
             return True
         # if this is a final entity not linked to the main variable
         var = selected[i+1].variable
@@ -74,7 +74,7 @@
     if nb_rows == 0 :
         return 'noresult'
     # entity result set
-    if not schema.eschema(rset.description[0][0]).is_final():
+    if not schema.eschema(rset.description[0][0]).final:
         if need_table_view(rset, schema):
             return 'table'
         if nb_rows == 1:
--- a/web/views/actions.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/actions.py	Thu Oct 15 20:29:21 2009 +0200
@@ -36,7 +36,7 @@
             return 1
         for rschema, targetschemas, role in AutomaticEntityForm.erelations_by_category(
             entity, ('primary', 'secondary'), 'add', strict=True):
-            if not rschema.is_final():
+            if not rschema.final:
                 return 1
         return 0
 
@@ -62,7 +62,7 @@
         if len(select.defined_vars) == 1 and len(select.solutions) == 1:
             rset._searched_etype = select.solutions[0].itervalues().next()
             eschema = cls.schema.eschema(rset._searched_etype)
-            if not (eschema.is_final() or eschema.is_subobject(strict=True)) \
+            if not (eschema.final or eschema.is_subobject(strict=True)) \
                    and eschema.has_perm(req, 'add'):
                 return 1
     return 0
@@ -266,7 +266,7 @@
         for role, rschemas in (('subject', eschema.subject_relations()),
                                ('object', eschema.object_relations())):
             for rschema in rschemas:
-                if rschema.is_final():
+                if rschema.final:
                     continue
                 # check the relation can be added as well
                 # XXX consider autoform_permissions_overrides?
--- a/web/views/autoform.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/autoform.py	Thu Oct 15 20:29:21 2009 +0200
@@ -86,7 +86,7 @@
                 if eid is None and '%s_on_new' % permission in permsoverrides.etype_get(eschema, rschema, role):
                     yield (rschema, targetschemas, role)
                     continue
-                if rschema.is_final():
+                if rschema.final:
                     if not rschema.has_perm(entity.req, permission, eid):
                         continue
                 elif role == 'subject':
@@ -126,7 +126,7 @@
         result = []
         for rschema, ttypes, role in cls.erelations_by_category(
             entity, categories, permission, strict=strict):
-            if rschema.is_final():
+            if rschema.final:
                 continue
             result.append((rschema.display_name(entity.req, role), rschema, role))
         return sorted(result)
--- a/web/views/csvexport.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/csvexport.py	Thu Oct 15 20:29:21 2009 +0200
@@ -45,7 +45,7 @@
             csvrow = []
             for colindex, val in enumerate(row):
                 etype = descr[rowindex][colindex]
-                if val is not None and not eschema(etype).is_final():
+                if val is not None and not eschema(etype).final:
                     # csvrow.append(val) # val is eid in that case
                     content = self.view('textincontext', rset,
                                         row=rowindex, col=colindex)
--- a/web/views/editcontroller.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/editcontroller.py	Thu Oct 15 20:29:21 2009 +0200
@@ -95,7 +95,7 @@
         # needs some information provided by those inlined relation. Moreover
         # this will generate less write queries.
         for rschema in entity.e_schema.subject_relations():
-            if rschema.is_final():
+            if rschema.final:
                 self.handle_attribute(entity, rschema, formparams)
             elif rschema.inlined:
                 self.handle_inlined_relation(rschema, formparams, entity)
@@ -129,11 +129,11 @@
             formparams[var] = eid
             execute(rql, formparams)
         for rschema in entity.e_schema.subject_relations():
-            if rschema.is_final() or rschema.inlined:
+            if rschema.final or rschema.inlined:
                 continue
             self.handle_relation(rschema, formparams, 'subject', entity)
         for rschema in entity.e_schema.object_relations():
-            if rschema.is_final():
+            if rschema.final:
                 continue
             self.handle_relation(rschema, formparams, 'object', entity)
         if edited:
@@ -228,7 +228,7 @@
                     #    self.relations.append('X %s_format %%(%s)s'
                     #                          % (attr, key))
                     # XXX suppose a File compatible schema
-                    if entity.e_schema.has_subject_relation('name') \
+                    if 'name' in entity.e_schema.subjrels \
                            and not formparams.get('name'):
                         formparams['name'] = value[0]
                         self.relations.append('X name %(name)s')
--- a/web/views/editforms.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/editforms.py	Thu Oct 15 20:29:21 2009 +0200
@@ -169,7 +169,7 @@
         rschema = entity.schema.rschema(rtype)
         lzone = self._build_landing_zone(landing_zone)
         # compute value, checking perms, build form
-        if rschema.is_final():
+        if rschema.final:
             onsubmit = ("return inlineValidateAttributeForm('%(rtype)s', '%(eid)s', '%(divid)s', "
                         "%(reload)s, '%(default)s');")
             form = self._build_form(
@@ -400,7 +400,7 @@
                                  self.copying.eid)
         for rschema, _, role in form.relations_by_category(form.attrcategories,
                                                            'add'):
-            if not rschema.is_final():
+            if not rschema.final:
                 # ensure relation cache is filed
                 rset = self.copying.related(rschema, role)
                 self.newentity.set_related_cache(rschema, role, rset)
--- a/web/views/forms.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/forms.py	Thu Oct 15 20:29:21 2009 +0200
@@ -346,8 +346,8 @@
             for field in field.actual_fields(self):
                 fieldname = field.name
                 if fieldname != 'eid' and (
-                    (eschema.has_subject_relation(fieldname) or
-                     eschema.has_object_relation(fieldname))):
+                    (fieldname in eschema.subjrels or
+                     fieldname in eschema.objrels)):
                     field.eidparam = True
                     self.fields.append(HiddenInitialValueField(field))
         return super(EntityFieldsForm, self).build_context(values)
@@ -375,7 +375,7 @@
             return INTERNAL_FIELD_VALUE
         if attr == '__type':
             return entity.id
-        if self.schema.rschema(attr).is_final():
+        if self.schema.rschema(attr).final:
             attrtype = entity.e_schema.destination(attr)
             if attrtype == 'Password':
                 return entity.has_eid() and INTERNAL_FIELD_VALUE or ''
@@ -457,7 +457,7 @@
         if isinstance(rtype, basestring):
             rtype = entity.schema.rschema(rtype)
         done = None
-        assert not rtype.is_final(), rtype
+        assert not rtype.final, rtype
         if entity.has_eid():
             done = set(e.eid for e in getattr(entity, str(rtype)))
         result = []
--- a/web/views/magicsearch.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/magicsearch.py	Thu Oct 15 20:29:21 2009 +0200
@@ -278,7 +278,7 @@
         eschema = self.schema.eschema(etype)
         rtype = self._get_attribute_name(word2, eschema)
         # expand shortcut if rtype is a non final relation
-        if not self.schema.rschema(rtype).is_final():
+        if not self.schema.rschema(rtype).final:
             return self._expand_shortcut(etype, rtype, word3)
         if '%' in word3:
             searchop = 'LIKE '
--- a/web/views/navigation.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/navigation.py	Thu Oct 15 20:29:21 2009 +0200
@@ -64,7 +64,7 @@
             def index_display(row):
                 entity = rset.get_entity(row, col)
                 return entity.printable_value(attrname, format='text/plain')
-        elif self.schema.eschema(rset.description[0][col]).is_final():
+        elif self.schema.eschema(rset.description[0][col]).final:
             def index_display(row):
                 return unicode(rset[row][col])
         else:
@@ -99,7 +99,7 @@
                 attrname = rel.r_type
                 if attrname == 'is':
                     continue
-                if not rschema(attrname).is_final():
+                if not rschema(attrname).final:
                     col = var.selected_index()
                     attrname = None
                 if col is None:
--- a/web/views/owl.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/owl.py	Thu Oct 15 20:29:21 2009 +0200
@@ -80,7 +80,7 @@
         """get a layout for a whole schema"""
         self.skiptypes = skiptypes
         entities = sorted(eschema for eschema in self.schema.entities()
-                          if not eschema.is_final() or eschema in skiptypes)
+                          if not eschema.final or eschema in skiptypes)
         self.w(u'<!-- classes definition -->')
         for eschema in entities:
             self.visit_entityschema(eschema)
--- a/web/views/plots.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/plots.py	Thu Oct 15 20:29:21 2009 +0200
@@ -177,7 +177,7 @@
 
         def _guess_vid(self, row):
             etype = self.rset.description[row][0]
-            if self.schema.eschema(etype).is_final():
+            if self.schema.eschema(etype).final:
                 return 'final'
             return 'textincontext'
 
--- a/web/views/primary.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/primary.py	Thu Oct 15 20:29:21 2009 +0200
@@ -104,7 +104,7 @@
     def render_entity_attributes(self, entity, siderelations=None):
         for rschema, tschemas, role, dispctrl in self._section_def(entity, 'attributes'):
             vid = dispctrl.get('vid', 'reledit')
-            if rschema.is_final() or vid == 'reledit':
+            if rschema.final or vid == 'reledit':
                 value = entity.view(vid, rtype=rschema.type, role=role)
             else:
                 rset = self._relation_rset(entity, rschema, role, dispctrl)
@@ -191,7 +191,7 @@
         self.w(u'</div>')
 
     def _render_attribute(self, rschema, value, role='subject'):
-        if rschema.is_final():
+        if rschema.final:
             show_label = self.show_attr_label
         else:
             show_label = self.show_rel_label
--- a/web/views/schema.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/schema.py	Thu Oct 15 20:29:21 2009 +0200
@@ -88,11 +88,11 @@
         schema = self.schema
         # compute entities
         entities = sorted(eschema for eschema in schema.entities()
-                          if not (eschema.is_final() or eschema in skiptypes))
+                          if not (eschema.final or eschema in skiptypes))
         # compute relations
         if display_relations:
             relations = sorted(rschema for rschema in schema.relations()
-                               if not (rschema.is_final()
+                               if not (rschema.final
                                        or rschema in skiptypes
                                        or rschema in META_RTYPES))
         else:
@@ -336,7 +336,7 @@
         viewer = SchemaViewer(self.req)
         layout = viewer.visit_relationschema(rschema)
         self.w(uilib.ureport_as_html(layout))
-        if not rschema.is_final():
+        if not rschema.final:
             msg = self.req._('graphical schema for %s') % entity.name
             self.w(tags.img(src=entity.absolute_url(vid='schemagraph'),
                             alt=msg))
--- a/web/views/sparql.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/sparql.py	Thu Oct 15 20:29:21 2009 +0200
@@ -102,7 +102,7 @@
 
     def cell_binding(self, row, col, varname):
         celltype = self.rset.description[row][col]
-        if self.schema.eschema(celltype).is_final():
+        if self.schema.eschema(celltype).final:
             cellcontent = self.view('cell', self.rset, row=row, col=col)
             return E.binding(E.literal(cellcontent,
                                        datatype=xmlschema(celltype)),
--- a/web/views/startup.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/startup.py	Thu Oct 15 20:29:21 2009 +0200
@@ -140,7 +140,7 @@
         """
         req = self.req
         for eschema in eschemas:
-            if eschema.is_final() or (not eschema.has_perm(req, 'read') and
+            if eschema.final or (not eschema.has_perm(req, 'read') and
                                       not eschema.has_local_role('read')):
                 continue
             etype = eschema.type
--- a/web/views/tableview.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/tableview.py	Thu Oct 15 20:29:21 2009 +0200
@@ -80,7 +80,7 @@
         eschema = self.vreg.schema.eschema
         for i, etype in enumerate(self.rset.description[0]):
             try:
-                if not eschema(etype).is_final():
+                if not eschema(etype).final:
                     return i
             except KeyError: # XXX possible?
                 continue
@@ -208,7 +208,7 @@
             # join, use the default non final subvid)
             if cellvids and colindex in cellvids:
                 column.append_renderer(cellvids[colindex], colindex)
-            elif coltype is not None and self.schema.eschema(coltype).is_final():
+            elif coltype is not None and self.schema.eschema(coltype).final:
                 column.append_renderer(self.finalview, colindex)
             else:
                 column.append_renderer(subvid or 'incontext', colindex)
@@ -237,7 +237,7 @@
         if val is None:
             return u''
         etype = self.rset.description[row][col]
-        if self.schema.eschema(etype).is_final():
+        if self.schema.eschema(etype).final:
             entity, rtype = self.rset.related_entity(row, col)
             if entity is None:
                 return val # remove_html_tags() ?
@@ -263,7 +263,7 @@
         :param cellvid: cell view (defaults to 'outofcontext')
         """
         etype, val = self.rset.description[row][col], self.rset[row][col]
-        if val is not None and not self.schema.eschema(etype).is_final():
+        if val is not None and not self.schema.eschema(etype).final:
             e = self.rset.get_entity(row, col)
             e.view(cellvid or 'outofcontext', w=self.w)
         elif val is None:
--- a/web/views/urlpublishing.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/urlpublishing.py	Thu Oct 15 20:29:21 2009 +0200
@@ -156,7 +156,7 @@
             if len(parts) == 2:
                 attrname = parts.pop(0).lower()
                 try:
-                    cls.e_schema.subject_relation(attrname)
+                    cls.e_schema.subjrels[attrname]
                 except KeyError:
                     raise PathDontMatch()
             else:
--- a/web/views/xmlrss.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/views/xmlrss.py	Thu Oct 15 20:29:21 2009 +0200
@@ -89,7 +89,7 @@
                 if '(' in tag:
                     attrs['expr'] = tag
                     tag = 'funccall'
-                if val is not None and not eschema(etype).is_final():
+                if val is not None and not eschema(etype).final:
                     attrs['eid'] = val
                     # csvrow.append(val) # val is eid in that case
                     val = self.view('textincontext', rset,
--- a/web/widgets.py	Thu Oct 15 18:43:04 2009 +0200
+++ b/web/widgets.py	Thu Oct 15 20:29:21 2009 +0200
@@ -193,7 +193,7 @@
         if the field is monovalued (like all attribute fields, but not all non
         final relation fields
         """
-        if self.rschema.is_final():
+        if self.rschema.final:
             return entity.attribute_values(self.name)
         elif entity.has_eid():
             return [row[0] for row in entity.related(self.name, self.role)]
@@ -844,7 +844,7 @@
         eclass, objschema = _eclass_eschema(objschema)
     if eclass is not None and rschema in getattr(eclass, 'widgets', ()):
         wcls = WIDGETS[eclass.widgets[rschema]]
-    elif not rschema.is_final():
+    elif not rschema.final:
         card = rschema.rproperty(subjschema, objschema, 'cardinality')
         if role == 'object':
             multiple = card[1] in '+*'