# Path: qkeras/safe_eval.py
# def GetParams(s):
#   """Extracts args and kwargs from string."""
#   # modified from https://stackoverflow.com/questions/38799223/parse-string-to-identify-kwargs-and-args  # pylint: disable=line-too-long
# 
#   _lparen = Suppress("(")  # pylint: disable=invalid-name
#   _rparen = Suppress(")")  # pylint: disable=invalid-name
#   _eq = Suppress("=")  # pylint: disable=invalid-name
# 
#   data = (_lparen + Optional(
#       delimitedList(
#           Group(Regex(r"[^=,)\s]+") + Optional(_eq + Regex(u"[^,)]*")))
#           )
#       ) + _rparen)
# 
#   items = data.parseString(s).asList()
# 
#   # need to make sure that kwargs only happen after args are processed
#   args = [GetArg(i[0]) for i in items if len(i) == 1]
#   kwargs = {i[0]: GetArg(i[1]) for i in items if len(i) == 2}
# 
#   # check for syntax error
#   for i in range(1, len(items)):
#     if (len(items[i]) == 1) and (len(items[i-1]) == 2):
#       raise SyntaxError(("Error with item " + str(i) + " \n" +
#                          "  parsing string " + s + "\n" +
#                          "  Items: " + str(items) + "\n" +
#                          "  Item[" + str(i-1) +"] :" + str(items[i-1]) + "\n" +
#                          "  Item[" + str(i) +"] :" + str(items[i]) ))
# 
#   return args, kwargs
# 
# Path: qkeras/safe_eval.py
# def safe_eval(eval_str, op_dict, *params, **kwparams):  # pylint: disable=invalid-name
#   """Replaces eval by a safe eval mechanism."""
# 
#   function_split = eval_str.split("(")
#   quantizer = op_dict.get(function_split[0], None)
# 
#   if len(function_split) == 2:
#     args, kwargs = GetParams("(" + function_split[1])
#   else:
#     args = []
#     kwargs = {}
# 
#   args = args + list(params)
#   for k in kwparams:
#     kwargs[k] = kwparams[k]
# 
#   # must be Keras activation object if None
#   if quantizer is None:
#     logging.info("keras dict %s", function_split[0])
#     quantizer = keras.activations.get(function_split[0])
# 
#   if len(function_split) == 2 or args or kwargs:
#     return quantizer(*args, **kwargs)
#   else:
#     if isinstance(quantizer, type):
#       # Check if quantizer is a class
#       return quantizer()
#     else:
#       # Otherwise it is a function, so just return it
#       return quantizer


import operator
import pytest
from qkeras.safe_eval import GetParams
from qkeras.safe_eval import safe_eval
  }


def test_safe_eval1():
  s = "add(3,3)"
  assert safe_eval(s, globals()) == 6


def i_func(s):
  return -s


def myadd2(a, b):
  return i_func(a) + i_func(b)


def myadd(a=32, b=10):
  return a + b

class myaddcls(object):
  def __call__(self, a=32, b=10):
    return a + b

def test_safe_eval2():
  s_add = [3, 39]
  assert safe_eval("add", globals(), *s_add) == 42


def test_safe_eval3():
  assert safe_eval("myadd()", globals()) == 42

# Path: qkeras/safe_eval.py
# def GetParams(s):
#   """Extracts args and kwargs from string."""
#   # modified from https://stackoverflow.com/questions/38799223/parse-string-to-identify-kwargs-and-args  # pylint: disable=line-too-long
# 
#   _lparen = Suppress("(")  # pylint: disable=invalid-name
#   _rparen = Suppress(")")  # pylint: disable=invalid-name
#   _eq = Suppress("=")  # pylint: disable=invalid-name
# 
#   data = (_lparen + Optional(
#       delimitedList(
#           Group(Regex(r"[^=,)\s]+") + Optional(_eq + Regex(u"[^,)]*")))
#           )
#       ) + _rparen)
# 
#   items = data.parseString(s).asList()
# 
#   # need to make sure that kwargs only happen after args are processed
#   args = [GetArg(i[0]) for i in items if len(i) == 1]
#   kwargs = {i[0]: GetArg(i[1]) for i in items if len(i) == 2}
# 
#   # check for syntax error
#   for i in range(1, len(items)):
#     if (len(items[i]) == 1) and (len(items[i-1]) == 2):
#       raise SyntaxError(("Error with item " + str(i) + " \n" +
#                          "  parsing string " + s + "\n" +
#                          "  Items: " + str(items) + "\n" +
#                          "  Item[" + str(i-1) +"] :" + str(items[i-1]) + "\n" +
#                          "  Item[" + str(i) +"] :" + str(items[i]) ))
# 
#   return args, kwargs
# 
# Path: qkeras/safe_eval.py
# def safe_eval(eval_str, op_dict, *params, **kwparams):  # pylint: disable=invalid-name
#   """Replaces eval by a safe eval mechanism."""
# 
#   function_split = eval_str.split("(")
#   quantizer = op_dict.get(function_split[0], None)
# 
#   if len(function_split) == 2:
#     args, kwargs = GetParams("(" + function_split[1])
#   else:
#     args = []
#     kwargs = {}
# 
#   args = args + list(params)
#   for k in kwparams:
#     kwargs[k] = kwparams[k]
# 
#   # must be Keras activation object if None
#   if quantizer is None:
#     logging.info("keras dict %s", function_split[0])
#     quantizer = keras.activations.get(function_split[0])
# 
#   if len(function_split) == 2 or args or kwargs:
#     return quantizer(*args, **kwargs)
#   else:
#     if isinstance(quantizer, type):
#       # Check if quantizer is a class
#       return quantizer()
#     else:
#       # Otherwise it is a function, so just return it
#       return quantizer


# Path: tests/safe_eval_test.py
import operator
import pytest
from qkeras.safe_eval import GetParams
from qkeras.safe_eval import safe_eval

  }


def test_safe_eval1():
  s = "add(3,3)"
  assert safe_eval(s, globals()) == 6


def i_func(s):
  return -s


def myadd2(a, b):
  return i_func(a) + i_func(b)


def myadd(a=32, b=10):
  return a + b

class myaddcls(object):
  def __call__(self, a=32, b=10):
    return a + b

def test_safe_eval2():
  s_add = [3, 39]
  assert safe_eval("add", globals(), *s_add) == 42


def test_safe_eval3():
  assert safe_eval("myadd()", globals()) == 42

  assert safe_eval("myadd(a=39)", globals(), b=3) == 42