generic-poky/meta/lib/oe/maketype.py

103 lines
2.9 KiB
Python
Raw Normal View History

Implement variable typing (sync from OE) This implementation consists of two components: - Type creation python modules, whose job it is to construct objects of the defined type for a given variable in the metadata - typecheck.bbclass, which iterates over all configuration variables with a type defined and uses oe.types to check the validity of the values This gives us a few benefits: - Automatic sanity checking of all configuration variables with a defined type - Avoid duplicating the "how do I make use of the value of this variable" logic between its users. For variables like PATH, this is simply a split(), for boolean variables, the duplication can result in confusing, or even mismatched semantics (is this 0/1, empty/nonempty, what?) - Make it easier to create a configuration UI, as the type information could be used to provide a better interface than a text edit box (e.g checkbox for 'boolean', dropdown for 'choice') This functionality is entirely opt-in right now. To enable the configuration variable type checking, simply INHERIT += "typecheck". Example of a failing type check: BAZ = "foo" BAZ[type] = "boolean" $ bitbake -p FATAL: BAZ: Invalid boolean value 'foo' $ Examples of leveraging oe.types in a python snippet: PACKAGES[type] = "list" python () { import oe.data for pkg in oe.data.typed_value("PACKAGES", d): bb.note("package: %s" % pkg) } LIBTOOL_HAS_SYSROOT = "yes" LIBTOOL_HAS_SYSROOT[type] = "boolean" python () { import oe.data assert(oe.data.typed_value("LIBTOOL_HAS_SYSROOT", d) == True) } (From OE-Core rev: a04ce490e933fc7534db33f635b025c25329c564) Signed-off-by: Chris Larson <chris_larson@mentor.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2010-11-09 21:48:13 +00:00
"""OpenEmbedded variable typing support
Types are defined in the metadata by name, using the 'type' flag on a
variable. Other flags may be utilized in the construction of the types. See
the arguments of the type's factory for details.
"""
import inspect
import oe.types as types
import collections
Implement variable typing (sync from OE) This implementation consists of two components: - Type creation python modules, whose job it is to construct objects of the defined type for a given variable in the metadata - typecheck.bbclass, which iterates over all configuration variables with a type defined and uses oe.types to check the validity of the values This gives us a few benefits: - Automatic sanity checking of all configuration variables with a defined type - Avoid duplicating the "how do I make use of the value of this variable" logic between its users. For variables like PATH, this is simply a split(), for boolean variables, the duplication can result in confusing, or even mismatched semantics (is this 0/1, empty/nonempty, what?) - Make it easier to create a configuration UI, as the type information could be used to provide a better interface than a text edit box (e.g checkbox for 'boolean', dropdown for 'choice') This functionality is entirely opt-in right now. To enable the configuration variable type checking, simply INHERIT += "typecheck". Example of a failing type check: BAZ = "foo" BAZ[type] = "boolean" $ bitbake -p FATAL: BAZ: Invalid boolean value 'foo' $ Examples of leveraging oe.types in a python snippet: PACKAGES[type] = "list" python () { import oe.data for pkg in oe.data.typed_value("PACKAGES", d): bb.note("package: %s" % pkg) } LIBTOOL_HAS_SYSROOT = "yes" LIBTOOL_HAS_SYSROOT[type] = "boolean" python () { import oe.data assert(oe.data.typed_value("LIBTOOL_HAS_SYSROOT", d) == True) } (From OE-Core rev: a04ce490e933fc7534db33f635b025c25329c564) Signed-off-by: Chris Larson <chris_larson@mentor.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2010-11-09 21:48:13 +00:00
available_types = {}
class MissingFlag(TypeError):
"""A particular flag is required to construct the type, but has not been
provided."""
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):
"""Return the factory for a specified type."""
if var_type is None:
raise TypeError("No type specified. Valid types: %s" %
', '.join(available_types))
try:
return available_types[var_type]
except KeyError:
raise TypeError("Invalid type '%s':\n Valid types: %s" %
(var_type, ', '.join(available_types)))
def create(value, var_type, **flags):
"""Create an object of the specified type, given the specified flags and
string value."""
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 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__
sig = inspect.signature(obj)
args = list(sig.parameters.keys())
defaults = list(s for s in sig.parameters.keys() if sig.parameters[s].default != inspect.Parameter.empty)
Implement variable typing (sync from OE) This implementation consists of two components: - Type creation python modules, whose job it is to construct objects of the defined type for a given variable in the metadata - typecheck.bbclass, which iterates over all configuration variables with a type defined and uses oe.types to check the validity of the values This gives us a few benefits: - Automatic sanity checking of all configuration variables with a defined type - Avoid duplicating the "how do I make use of the value of this variable" logic between its users. For variables like PATH, this is simply a split(), for boolean variables, the duplication can result in confusing, or even mismatched semantics (is this 0/1, empty/nonempty, what?) - Make it easier to create a configuration UI, as the type information could be used to provide a better interface than a text edit box (e.g checkbox for 'boolean', dropdown for 'choice') This functionality is entirely opt-in right now. To enable the configuration variable type checking, simply INHERIT += "typecheck". Example of a failing type check: BAZ = "foo" BAZ[type] = "boolean" $ bitbake -p FATAL: BAZ: Invalid boolean value 'foo' $ Examples of leveraging oe.types in a python snippet: PACKAGES[type] = "list" python () { import oe.data for pkg in oe.data.typed_value("PACKAGES", d): bb.note("package: %s" % pkg) } LIBTOOL_HAS_SYSROOT = "yes" LIBTOOL_HAS_SYSROOT[type] = "boolean" python () { import oe.data assert(oe.data.typed_value("LIBTOOL_HAS_SYSROOT", d) == True) } (From OE-Core rev: a04ce490e933fc7534db33f635b025c25329c564) Signed-off-by: Chris Larson <chris_larson@mentor.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2010-11-09 21:48:13 +00:00
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."""
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):
"""Register a type, given its name and a factory callable.
Determines the required and optional flags from the factory's
arguments."""
factory_setup(name, factory)
available_types[factory.name] = factory
# Register all our included types
for name in dir(types):
if name.startswith('_'):
continue
obj = getattr(types, name)
if not isinstance(obj, collections.Callable):
Implement variable typing (sync from OE) This implementation consists of two components: - Type creation python modules, whose job it is to construct objects of the defined type for a given variable in the metadata - typecheck.bbclass, which iterates over all configuration variables with a type defined and uses oe.types to check the validity of the values This gives us a few benefits: - Automatic sanity checking of all configuration variables with a defined type - Avoid duplicating the "how do I make use of the value of this variable" logic between its users. For variables like PATH, this is simply a split(), for boolean variables, the duplication can result in confusing, or even mismatched semantics (is this 0/1, empty/nonempty, what?) - Make it easier to create a configuration UI, as the type information could be used to provide a better interface than a text edit box (e.g checkbox for 'boolean', dropdown for 'choice') This functionality is entirely opt-in right now. To enable the configuration variable type checking, simply INHERIT += "typecheck". Example of a failing type check: BAZ = "foo" BAZ[type] = "boolean" $ bitbake -p FATAL: BAZ: Invalid boolean value 'foo' $ Examples of leveraging oe.types in a python snippet: PACKAGES[type] = "list" python () { import oe.data for pkg in oe.data.typed_value("PACKAGES", d): bb.note("package: %s" % pkg) } LIBTOOL_HAS_SYSROOT = "yes" LIBTOOL_HAS_SYSROOT[type] = "boolean" python () { import oe.data assert(oe.data.typed_value("LIBTOOL_HAS_SYSROOT", d) == True) } (From OE-Core rev: a04ce490e933fc7534db33f635b025c25329c564) Signed-off-by: Chris Larson <chris_larson@mentor.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2010-11-09 21:48:13 +00:00
continue
register(name, obj)