[schema] extend .rdef(...) with a parameter to silence the ambiguity warning

Sometimes clients of .rdef really do not care about the target types. We keep this feature but the client has to make it explicit, else he will get the warning.

Follows #109207

authorAurelien Campeas <aurelien.campeas@logilab.fr>
changesete3170981e431
branchdefault
phasedraft
hiddenyes
parent revision#c2233d792030 Added tag yams-version-0.38.0, yams-debian-version-0.38.0-1, yams-centos-version-0.38.0-1 for changeset 417d554000a4
child revision#0e4482ca9365 Remove dead and deprecated code (closes #149361)
files modified by this revision
schema.py
# HG changeset patch
# User Aurelien Campeas <aurelien.campeas@logilab.fr>
# Date 1372260841 -7200
# Wed Jun 26 17:34:01 2013 +0200
# Node ID e3170981e4319a7854d9f15c05da341f97367930
# Parent c2233d792030d9a0acc49f5b76e67fae5e80a263
[schema] extend .rdef(...) with a parameter to silence the ambiguity warning

Sometimes clients of .rdef really do not care about the target types.
We keep this feature but the client has to make it explicit, else
he will get the warning.

Follows #109207

diff --git a/schema.py b/schema.py
@@ -193,11 +193,11 @@
1      def check_unique_together(self):
2          errors = []
3          for unique_together in self._unique_together:
4              for name in unique_together:
5                  try:
6 -                    rschema = self.rdef(name)
7 +                    rschema = self.rdef(name, takefirst=True)
8                  except KeyError:
9                      errors.append('no such attribute or relation %s' % name)
10                  else:
11                      if not (rschema.final or rschema.rtype.inlined):
12                          errors.append('%s is not an attribute or an inlined '
@@ -287,24 +287,24 @@
13          """return a list of relations that may have this type of entity as
14          object
15          """
16          return self.objrels.values()
17 
18 -    def rdef(self, rtype, role='subject', targettype=None):
19 +    def rdef(self, rtype, role='subject', targettype=None, takefirst=False):
20          """return a relation definition schema for a relation of this entity type
21 
22          Notice that when targettype is not specified and the relation may lead
23          to different entity types (ambiguous relation), one of them is picked
24 -        randomly.
25 +        randomly. If also takefirst is False, a warning will be emitted.
26          """
27          rschema = self.schema.rschema(rtype)
28          if targettype is None:
29              if role == 'subject':
30                  types = rschema.objects(self)
31              else:
32                  types = rschema.subjects(self)
33 -            if len(types) != 1:
34 +            if len(types) != 1 and not takefirst:
35                  warnings.warn('[yams 0.38] no targettype specified and there are several '
36                                'relation definitions for rtype %s: %s. Yet you get the first '
37                                'rdef.' % (rtype, [eschema.type for eschema in types]),
38                                Warning, stacklevel=2)
39              targettype = types[0]
@@ -380,11 +380,11 @@
40                      # XXX return a RelationDefinitionSchema
41                      yield rschema, value
42 
43      def default(self, rtype):
44          """return the default value of a subject relation"""
45 -        rdef = self.rdef(rtype)
46 +        rdef = self.rdef(rtype, takefirst=True)
47          default =  rdef.default
48          if callable(default):
49              default = default()
50          if default is MARKER:
51              default = None
@@ -499,20 +499,20 @@
52          return True if this entity type *must* be contained by another.
53          """
54          for rschema in self.object_relations():
55              if (rschema, 'object') in skiprels:
56                  continue
57 -            rdef = self.rdef(rschema, 'object')
58 +            rdef = self.rdef(rschema, 'object', takefirst=True)
59              if rdef.composite == 'subject':
60                  if not strict or rdef.cardinality[1] in '1+':
61                      return True
62          for rschema in self.subject_relations():
63              if (rschema, 'subject') in skiprels:
64                  continue
65              if rschema.final:
66                  continue
67 -            rdef = self.rdef(rschema, 'subject')
68 +            rdef = self.rdef(rschema, 'subject', takefirst=True)
69              if rdef.composite == 'object':
70                  if not strict or rdef.cardinality[0] in '1+':
71                      return True
72          return False
73