[buildobj] Allow to define specific parameters in _make_type function , closes #124342

authorVincent Michel <vincent.michel@logilab.fr>
changeset1fb1755142fa
branchdefault
phasedraft
hiddenyes
parent revision#490deb287d19 [schema] Add a new TYPE_PROPERTIES for adding new data types on the fly
child revision#26570262e483 Add functions to register and make a base type., #81d778dc602c Add functions to register and make a base type.
files modified by this revision
buildobjs.py
test/unittest_schema.py
# HG changeset patch
# User Vincent Michel <vincent.michel@logilab.fr>
# Date 1365165425 -7200
# Fri Apr 05 14:37:05 2013 +0200
# Node ID 1fb1755142fa78cab11266492ff019d71e1fad8d
# Parent 490deb287d197641f4e018c78ff81bcd60b4bd4e
[buildobj] Allow to define specific parameters in _make_type function , closes #124342

diff --git a/buildobjs.py b/buildobjs.py
@@ -594,10 +594,11 @@
1  # \2 = \1Relation(
2 
3  class ObjectRelation(Relation):
4      cardinality = MARKER
5      constraints = MARKER
6 +    type_parameters = ()
7 
8      def __init__(self, etype, **kwargs):
9          if self.__class__.__name__ == 'ObjectRelation':
10              warn('[yams 0.29] ObjectRelation is deprecated, '
11                   'use RelationDefinition subclass', DeprecationWarning,
@@ -613,11 +614,13 @@
12          if 'symetric' in kwargs:
13              kwargs['symmetric'] = kwargs.pop('symetric')
14              warn('[yams 0.27.0] symetric has been respelled symmetric',
15                   DeprecationWarning, stacklevel=2)
16          try:
17 -            _check_kwargs(kwargs, REL_PROPERTIES)
18 +            # Add additional parameters for custom base types
19 +            rdef_properties = REL_PROPERTIES + self.type_parameters
20 +            _check_kwargs(kwargs, rdef_properties)
21          except BadSchemaDefinition, bad:
22              # XXX (auc) bad field name + required attribute can lead there instead of schema.py ~ 920
23              bsd_ex = BadSchemaDefinition(('%s in relation to entity %r (also is %r defined ? (check two '
24                                            'lines above in the backtrace))') % (bad.args, etype, etype))
25              bsd_ex.tb_offset = 2
@@ -683,11 +686,11 @@
26              _add_constraint(kwargs, UniqueConstraint())
27          # use the etype attribute provided by subclasses
28          super(AbstractTypedAttribute, self).__init__(self.etype, **kwargs)
29          # reassign creation rank
30          #
31 -        # Main attribute are marked as created before it's metadata.
32 +        # Main attribute are marked as created before its metadata.
33          # order in meta data is preserved.
34          if self.metadata:
35              meta = sorted(metadata.values(), key= lambda x: x.creation_rank)
36              if meta[0].creation_rank < self.creation_rank:
37                  m_iter = iter(meta)
@@ -709,12 +712,22 @@
38 
39      def __repr__(self):
40          return '<%(name)s(%(etype)s)>' % self.__dict__
41 
42  # build a specific class for each base type
43 -def _make_type(etype):
44 -    return type(etype, (AbstractTypedAttribute,), {'etype' : etype})
45 +def _make_type(etype, type_parameters=()):
46 +    """Add params is a tuple of user defined / custom type parameters name.
47 +    It is now possible to create a specific type with user-defined params, e.g.:
48 +
49 +    etype = 'Geometry' (c.f. postgis)
50 +    type_parameters = ('geom_type', 'srid', 'coord_dimension')
51 +
52 +    This will allow the use of :
53 +        Geometry(geom_type='POINT', srid=-1, coord_dimension=2)
54 +    in a Yams schema.
55 +    """
56 +    return type(etype, (AbstractTypedAttribute,), {'etype' : etype, 'type_parameters': type_parameters})
57 
58  String = _make_type('String')
59  Password = _make_type('Password')
60  Bytes = _make_type('Bytes')
61  Int = _make_type('Int')
diff --git a/test/unittest_schema.py b/test/unittest_schema.py
@@ -25,11 +25,11 @@
62  from copy import copy, deepcopy
63  from tempfile import mktemp
64 
65  from yams import BadSchemaDefinition
66  from yams.buildobjs import (register_base_types, EntityType, RelationType,
67 -                            RelationDefinition, _add_relation)
68 +                            RelationDefinition, _add_relation, _make_type)
69  from yams.schema import *
70  from yams.constraints import *
71  from yams.reader import SchemaLoader
72 
73 
@@ -545,7 +545,21 @@
74          self.assertEqual(subj_types,
75                            [('Bug', ['Bug', 'Project', 'Story']),
76                             ('Project', ['Bug', 'Project', 'Story']),
77                             ('Story', ['Bug', 'Project', 'Story'])])
78 
79 +
80 +class MakeTypeTC(TestCase):
81 +
82 +    def test_make_type(self):
83 +        _type = _make_type('Test')
84 +        self.assertEqual(_type.etype, 'Test')
85 +        self.assertEqual(_type.type_parameters, ())
86 +
87 +    def test_make_type_parameters(self):
88 +        _type = _make_type('Test', ('test1', 'test2'))
89 +        self.assertEqual(_type.etype, 'Test')
90 +        self.assertEqual(_type.type_parameters, ('test1', 'test2'))
91 +
92 +
93  if __name__ == '__main__':
94      unittest_main()