text: """Translate an Expression to a Type value."""
  
  from typing import Optional
  
  from mypy.nodes import (
      Expression,
      NameExpr,
      MemberExpr,
      IndexExpr,
      TupleExpr,
      IntExpr,
      FloatExpr,
      UnaryExpr,
      ComplexExpr,
      ListExpr,
      StrExpr,
      BytesExpr,
      UnicodeExpr,
      EllipsisExpr,
      CallExpr,
      get_member_expr_fullname,
  )
  from mypy.fastparse import parse_type_string
  from mypy.types import (
      Type,
      UnboundType,
      TypeList,
      EllipsisType,
      AnyType,
      CallableArgument,
      TypeOfAny,
      RawExpressionType,
      ProperType,
  )
  
  
  class TypeTranslationError(Exception):
      """Exception raised when an expression is not valid as a type."""
  
  
  def _extract_argument_name(expr: Expression) -> Optional[str]:
      if isinstance(expr, NameExpr) and expr.name == "None":
          return None
      elif isinstance(expr, StrExpr):
          return expr.value
      elif isinstance(expr, UnicodeExpr):
          return expr.value
      else:
          raise TypeTranslationError()
  
  
  def expr_to_unanalyzed_type(
      expr: Expression, _parent: Optional[Expression] = None
  ) -> ProperType:
      """Translate an expression to the corresponding type.
  
      The result is not semantically analyzed. It can be UnboundType or TypeList.
      Raise TypeTranslationError if the expression cannot represent a type.
      """
      # The `parent` parameter is used in recursive calls to provide context for
      # understanding whether an CallableArgument is ok.
      name = None  # type: Optional[str]
      if isinstance(expr, NameExpr):
          name = expr.name
          if name == "True":
              return RawExpressionType(
                  True, "builtins.bool", line=expr.line, column=expr.column
              )
          elif name == "False":
              return RawExpressionType(
                  False, "builtins.bool", line=expr.line, column=expr.column
              )
          else:
              return UnboundType(name, line=expr.line, column=expr.column)
      elif isinstance(expr, MemberExpr):
          fullname = get_member_expr_fullname(expr)
          if fullname:
              return UnboundType(fullname, line=expr.line, column=expr.column)
          else:
              raise TypeTranslationError()
      elif isinstance(expr, IndexExpr):
          base = expr_to_unanalyzed_type(expr.base, expr)
          if isinstance(base, UnboundType):
              if base.args:
                  raise TypeTranslationError()
              if isinstance(expr.index, TupleExpr):
                  args = expr.index.items
              else:
                  args = [expr.index]
              base.args = [expr_to_unanalyzed_type(arg, expr) for arg in args]
              if not base.args:
                  base.empty_tuple_index = True
              return base
          else:
              raise TypeTranslationError()
      elif isinstance(expr, CallExpr) and isinstance(_parent, ListExpr):
          c = expr.callee
          names = []
          # Go through the dotted member expr chain to get the full arg
          # constructor name to look up
          while True:
              if isinstance(c, NameExpr):
                  names.append(c.name)
                  break
              elif isinstance(c, MemberExpr):
                  names.append(c.name)
                  c = c.expr
              else:
                  raise TypeTranslationError()
          arg_const = ".".join(reversed(names))
  
          # Go through the constructor args to get its name and type.
          name = None
          default_type = AnyType(TypeOfAny.unannotated)
          typ = default_type  # type: Type
          for i, arg in enumerate(expr.args):
              if expr.arg_names[i] is not None:
                  if expr.arg_names[i] == "name":
                      if name is not None:
                          # Two names
                          raise TypeTranslationError()
                      name = _extract_argument_name(arg)
                      continue
                  elif expr.arg_names[i] == "type":
                      if typ is not default_type:
                          # Two types
                          raise TypeTranslationError()
                      typ = expr_to_unanalyzed_type(arg, expr)
                      continue
                  else:
                      raise TypeTranslationError()
              elif i == 0:
                  typ = expr_to_unanalyzed_type(arg, expr)
              elif i == 1:
                  name = _extract_argument_name(arg)
              else:
                  raise TypeTranslationError()
          return CallableArgument(typ, name, arg_const, expr.line, expr.column)
      elif isinstance(expr, ListExpr):
          return TypeList(
              [expr_to_unanalyzed_type(t, expr) for t in expr.items],
              line=expr.line,
              column=expr.column,
          )
      elif isinstance(expr, StrExpr):
          return parse_type_string(
              expr.value,
              "builtins.str",
              expr.line,
              expr.column,
              assume_str_is_unicode=expr.from_python_3,
          )
      elif isinstance(expr, BytesExpr):
          return parse_type_string(
              expr.value,
              "builtins.bytes",
              expr.line,
              expr.column,
              assume_str_is_unicode=False,
          )
      elif isinstance(expr, UnicodeExpr):
          return parse_type_string(
              expr.value,
              "builtins.unicode",
              expr.line,
              expr.column,
              assume_str_is_unicode=True,
          )
      elif isinstance(expr, UnaryExpr):
          typ = expr_to_unanalyzed_type(expr.expr)
          if isinstance(typ, RawExpressionType):
              if isinstance(typ.literal_value, int) and expr.op == "-":
                  typ.literal_value *= -1
                  return typ
          raise TypeTranslationError()
      elif isinstance(expr, IntExpr):
          return RawExpressionType(
              expr.value, "builtins.int", line=expr.line, column=expr.column
          )
      elif isinstance(expr, FloatExpr):
          # Floats are not valid parameters for RawExpressionType , so we just
          # pass in 'None' for now. We'll report the appropriate error at a later stage.
          return RawExpressionType(
              None, "builtins.float", line=expr.line, column=expr.column
          )
      elif isinstance(expr, ComplexExpr):
          # Same thing as above with complex numbers.
          return RawExpressionType(
              None, "builtins.complex", line=expr.line, column=expr.column
          )
      elif isinstance(expr, EllipsisExpr):
          return EllipsisType(expr.line)
      else:
          raise TypeTranslationError()
  