summaryrefslogtreecommitdiffstats
path: root/meta/lib/oe/maketype.py
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/oe/maketype.py')
-rw-r--r--meta/lib/oe/maketype.py100
1 files changed, 100 insertions, 0 deletions
diff --git a/meta/lib/oe/maketype.py b/meta/lib/oe/maketype.py
new file mode 100644
index 0000000000..0e9dbc67fb
--- /dev/null
+++ b/meta/lib/oe/maketype.py
@@ -0,0 +1,100 @@
1"""OpenEmbedded variable typing support
2
3Types are defined in the metadata by name, using the 'type' flag on a
4variable. Other flags may be utilized in the construction of the types. See
5the arguments of the type's factory for details.
6"""
7
8import bb
9import inspect
10import types
11
12available_types = {}
13
14class MissingFlag(TypeError):
15 """A particular flag is required to construct the type, but has not been
16 provided."""
17 def __init__(self, flag, type):
18 self.flag = flag
19 self.type = type
20 TypeError.__init__(self)
21
22 def __str__(self):
23 return "Type '%s' requires flag '%s'" % (self.type, self.flag)
24
25def factory(var_type):
26 """Return the factory for a specified type."""
27 if var_type is None:
28 raise TypeError("No type specified. Valid types: %s" %
29 ', '.join(available_types))
30 try:
31 return available_types[var_type]
32 except KeyError:
33 raise TypeError("Invalid type '%s':\n Valid types: %s" %
34 (var_type, ', '.join(available_types)))
35
36def create(value, var_type, **flags):
37 """Create an object of the specified type, given the specified flags and
38 string value."""
39 obj = factory(var_type)
40 objflags = {}
41 for flag in obj.flags:
42 if flag not in flags:
43 if flag not in obj.optflags:
44 raise MissingFlag(flag, var_type)
45 else:
46 objflags[flag] = flags[flag]
47
48 return obj(value, **objflags)
49
50def get_callable_args(obj):
51 """Grab all but the first argument of the specified callable, returning
52 the list, as well as a list of which of the arguments have default
53 values."""
54 if type(obj) is type:
55 obj = obj.__init__
56
57 args, varargs, keywords, defaults = inspect.getargspec(obj)
58 flaglist = []
59 if args:
60 if len(args) > 1 and args[0] == 'self':
61 args = args[1:]
62 flaglist.extend(args)
63
64 optional = set()
65 if defaults:
66 optional |= set(flaglist[-len(defaults):])
67 return flaglist, optional
68
69def factory_setup(name, obj):
70 """Prepare a factory for use."""
71 args, optional = get_callable_args(obj)
72 extra_args = args[1:]
73 if extra_args:
74 obj.flags, optional = extra_args, optional
75 obj.optflags = set(optional)
76 else:
77 obj.flags = obj.optflags = ()
78
79 if not hasattr(obj, 'name'):
80 obj.name = name
81
82def register(name, factory):
83 """Register a type, given its name and a factory callable.
84
85 Determines the required and optional flags from the factory's
86 arguments."""
87 factory_setup(name, factory)
88 available_types[factory.name] = factory
89
90
91# Register all our included types
92for name in dir(types):
93 if name.startswith('_'):
94 continue
95
96 obj = getattr(types, name)
97 if not callable(obj):
98 continue
99
100 register(name, obj)