docstr: Find the value of the given node.
  If it cannot be evaluated safely, this raises `CannotEval`.
  The result is cached either way.
  
  :param node: an AST expression to evaluate
  :return: the value of the node
docstr_tok: ["Find","the","value","of","the","given","node",".","If","it","can","not","be","evaluated","safely",",","this","raises","`","CannotEval","`",".","The","result","is","cached","either","way",".",":","param","node",":","an","AST","expression","to","evaluate",":","return",":","the","value","of","the","node"]
code: def __getitem__(self, node: ast.expr) -> Any:
      """
      Find the value of the given node.
      If it cannot be evaluated safely, this raises `CannotEval`.
      The result is cached either way.
  
      :param node: an AST expression to evaluate
      :return: the value of the node
      """
  
      if not isinstance(node, ast.expr):
          raise TypeError(
              "node should be an ast.expr, not {!r}".format(
                  type(node).__name__
              )
          )
  
      with suppress(KeyError):
          result = self._cache[node]
          if result is CannotEval:
              raise CannotEval
          else:
              return result
  
      try:
          self._cache[node] = result = self._handle(node)
          return result
      except CannotEval:
          self._cache[node] = CannotEval
          raise
  
imports: import ast
  import builtins
  import operator
  from collections import ChainMap, OrderedDict, deque
  from contextlib import suppress
  from types import FrameType
  from typing import Any, Tuple, Iterable, List, Mapping, Dict, Union, Set
  from pure_eval.my_getattr_static import getattr_static
  from pure_eval.utils import CannotEval, has_ast_name, copy_ast_without_context, is_standard_types, of_standard_types, is_any, of_type, ensure_dict
label_desc: Use image node_id 3 for calling the Evaluator obj's underlying member method code with example usage: obj.__getitem__(node) and returns: result, result