diff options
Diffstat (limited to 'lib/oe/types.py')
-rw-r--r-- | lib/oe/types.py | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/lib/oe/types.py b/lib/oe/types.py new file mode 100644 index 0000000000..963e964212 --- /dev/null +++ b/lib/oe/types.py @@ -0,0 +1,97 @@ +# Constructs objects of the specified type for a given variable in the +# metadata. The 'type' flag of the variable defines which of the factory +# functions in this module will be called. +# +# If no type is defined, the value() function will simply return the expanded +# string value as is. + +import bb +import inspect +import _types + +types = {} + +class MissingFlag(TypeError): + def __init__(self, flag, type): + self.flag = flag + self.type = type + TypeError.__init__(self) + + def __str__(self): + return "Type '%s' requires flag '%s'" % (self.type, self.flag) + +def factory(var_type): + try: + return types[var_type] + except KeyError: + raise TypeError("Invalid type '%s'" % var_type) + +def create(value, var_type, **flags): + obj = factory(var_type) + objflags = {} + for flag in obj.flags: + if flag not in flags: + if flag not in obj.optflags: + raise MissingFlag(flag, var_type) + else: + objflags[flag] = flags[flag] + + return obj(value, **objflags) + +def value(key, d): + """Construct a value for a metadata variable, based upon its flags""" + + var_type = d.getVarFlag(key, 'type') + flags = d.getVarFlags(key) + + try: + return create(d.getVar(key, True) or '', var_type, **flags) + except (TypeError, ValueError), exc: + bb.fatal("%s: %s" % (key, str(exc))) + +def get_callable_args(obj): + """Grab all but the first argument of the specified callable, returning + the list, as well as a list of which of the arguments have default + values.""" + if type(obj) is type: + obj = obj.__init__ + + args, varargs, keywords, defaults = inspect.getargspec(obj) + flaglist = [] + if args: + if len(args) > 1 and args[0] == 'self': + args = args[1:] + flaglist.extend(args) + + optional = set() + if defaults: + optional |= set(flaglist[-len(defaults):]) + return flaglist, optional + +def factory_setup(name, obj): + """Prepare a factory for use by oe.types""" + args, optional = get_callable_args(obj) + extra_args = args[1:] + if extra_args: + obj.flags, optional = extra_args, optional + obj.optflags = set(optional) + else: + obj.flags = obj.optflags = () + + if not hasattr(obj, 'name'): + obj.name = name + +def register(name, factory): + factory_setup(name, factory) + types[factory.name] = factory + +# Set the 'flags' and 'optflags' attributes of all our types +for name in dir(_types): + if name.startswith('_'): + continue + + obj = getattr(_types, name) + if not callable(obj): + continue + + register(name, obj) |