# Path: picatrix/lib/error.py
# class Error(Exception):
# class ArgParserNonZeroStatus(Error):
# 
# Path: picatrix/lib/manager.py
# class Helper:
# class MagicManager:
#   MAGICS_DF_COLUMNS = ['name', 'description', 'line', 'cell', 'function']
#   def clear_helpers(cls):
#   def clear_magics(cls):
#   def deregister_helper(cls, helper_name: Text):
#   def deregister_magic(cls, magic_name: Text):
#   def get_helper(cls, helper_name: Text) -> Optional[Callable[..., Any]]:
#   def get_magic(cls, magic_name: Text) -> Callable[[Text, Text], Text]:
#   def get_helper_info(
#       cls,
#       as_pandas: Optional[bool] = True
#   ) -> Union[pandas.DataFrame, List[Tuple[Text, Text]]]:
#   def get_magic_info(
#       cls,
#       as_pandas: Optional[bool] = True
#   ) -> Union[pandas.DataFrame, List[Tuple[Text, Text]]]:
#   def register_helper(
#       cls, name: Text, helper: Any, typing_help: Dict[Text, Any]):
#   def register_magic(
#       cls,
#       function: Callable[[Text, Text], Text],
#       conditional: Callable[[], bool] = None):
#     def capture_output(function, name):
#       def wrapper(*args, **kwargs):
# 
# Path: picatrix/lib/state.py
# def state(refresh_state: bool = False):
#   """Property that returns a state object."""
#   # pylint: disable=global-statement
#   # Making sure we have only one state object.
#   global __state
# 
#   with _LOCK:
#     if refresh_state or __state is None:
#       __state = State()
# 
#     return __state
# 
# Path: picatrix/lib/utils.py
# def ask_question(question: Text, input_type: Optional[Any] = Text) -> Any:
# def clear_notebook_output():
# def ipython_bind_global(name: Text, value: Any) -> Any:
# def ipython_get_global(name: Text) -> Any:
# def ipython_remove_global(name: Text):


import argparse
import functools
import inspect
import types
import typing
from typing import Any, Callable, Dict, List, Optional, Text
  from typing import Protocol
  from typing_extensions import Protocol
from picatrix.lib import error, manager, state, utils
    option_dict = options.__dict__
    del option_dict['bindto']

    # TODO: Change this so that there is no variable expansion
    # done by the core and all variable expansion is only done here.
    for key, value in iter(option_dict.items()):
      if not value:
        continue

      if not isinstance(value, str):
        continue

      if value[0] == '{' and value[-1] == '}':
        var_name = value[1:-1]
        var_type = self.argument_parser.storage.get(key)

        if '{' not in var_name and '}' not in var_name:
          var_obj = utils.ipython_get_global(var_name)
          if var_type and var_type != 'object':
            type_string = type(var_obj).__name__
            if (type_string != var_type) and not type_string.endswith(
                var_type) and not var_type.endswith(type_string):
              raise KeyError(
                  (
                      'Variable [{0:s}] is not of the correct type [{1:s}] for '
                      'this magic. Type is: {2!s}').format(
                          var_name, var_type, type(var_obj)))
          option_dict[key] = var_obj

    return_value = self.fn(**option_dict)

# Path: picatrix/lib/error.py
# class Error(Exception):
# class ArgParserNonZeroStatus(Error):
# 
# Path: picatrix/lib/manager.py
# class Helper:
# class MagicManager:
#   MAGICS_DF_COLUMNS = ['name', 'description', 'line', 'cell', 'function']
#   def clear_helpers(cls):
#   def clear_magics(cls):
#   def deregister_helper(cls, helper_name: Text):
#   def deregister_magic(cls, magic_name: Text):
#   def get_helper(cls, helper_name: Text) -> Optional[Callable[..., Any]]:
#   def get_magic(cls, magic_name: Text) -> Callable[[Text, Text], Text]:
#   def get_helper_info(
#       cls,
#       as_pandas: Optional[bool] = True
#   ) -> Union[pandas.DataFrame, List[Tuple[Text, Text]]]:
#   def get_magic_info(
#       cls,
#       as_pandas: Optional[bool] = True
#   ) -> Union[pandas.DataFrame, List[Tuple[Text, Text]]]:
#   def register_helper(
#       cls, name: Text, helper: Any, typing_help: Dict[Text, Any]):
#   def register_magic(
#       cls,
#       function: Callable[[Text, Text], Text],
#       conditional: Callable[[], bool] = None):
#     def capture_output(function, name):
#       def wrapper(*args, **kwargs):
# 
# Path: picatrix/lib/state.py
# def state(refresh_state: bool = False):
#   """Property that returns a state object."""
#   # pylint: disable=global-statement
#   # Making sure we have only one state object.
#   global __state
# 
#   with _LOCK:
#     if refresh_state or __state is None:
#       __state = State()
# 
#     return __state
# 
# Path: picatrix/lib/utils.py
# def ask_question(question: Text, input_type: Optional[Any] = Text) -> Any:
# def clear_notebook_output():
# def ipython_bind_global(name: Text, value: Any) -> Any:
# def ipython_get_global(name: Text) -> Any:
# def ipython_remove_global(name: Text):


# Path: picatrix/lib/framework.py
import argparse
import functools
import inspect
import types
import typing
from typing import Any, Callable, Dict, List, Optional, Text
  from typing import Protocol
  from typing_extensions import Protocol
from picatrix.lib import error, manager, state, utils

    option_dict = options.__dict__
    del option_dict['bindto']

    # TODO: Change this so that there is no variable expansion
    # done by the core and all variable expansion is only done here.
    for key, value in iter(option_dict.items()):
      if not value:
        continue

      if not isinstance(value, str):
        continue

      if value[0] == '{' and value[-1] == '}':
        var_name = value[1:-1]
        var_type = self.argument_parser.storage.get(key)

        if '{' not in var_name and '}' not in var_name:
          var_obj = utils.ipython_get_global(var_name)
          if var_type and var_type != 'object':
            type_string = type(var_obj).__name__
            if (type_string != var_type) and not type_string.endswith(
                var_type) and not var_type.endswith(type_string):
              raise KeyError(
                  (
                      'Variable [{0:s}] is not of the correct type [{1:s}] for '
                      'this magic. Type is: {2!s}').format(
                          var_name, var_type, type(var_obj)))
          option_dict[key] = var_obj

    return_value = self.fn(**option_dict)

    state_obj = state.state()