summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Magnusson <ulfalizer@gmail.com>2018-03-05 22:56:53 +0100
committerUlf Magnusson <ulfalizer@gmail.com>2018-03-05 23:44:48 +0100
commitb499d06a8513ba599ca72d4d7bb6ae7fb6f1a9f9 (patch)
tree0c8d36462a2e848ead104bdf6fa8789f5ae579be
parent80767d52e5ab3c2669b96749c49d80a34f1b2fb5 (diff)
Use comments instead of docstrings for internal functions
The original idea was that it might be handy to look up docstrings for internal functions from the Python prompt (or an IDE) while figuring out the code. Not sure it's that useful in practice though. Comments shorten the code a bit, and might make it clearer at a glance that the function is internal.
-rw-r--r--kconfiglib.py427
1 files changed, 191 insertions, 236 deletions
diff --git a/kconfiglib.py b/kconfiglib.py
index 93dc577..b733262 100644
--- a/kconfiglib.py
+++ b/kconfiglib.py
@@ -1087,6 +1087,7 @@ class Kconfig(object):
#
# A separate helper function is neater than complicating write_config()
# by passing a flag to it, plus we only need to look at symbols here.
+
with open("auto.conf", "w") as f:
for sym in self.defined_syms:
sym._written = False
@@ -1253,10 +1254,9 @@ class Kconfig(object):
#
def _open(self, filename):
- """
- First tries to open 'filename', then '$srctree/filename' if $srctree
- was set when the configuration was loaded.
- """
+ # First tries to open 'filename', then '$srctree/filename' if $srctree
+ # was set when the configuration was loaded
+
try:
return open(filename, _UNIVERSAL_NEWLINES_MODE)
except IOError as e:
@@ -1282,10 +1282,9 @@ class Kconfig(object):
'"{}"'.format(self.srctree)))
def _enter_file(self, filename):
- """
- Jumps to the beginning of a sourced Kconfig file, saving the previous
- position and file object.
- """
+ # Jumps to the beginning of a sourced Kconfig file, saving the previous
+ # position and file object
+
# Check for recursive 'source'
for _, name, _ in self._filestack:
if name == filename:
@@ -1316,17 +1315,15 @@ class Kconfig(object):
self._linenr = 0
def _leave_file(self):
- """
- Returns from a Kconfig file to the file that sourced it.
- """
+ # Returns from a Kconfig file to the file that sourced it
+
self._file.close()
self._file, self._filename, self._linenr = self._filestack.pop()
def _next_line(self):
- """
- Fetches and tokenizes the next line from the current Kconfig file.
- Returns False at EOF and True otherwise.
- """
+ # Fetches and tokenizes the next line from the current Kconfig file.
+ # Returns False at EOF and True otherwise.
+
# _saved_line provides a single line of "unget", currently only used
# for help texts.
#
@@ -1355,11 +1352,10 @@ class Kconfig(object):
#
def _lookup_sym(self, name):
- """
- Fetches the symbol 'name' from the symbol table, creating and
- registering it if it does not exist. If '_parsing_kconfigs' is False,
- it means we're in eval_string(), and new symbols won't be registered.
- """
+ # Fetches the symbol 'name' from the symbol table, creating and
+ # registering it if it does not exist. If '_parsing_kconfigs' is False,
+ # it means we're in eval_string(), and new symbols won't be registered.
+
if name in self.syms:
return self.syms[name]
@@ -1377,9 +1373,8 @@ class Kconfig(object):
return sym
def _lookup_const_sym(self, name):
- """
- Like _lookup_sym(), for constant (quoted) symbols
- """
+ # Like _lookup_sym(), for constant (quoted) symbols
+
if name in self.const_syms:
return self.const_syms[name]
@@ -1395,14 +1390,13 @@ class Kconfig(object):
return sym
def _tokenize(self):
- """
- Parses Kconfig._line, putting the tokens in Kconfig._tokens. Registers
- any new symbols encountered with _lookup(_const)_sym().
+ # Parses Kconfig._line, putting the tokens in Kconfig._tokens.
+ # Registers any new symbols encountered with _lookup(_const)_sym().
+ #
+ # Tries to be reasonably speedy by processing chunks of text via
+ # regexes and string operations where possible. This is the biggest
+ # hotspot during parsing.
- Tries to be reasonably speedy by processing chunks of text via regexes
- and string operations where possible. This is the biggest hotspot
- during parsing.
- """
s = self._line
# Token index (minus one). Set for later -- not further updated here.
@@ -1666,9 +1660,8 @@ class Kconfig(object):
def _check_token(self, token):
- """
- If the next token is 'token', removes it and returns True.
- """
+ # If the next token is 'token', removes it and returns True
+
if self._tokens[self._tokens_i + 1] == token:
self._tokens_i += 1
return True
@@ -1680,9 +1673,8 @@ class Kconfig(object):
#
def _make_and(self, e1, e2):
- """
- Constructs an AND (&&) expression. Performs trivial simplification.
- """
+ # Constructs an AND (&&) expression. Performs trivial simplification.
+
if e1 is self.y:
return e2
@@ -1695,9 +1687,8 @@ class Kconfig(object):
return (AND, e1, e2)
def _make_or(self, e1, e2):
- """
- Constructs an OR (||) expression. Performs trivial simplification.
- """
+ # Constructs an OR (||) expression. Performs trivial simplification.
+
if e1 is self.n:
return e2
@@ -1710,35 +1701,33 @@ class Kconfig(object):
return (OR, e1, e2)
def _parse_block(self, end_token, parent, visible_if_deps, prev_node):
- """
- Parses a block, which is the contents of either a file or an if, menu,
- or choice statement.
-
- end_token:
- The token that ends the block, e.g. _T_ENDIF ("endif") for ifs. None
- for files.
-
- parent:
- The parent menu node, corresponding to a menu, Choice, or 'if'. 'if's
- are flattened after parsing.
-
- visible_if_deps:
- 'visible if' dependencies from enclosing menus. Propagated to Symbol
- and Choice prompts.
-
- prev_node:
- The previous menu node. New nodes will be added after this one (by
- modifying their 'next' pointer).
-
- prev_node is reused to parse a list of child menu nodes (for a menu
- or Choice): After parsing the children, the 'next' pointer is
- assigned to the 'list' pointer to "tilt up" the children above the
- node.
-
+ # Parses a block, which is the contents of either a file or an if,
+ # menu, or choice statement.
+ #
+ # end_token:
+ # The token that ends the block, e.g. _T_ENDIF ("endif") for ifs.
+ # None for files.
+ #
+ # parent:
+ # The parent menu node, corresponding to a menu, Choice, or 'if'.
+ # 'if's are flattened after parsing.
+ #
+ # visible_if_deps:
+ # 'visible if' dependencies from enclosing menus. Propagated to
+ # Symbol and Choice prompts.
+ #
+ # prev_node:
+ # The previous menu node. New nodes will be added after this one (by
+ # modifying their 'next' pointer).
+ #
+ # prev_node is reused to parse a list of child menu nodes (for a menu
+ # or Choice): After parsing the children, the 'next' pointer is
+ # assigned to the 'list' pointer to "tilt up" the children above the
+ # node.
+ #
+ # Returns the final menu node in the block (or prev_node if the block is
+ # empty). This allows chaining.
- Returns the final menu node in the block (or prev_node if the block is
- empty). This allows chaining.
- """
# We might already have tokens from parsing a line to check if it's a
# property and discovering it isn't. self._has_tokens functions as a
# kind of "unget".
@@ -1913,31 +1902,29 @@ class Kconfig(object):
return prev_node
def _parse_cond(self):
- """
- Parses an optional 'if <expr>' construct and returns the parsed <expr>,
- or self.y if the next token is not _T_IF
- """
+ # Parses an optional 'if <expr>' construct and returns the parsed
+ # <expr>, or self.y if the next token is not _T_IF
+
expr = self._parse_expr(True) if self._check_token(_T_IF) else self.y
if self._peek_token() is not None:
self._parse_error("extra tokens at end of line")
return expr
def _parse_properties(self, node, visible_if_deps):
- """
- Parses properties for symbols, menus, choices, and comments. Also takes
- care of propagating dependencies from the menu node to the properties
- of the item (this mirrors the C tools, though they do it after
- parsing).
-
- node:
- The menu node we're parsing properties on. Prompt, help text,
- 'depends on', and 'visible if' properties apply to the Menu node,
- while the others apply to the contained item.
-
- visible_if_deps:
- 'visible if' dependencies from enclosing menus. Propagated to Symbol
- and Choice prompts.
- """
+ # Parses properties for symbols, menus, choices, and comments. Also
+ # takes care of propagating dependencies from the menu node to the
+ # properties of the item (this mirrors the C tools, though they do it
+ # after parsing).
+ #
+ # node:
+ # The menu node we're parsing properties on. Prompt, help text,
+ # 'depends on', and 'visible if' properties apply to the Menu node,
+ # while other properties apply to the contained item.
+ #
+ # visible_if_deps:
+ # 'visible if' dependencies from enclosing menus. Propagated to
+ # Symbol and Choice prompts.
+
# New properties encountered at this location. A local 'depends on'
# only applies to these, in case a symbol is defined in multiple
# locations.
@@ -2224,14 +2211,14 @@ class Kconfig(object):
node.dep)))
def _parse_expr(self, transform_m):
- """
- Parses an expression from the tokens in Kconfig._tokens using a simple
- top-down approach. See the module docstring for the expression format.
+ # Parses an expression from the tokens in Kconfig._tokens using a
+ # simple top-down approach. See the module docstring for the expression
+ # format.
+ #
+ # transform_m:
+ # True if m should be rewritten to m && MODULES. See the
+ # Kconfig.eval_string() documentation.
- transform_m:
- True if m should be rewritten to m && MODULES. See the
- Kconfig.eval_string() documentation.
- """
# Grammar:
#
# expr: and_expr ['||' expr]
@@ -2314,15 +2301,14 @@ class Kconfig(object):
#
def _build_dep(self):
- """
- Populates the Symbol/Choice._dependents sets, which contain all other
- items (symbols and choices) that immediately depend on the item in the
- sense that changing the value of the item might affect the value of the
- dependent items. This is used for caching/invalidation.
+ # Populates the Symbol/Choice._dependents sets, which contain all other
+ # items (symbols and choices) that immediately depend on the item in
+ # the sense that changing the value of the item might affect the value
+ # of the dependent items. This is used for caching/invalidation.
+ #
+ # The calculated sets might be larger than necessary as we don't do any
+ # complex analysis of the expressions.
- The calculated sets might be larger than necessary as we don't do any
- complex analysis of the expressions.
- """
# Only calculate _dependents for defined symbols. Constant and
# undefined symbols could theoretically be selected/implied, but it
# wouldn't change their value, so it's not a true dependency.
@@ -2394,10 +2380,9 @@ class Kconfig(object):
#
def _expand_syms(self, s):
- """
- Expands $-references to symbols in 's' to symbol values, or to the
- empty string for undefined symbols.
- """
+ # Expands $-references to symbols in 's' to symbol values, or to the
+ # empty string for undefined symbols
+
while 1:
sym_ref_match = _sym_ref_re_search(s)
if not sym_ref_match:
@@ -2419,31 +2404,27 @@ class Kconfig(object):
"{}Couldn't parse '{}': {}".format(loc, self._line.rstrip(), msg))
def _warn(self, msg, filename=None, linenr=None):
- """
- For printing general warnings.
- """
+ # For printing general warnings
+
if self._print_warnings:
_stderr_msg("warning: " + msg, filename, linenr)
def _warn_undef_assign(self, msg, filename=None, linenr=None):
- """
- See the class documentation.
- """
+ # See the class documentation
+
if self._print_undef_assign:
_stderr_msg("warning: " + msg, filename, linenr)
def _warn_undef_assign_load(self, name, val, filename, linenr):
- """
- Special version for load_config().
- """
+ # Special version for load_config()
+
self._warn_undef_assign(
'attempt to assign the value "{}" to the undefined symbol {}'
.format(val, name), filename, linenr)
def _warn_redun_assign(self, msg, filename=None, linenr=None):
- """
- See the class documentation.
- """
+ # See the class documentation
+
if self._print_redun_assign:
_stderr_msg("warning: " + msg, filename, linenr)
@@ -3147,9 +3128,8 @@ class Symbol(object):
self._dependents = set()
def _assignable(self):
- """
- Worker function for the 'assignable' attribute.
- """
+ # Worker function for the 'assignable' attribute
+
if self.orig_type not in (BOOL, TRISTATE):
return ()
@@ -3195,16 +3175,14 @@ class Symbol(object):
return (1,)
def _invalidate(self):
- """
- Marks the symbol as needing to be recalculated.
- """
+ # Marks the symbol as needing to be recalculated
+
self._cached_str_val = self._cached_tri_val = self._cached_vis = \
self._cached_assignable = None
def _rec_invalidate(self):
- """
- Invalidates the symbol and all items that (possibly) depend on it.
- """
+ # Invalidates the symbol and all items that (possibly) depend on it
+
if self is self.kconfig.modules:
# Invalidating MODULES has wide-ranging effects
self.kconfig._invalidate_all()
@@ -3234,19 +3212,18 @@ class Symbol(object):
item._rec_invalidate()
def _rec_invalidate_if_has_prompt(self):
- """
- Invalidates the symbol and its dependent symbols, but only if the
- symbol has a prompt. User values never have an effect on promptless
- symbols, so we skip invalidation for them as an optimization.
-
- This also prevents constant (quoted) symbols from being invalidated if
- set_value() is called on them, which would cause them to lose their
- value and break things.
+ # Invalidates the symbol and its dependent symbols, but only if the
+ # symbol has a prompt. User values never have an effect on promptless
+ # symbols, so we skip invalidation for them as an optimization.
+ #
+ # This also prevents constant (quoted) symbols from being invalidated
+ # if set_value() is called on them, which would cause them to lose
+ # their value and break things.
+ #
+ # Prints a warning if the symbol has no prompt. In some contexts (e.g.
+ # when loading a .config files) assignments to promptless symbols are
+ # normal and expected, so the warning can be disabled.
- Prints a warning if the symbol has no prompt. In some contexts (e.g.
- when loading a .config files) assignments to promptless symbols are
- normal and expected, so the warning can be disabled.
- """
for node in self.nodes:
if node.prompt:
self._rec_invalidate()
@@ -3257,11 +3234,10 @@ class Symbol(object):
"meaning user values have no effect on it")
def _warn_select_unsatisfied_deps(self):
- """
- Helper for printing an informative warning when a symbol with
- unsatisfied direct dependencies (dependencies from 'depends on', ifs,
- and menus) is selected by some other symbol
- """
+ # Helper for printing an informative warning when a symbol with
+ # unsatisfied direct dependencies (dependencies from 'depends on', ifs,
+ # and menus) is selected by some other symbol
+
warn_msg = "{} has unsatisfied direct dependencies ({}), but is " \
"currently being selected by the following symbols:" \
.format(_name_and_loc_str(self),
@@ -3676,9 +3652,8 @@ class Choice(object):
self._dependents = set()
def _assignable(self):
- """
- Worker function for the 'assignable' attribute.
- """
+ # Worker function for the 'assignable' attribute
+
# Warning: See Symbol._rec_invalidate(), and note that this is a hidden
# function call (property magic)
vis = self.visibility
@@ -3696,9 +3671,8 @@ class Choice(object):
return (0, 1) if self.is_optional else (1,)
def _selection(self):
- """
- Worker function for the 'selection' attribute.
- """
+ # Worker function for the 'selection' attribute
+
# Warning: See Symbol._rec_invalidate(), and note that this is a hidden
# function call (property magic)
if self.tri_value != 2:
@@ -3728,9 +3702,8 @@ class Choice(object):
self._cached_selection = _NO_CACHED_SELECTION
def _rec_invalidate(self):
- """
- See Symbol._rec_invalidate()
- """
+ # See Symbol._rec_invalidate()
+
self._invalidate()
for item in self._dependents:
@@ -4053,12 +4026,11 @@ def unescape(s):
#
def _visibility(sc):
- """
- Symbols and Choices have a "visibility" that acts as an upper bound on the
- values a user can set for them, corresponding to the visibility in e.g.
- 'make menuconfig'. This function calculates the visibility for the Symbol
- or Choice 'sc' -- the logic is nearly identical.
- """
+ # Symbols and Choices have a "visibility" that acts as an upper bound on
+ # the values a user can set for them, corresponding to the visibility in
+ # e.g. 'make menuconfig'. This function calculates the visibility for the
+ # Symbol or Choice 'sc' -- the logic is nearly identical.
+
vis = 0
for node in sc.nodes:
@@ -4083,10 +4055,9 @@ def _visibility(sc):
return vis
def _make_depend_on(sym, expr):
- """
- Adds 'sym' as a dependency to all symbols in 'expr'. Constant symbols in
- 'expr' are skipped as they can never change value anyway.
- """
+ # Adds 'sym' as a dependency to all symbols in 'expr'. Constant symbols in
+ # 'expr' are skipped as they can never change value anyway.
+
if not isinstance(expr, tuple):
if not expr.is_constant:
expr._dependents.add(sym)
@@ -4109,33 +4080,30 @@ def _make_depend_on(sym, expr):
"expression with token stream {}.".format(expr))
def _format_and_op(expr):
- """
- expr_str() helper. Returns the string representation of 'expr', which is
- assumed to be an operand to AND, with parentheses added if needed.
- """
+ # expr_str() helper. Returns the string representation of 'expr', which is
+ # assumed to be an operand to AND, with parentheses added if needed.
+
if isinstance(expr, tuple) and expr[0] == OR:
return "({})".format(expr_str(expr))
return expr_str(expr)
def _indentation(line):
- """
- Returns the length of the line's leading whitespace, treating tab stops as
- being spaced 8 characters apart.
- """
+ # Returns the length of the line's leading whitespace, treating tab stops
+ # as being spaced 8 characters apart.
+
line = line.expandtabs()
return len(line) - len(line.lstrip())
def _dedent_rstrip(line, indent):
- r"""
- De-indents 'line' by 'indent' spaces and rstrip()s it to remove any
- newlines (which gets rid of other trailing whitespace too, but that's
- fine).
-
- Used to prepare help text lines in a speedy way: The [indent:] might
- already remove trailing newlines for lines shorter than indent (e.g. empty
- lines). The rstrip() makes it consistent, meaning we can join the lines
- with "\n" later.
- """
+ # De-indents 'line' by 'indent' spaces and rstrip()s it to remove any
+ # newlines (which gets rid of other trailing whitespace too, but that's
+ # fine).
+ #
+ # Used to prepare help text lines in a speedy way: The [indent:] might
+ # already remove trailing newlines for lines shorter than indent (e.g.
+ # empty lines). The rstrip() makes it consistent, meaning we can join the
+ # lines with "\n" later.
+
return line.expandtabs()[indent:].rstrip()
def _is_base_n(s, n):
@@ -4146,16 +4114,14 @@ def _is_base_n(s, n):
return False
def _strcmp(s1, s2):
- """
- strcmp()-alike that returns -1, 0, or 1.
- """
+ # strcmp()-alike that returns -1, 0, or 1
+
return (s1 > s2) - (s1 < s2)
def _sym_to_num(sym):
- """
- expr_value() helper for converting a symbol to a number. Raises ValueError
- for symbols that can't be converted.
- """
+ # expr_value() helper for converting a symbol to a number. Raises
+ # ValueError for symbols that can't be converted.
+
# For BOOL and TRISTATE, n/m/y count as 0/1/2. This mirrors 9059a3493ef
# ("kconfig: fix relational operators for bool and tristate symbols") in
# the C implementation.
@@ -4178,10 +4144,9 @@ def _internal_error(msg):
# Printing functions
def _sym_choice_str(sc):
- """
- Symbol/choice __str__() implementation. These have many properties in
- common, so it makes sense to handle them together.
- """
+ # Symbol/choice __str__() implementation. These have many properties in
+ # common, so it makes sense to handle them together.
+
lines = []
def indent_add(s):
@@ -4280,10 +4245,8 @@ def _sym_choice_str(sc):
return "\n".join(lines) + "\n"
def _name_and_loc_str(sc):
- """
- Helper for giving the symbol/choice name and location(s) in e.g.
- warnings
- """
+ # Helper for giving the symbol/choice name and location(s) in e.g. warnings
+
name = sc.name or "<choice>"
if not sc.nodes:
@@ -4298,11 +4261,10 @@ def _name_and_loc_str(sc):
# Menu manipulation
def _expr_depends_on(expr, sym):
- """
- Reimplementation of expr_depends_symbol() from mconf.c. Used to
- determine if a submenu should be implicitly created. This also influences
- which items inside choice statements are considered choice items.
- """
+ # Reimplementation of expr_depends_symbol() from mconf.c. Used to determine
+ # if a submenu should be implicitly created. This also influences which
+ # items inside choice statements are considered choice items.
+
if not isinstance(expr, tuple):
return expr is sym
@@ -4329,11 +4291,10 @@ def _expr_depends_on(expr, sym):
return False
def _has_auto_menu_dep(node1, node2):
- """
- Returns True if node2 has an "automatic menu dependency" on node1. If node2
- has a prompt, we check its condition. Otherwise, we look directly at
- node2.dep.
- """
+ # Returns True if node2 has an "automatic menu dependency" on node1. If
+ # node2 has a prompt, we check its condition. Otherwise, we look directly
+ # at node2.dep.
+
if node2.prompt:
return _expr_depends_on(node2.prompt[1], node1.item)
@@ -4341,12 +4302,11 @@ def _has_auto_menu_dep(node1, node2):
return _expr_depends_on(node2.dep, node1.item)
def _flatten(node):
- """
- "Flattens" menu nodes without prompts (e.g. 'if' nodes and non-visible
- symbols with children from automatic menu creation) so that their children
- appear after them instead. This gives a clean menu structure with no
- unexpected "jumps" in the indentation.
- """
+ # "Flattens" menu nodes without prompts (e.g. 'if' nodes and non-visible
+ # symbols with children from automatic menu creation) so that their
+ # children appear after them instead. This gives a clean menu structure
+ # with no unexpected "jumps" in the indentation.
+
while node:
if node.list and (not node.prompt or node.prompt[0] == ""):
@@ -4364,12 +4324,11 @@ def _flatten(node):
node = node.next
def _remove_ifs(node):
- """
- Removes 'if' nodes (which can be recognized by MenuNode.item being None),
- which are assumed to already have been flattened. The C implementation
- doesn't bother to do this, but we expose the menu tree directly, and it
- makes it nicer to work with.
- """
+ # Removes 'if' nodes (which can be recognized by MenuNode.item being None),
+ # which are assumed to already have been flattened. The C implementation
+ # doesn't bother to do this, but we expose the menu tree directly, and it
+ # makes it nicer to work with.
+
first = node.list
while first and first.item is None:
first = first.next
@@ -4383,11 +4342,10 @@ def _remove_ifs(node):
node.list = first
def _finalize_choice(node):
- """
- Finalizes a choice, marking each symbol whose menu node has the choice as
- the parent as a choice symbol, and automatically determining types if not
- specified.
- """
+ # Finalizes a choice, marking each symbol whose menu node has the choice as
+ # the parent as a choice symbol, and automatically determining types if not
+ # specified.
+
choice = node.item
cur = node.list
@@ -4411,12 +4369,11 @@ def _finalize_choice(node):
sym.orig_type = choice.orig_type
def _finalize_tree(node):
- """
- Creates implicit menus from dependencies (see kconfig-language.txt),
- removes 'if' nodes, and finalizes choices. This pretty closely mirrors
- menu_finalize() from the C implementation, though we propagate dependencies
- during parsing instead.
- """
+ # Creates implicit menus from dependencies (see kconfig-language.txt),
+ # removes 'if' nodes, and finalizes choices. This pretty closely mirrors
+ # menu_finalize() from the C implementation, though we propagate
+ # dependencies during parsing instead.
+
if node.list:
# The menu node is a choice, menu, or if. Finalize each child in it.
cur = node.list
@@ -4459,10 +4416,9 @@ def _finalize_tree(node):
_check_choice_sanity(node.item)
def _check_sym_sanity(sym):
- """
- Checks various symbol properties that are handiest to check after parsing.
- Only generates errors and warnings.
- """
+ # Checks various symbol properties that are handiest to check after
+ # parsing. Only generates errors and warnings.
+
if sym.orig_type in (BOOL, TRISTATE):
# A helper function could be factored out here, but keep it
# speedy/straightforward for now. bool/tristate symbols are by far the
@@ -4536,10 +4492,9 @@ def _int_hex_value_is_sane(sym, type_):
sym.orig_type == type_
def _check_choice_sanity(choice):
- """
- Checks various choice properties that are handiest to check after parsing.
- Only generates errors and warnings.
- """
+ # Checks various choice properties that are handiest to check after
+ # parsing. Only generates errors and warnings.
+
if choice.orig_type not in (BOOL, TRISTATE):
choice.kconfig._warn("{} defined with type {}"
.format(_name_and_loc_str(choice),