# Path: graphscale/check.py
# def isinst(obj: Any, ttype: Type, _msg: str=None) -> None:
# def invariant(condition: Any, msg: str) -> None:
# def failed(msg: str) -> NoReturn:
# 
# Path: graphscale/pent.py
# class PentContext:
#     def __init__(self, *, kvetch: Kvetch, config: PentConfig) -> None:
#         self.__kvetch = kvetch
#         self.__config = config
#         self.loader = PentLoader(self)
# 
#     def cls_from_name(self, name: str) -> Type:
#         return self.__config.get_class_from_name(name)
# 
#     @property
#     def kvetch(self) -> Kvetch:
#         return self.__kvetch
# 
#     @property
#     def config(self) -> PentConfig:
#         return self.__config
# 
#     # had to change things to nuke loader at beginning of request again
#     # @property
#     # def loader(self) -> 'PentLoader':
#     #     return self.__loader
# 
# class PentContextfulObject:
#     def __init__(self, context: PentContext) -> None:
#         self.__context = context
# 
#     @property
#     def context(self) -> PentContext:
#         return self.__context
# 
# Path: graphscale/sql.py
# class ConnectionInfo(NamedTuple):
#     host: str
#     user: str
#     password: str
#     db: str
#     charset: str = 'utf8mb4'
# 
# def pymysql_conn_from_info(conn_info: ConnectionInfo) -> pymysql.Connection:
#     return pymysql.connect(
#         host=conn_info.host,
#         user=conn_info.user,
#         password=conn_info.password,
#         db=conn_info.db,
#         charset=conn_info.charset,
#         cursorclass=pymysql.cursors.DictCursor,
#         autocommit=True,
#     )
# 
# Path: graphscale/utils.py
# def print_error(val: Any) -> None:
#     """Print value to stderr"""
#     sys.stderr.write(str(val) + '\n')


import traceback
import pymysql
import pymysql.cursors
from typing import Callable, List, Dict, Any
from graphql import GraphQLSchema, graphql
from graphscale import check
from graphscale.pent import PentContext, PentContextfulObject
from graphscale.sql import ConnectionInfo, pymysql_conn_from_info
from graphscale.utils import print_error

async def async_test_graphql(
    query: str,
    pent_context: PentContext,
    graphql_schema: GraphQLSchema,
    root_value: PentContextfulObject=None,
    variable_values: Dict[str, Any]=None,
):
    # check.str_param(query, 'query')
    # check.param(pent_context, PentContext, 'pent_context')
    # check.param(graphql_schema, GraphQLSchema, 'graphql_schema')
    # check.opt_dict_param(variable_values, 'variable_values')

    result = await graphql(
        graphql_schema,
        query,
        context_value=pent_context,
        root_value=root_value,
        variable_values=variable_values
    )
    if result.errors:
        error = result.errors[0]
        print_error('GRAPHQL ERROR')
        print_error(error)
        orig = error.original_error

        print_error('ORIGINAL ERROR')
        print_error(orig)

        trace = orig.__traceback__

# Path: graphscale/check.py
# def isinst(obj: Any, ttype: Type, _msg: str=None) -> None:
# def invariant(condition: Any, msg: str) -> None:
# def failed(msg: str) -> NoReturn:
# 
# Path: graphscale/pent.py
# class PentContext:
#     def __init__(self, *, kvetch: Kvetch, config: PentConfig) -> None:
#         self.__kvetch = kvetch
#         self.__config = config
#         self.loader = PentLoader(self)
# 
#     def cls_from_name(self, name: str) -> Type:
#         return self.__config.get_class_from_name(name)
# 
#     @property
#     def kvetch(self) -> Kvetch:
#         return self.__kvetch
# 
#     @property
#     def config(self) -> PentConfig:
#         return self.__config
# 
#     # had to change things to nuke loader at beginning of request again
#     # @property
#     # def loader(self) -> 'PentLoader':
#     #     return self.__loader
# 
# class PentContextfulObject:
#     def __init__(self, context: PentContext) -> None:
#         self.__context = context
# 
#     @property
#     def context(self) -> PentContext:
#         return self.__context
# 
# Path: graphscale/sql.py
# class ConnectionInfo(NamedTuple):
#     host: str
#     user: str
#     password: str
#     db: str
#     charset: str = 'utf8mb4'
# 
# def pymysql_conn_from_info(conn_info: ConnectionInfo) -> pymysql.Connection:
#     return pymysql.connect(
#         host=conn_info.host,
#         user=conn_info.user,
#         password=conn_info.password,
#         db=conn_info.db,
#         charset=conn_info.charset,
#         cursorclass=pymysql.cursors.DictCursor,
#         autocommit=True,
#     )
# 
# Path: graphscale/utils.py
# def print_error(val: Any) -> None:
#     """Print value to stderr"""
#     sys.stderr.write(str(val) + '\n')


# Path: graphscale/test/utils.py
import traceback
import pymysql
import pymysql.cursors
from typing import Callable, List, Dict, Any
from graphql import GraphQLSchema, graphql
from graphscale import check
from graphscale.pent import PentContext, PentContextfulObject
from graphscale.sql import ConnectionInfo, pymysql_conn_from_info
from graphscale.utils import print_error


async def async_test_graphql(
    query: str,
    pent_context: PentContext,
    graphql_schema: GraphQLSchema,
    root_value: PentContextfulObject=None,
    variable_values: Dict[str, Any]=None,
):
    # check.str_param(query, 'query')
    # check.param(pent_context, PentContext, 'pent_context')
    # check.param(graphql_schema, GraphQLSchema, 'graphql_schema')
    # check.opt_dict_param(variable_values, 'variable_values')

    result = await graphql(
        graphql_schema,
        query,
        context_value=pent_context,
        root_value=root_value,
        variable_values=variable_values
    )
    if result.errors:
        error = result.errors[0]
        print_error('GRAPHQL ERROR')
        print_error(error)
        orig = error.original_error

        print_error('ORIGINAL ERROR')
        print_error(orig)

        trace = orig.__traceback__

        print_error(''.join(traceback.format_tb(trace)))