summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Magnusson <ulfalizer@gmail.com>2017-10-28 00:46:00 +0200
committerUlf Magnusson <ulfalizer@gmail.com>2017-10-28 00:57:36 +0200
commit481bfd60d0b283f30b906d2edf8228aeb82e8492 (patch)
tree0e2451c219de37e71f4478596c9da32de545005a
parent9b1cc0dbad8e19930d5e1c6365745e14c7fa6076 (diff)
Nearly finalize API
Probably just some usability tweaks left. Having to do STR_TO_TRI[] for comparisons against 'assignable' values is kinda ugly and confusing.
-rw-r--r--examples/allnoconfig.py4
-rw-r--r--examples/allyesconfig.py10
-rw-r--r--kconfiglib.py617
-rw-r--r--testsuite.py561
4 files changed, 582 insertions, 610 deletions
diff --git a/examples/allnoconfig.py b/examples/allnoconfig.py
index 8d41912..2348da4 100644
--- a/examples/allnoconfig.py
+++ b/examples/allnoconfig.py
@@ -8,7 +8,7 @@
#
# $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/examples/allnoconfig.py
-from kconfiglib import Config, Symbol, tri_less
+from kconfiglib import Config, Symbol, STR_TO_TRI
import sys
def do_allnoconfig(node):
@@ -27,7 +27,7 @@ def do_allnoconfig(node):
if (sym.choice is None and
not sym.is_allnoconfig_y and
sym.assignable and
- tri_less(sym.assignable[0], sym.value)):
+ STR_TO_TRI[sym.assignable[0]] < sym.tri_value):
# Yup, lower it
sym.set_value(sym.assignable[0])
diff --git a/examples/allyesconfig.py b/examples/allyesconfig.py
index 32b302c..f91b6d7 100644
--- a/examples/allyesconfig.py
+++ b/examples/allyesconfig.py
@@ -18,7 +18,7 @@
#
# $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/examples/allyesconfig.py
-from kconfiglib import Config, Choice, tri_less
+from kconfiglib import Config, Choice, STR_TO_TRI
import sys
conf = Config(sys.argv[1])
@@ -70,7 +70,7 @@ while 1:
for sym in non_choice_syms:
# See allnoconfig example. [-1] gives the last (highest) assignable
# value.
- if sym.assignable and tri_less(sym.value, sym.assignable[-1]):
+ if sym.assignable and sym.tri_value < STR_TO_TRI[sym.assignable[-1]]:
sym.set_value(sym.assignable[-1])
no_changes = False
@@ -79,7 +79,7 @@ while 1:
for choice in choices:
# Handle a choice whose visibility allows it to be in "y" mode
- if choice.visibility == "y":
+ if choice.visibility == 2:
selection = choice.default_selection
# Does the choice have a default selection that we haven't already
@@ -95,12 +95,12 @@ while 1:
# This might happen if a choice depends on a symbol that can only be
# "m", for example.
- elif choice.visibility == "m":
+ elif choice.visibility == 1:
for sym in choice.symbols:
# Does the choice have a symbol that can be "m" that we haven't
# already set to "m"?
- if sym.user_value != "m" and "m" in sym.assignable:
+ if sym.user_tri_value != 1 and "m" in sym.assignable:
# Yup, set it
sym.set_value("m")
diff --git a/kconfiglib.py b/kconfiglib.py
index d0c46c6..25bb380 100644
--- a/kconfiglib.py
+++ b/kconfiglib.py
@@ -338,7 +338,8 @@ class Config(object):
sym.name = nmy
sym.is_constant = True
sym._type = TRISTATE
- sym._cached_val = nmy
+ sym._cached_tri_val = STR_TO_TRI[nmy]
+ sym._cached_str_val = nmy
self.const_syms[nmy] = sym
@@ -416,9 +417,10 @@ class Config(object):
"""
if self.defconfig_list is None:
return None
+
for filename, cond_expr in self.defconfig_list.defaults:
- if eval_expr(cond_expr) != "n":
- filename = self._expand_sym_refs(filename.value)
+ if eval_expr(cond_expr):
+ filename = self._expand_sym_refs(filename.str_value)
try:
with self._open(filename) as f:
return f.name
@@ -474,6 +476,7 @@ class Config(object):
self._warn("malformed string literal",
filename, linenr)
continue
+
# Strip quotes and remove escapings. The unescaping
# procedure should be safe since " can only appear as
# \" inside the string.
@@ -481,7 +484,7 @@ class Config(object):
.replace("\\\\", "\\")
if sym.choice is not None:
- mode = sym.choice.user_value
+ mode = sym.choice.user_str_value
if mode is not None and mode != val:
self._warn("assignment to {} changes mode of "
'containing choice from "{}" to "{}".'
@@ -504,10 +507,10 @@ class Config(object):
# Done parsing the assignment. Set the value.
- if sym.user_value is not None:
+ if sym.user_str_value is not None:
self._warn('{} set more than once. Old value: "{}", new '
'value: "{}".'
- .format(name, sym.user_value, val),
+ .format(name, sym.user_str_value, val),
filename, linenr)
sym._set_value_no_invalidate(val, True)
@@ -542,7 +545,7 @@ class Config(object):
returns "y".
This function always yields a tristate value. To get the value of
- non-bool, non-tristate symbols, use Symbol.value.
+ non-bool, non-tristate symbols, use Symbol.str_value.
The result of this function is consistent with how evaluation works for
conditional ('if ...') expressions in the configuration (as well as in
@@ -571,11 +574,12 @@ class Config(object):
for sym in self.defined_syms:
# We're iterating over all symbols, so no need for symbols to
# invalidate their dependent symbols
- sym.user_value = None
+ sym.user_str_value = sym.user_tri_value = None
sym._invalidate()
for choice in self._choices:
- choice.user_value = choice.user_selection = None
+ choice.user_str_value = choice.user_tri_value = \
+ choice.user_selection = None
choice._invalidate()
def enable_warnings(self):
@@ -616,7 +620,7 @@ class Config(object):
'config symbol prefix "{}"'.format(self.config_prefix),
"warnings " + ("enabled" if self._print_warnings else "disabled"),
"undef. symbol assignment warnings " +
- ("enabled" if self._print_undef_assign else "disabled")
+ ("enabled" if self._print_undef_assign else "disabled"),
)
return "<{}>".format(", ".join(fields))
@@ -1007,10 +1011,7 @@ class Config(object):
prev_node.next = prev_node = node
elif t0 == _T_SOURCE:
- kconfig_file = self._next_token()
- exp_kconfig_file = self._expand_sym_refs(kconfig_file)
-
- self._enter_file(exp_kconfig_file)
+ self._enter_file(self._expand_sym_refs(self._next_token()))
prev_node = self._parse_block(None, # end_token
parent,
visible_if_deps,
@@ -1030,8 +1031,7 @@ class Config(object):
node.parent = parent
node.filename = self._filename
node.linenr = self._linenr
- node.dep = \
- self._make_and(parent.dep, self._parse_expr(True))
+ node.dep = self._make_and(parent.dep, self._parse_expr(True))
self._parse_block(_T_ENDIF,
node, # parent
@@ -1259,16 +1259,10 @@ class Config(object):
node.item.env_var = env_var
if env_var not in os.environ:
- self._warn("the symbol {0} references the "
- "non-existent environment variable {1} "
- "(meaning the 'option env=\"{1}\"' will "
- "have no effect). If you're using "
- "Kconfiglib via 'make (i)scriptconfig', it "
- "should have set up the environment "
- "correctly for you. If you still got this "
- "message, that might be an error, and you "
- "should email ulfalizer a.t Google's email "
- "service.".format(node.item.name, env_var),
+ self._warn("'option env=\"{0}\"' on symbol {1} will "
+ "have no effect, because the environment "
+ "variable {0} is not set"
+ .format(node.item.name, env_var),
self._filename, self._linenr)
else:
defaults.append(
@@ -1565,9 +1559,9 @@ class Config(object):
add_fn(config_string)
sym._already_written = True
- elif (node.item == MENU and eval_expr(node.dep) != "n" and
- eval_expr(node.visibility) != "n") or \
- (node.item == COMMENT and eval_expr(node.dep) != "n"):
+ elif eval_expr(node.dep) and \
+ ((node.item == MENU and eval_expr(node.visibility)) or
+ node.item == COMMENT):
add_fn("\n#\n# {}\n#\n".format(node.prompt[0]))
@@ -1669,13 +1663,13 @@ class Config(object):
while 1:
sym_ref_match = _sym_ref_re_search(s)
- if sym_ref_match is None:
+ if not sym_ref_match:
return s
sym = self.syms.get(sym_ref_match.group(1))
s = s[:sym_ref_match.start()] + \
- (sym.value if sym is not None else "") + \
+ (sym.str_value if sym is not None else "") + \
s[sym_ref_match.end():]
#
@@ -1772,10 +1766,14 @@ class Symbol(object):
menuconfig-like functionality. (Check the implementation of the property
if you need to get the original type.)
- value:
+ str_value:
+ TODO
The current value of the symbol. Automatically recalculated as
dependencies change.
+ tri_value:
+ TODO
+
assignable:
A string containing the tristate values that can be assigned to the
symbol, ordered from lowest (n) to highest (y). This corresponds to the
@@ -1819,13 +1817,23 @@ class Symbol(object):
dependencies) are propagated to the prompt dependencies. Additional
dependencies can be specified with e.g. 'bool "foo" if <cond>".
- user_value:
- The value assigned with Symbol.set_value(), or None if no value has been
- assigned. This won't necessarily match 'value' even if set, as
- dependencies and prompt visibility take precedence.
+ user_str_value:
+ The string value assigned with Symbol.set_value(), or None if no value
+ has been assigned. This won't necessarily match 'str_value' even if set,
+ as dependencies and prompt visibility take precedence.
+
+ Note that you should use Symbol.set_value() to change this value (which
+ will also change user_tri_value). Changing the value directly will break
+ things, as Kconfiglib might need to invalidate other symbols. Properties
+ are always read-only.
+
+ The string value is only used in comparisons (e.g.
+ 'depends on SYMBOL = "foo"'). See user_tri_value.
- Note that you should use Symbol.set_value() to change this value.
- Properties are always read-only.
+ user_tri_value:
+ The tristate value corresponding to user_str_value. The rule is that "n",
+ "m", and "y" correspond to 0, 1, and 2 for BOOL and TRISTATE symbols.
+ Other symbol types always evaluate to 0 (n) in a tristate sense.
config_string:
The .config assignment string that would get written out for the symbol
@@ -1917,7 +1925,8 @@ class Symbol(object):
"_already_written",
"_cached_assignable",
"_cached_deps",
- "_cached_val",
+ "_cached_str_val",
+ "_cached_tri_val",
"_cached_vis",
"_direct_dependents",
"_type",
@@ -1935,7 +1944,8 @@ class Symbol(object):
"ranges",
"rev_dep",
"selects",
- "user_value",
+ "user_str_value",
+ "user_tri_value",
"weak_rev_dep",
)
@@ -1950,138 +1960,79 @@ class Symbol(object):
"""
if self._type == TRISTATE and \
- ((self.choice is not None and self.choice.value == "y") or
- self.config.modules.value == "n"):
+ ((self.choice is not None and self.choice.tri_value == 2) or
+ not self.config.modules.tri_value):
return BOOL
return self._type
@property
- def value(self):
+ def str_value(self):
"""
See the class documentation.
"""
- if self._cached_val is not None:
- return self._cached_val
+ if self._cached_str_val is not None:
+ return self._cached_str_val
+
+ if self._type in (BOOL, TRISTATE):
+ self._cached_str_val = TRI_TO_STR[self.tri_value]
+ return self._cached_str_val
# As a quirk of Kconfig, undefined symbols get their name as their
- # value. This is why things like "FOO = bar" work for seeing if FOO has
- # the value "bar".
+ # string value. This is why things like "FOO = bar" work for seeing if
+ # FOO has the value "bar".
if self._type == UNKNOWN:
- self._cached_val = self.name
+ self._cached_str_val = self.name
return self.name
- # This will hold the value at the end of the function
- val = _DEFAULT_VALUE[self._type]
-
+ val = ""
vis = self.visibility
- if self._type in (BOOL, TRISTATE):
- if self.choice is None:
- self._write_to_conf = (vis != "n")
+ self._write_to_conf = (vis != 0)
- if vis != "n" and self.user_value is not None:
- # If the symbol is visible and has a user value, we use
- # that
- val = _tri_min(self.user_value, vis)
-
- else:
- # Otherwise, we look at defaults and weak reverse
- # dependencies (implies)
-
- for default, cond in self.defaults:
- cond_val = eval_expr(cond)
- if cond_val != "n":
- self._write_to_conf = True
- val = _tri_min(eval_expr(default), cond_val)
- break
-
- # Weak reverse dependencies are only considered if our
- # direct dependencies are met
- if eval_expr(self.direct_dep) != "n":
- weak_rev_dep_val = \
- eval_expr(self.weak_rev_dep)
- if weak_rev_dep_val != "n":
- self._write_to_conf = True
- val = _tri_max(val, weak_rev_dep_val)
-
- # Reverse (select-related) dependencies take precedence
- rev_dep_val = eval_expr(self.rev_dep)
- if rev_dep_val != "n":
- self._write_to_conf = True
- val = _tri_max(val, rev_dep_val)
-
- else:
- # (bool/tristate) symbol in choice. See _get_visibility() for
- # more choice-related logic.
-
- # Initially
- self._write_to_conf = False
-
- if vis != "n":
- mode = self.choice.value
-
- if mode != "n":
- self._write_to_conf = True
-
- if mode == "y":
- val = "y" if self.choice.selection is self else "n"
- elif self.user_value in ("m", "y"):
- # mode == "m" and self.user_value is not None or
- # "n"
- val = "m"
-
- # "m" is promoted to "y" in two circumstances:
- # 1) If our type is boolean
- # 2) If our weak_rev_dep (from IMPLY) is "y"
- if val == "m" and \
- (self.type == BOOL or eval_expr(self.weak_rev_dep) == "y"):
- val = "y"
-
- elif self._type in (INT, HEX):
+ if self._type in (INT, HEX):
base = _TYPE_TO_BASE[self._type]
# Check if a range is in effect
for low_expr, high_expr, cond_expr in self.ranges:
- if eval_expr(cond_expr) != "n":
+ if eval_expr(cond_expr):
has_active_range = True
- low = int(low_expr.value, base) if \
- _is_base_n(low_expr.value, base) else 0
- high = int(high_expr.value, base) if \
- _is_base_n(high_expr.value, base) else 0
+ low = int(low_expr.str_value, base) if \
+ _is_base_n(low_expr.str_value, base) else 0
+ high = int(high_expr.str_value, base) if \
+ _is_base_n(high_expr.str_value, base) else 0
break
else:
has_active_range = False
- self._write_to_conf = (vis != "n")
-
- if vis != "n" and self.user_value is not None and \
- _is_base_n(self.user_value, base) and \
+ if vis and self.user_str_value is not None and \
+ _is_base_n(self.user_str_value, base) and \
(not has_active_range or
- low <= int(self.user_value, base) <= high):
+ low <= int(self.user_str_value, base) <= high):
# If the user value is well-formed and satisfies range
# contraints, it is stored in exactly the same form as
# specified in the assignment (with or without "0x", etc.)
- val = self.user_value
+ val = self.user_str_value
else:
# No user value or invalid user value. Look at defaults.
for val_expr, cond_expr in self.defaults:
- if eval_expr(cond_expr) != "n":
+ if eval_expr(cond_expr):
self._write_to_conf = True
# Similarly to above, well-formed defaults are
# preserved as is. Defaults that do not satisfy a range
# constraints are clamped and take on a standard form.
- val = val_expr.value
+ val = val_expr.str_value
if _is_base_n(val, base):
val_num = int(val, base)
+ # TODO: move outside?
if has_active_range:
clamped_val = None
@@ -2105,18 +2056,93 @@ class Symbol(object):
val = (hex(low) if self._type == HEX else str(low))
elif self._type == STRING:
- self._write_to_conf = (vis != "n")
-
- if vis != "n" and self.user_value is not None:
- val = self.user_value
+ if vis and self.user_str_value is not None:
+ val = self.user_str_value
else:
for val_expr, cond_expr in self.defaults:
- if eval_expr(cond_expr) != "n":
+ if eval_expr(cond_expr):
self._write_to_conf = True
- val = val_expr.value
+ val = val_expr.str_value
break
- self._cached_val = val
+ self._cached_str_val = val
+ return val
+
+ @property
+ def tri_value(self):
+ """
+ See the class documentation.
+ """
+
+ if self._cached_tri_val is not None:
+ return self._cached_tri_val
+
+ if self._type not in (BOOL, TRISTATE):
+ self._cached_tri_val = 0
+ return self._cached_tri_val
+
+ val = 0
+ vis = self.visibility
+
+ if self.choice is None:
+ self._write_to_conf = (vis != 0)
+
+ if vis and self.user_tri_value is not None:
+ # If the symbol is visible and has a user value, we use that
+ val = min(self.user_tri_value, vis)
+
+ else:
+ # Otherwise, we look at defaults and weak reverse dependencies
+ # (implies)
+
+ for default, cond in self.defaults:
+ cond_val = eval_expr(cond)
+ if cond_val:
+ val = min(cond_val, eval_expr(default))
+ self._write_to_conf = True
+ break
+
+ # Weak reverse dependencies are only considered if our
+ # direct dependencies are met
+ if eval_expr(self.direct_dep):
+ weak_rev_dep_val = eval_expr(self.weak_rev_dep)
+ if weak_rev_dep_val:
+ val = max(weak_rev_dep_val, val)
+ self._write_to_conf = True
+
+ # Reverse (select-related) dependencies take precedence
+ rev_dep_val = eval_expr(self.rev_dep)
+ if rev_dep_val:
+ val = max(rev_dep_val, val)
+ self._write_to_conf = True
+
+ else:
+ # (bool/tristate) symbol in choice. See _get_visibility() for
+ # more choice-related logic.
+
+ # Initially
+ self._write_to_conf = False
+
+ if vis:
+ mode = self.choice.tri_value
+
+ if mode:
+ self._write_to_conf = True
+
+ if mode == 2:
+ val = 2 if self.choice.selection is self else 0
+ elif self.user_tri_value:
+ # mode == 1, user value available and not 0
+ val = 1
+
+ # m is promoted to y in two circumstances:
+ # 1) If our type is boolean
+ # 2) If our weak_rev_dep (from IMPLY) is y
+ if val == 1 and \
+ (self.type == BOOL or eval_expr(self.weak_rev_dep) == 2):
+ val = 2
+
+ self._cached_tri_val = val
return val
@property
@@ -2152,8 +2178,9 @@ class Symbol(object):
# corresponds to the SYMBOL_AUTO flag in the C implementation.
return None
- # Note: _write_to_conf is determined when the value is calculated
- val = self.value
+ # Note: _write_to_conf is determined when the value is calculated. This
+ # is a hidden function call due to property magic.
+ val = self.str_value
if not self._write_to_conf:
return None
@@ -2184,10 +2211,11 @@ class Symbol(object):
Equal in effect to assigning the value to the symbol within a .config
file. Use the 'assignable' attribute to check which values can
currently be assigned. Setting values outside 'assignable' will cause
- Symbol.user_value to differ from Symbol.value (be truncated down or
- up). Values that are invalid for the type (such as "foo" or "m" for a
- BOOL) are ignored (and won't be stored in Symbol.user_value). A warning
- is printed for attempts to assign invalid values.
+ Symbol.user_str/tri_value to differ from Symbol.str/tri_value (be
+ truncated down or up). Values that are invalid for the type (such as
+ "foo" or "m" for a BOOL) are ignored (and won't be stored in
+ Symbol.user_str/tri_value). A warning is printed for attempts to assign
+ invalid values.
The values of other symbols that depend on this symbol are
automatically recalculated to reflect the new value.
@@ -2208,7 +2236,7 @@ class Symbol(object):
Resets the user value of the symbol, as if the symbol had never gotten
a user value via Config.load_config() or Symbol.set_value().
"""
- self.user_value = None
+ self.user_str_value = self.user_tri_value = None
self._rec_invalidate()
def __str__(self):
@@ -2229,17 +2257,17 @@ class Symbol(object):
def __repr__(self):
"""
Prints some information about the symbol (including its name, value,
- and visibility) when it is evaluated.
+ visibility, and location(s)) when it is evaluated.
"""
fields = [
"symbol " + self.name,
_TYPENAME[self.type],
- 'value "{}"'.format(self.value),
- "visibility {}".format(self.visibility)
+ 'value "{}"'.format(self.str_value),
+ "visibility " + TRI_TO_STR[self.visibility],
]
- if self.user_value is not None:
- fields.append('user value "{}"'.format(self.user_value))
+ if self.user_str_value is not None:
+ fields.append('user value "{}"'.format(self.user_str_value))
if self.choice is not None:
fields.append("choice symbol")
@@ -2256,11 +2284,13 @@ class Symbol(object):
if self is self.config.modules:
fields.append("is the modules symbol")
- fields.append("direct deps " + eval_expr(self.direct_dep))
+ fields.append("direct deps " + TRI_TO_STR[eval_expr(self.direct_dep)])
- fields.append("{} menu node{}"
- .format(len(self.nodes),
- "" if len(self.nodes) == 1 else "s"))
+ if self.nodes:
+ for node in self.nodes:
+ fields.append("{}:{}".format(node.filename, node.linenr))
+ else:
+ fields.append("undefined")
return "<{}>".format(", ".join(fields))
@@ -2292,7 +2322,7 @@ class Symbol(object):
self.nodes = []
- self.user_value = None
+ self.user_str_value = self.user_tri_value = None
# Populated in Config._build_dep() after parsing. Links the symbol to
# the symbols that immediately depend on it (in a caching/invalidation
@@ -2302,15 +2332,8 @@ class Symbol(object):
# Cached values
- # Caches the calculated value
- self._cached_val = None
- # Caches the visibility
- self._cached_vis = None
- # Caches the total list of dependent symbols. Calculated in
- # _get_dependent().
- self._cached_deps = None
- # Caches the 'assignable' attribute
- self._cached_assignable = None
+ self._cached_str_val = self._cached_tri_val = self._cached_vis = \
+ self._cached_deps = self._cached_assignable = None
# Flags
@@ -2332,35 +2355,35 @@ class Symbol(object):
vis = self.visibility
- if vis == "n":
+ if not vis:
return ""
rev_dep_val = eval_expr(self.rev_dep)
- if vis == "y":
- if rev_dep_val == "n":
- if self.type == BOOL or eval_expr(self.weak_rev_dep) == "y":
+ if vis == 2:
+ if not rev_dep_val:
+ if self.type == BOOL or eval_expr(self.weak_rev_dep) == 2:
return "ny"
return "nmy"
- if rev_dep_val == "y":
+ if rev_dep_val == 2:
return "y"
- # rev_dep_val == "m"
+ # rev_dep_val == 1
- if self.type == BOOL or eval_expr(self.weak_rev_dep) == "y":
+ if self.type == BOOL or eval_expr(self.weak_rev_dep) == 2:
return "y"
return "my"
- # vis == "m"
+ # vis == 1
- if rev_dep_val == "n":
- return "m" if eval_expr(self.weak_rev_dep) != "y" else "y"
+ if not rev_dep_val:
+ return "m" if eval_expr(self.weak_rev_dep) != 2 else "y"
- if rev_dep_val == "y":
+ if rev_dep_val == 2:
return "y"
- # vis == "m", rev_dep == "m" (rare)
+ # vis == rev_dep_val == 1
return "m"
@@ -2399,20 +2422,29 @@ class Symbol(object):
"promptless symbol {} will have no effect"
.format(value, self.name))
- self.user_value = value
+ self.user_str_value = value
+ self.user_tri_value = \
+ STR_TO_TRI[value] \
+ if self._type in (BOOL, TRISTATE) else \
+ 0
+
+ # TODO: assigning automatically changes choice yada yada
- if self.choice is not None and self._type in (BOOL, TRISTATE):
- if value == "y":
- self.choice.user_value = "y"
+ if self.choice is not None:
+ if self.user_tri_value == 2:
+ self.choice.user_str_value = "y"
+ self.choice.user_tri_value = 2
self.choice.user_selection = self
- elif value == "m":
- self.choice.user_value = "m"
+ elif self.user_tri_value == 1:
+ self.choice.user_str_value = "m"
+ self.choice.user_tri_value = 1
def _invalidate(self):
"""
Marks the symbol as needing to be recalculated.
"""
- self._cached_val = self._cached_vis = self._cached_assignable = None
+ self._cached_str_val = self._cached_tri_val = self._cached_vis = \
+ self._cached_assignable = None
def _rec_invalidate(self):
"""
@@ -2531,10 +2563,13 @@ class Choice(object):
The symbol that would be selected by default, had the user not selected
any symbol. Can be None for the same reasons as 'selected'.
- user_value:
+ user_str_value: TODO
The value (mode) selected by the user (by assigning some choice symbol or
calling Choice.set_value()). This does not necessarily match Choice.value
- for the same reasons that Symbol.user_value might not match Symbol.value.
+ for the same reasons that Symbol.user_str_value might not match
+ Symbol.value.
+
+ user_tri_value: TODO
user_selection:
The symbol selected by the user (by setting it to "y"). Ignored if the
@@ -2585,7 +2620,8 @@ class Choice(object):
"nodes",
"syms",
"user_selection",
- "user_value",
+ "user_str_value",
+ "user_tri_value",
)
#
@@ -2595,25 +2631,32 @@ class Choice(object):
@property
def type(self):
"""Returns the type of the choice. See Symbol.type."""
- if self._type == TRISTATE and self.config.modules.value == "n":
+ if self._type == TRISTATE and not self.config.modules.tri_value:
return BOOL
return self._type
@property
- def value(self):
+ def str_value(self):
"""
See the class documentation.
"""
- if self.user_value is not None:
- val = _tri_min(self.user_value, self.visibility)
+ return TRI_TO_STR[self.tri_value]
+
+ @property
+ def tri_value(self):
+ """
+ See the class documentation.
+ """
+ if self.user_tri_value is not None:
+ val = min(self.user_tri_value, self.visibility)
else:
- val = "n"
+ val = 0
- if val == "n" and not self.is_optional:
- val = "m"
+ if not val and not self.is_optional:
+ val = 1
# Promote "m" to "y" for boolean choices
- return "y" if val == "m" and self.type == BOOL else val
+ return 2 if val == 1 and self.type == BOOL else val
@property
def assignable(self):
@@ -2645,13 +2688,13 @@ class Choice(object):
if self._cached_selection is not _NO_CACHED_SELECTION:
return self._cached_selection
- if self.value != "y":
+ if self.tri_value != 2:
self._cached_selection = None
return None
# User choice available?
if self.user_selection is not None and \
- self.user_selection.visibility == "y":
+ self.user_selection.visibility == 2:
self._cached_selection = self.user_selection
return self.user_selection
@@ -2666,14 +2709,12 @@ class Choice(object):
See the class documentation.
"""
for sym, cond_expr in self.defaults:
- if (eval_expr(cond_expr) != "n" and
- # Must be visible too
- sym.visibility != "n"):
+ if eval_expr(cond_expr) and sym.visibility:
return sym
# Otherwise, pick the first visible symbol, if any
for sym in self.syms:
- if sym.visibility != "n":
+ if sym.visibility:
return sym
# Couldn't find a default
@@ -2692,7 +2733,8 @@ class Choice(object):
"which has type {}. Assignment ignored"
.format(value, _TYPENAME[self._type]))
- self.user_value = value
+ self.user_str_value = value
+ self.user_tri_value = STR_TO_TRI[value]
if self.syms:
# Hackish way to invalidate the choice and all the choice symbols
@@ -2703,7 +2745,7 @@ class Choice(object):
Resets the user value (mode) and user selection of the Choice, as if
the user had never touched the mode or any of the choice symbols.
"""
- self.user_value = self.user_selection = None
+ self.user_str_value = self.user_tri_value = self.user_selection = None
if self.syms:
# Hackish way to invalidate the choice and all the choice symbols
self.syms[0]._rec_invalidate()
@@ -2716,11 +2758,14 @@ class Choice(object):
return _sym_choice_str(self)
def __repr__(self):
+ """
+ TODO
+ """
fields = [
"choice" if self.name is None else "choice " + self.name,
_TYPENAME[self.type],
- "mode " + self.value,
- "visibility " + self.visibility
+ "mode " + self.str_value,
+ "visibility " + TRI_TO_STR[self.visibility],
]
if self.is_optional:
@@ -2729,13 +2774,11 @@ class Choice(object):
if self.selection is not None:
fields.append("{} selected".format(self.selection.name))
- fields.append("{} menu node{}"
- .format(len(self.nodes),
- "" if len(self.nodes) == 1 else "s"))
+ for node in self.nodes:
+ fields.append("{}:{}".format(node.filename, node.linenr))
return "<{}>".format(", ".join(fields))
-
#
# Private methods
#
@@ -2757,17 +2800,15 @@ class Choice(object):
self.nodes = []
- self.user_value = None
- self.user_selection = None
+ self.user_str_value = self.user_tri_value = self.user_selection = None
# The prompts and default values without any dependencies from
# enclosing menus and ifs propagated
self.defaults = []
# Cached values
+ self._cached_vis = self._cached_assignable = None
self._cached_selection = _NO_CACHED_SELECTION
- self._cached_vis = None
- self._cached_assignable = None
self.is_optional = False
@@ -2778,21 +2819,21 @@ class Choice(object):
vis = self.visibility
- if vis == "n":
+ if not vis:
return ""
- if vis == "y":
+ if vis == 2:
if not self.is_optional:
return "y" if self.type == BOOL else "my"
return "y"
- # vis == "m"
+ # vis == 1
return "nm" if self.is_optional else "m"
def _invalidate(self):
- self._cached_selection = _NO_CACHED_SELECTION
self._cached_vis = self._cached_assignable = None
+ self._cached_selection = _NO_CACHED_SELECTION
class MenuNode(object):
"""
@@ -2920,15 +2961,17 @@ class MenuNode(object):
if self.prompt is not None:
fields.append('prompt "{}" (visibility {})'
- .format(self.prompt[0], eval_expr(self.prompt[1])))
+ .format(self.prompt[0],
+ TRI_TO_STR[eval_expr(self.prompt[1])]))
if isinstance(self.item, Symbol) and self.is_menuconfig:
fields.append("is menuconfig")
- fields.append("deps " + eval_expr(self.dep))
+ fields.append("deps " + TRI_TO_STR[eval_expr(self.dep)])
if self.item == MENU:
- fields.append("'visible if' deps " + eval_expr(self.visibility))
+ fields.append("'visible if' deps " + \
+ TRI_TO_STR[eval_expr(self.visibility)])
if isinstance(self.item, (Symbol, Choice)) and self.help is not None:
fields.append("has help")
@@ -2957,65 +3000,26 @@ class InternalError(Exception):
# Public functions
#
-def tri_less(v1, v2):
- """
- Returns True if the tristate v1 is less than the tristate v2, where "n",
- "m" and "y" are ordered from lowest to highest.
- """
- return _TRI_TO_INT[v1] < _TRI_TO_INT[v2]
-
-def tri_less_eq(v1, v2):
- """
- Returns True if the tristate v1 is less than or equal to the tristate v2,
- where "n", "m" and "y" are ordered from lowest to highest.
- """
- return _TRI_TO_INT[v1] <= _TRI_TO_INT[v2]
-
-def tri_greater(v1, v2):
- """
- Returns True if the tristate v1 is greater than the tristate v2, where "n",
- "m" and "y" are ordered from lowest to highest.
- """
- return _TRI_TO_INT[v1] > _TRI_TO_INT[v2]
-
-def tri_greater_eq(v1, v2):
- """
- Returns True if the tristate v1 is greater than or equal to the tristate
- v2, where "n", "m" and "y" are ordered from lowest to highest.
- """
- return _TRI_TO_INT[v1] >= _TRI_TO_INT[v2]
-
-# Expression evaluation
-
def eval_expr(expr):
"""
- Evaluates an expression to "n", "m", or "y".
+ TODO
"""
-
if isinstance(expr, Symbol):
- # Non-bool/tristate symbols are always "n" in a tristate sense,
- # regardless of their value
- return expr.value if expr._type in (BOOL, TRISTATE) else "n"
+ return expr.tri_value
if expr[0] == AND:
- ev1 = eval_expr(expr[1])
-
- # Short-circuit the ev1 == "n" case
- return "n" if ev1 == "n" else \
- _tri_min(ev1, eval_expr(expr[2]))
+ v1 = eval_expr(expr[1])
+ # Short-circuit the n case as an optimization (~5% faster
+ # allnoconfig.py and allyesconfig.py, as of writing)
+ return 0 if not v1 else min(v1, eval_expr(expr[2]))
if expr[0] == OR:
- ev1 = eval_expr(expr[1])
-
- # Short-circuit the ev1 == "y" case
- return "y" if ev1 == "y" else \
- _tri_max(ev1, eval_expr(expr[2]))
+ v1 = eval_expr(expr[1])
+ # Short-circuit the y case as an optimization
+ return 2 if v1 == 2 else max(v1, eval_expr(expr[2]))
if expr[0] == NOT:
- ev = eval_expr(expr[1])
- return "n" if ev == "y" else \
- "y" if ev == "n" else \
- "m"
+ return 2 - eval_expr(expr[1])
if expr[0] in _RELATIONS:
# Implements <, <=, >, >= comparisons as well. These were added to
@@ -3030,16 +3034,16 @@ def eval_expr(expr):
# If both operands are strings...
if op1._type == STRING and op2._type == STRING:
# ...then compare them lexicographically
- comp = _strcmp(op1.value, op2.value)
+ comp = _strcmp(op1.str_value, op2.str_value)
else:
# Otherwise, try to compare them as numbers...
try:
- comp = int(op1.value, _TYPE_TO_BASE[op1._type]) - \
- int(op2.value, _TYPE_TO_BASE[op2._type])
+ comp = int(op1.str_value, _TYPE_TO_BASE[op1._type]) - \
+ int(op2.str_value, _TYPE_TO_BASE[op2._type])
except ValueError:
# Fall back on a lexicographic comparison if the operands don't
# parse as numbers
- comp = _strcmp(op1.value, op2.value)
+ comp = _strcmp(op1.str_value, op2.str_value)
if oper == EQUAL: res = comp == 0
elif oper == UNEQUAL: res = comp != 0
@@ -3048,12 +3052,15 @@ def eval_expr(expr):
elif oper == GREATER: res = comp > 0
elif oper == GREATER_EQUAL: res = comp >= 0
- return "y" if res else "n"
+ return 2*res
_internal_error("Internal error while evaluating expression: "
"unknown operation {}.".format(expr[0]))
def expr_str(expr):
+ """
+ TODO
+ """
if isinstance(expr, Symbol):
return expr.name if not expr.is_constant else '"{}"'.format(expr.name)
@@ -3085,47 +3092,35 @@ def _get_visibility(sc):
'make menuconfig'. This function calculates the visibility for the Symbol
or Choice 'sc' -- the logic is nearly identical.
"""
- vis = "n"
+ vis = 0
for node in sc.nodes:
if node.prompt:
- vis = _tri_max(vis, eval_expr(node.prompt[1]))
+ vis = max(vis, eval_expr(node.prompt[1]))
if isinstance(sc, Symbol) and sc.choice is not None:
if sc.choice._type == TRISTATE and sc._type != TRISTATE and \
- sc.choice.value != "y":
+ sc.choice.tri_value != 2:
# Non-tristate choice symbols in tristate choices depend on the
# choice being in mode "y"
- return "n"
+ return 0
- if sc._type == TRISTATE and vis == "m" and sc.choice.value == "y":
+ if sc._type == TRISTATE and vis == 1 and sc.choice.tri_value == 2:
# Choice symbols with visibility "m" are not visible if the
# choice has mode "y"
- return "n"
+ return 0
- vis = _tri_min(vis, sc.choice.visibility)
+ vis = min(vis, sc.choice.visibility)
- # Promote "m" to "y" if we're dealing with a non-tristate. This might lead
- # to infinite recursion if something really weird is done with MODULES, but
+ # Promote m to y if we're dealing with a non-tristate. This might lead to
+ # infinite recursion if something really weird is done with MODULES, but
# it's not a problem in practice.
- if vis == "m" and \
- (sc._type != TRISTATE or sc.config.modules.value == "n"):
- return "y"
+ if vis == 1 and \
+ (sc._type != TRISTATE or not sc.config.modules.tri_value):
+ return 2
return vis
-def _tri_min(v1, v2):
- """
- Returns the smallest tristate value among v1 and v2.
- """
- return v1 if _TRI_TO_INT[v1] <= _TRI_TO_INT[v2] else v2
-
-def _tri_max(v1, v2):
- """
- Returns the largest tristate value among v1 and v2.
- """
- return v1 if _TRI_TO_INT[v1] >= _TRI_TO_INT[v2] else v2
-
def _make_depend_on(sym, expr):
"""
Adds 'sym' as a dependency to all symbols in 'expr'. Constant symbols in
@@ -3192,10 +3187,8 @@ def _strcmp(s1, s2):
return (s1 > s2) - (s1 < s2)
def _stderr_msg(msg, filename, linenr):
- if filename is None:
- s = msg
- else:
- s = "{}:{}: ".format(filename, linenr)
+ if filename is not None:
+ msg = "{}:{}: {}".format(filename, linenr, msg)
sys.stderr.write(msg + "\n")
@@ -3509,6 +3502,18 @@ def _finalize_tree(node):
COMMENT,
) = range(2)
+TRI_TO_STR = {
+ 0: "n",
+ 1: "m",
+ 2: "y",
+}
+
+STR_TO_TRI = {
+ "n": 0,
+ "m": 1,
+ "y": 2,
+}
+
#
# Internal global constants
#
@@ -3643,12 +3648,12 @@ _sym_ref_re_search = re.compile(r"\$([A-Za-z0-9_]+)").search
# Strings to use for types
_TYPENAME = {
- UNKNOWN: "unknown",
- BOOL: "bool",
+ UNKNOWN: "unknown",
+ BOOL: "bool",
TRISTATE: "tristate",
- STRING: "string",
- HEX: "hex",
- INT: "int",
+ STRING: "string",
+ HEX: "hex",
+ INT: "int",
}
# Token to type mapping
@@ -3662,16 +3667,6 @@ _TOKEN_TO_TYPE = {
_T_TRISTATE: TRISTATE,
}
-# Default values for symbols of different types (the value the symbol gets if
-# it is not assigned a user value and none of its 'default' clauses kick in)
-_DEFAULT_VALUE = {
- BOOL: "n",
- TRISTATE: "n",
- HEX: "",
- INT: "",
- STRING: "",
-}
-
# Constant representing that there's no cached choice selection. This is
# distinct from a cached None (no selection). We create a unique object (any
# will do) for it so we can test with 'is'.
diff --git a/testsuite.py b/testsuite.py
index e81ba1d..711a0fb 100644
--- a/testsuite.py
+++ b/testsuite.py
@@ -168,9 +168,9 @@ def run_selftests():
Verifies that a symbol has a particular value.
"""
sym = c.syms[sym_name]
- verify(sym.value == val,
+ verify(sym.str_value == val,
'expected {} to have the value "{}", had the value "{}"'
- .format(sym_name, val, sym.value))
+ .format(sym_name, val, sym.str_value))
def assign_and_verify_value(sym_name, val, new_val):
"""
@@ -178,13 +178,13 @@ def run_selftests():
'new_val'.
"""
sym = c.syms[sym_name]
- old_val = sym.value
+ old_val = sym.str_value
sym.set_value(val)
- verify(sym.value == new_val,
+ verify(sym.str_value == new_val,
'expected {} to have the value "{}" after being assigned the '
'value "{}". Instead, the value is "{}". The old value was '
'"{}".'
- .format(sym_name, new_val, val, sym.value, old_val))
+ .format(sym_name, new_val, val, sym.str_value, old_val))
def assign_and_verify(sym_name, user_val):
"""
@@ -197,51 +197,19 @@ def run_selftests():
"""Assigns a user value to the symbol and verifies the new user
value."""
sym = c.syms[sym_name]
- sym_old_user_val = sym.user_value
+ sym_old_user_val = sym.user_str_value
sym.set_value(val)
- verify(sym.user_value == user_val,
+ verify(sym.user_str_value == user_val,
"{} should have the user value '{}' after being assigned "
"the user value '{}'. Instead, the new user value was '{}'. "
"The old user value was '{}'."
- .format(sym_name, user_val, user_val, sym.user_value,
+ .format(sym_name, user_val, user_val, sym.user_str_value,
sym_old_user_val))
#
# Selftests
#
- print("Testing tristate comparisons")
-
- def verify_truth_table(comp_fn, *table):
- for (x, y), expected in zip((("n", "n"), ("n", "m"), ("n", "y"),
- ("m", "n"), ("m", "m"), ("m", "y"),
- ("y", "n"), ("y", "m"), ("y", "y")),
- table):
- verify(comp_fn(x, y) == expected,
- "expected {} on ('{}', '{}') to be '{}'".
- format(comp_fn, x, y, expected))
-
- verify_truth_table(kconfiglib.tri_less,
- False, True, True,
- False, False, True,
- False, False, False)
-
- verify_truth_table(kconfiglib.tri_less_eq,
- True, True, True,
- False, True, True,
- False, False, True)
-
- verify_truth_table(kconfiglib.tri_greater,
- False, False, False,
- True, False, False,
- True, True, False)
-
- verify_truth_table(kconfiglib.tri_greater_eq,
- True, False, False,
- True, True, False,
- True, True, True)
-
-
print("Testing string literal lexing")
# Dummy empty configuration just to get a Config object
@@ -250,14 +218,12 @@ def run_selftests():
def verify_string_lex(s, res):
"""
Verifies that a constant symbol with the name 'res' is produced from
- lexing 's'. Strips the first and last characters from 's' so that
- readable raw strings can be used as input
+ lexing 's'
"""
- c._line = s[1:-1]
- c._tokenize(True)
+ c.eval_string(s)
verify(c._tokens[0].name == res,
- 'expected {} to produced the constant symbol {}, produced {}'
- .format(s, c._tokens[0].name, res))
+ "expected <{}> to produced the constant symbol <{}>, "
+ 'produced <{}>'.format(s[1:-1], c._tokens[0].name, res))
verify_string_lex(r""" "" """, "")
verify_string_lex(r""" '' """, "")
@@ -293,13 +259,12 @@ def run_selftests():
first and last characters from 's' so we can use readable raw strings
as input.
"""
- c._line = s[1:-1]
try:
- c._tokenize(True)
+ c.eval_string(s)
except kconfiglib.KconfigSyntaxError:
pass
else:
- fail("expected tokenization of {} to fail, didn't".format(s))
+ fail("expected tokenization of {} to fail, didn't".format(s[1:-1]))
verify_string_bad(r""" " """)
verify_string_bad(r""" ' """)
@@ -323,168 +288,168 @@ def run_selftests():
"'{}' evaluated to {}, expected {}".format(expr, res, val))
# No modules
- verify_eval("n", "n")
- verify_eval("m", "n")
- verify_eval("y", "y")
- verify_eval("'n'", "n")
- verify_eval("'m'", "n")
- verify_eval("'y'", "y")
- verify_eval("M", "y")
+ verify_eval("n", 0)
+ verify_eval("m", 0)
+ verify_eval("y", 2)
+ verify_eval("'n'", 0)
+ verify_eval("'m'", 0)
+ verify_eval("'y'", 2)
+ verify_eval("M", 2)
# Modules
- c.syms["MODULES"].set_value("y")
- verify_eval("n", "n")
- verify_eval("m", "m")
- verify_eval("y", "y")
- verify_eval("'n'", "n")
- verify_eval("'m'", "m")
- verify_eval("'y'", "y")
- verify_eval("M", "m")
- verify_eval("(Y || N) && (m && y)", "m")
+ c.modules.set_value("y")
+ verify_eval("n", 0)
+ verify_eval("m", 1)
+ verify_eval("y", 2)
+ verify_eval("'n'", 0)
+ verify_eval("'m'", 1)
+ verify_eval("'y'", 2)
+ verify_eval("M", 1)
+ verify_eval("(Y || N) && (m && y)", 1)
# Non-bool/non-tristate symbols are always "n" in a tristate sense
- verify_eval("Y_STRING", "n")
- verify_eval("Y_STRING || m", "m")
+ verify_eval("Y_STRING", 0)
+ verify_eval("Y_STRING || m", 1)
# As are all constants besides "y" and "m"
- verify_eval('"foo"', "n")
- verify_eval('"foo" || "bar"', "n")
- verify_eval('"foo" || m', "m")
+ verify_eval('"foo"', 0)
+ verify_eval('"foo" || "bar"', 0)
+ verify_eval('"foo" || m', 1)
# Test equality for symbols
- verify_eval("N = N", "y")
- verify_eval("N = n", "y")
- verify_eval("N = 'n'", "y")
- verify_eval("N != N", "n")
- verify_eval("N != n", "n")
- verify_eval("N != 'n'", "n")
-
- verify_eval("M = M", "y")
- verify_eval("M = m", "y")
- verify_eval("M = 'm'", "y")
- verify_eval("M != M", "n")
- verify_eval("M != m", "n")
- verify_eval("M != 'm'", "n")
-
- verify_eval("Y = Y", "y")
- verify_eval("Y = y", "y")
- verify_eval("Y = 'y'", "y")
- verify_eval("Y != Y", "n")
- verify_eval("Y != y", "n")
- verify_eval("Y != 'y'", "n")
-
- verify_eval("N != M", "y")
- verify_eval("N != Y", "y")
- verify_eval("M != Y", "y")
-
- verify_eval("Y_STRING = y", "y")
- verify_eval("Y_STRING = 'y'", "y")
- verify_eval('FOO_BAR_STRING = "foo bar"', "y")
- verify_eval('FOO_BAR_STRING != "foo bar baz"', "y")
- verify_eval('INT_37 = 37', "y")
- verify_eval("INT_37 = '37'", "y")
- verify_eval('HEX_0X37 = 0x37', "y")
- verify_eval("HEX_0X37 = '0x37'", "y")
+ verify_eval("N = N", 2)
+ verify_eval("N = n", 2)
+ verify_eval("N = 'n'", 2)
+ verify_eval("N != N", 0)
+ verify_eval("N != n", 0)
+ verify_eval("N != 'n'", 0)
+
+ verify_eval("M = M", 2)
+ verify_eval("M = m", 2)
+ verify_eval("M = 'm'", 2)
+ verify_eval("M != M", 0)
+ verify_eval("M != m", 0)
+ verify_eval("M != 'm'", 0)
+
+ verify_eval("Y = Y", 2)
+ verify_eval("Y = y", 2)
+ verify_eval("Y = 'y'", 2)
+ verify_eval("Y != Y", 0)
+ verify_eval("Y != y", 0)
+ verify_eval("Y != 'y'", 0)
+
+ verify_eval("N != M", 2)
+ verify_eval("N != Y", 2)
+ verify_eval("M != Y", 2)
+
+ verify_eval("Y_STRING = y", 2)
+ verify_eval("Y_STRING = 'y'", 2)
+ verify_eval('FOO_BAR_STRING = "foo bar"', 2)
+ verify_eval('FOO_BAR_STRING != "foo bar baz"', 2)
+ verify_eval('INT_37 = 37', 2)
+ verify_eval("INT_37 = '37'", 2)
+ verify_eval('HEX_0X37 = 0x37', 2)
+ verify_eval("HEX_0X37 = '0x37'", 2)
# These should also hold after 31847b67 (kconfig: allow use of relations
# other than (in)equality)
- verify_eval("HEX_0X37 = '0x037'", "y")
- verify_eval("HEX_0X37 = '0x0037'", "y")
+ verify_eval("HEX_0X37 = '0x037'", 2)
+ verify_eval("HEX_0X37 = '0x0037'", 2)
# Constant symbol comparisons
- verify_eval('"foo" != "bar"', "y")
- verify_eval('"foo" = "bar"', "n")
- verify_eval('"foo" = "foo"', "y")
+ verify_eval('"foo" != "bar"', 2)
+ verify_eval('"foo" = "bar"', 0)
+ verify_eval('"foo" = "foo"', 2)
# Undefined symbols get their name as their value
c.disable_warnings()
- verify_eval("'not_defined' = not_defined", "y")
- verify_eval("not_defined_2 = not_defined_2", "y")
- verify_eval("not_defined_1 != not_defined_2", "y")
+ verify_eval("'not_defined' = not_defined", 2)
+ verify_eval("not_defined_2 = not_defined_2", 2)
+ verify_eval("not_defined_1 != not_defined_2", 2)
# Test less than/greater than
# Basic evaluation
- verify_eval("INT_37 < 38", "y")
- verify_eval("38 < INT_37", "n")
- verify_eval("INT_37 < '38'", "y")
- verify_eval("'38' < INT_37", "n")
- verify_eval("INT_37 < 138", "y")
- verify_eval("138 < INT_37", "n")
- verify_eval("INT_37 < '138'", "y")
- verify_eval("'138' < INT_37", "n")
- verify_eval("INT_37 < -138", "n")
- verify_eval("-138 < INT_37", "y")
- verify_eval("INT_37 < '-138'", "n")
- verify_eval("'-138' < INT_37", "y")
- verify_eval("INT_37 < 37", "n")
- verify_eval("37 < INT_37", "n")
- verify_eval("INT_37 < 36", "n")
- verify_eval("36 < INT_37", "y")
+ verify_eval("INT_37 < 38", 2)
+ verify_eval("38 < INT_37", 0)
+ verify_eval("INT_37 < '38'", 2)
+ verify_eval("'38' < INT_37", 0)
+ verify_eval("INT_37 < 138", 2)
+ verify_eval("138 < INT_37", 0)
+ verify_eval("INT_37 < '138'", 2)
+ verify_eval("'138' < INT_37", 0)
+ verify_eval("INT_37 < -138", 0)
+ verify_eval("-138 < INT_37", 2)
+ verify_eval("INT_37 < '-138'", 0)
+ verify_eval("'-138' < INT_37", 2)
+ verify_eval("INT_37 < 37", 0)
+ verify_eval("37 < INT_37", 0)
+ verify_eval("INT_37 < 36", 0)
+ verify_eval("36 < INT_37", 2)
# Different formats in comparison
- verify_eval("INT_37 < 0x26", "y") # 38
- verify_eval("INT_37 < 0x25", "n") # 37
- verify_eval("INT_37 < 0x24", "n") # 36
- verify_eval("HEX_0X37 < 56", "y") # 0x38
- verify_eval("HEX_0X37 < 55", "n") # 0x37
- verify_eval("HEX_0X37 < 54", "n") # 0x36
+ verify_eval("INT_37 < 0x26", 2) # 38
+ verify_eval("INT_37 < 0x25", 0) # 37
+ verify_eval("INT_37 < 0x24", 0) # 36
+ verify_eval("HEX_0X37 < 56", 2) # 0x38
+ verify_eval("HEX_0X37 < 55", 0) # 0x37
+ verify_eval("HEX_0X37 < 54", 0) # 0x36
# Other int comparisons
- verify_eval("INT_37 <= 38", "y")
- verify_eval("INT_37 <= 37", "y")
- verify_eval("INT_37 <= 36", "n")
- verify_eval("INT_37 > 38", "n")
- verify_eval("INT_37 > 37", "n")
- verify_eval("INT_37 > 36", "y")
- verify_eval("INT_37 >= 38", "n")
- verify_eval("INT_37 >= 37", "y")
- verify_eval("INT_37 >= 36", "y")
+ verify_eval("INT_37 <= 38", 2)
+ verify_eval("INT_37 <= 37", 2)
+ verify_eval("INT_37 <= 36", 0)
+ verify_eval("INT_37 > 38", 0)
+ verify_eval("INT_37 > 37", 0)
+ verify_eval("INT_37 > 36", 2)
+ verify_eval("INT_37 >= 38", 0)
+ verify_eval("INT_37 >= 37", 2)
+ verify_eval("INT_37 >= 36", 2)
# Other hex comparisons
- verify_eval("HEX_0X37 <= 0x38", "y")
- verify_eval("HEX_0X37 <= 0x37", "y")
- verify_eval("HEX_0X37 <= 0x36", "n")
- verify_eval("HEX_0X37 > 0x38", "n")
- verify_eval("HEX_0X37 > 0x37", "n")
- verify_eval("HEX_0X37 > 0x36", "y")
- verify_eval("HEX_0X37 >= 0x38", "n")
- verify_eval("HEX_0X37 >= 0x37", "y")
- verify_eval("HEX_0X37 >= 0x36", "y")
+ verify_eval("HEX_0X37 <= 0x38", 2)
+ verify_eval("HEX_0X37 <= 0x37", 2)
+ verify_eval("HEX_0X37 <= 0x36", 0)
+ verify_eval("HEX_0X37 > 0x38", 0)
+ verify_eval("HEX_0X37 > 0x37", 0)
+ verify_eval("HEX_0X37 > 0x36", 2)
+ verify_eval("HEX_0X37 >= 0x38", 0)
+ verify_eval("HEX_0X37 >= 0x37", 2)
+ verify_eval("HEX_0X37 >= 0x36", 2)
# A hex holding a value without a "0x" prefix should still be treated as
# hexadecimal
- verify_eval("HEX_37 < 0x38", "y")
- verify_eval("HEX_37 < 0x37", "n")
- verify_eval("HEX_37 < 0x36", "n")
+ verify_eval("HEX_37 < 0x38", 2)
+ verify_eval("HEX_37 < 0x37", 0)
+ verify_eval("HEX_37 < 0x36", 0)
# Symbol comparisons
- verify_eval("INT_37 < HEX_0X37", "y")
- verify_eval("INT_37 > HEX_0X37", "n")
- verify_eval("HEX_0X37 < INT_37 ", "n")
- verify_eval("HEX_0X37 > INT_37 ", "y")
- verify_eval("INT_37 < INT_37 ", "n")
- verify_eval("INT_37 <= INT_37 ", "y")
- verify_eval("INT_37 > INT_37 ", "n")
- verify_eval("INT_37 <= INT_37 ", "y")
+ verify_eval("INT_37 < HEX_0X37", 2)
+ verify_eval("INT_37 > HEX_0X37", 0)
+ verify_eval("HEX_0X37 < INT_37 ", 0)
+ verify_eval("HEX_0X37 > INT_37 ", 2)
+ verify_eval("INT_37 < INT_37 ", 0)
+ verify_eval("INT_37 <= INT_37 ", 2)
+ verify_eval("INT_37 > INT_37 ", 0)
+ verify_eval("INT_37 <= INT_37 ", 2)
# Strings compare lexicographically
- verify_eval("'aa' < 'ab'", "y")
- verify_eval("'aa' > 'ab'", "n")
- verify_eval("'ab' < 'aa'", "n")
- verify_eval("'ab' > 'aa'", "y")
+ verify_eval("'aa' < 'ab'", 2)
+ verify_eval("'aa' > 'ab'", 0)
+ verify_eval("'ab' < 'aa'", 0)
+ verify_eval("'ab' > 'aa'", 2)
# Comparisons where one of the operands doesn't parse as a number also give
# a lexicographic comparison
- verify_eval("INT_37 < '37a' ", "y")
- verify_eval("'37a' > INT_37", "y")
- verify_eval("INT_37 <= '37a' ", "y")
- verify_eval("'37a' >= INT_37", "y")
- verify_eval("INT_37 >= '37a' ", "n")
- verify_eval("INT_37 > '37a' ", "n")
- verify_eval("'37a' < INT_37", "n")
- verify_eval("'37a' <= INT_37", "n")
+ verify_eval("INT_37 < '37a' ", 2)
+ verify_eval("'37a' > INT_37", 2)
+ verify_eval("INT_37 <= '37a' ", 2)
+ verify_eval("'37a' >= INT_37", 2)
+ verify_eval("INT_37 >= '37a' ", 0)
+ verify_eval("INT_37 > '37a' ", 0)
+ verify_eval("'37a' < INT_37", 0)
+ verify_eval("'37a' <= INT_37", 0)
def verify_eval_bad(expr):
try:
@@ -519,6 +484,8 @@ def run_selftests():
c = kconfiglib.Config("Kconfiglib/tests/Kstr", warn=False)
+ c.modules.set_value("y")
+
verify_str(c.syms["UNDEFINED"], """
""")
@@ -582,8 +549,10 @@ config INT
# We still hardcode the modules symbol. Otherwise OPTIONS would have made
# more sense as a name here.
- verify_str(c.syms["MODULES"], """
+ verify_str(c.modules, """
config MODULES
+ bool
+ prompt "MODULES"
option modules
""")
@@ -619,59 +588,58 @@ choice
c = kconfiglib.Config("Kconfiglib/tests/Krepr", warn=False)
verify_repr(c.syms["UNDEFINED"], """
-<symbol UNDEFINED, unknown, value "UNDEFINED", visibility n, direct deps n, 0 menu nodes>
+<symbol UNDEFINED, unknown, value "UNDEFINED", visibility n, direct deps n, undefined>
""")
verify_repr(c.syms["BASIC"], """
-<symbol BASIC, bool, value "y", visibility n, direct deps y, 1 menu node>
+<symbol BASIC, bool, value "y", visibility n, direct deps y, Kconfiglib/tests/Krepr:9>
""")
verify_repr(c.syms["VISIBLE"], """
-<symbol VISIBLE, bool, value "n", visibility y, direct deps y, 1 menu node>
+<symbol VISIBLE, bool, value "n", visibility y, direct deps y, Kconfiglib/tests/Krepr:14>
""")
verify_repr(c.syms["DIR_DEP_N"], """
-<symbol DIR_DEP_N, unknown, value "DIR_DEP_N", visibility n, direct deps n, 1 menu node>
+<symbol DIR_DEP_N, unknown, value "DIR_DEP_N", visibility n, direct deps n, Kconfiglib/tests/Krepr:17>
""")
verify_repr(c.syms["OPTIONS"], """
-<symbol OPTIONS, unknown, value "OPTIONS", visibility n, allnoconfig_y, is the defconfig_list symbol, from environment variable ENV, direct deps y, 1 menu node>
+<symbol OPTIONS, unknown, value "OPTIONS", visibility n, allnoconfig_y, is the defconfig_list symbol, from environment variable ENV, direct deps y, Kconfiglib/tests/Krepr:20>
""")
verify_repr(c.syms["MULTI_DEF"], """
-<symbol MULTI_DEF, unknown, value "MULTI_DEF", visibility n, direct deps y, 2 menu nodes>
+<symbol MULTI_DEF, unknown, value "MULTI_DEF", visibility n, direct deps y, Kconfiglib/tests/Krepr:25, Kconfiglib/tests/Krepr:26>
""")
verify_repr(c.syms["CHOICE_1"], """
-<symbol CHOICE_1, tristate, value "n", visibility y, choice symbol, direct deps y, 1 menu node>
+<symbol CHOICE_1, tristate, value "n", visibility y, choice symbol, direct deps y, Kconfiglib/tests/Krepr:33>
""")
- verify_repr(c.syms["MODULES"], """
-<symbol MODULES, bool, value "y", visibility n, is the modules symbol, direct deps y, 1 menu node>
+ verify_repr(c.modules, """
+<symbol MODULES, bool, value "y", visibility n, is the modules symbol, direct deps y, Kconfiglib/tests/Krepr:1>
""")
-
print("Testing Choice.__repr__()")
verify_repr(c.named_choices["CHOICE"], """
-<choice CHOICE, tristate, mode m, visibility y, 1 menu node>
+<choice CHOICE, tristate, mode m, visibility y, Kconfiglib/tests/Krepr:30>
""")
c.named_choices["CHOICE"].set_value("y")
verify_repr(c.named_choices["CHOICE"], """
-<choice CHOICE, tristate, mode y, visibility y, CHOICE_1 selected, 1 menu node>
+<choice CHOICE, tristate, mode y, visibility y, CHOICE_1 selected, Kconfiglib/tests/Krepr:30>
""")
c.syms["CHOICE_2"].set_value("y")
verify_repr(c.named_choices["CHOICE"], """
-<choice CHOICE, tristate, mode y, visibility y, CHOICE_2 selected, 1 menu node>
+<choice CHOICE, tristate, mode y, visibility y, CHOICE_2 selected, Kconfiglib/tests/Krepr:30>
""")
verify_repr(c.syms["CHOICE_HOOK"].nodes[0].next.item, """
-<choice, tristate, mode n, visibility n, optional, 1 menu node>
+<choice, tristate, mode n, visibility n, optional, Kconfiglib/tests/Krepr:43>
""")
@@ -830,13 +798,13 @@ g
c = kconfiglib.Config("Kconfiglib/tests/Kvisibility")
def verify_visibility(item, no_module_vis, module_vis):
- c.syms["MODULES"].set_value("n")
+ c.modules.set_value("n")
verify(item.visibility == no_module_vis,
"expected {} to have visibility {} without modules, had "
"visibility {}".
format(repr(item), no_module_vis, item.visibility))
- c.syms["MODULES"].set_value("y")
+ c.modules.set_value("y")
verify(item.visibility == module_vis,
"expected {} to have visibility {} with modules, had "
"visibility {}".
@@ -844,72 +812,70 @@ g
# Symbol visibility
- verify_visibility(c.syms["NO_PROMPT"], "n", "n")
- verify_visibility(c.syms["BOOL_N"], "n", "n")
- verify_visibility(c.syms["BOOL_M"], "n", "y")
- verify_visibility(c.syms["BOOL_MOD"], "y", "y")
- verify_visibility(c.syms["BOOL_Y"], "y", "y")
- verify_visibility(c.syms["TRISTATE_M"], "n", "m")
- verify_visibility(c.syms["TRISTATE_MOD"], "y", "m")
- verify_visibility(c.syms["TRISTATE_Y"], "y", "y")
- verify_visibility(c.syms["BOOL_IF_N"], "n", "n")
- verify_visibility(c.syms["BOOL_IF_M"], "n", "y")
- verify_visibility(c.syms["BOOL_IF_Y"], "y", "y")
- verify_visibility(c.syms["BOOL_MENU_N"], "n", "n")
- verify_visibility(c.syms["BOOL_MENU_M"], "n", "y")
- verify_visibility(c.syms["BOOL_MENU_Y"], "y", "y")
- verify_visibility(c.syms["BOOL_CHOICE_N"], "n", "n")
+ verify_visibility(c.syms["NO_PROMPT"], 0, 0)
+ verify_visibility(c.syms["BOOL_N"], 0, 0)
+ verify_visibility(c.syms["BOOL_M"], 0, 2)
+ verify_visibility(c.syms["BOOL_MOD"], 2, 2)
+ verify_visibility(c.syms["BOOL_Y"], 2, 2)
+ verify_visibility(c.syms["TRISTATE_M"], 0, 1)
+ verify_visibility(c.syms["TRISTATE_MOD"], 2, 1)
+ verify_visibility(c.syms["TRISTATE_Y"], 2, 2)
+ verify_visibility(c.syms["BOOL_IF_N"], 0, 0)
+ verify_visibility(c.syms["BOOL_IF_M"], 0, 2)
+ verify_visibility(c.syms["BOOL_IF_Y"], 2, 2)
+ verify_visibility(c.syms["BOOL_MENU_N"], 0, 0)
+ verify_visibility(c.syms["BOOL_MENU_M"], 0, 2)
+ verify_visibility(c.syms["BOOL_MENU_Y"], 2, 2)
+ verify_visibility(c.syms["BOOL_CHOICE_N"], 0, 0)
# Non-tristate symbols in tristate choices are only visible if the choice
- # is in "y" mode
- verify_visibility(c.syms["BOOL_CHOICE_M"], "n", "n")
+ # is in 2 mode
+ verify_visibility(c.syms["BOOL_CHOICE_M"], 0, 0)
- # Tristate choices start out in "m" mode. When running without modules,
- # their type gets adjusted to bool.
- verify_visibility(c.syms["BOOL_CHOICE_Y"], "y", "n")
+ # Tristate choices start out in m mode. When running without modules, their
+ # type gets adjusted to bool.
+ verify_visibility(c.syms["BOOL_CHOICE_Y"], 2, 0)
c.syms["TRISTATE_CHOICE_M"].set_value("y")
c.syms["TRISTATE_CHOICE_Y"].set_value("y")
# Still limited by the visibility of the choice
- verify_visibility(c.syms["BOOL_CHOICE_M"], "n", "n")
+ verify_visibility(c.syms["BOOL_CHOICE_M"], 0, 0)
# This one should become visible now
- verify_visibility(c.syms["BOOL_CHOICE_Y"], "y", "y")
-
- verify_visibility(c.syms["TRISTATE_IF_N"], "n", "n")
- verify_visibility(c.syms["TRISTATE_IF_M"], "n", "m")
- verify_visibility(c.syms["TRISTATE_IF_Y"], "y", "y")
- verify_visibility(c.syms["TRISTATE_MENU_N"], "n", "n")
- verify_visibility(c.syms["TRISTATE_MENU_M"], "n", "m")
- verify_visibility(c.syms["TRISTATE_MENU_Y"], "y", "y")
- verify_visibility(c.syms["TRISTATE_CHOICE_N"], "n", "n")
- verify_visibility(c.syms["TRISTATE_CHOICE_M"], "n", "m")
- verify_visibility(c.syms["TRISTATE_CHOICE_Y"], "y", "y")
-
- verify_visibility(c.named_choices["BOOL_CHOICE_N"], "n", "n")
- verify_visibility(c.named_choices["BOOL_CHOICE_M"], "n", "y")
- verify_visibility(c.named_choices["BOOL_CHOICE_Y"], "y", "y")
- verify_visibility(c.named_choices["TRISTATE_CHOICE_N"], "n", "n")
- verify_visibility(c.named_choices["TRISTATE_CHOICE_M"], "n", "m")
- verify_visibility(c.named_choices["TRISTATE_CHOICE_Y"], "y", "y")
-
- verify_visibility(c.named_choices["TRISTATE_CHOICE_IF_M_AND_Y"],
- "n", "m")
- verify_visibility(c.named_choices["TRISTATE_CHOICE_MENU_N_AND_Y"],
- "n", "n")
+ verify_visibility(c.syms["BOOL_CHOICE_Y"], 2, 2)
+
+ verify_visibility(c.syms["TRISTATE_IF_N"], 0, 0)
+ verify_visibility(c.syms["TRISTATE_IF_M"], 0, 1)
+ verify_visibility(c.syms["TRISTATE_IF_Y"], 2, 2)
+ verify_visibility(c.syms["TRISTATE_MENU_N"], 0, 0)
+ verify_visibility(c.syms["TRISTATE_MENU_M"], 0, 1)
+ verify_visibility(c.syms["TRISTATE_MENU_Y"], 2, 2)
+ verify_visibility(c.syms["TRISTATE_CHOICE_N"], 0, 0)
+ verify_visibility(c.syms["TRISTATE_CHOICE_M"], 0, 1)
+ verify_visibility(c.syms["TRISTATE_CHOICE_Y"], 2, 2)
+
+ verify_visibility(c.named_choices["BOOL_CHOICE_N"], 0, 0)
+ verify_visibility(c.named_choices["BOOL_CHOICE_M"], 0, 2)
+ verify_visibility(c.named_choices["BOOL_CHOICE_Y"], 2, 2)
+ verify_visibility(c.named_choices["TRISTATE_CHOICE_N"], 0, 0)
+ verify_visibility(c.named_choices["TRISTATE_CHOICE_M"], 0, 1)
+ verify_visibility(c.named_choices["TRISTATE_CHOICE_Y"], 2, 2)
+
+ verify_visibility(c.named_choices["TRISTATE_CHOICE_IF_M_AND_Y"], 0, 1)
+ verify_visibility(c.named_choices["TRISTATE_CHOICE_MENU_N_AND_Y"], 0, 0)
# Menu visibility
def verify_menu_visibility(menu, no_module_vis, module_vis):
- c["MODULES"].set_value("n")
+ c.modules.set_value("n")
menu_vis = kconfiglib.eval_expr(menu.node.dep)
verify(menu_vis == no_module_vis,
"menu \"{}\" should have visibility '{}' without modules, "
"has visibility '{}'"
.format(menu.title, no_module_vis, menu_vis))
- c["MODULES"].set_value("y")
+ c.modules.set_value("y")
menu_vis = kconfiglib.eval_expr(menu.node.dep)
verify(menu_vis == module_vis,
"menu \"{}\" should have visibility '{}' with modules, "
@@ -935,14 +901,14 @@ g
menu_visible_if_m_2 = get_menus(c)[13:]
def verify_visible_if_visibility(menu, no_module_vis, module_vis):
- c["MODULES"].set_value("n")
+ c.modules.set_value("n")
menu_vis = menu.get_visible_if_visibility()
verify(menu_vis == no_module_vis,
"menu \"{}\" should have 'visible if' visibility '{}' "
"without modules, has 'visible if' visibility '{}'".
format(menu.title, no_module_vis, menu_vis))
- c["MODULES"].set_value("y")
+ c.modules.set_value("y")
menu_vis = menu.get_visible_if_visibility()
verify(menu_vis == module_vis,
"menu \"{}\" should have 'visible if' visibility '{}' "
@@ -963,15 +929,15 @@ g
#verify_visible_if_visibility(menu_visible_if_m_2, "n", "m")
# Verify that 'visible if' visibility gets propagated to prompts
- verify_visibility(c.syms["VISIBLE_IF_N"], "n", "n")
- verify_visibility(c.syms["VISIBLE_IF_M"], "n", "m")
- verify_visibility(c.syms["VISIBLE_IF_Y"], "y", "y")
- verify_visibility(c.syms["VISIBLE_IF_M_2"], "n", "m")
+ verify_visibility(c.syms["VISIBLE_IF_N"], 0, 0)
+ verify_visibility(c.syms["VISIBLE_IF_M"], 0, 1)
+ verify_visibility(c.syms["VISIBLE_IF_Y"], 2, 2)
+ verify_visibility(c.syms["VISIBLE_IF_M_2"], 0, 1)
# Comment visibility
def verify_comment_visibility(comment, no_module_vis, module_vis):
- c["MODULES"].set_value("n")
+ c.modules.set_value("n")
# TODO: uninternalize
comment_vis = kconfiglib.eval_expr(comment.node.dep)
verify(comment_vis == no_module_vis,
@@ -979,7 +945,7 @@ g
"modules, has visibility '{}'".
format(comment.text, no_module_vis, comment_vis))
- c["MODULES"].set_value("y")
+ c.modules.set_value("y")
comment_vis = kconfiglib.eval_expr(comment.node.dep)
verify(comment_vis == module_vis,
"comment \"{}\" should have visibility '{}' with "
@@ -1251,7 +1217,7 @@ g
("BOOL", "TRISTATE", "STRING", "INT", "HEX")]
for sym in syms:
- verify(sym.user_value is None,
+ verify(sym.user_str_value is None and sym.user_tri_value is None,
"{} should not have a user value to begin with")
# Assign valid values for the types
@@ -1278,7 +1244,7 @@ g
for s in syms:
s.unset_value()
- verify(s.user_value is None,
+ verify(s.user_str_value is None and s.user_tri_value is None,
"{} should not have a user value after being reset".
format(s.name))
@@ -1399,7 +1365,7 @@ g
# .config
#
- print("Testing .config...")
+ print("Testing Config separation...")
c1 = kconfiglib.Config("Kconfiglib/tests/Kmisc", warn=False)
c2 = kconfiglib.Config("Kconfiglib/tests/Kmisc", warn=False)
@@ -1547,9 +1513,8 @@ g
def select_and_verify(sym):
choice = get_parent(sym)
sym.set_value("y")
- verify(choice.value == "y",
- 'The mode of the choice should be "y" after selecting a '
- "symbol")
+ verify(choice.str_value == "y",
+ "The mode of the choice should be y after selecting a symbol")
verify(sym.choice.selection is sym,
"{} should be the selected choice symbol"
.format(sym.name))
@@ -1568,25 +1533,24 @@ g
select_and_verify(choice.syms[i])
def verify_mode(choice, no_modules_mode, modules_mode):
- c.syms["MODULES"].set_value("n")
- choice_mode = choice.value
+ c.modules.set_value("n")
+ choice_mode = choice.tri_value
verify(choice_mode == no_modules_mode,
- 'Wrong mode for choice {} with no modules. Expected "{}", '
- 'got "{}".'.format(choice.name, no_modules_mode, choice_mode))
+ 'Wrong mode for choice {} with no modules. Expected {}, got {}.'
+ .format(choice.name, no_modules_mode, choice_mode))
- c.syms["MODULES"].set_value("y")
- choice_mode = choice.value
+ c.modules.set_value("y")
+ choice_mode = choice.tri_value
verify(choice_mode == modules_mode,
- 'Wrong mode for choice {} with modules. Expected "{}", '
- 'got "{}".'.format(choice.name, modules_mode,
- choice_mode))
+ 'Wrong mode for choice {} with modules. Expected {}, got {}.'
+ .format(choice.name, modules_mode, choice_mode))
- verify_mode(choice_bool, "y", "y")
- verify_mode(choice_bool_opt, "n", "n")
- verify_mode(choice_tristate, "y", "m")
- verify_mode(choice_tristate_opt, "n", "n")
- verify_mode(choice_bool_m, "y", "y")
- verify_mode(choice_tristate_m, "y", "m")
+ verify_mode(choice_bool, 2, 2)
+ verify_mode(choice_bool_opt, 0, 0)
+ verify_mode(choice_tristate, 2, 1)
+ verify_mode(choice_tristate_opt, 0, 0)
+ verify_mode(choice_bool_m, 2, 2)
+ verify_mode(choice_tristate_m, 2, 1)
# Test defaults
@@ -1606,7 +1570,7 @@ g
# Test "y" mode selection
- c.syms["MODULES"].set_value("y")
+ c.modules.set_value("y")
select_and_verify_all(choice_bool)
select_and_verify_all(choice_bool_opt)
@@ -1621,12 +1585,12 @@ g
for sym_name in ("T_1", "T_2"):
assign_and_verify_value(sym_name, "m", "m")
- verify(choice_tristate.value == "m",
+ verify(choice_tristate.tri_value == 1,
'Selecting {} to "m" should have changed the mode of the '
'choice to "m"'.format(sym_name))
assign_and_verify_value(sym_name, "y", "y")
- verify(choice_tristate.value == "y" and
+ verify(choice_tristate.tri_value == 2 and
choice_tristate.selection is c.syms[sym_name],
'Selecting {} to "y" should have changed the mode of the '
'choice to "y" and made it the selection'.format(sym_name))
@@ -1638,7 +1602,7 @@ g
assign_and_verify_value(sym_name, "n", "n")
# "y" should be truncated
assign_and_verify_value(sym_name, "y", "m")
- verify(choice_tristate_m.value == "m",
+ verify(choice_tristate_m.tri_value == 1,
'A choice that can only be in "m" mode was not')
# Verify that choices with no explicitly specified type get the type of the
@@ -1746,8 +1710,10 @@ g
"\nSome selftests failed\n")
def run_compatibility_tests():
- """Runs tests on configurations from the kernel. Tests compability with the
- C implementation by comparing outputs."""
+ """
+ Runs tests on configurations from the kernel. Tests compability with the
+ C implementation by comparing outputs.
+ """
os.environ.pop("ARCH", None)
os.environ.pop("SRCARCH", None)
@@ -1798,9 +1764,9 @@ def run_compatibility_tests():
if compare_configs:
if equal_confs():
- print(" {:14}OK".format(arch))
+ print("{:14}OK".format(arch))
else:
- print(" {:14}FAIL".format(arch))
+ print("{:14}FAIL".format(arch))
fail()
if all_passed:
@@ -1810,8 +1776,9 @@ def run_compatibility_tests():
print("Some tests failed")
def get_arch_srcarch_list():
- """Returns a list of (ARCH, SRCARCH) tuples to test."""
-
+ """
+ Returns a list of (ARCH, SRCARCH) tuples to test.
+ """
res = []
def add_arch(arch):
@@ -1837,16 +1804,17 @@ def get_arch_srcarch_list():
return res
def test_load(conf, arch):
- """Load all arch Kconfigs to make sure we don't throw any errors"""
- print(" {:14}OK".format(arch))
+ """
+ Load all arch Kconfigs to make sure we don't throw any errors
+ """
+ print("{:14}OK".format(arch))
-# The weird docstring formatting is to get the format right when we print the
-# docstring ourselves
def test_all_no(conf, arch):
"""
Verify that our examples/allnoconfig.py script generates the same .config
as 'make allnoconfig', for each architecture. Runs the script via
- 'make scriptconfig', so kinda slow even in speedy mode."""
+ 'make scriptconfig', so kinda slow even in speedy mode.
+ """
# TODO: Support speedy mode for running the script
shell("make scriptconfig SCRIPT=Kconfiglib/examples/allnoconfig.py "
@@ -1861,7 +1829,8 @@ def test_all_no_simpler(conf, arch):
"""
Verify that our examples/allnoconfig_simpler.py script generates the same
.config as 'make allnoconfig', for each architecture. Runs the script via
- 'make scriptconfig', so kinda slow even in speedy mode."""
+ 'make scriptconfig', so kinda slow even in speedy mode.
+ """
# TODO: Support speedy mode for running the script
shell("make scriptconfig SCRIPT=Kconfiglib/examples/allnoconfig_simpler.py "
@@ -1876,7 +1845,8 @@ def test_all_yes(conf, arch):
"""
Verify that our examples/allyesconfig.py script generates the same .config
as 'make allyesconfig', for each architecture. Runs the script via
- 'make scriptconfig', so kinda slow even in speedy mode."""
+ 'make scriptconfig', so kinda slow even in speedy mode.
+ """
# TODO: Support speedy mode for running the script
shell("make scriptconfig SCRIPT=Kconfiglib/examples/allyesconfig.py "
@@ -1889,11 +1859,12 @@ def test_all_yes(conf, arch):
def test_call_all(conf, arch):
"""
- Call all public methods on all symbols, menus, choices, and comments for
+ Call all public methods on all symbols, choices, and TODO menu nodes for
all architectures to make sure we never crash or hang. (Nearly all public
methods: some are hard to test like this, but are exercised by other
- tests.)"""
- print(" For {}...".format(arch))
+ tests.)
+ """
+ print("For {}...".format(arch))
conf.defconfig_filename
conf.mainmenu_text
@@ -1909,7 +1880,8 @@ def test_call_all(conf, arch):
s.__repr__()
s.assignable
s.type
- s.value
+ s.str_value
+ s.tri_value
s.visibility
s.unset_value()
@@ -1933,7 +1905,8 @@ def test_call_all(conf, arch):
for c in conf._choices:
c.__str__()
c.__repr__()
- c.value
+ c.str_value
+ c.tri_value
c.assignable
c.selection
c.default_selection
@@ -1943,7 +1916,8 @@ def test_call_all(conf, arch):
def test_config_absent(conf, arch):
"""
Verify that Kconfiglib generates the same .config as 'make alldefconfig',
- for each architecture"""
+ for each architecture
+ """
conf.write_config("._config")
if speedy:
shell("scripts/kconfig/conf --alldefconfig Kconfig")
@@ -1959,7 +1933,8 @@ def test_defconfig(conf, arch):
run.
With logging enabled, this test appends any failures to a file
- test_defconfig_fails in the root."""
+ test_defconfig_fails in the root.
+ """
global nconfigs
defconfigs = []
@@ -2037,8 +2012,10 @@ def test_defconfig(conf, arch):
#
def rm_configs():
- """Delete any old ".config" (generated by the C implementation) and
- "._config" (generated by us), if present."""
+ """
+ Delete any old ".config" (generated by the C implementation) and
+ "._config" (generated by us), if present.
+ """
def rm_if_exists(f):
if os.path.exists(f):
os.remove(f)