parameters: (expr)
return_statement: return 2 * (
          comp == 0
          if rel is EQUAL
          else comp != 0
          if rel is UNEQUAL
          else comp < 0
          if rel is LESS
          else comp <= 0
          if rel is LESS_EQUAL
          else comp > 0
          if rel is GREATER
          else comp >= 0
      )
docstring: Evaluates the expression 'expr' to a tristate value. Returns 0 (n), 1 (m),
      or 2 (y).
  
      'expr' must be an already-parsed expression from a Symbol, Choice, or
      MenuNode property. To evaluate an expression represented as a string, use
      Kconfig.eval_string().
  
      Passing subexpressions of expressions to this function works as expected.
docstring_summary: Evaluates the expression 'expr' to a tristate value. Returns 0 (n), 1 (m),
      or 2 (y).
docstring_tokens: Evaluates the expression expr to a tristate value . Returns 0 ( n ) 1 ( m ) or 2 ( y ) .
function: def expr_value(expr):
      """
      Evaluates the expression 'expr' to a tristate value. Returns 0 (n), 1 (m),
      or 2 (y).
  
      'expr' must be an already-parsed expression from a Symbol, Choice, or
      MenuNode property. To evaluate an expression represented as a string, use
      Kconfig.eval_string().
  
      Passing subexpressions of expressions to this function works as expected.
      """
      if expr.__class__ is not tuple:
          return expr.tri_value
  
      if expr[0] is AND:
          v1 = expr_value(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, expr_value(expr[2]))
  
      if expr[0] is OR:
          v1 = expr_value(expr[1])
          # Short-circuit the y case as an optimization
          return 2 if v1 == 2 else max(v1, expr_value(expr[2]))
  
      if expr[0] is NOT:
          return 2 - expr_value(expr[1])
  
      # Relation
      #
      # Implements <, <=, >, >= comparisons as well. These were added to
      # kconfig in 31847b67 (kconfig: allow use of relations other than
      # (in)equality).
  
      rel, v1, v2 = expr
  
      # If both operands are strings...
      if v1.orig_type is STRING and v2.orig_type is STRING:
          # ...then compare them lexicographically
          comp = _strcmp(v1.str_value, v2.str_value)
      else:
          # Otherwise, try to compare them as numbers
          try:
              comp = _sym_to_num(v1) - _sym_to_num(v2)
          except ValueError:
              # Fall back on a lexicographic comparison if the operands don't
              # parse as numbers
              comp = _strcmp(v1.str_value, v2.str_value)
  
      return 2 * (
          comp == 0
          if rel is EQUAL
          else comp != 0
          if rel is UNEQUAL
          else comp < 0
          if rel is LESS
          else comp <= 0
          if rel is LESS_EQUAL
          else comp > 0
          if rel is GREATER
          else comp >= 0
      )
function_tokens: def expr_value ( expr ) : if expr . __class__ is not tuple : return expr . tri_value if expr [ 0 ] is AND : v1 = expr_value ( 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 , expr_value ( expr [ 2 ] ) ) if expr [ 0 ] is OR : v1 = expr_value ( expr [ 1 ] ) # Short-circuit the y case as an optimization return 2 if v1 == 2 else max ( v1 , expr_value ( expr [ 2 ] ) ) if expr [ 0 ] is NOT : return 2 - expr_value ( expr [ 1 ] ) # Relation # # Implements <, <=, >, >= comparisons as well. These were added to # kconfig in 31847b67 (kconfig: allow use of relations other than # (in)equality). rel , v1 , v2 = expr # If both operands are strings... if v1 . orig_type is STRING and v2 . orig_type is STRING : # ...then compare them lexicographically comp = _strcmp ( v1 . str_value , v2 . str_value ) else : # Otherwise, try to compare them as numbers try : comp = _sym_to_num ( v1 ) - _sym_to_num ( v2 ) except ValueError : # Fall back on a lexicographic comparison if the operands don't # parse as numbers comp = _strcmp ( v1 . str_value , v2 . str_value ) return 2 * ( comp == 0 if rel is EQUAL else comp != 0 if rel is UNEQUAL else comp < 0 if rel is LESS else comp <= 0 if rel is LESS_EQUAL else comp > 0 if rel is GREATER else comp >= 0 )