create an operation function closure
    don't call directly, use parse_operations
    returns a function which itself takes and returns ndarrays
515342
def _op_factory(func, kwargs, opname, bands, rgb_op=False):
    

    def f(arr):
        # Avoid mutation by copying
        newarr = arr.copy()
        if rgb_op:
            # apply func to array's first 3 bands, assumed r,g,b
            # additional band(s) are untouched
            newarr[0:3] = func(newarr[0:3], **kwargs)
        else:
            # apply func to array band at a time
            for b in bands:
                newarr[b - 1] = func(arr[b - 1], **kwargs)
        return newarr

    f.__name__ = str(opname)
    return f
828321
def results(cls, function, group=None):
        
        return numpy.array(cls._results[group][function])
807662
def hook_fn(self, module:nn.Module, input:Tensors, output:Tensors):
        ""
        if self.detach:
            input  = (o.detach() for o in input ) if is_listy(input ) else input.detach()
            output = (o.detach() for o in output) if is_listy(output) else output.detach()
        self.stored = self.hook_func(module, input, output)
179828
def _nargs(f) -> Optional[int]:
    '''
        
    '''
    if isinstance(f, Function):
        return f.nargs
    spec = inspect.getfullargspec(f)
    if spec.varargs is not None:
        return None
    return len(spec.args)
784712
def _generate_ndarray_function_code(handle, name, func_name, signature_only=False):
    """"""
    real_name = ctypes.c_char_p()
    desc = ctypes.c_char_p()
    num_args = mx_uint()
    arg_names = ctypes.POINTER(ctypes.c_char_p)()
    arg_types = ctypes.POINTER(ctypes.c_char_p)()
    arg_descs = ctypes.POINTER(ctypes.c_char_p)()
    key_var_num_args = ctypes.c_char_p()
    ret_type = ctypes.c_char_p()

    check_call(_LIB.MXSymbolGetAtomicSymbolInfo(
        handle, ctypes.byref(real_name), ctypes.byref(desc),
        ctypes.byref(num_args),
        ctypes.byref(arg_names),
        ctypes.byref(arg_types),
        ctypes.byref(arg_descs),
        ctypes.byref(key_var_num_args),
        ctypes.byref(ret_type)))
    narg = int(num_args.value)
    arg_names = [py_str(arg_names[i]) for i in range(narg)]
    arg_types = [py_str(arg_types[i]) for i in range(narg)]
    key_var_num_args = py_str(key_var_num_args.value)
    ret_type = py_str(ret_type.value) if ret_type.value is not None else ''
    doc_str = _build_doc(name,
                         py_str(desc.value),
                         arg_names,
                         arg_types,
                         [py_str(arg_descs[i]) for i in range(narg)],
                         key_var_num_args,
                         ret_type)

    dtype_name = None
    arr_name = None
    ndsignature = []
    signature = []
    ndarg_names = []
    kwarg_names = []
    for i in range(narg):
        name, atype = arg_names[i], arg_types[i]
        if name == 'dtype':
            dtype_name = name
            signature.append('%s=_Null'%name)
        elif atype.startswith('NDArray') or atype.startswith('Symbol'):
            assert not arr_name, \
                "Op can only have one argument with variable " \
                "size and it must be the last argument."
            if atype.endswith('[]'):
                ndsignature.append('*%s'%name)
                arr_name = name
            else:
                ndsignature.append('%s=None'%name)
                ndarg_names.append(name)
        else:
            signature.append('%s=_Null'%name)
            kwarg_names.append(name)
    signature.append('out=None')
    signature.append('name=None')
    signature.append('**kwargs')
    signature = ndsignature + signature

    code = []
    if arr_name:
        code.append("""
def %s(*%s, **kwargs):"""%(func_name, arr_name))
        if not signature_only:
            code.append("""
    ndargs = []
    for i in {}:
        assert isinstance(i, NDArrayBase), \\
            "Positional arguments must have NDArray type, " \\
            "but got %s"%str(i)
        ndargs.append(i)""".format(arr_name))
            if dtype_name is not None:
                code.append("""
    if '%s' in kwargs:
        kwargs['%s'] = _np.dtype(kwargs['%s']).name"""%(
            dtype_name, dtype_name, dtype_name))
            code.append("""
    _ = kwargs.pop('name', None)
    out = kwargs.pop('out', None)
    keys = list(kwargs.keys())
    vals = list(kwargs.values())""")
    else:
        code.append("""
def %s(%s):"""%(func_name, ', '.join(signature)))
        if not signature_only:
            code.append("""
    ndargs = []
    keys = list(kwargs.keys())
    vals = list(kwargs.values())""")
            # NDArray args
            for name in ndarg_names: # pylint: disable=redefined-argument-from-local
                code.append("""
    if {name} is not None:
        assert isinstance({name}, NDArrayBase), \\
            "Argument {name} must have NDArray type, but got %s"%str({name})
        ndargs.append({name})""".format(name=name))
            # kwargs
            for name in kwarg_names: # pylint: disable=redefined-argument-from-local
                code.append("""
    if %s is not _Null:
        keys.append('%s')
        vals.append(%s)"""%(name, name, name))
            # dtype
            if dtype_name is not None:
                code.append("""
    if %s is not _Null:
        keys.append('%s')
        vals.append(_np.dtype(%s).name)"""%(dtype_name, dtype_name, dtype_name))

    if not signature_only:
        code.append("""
    return _imperative_invoke(%d, ndargs, keys, vals, out)"""%(
        handle.value))
    else:
        code.append("""
    return (0,)""")

    doc_str_lines = _os.linesep+''.join(['    '+s if s.strip() else s
                                         for s in 'r"""{doc_str}"""'.format(doc_str=doc_str)
                                         .splitlines(True)])
    code.insert(1, doc_str_lines)
    return ''.join(code), doc_str
1139838
def get_function_pars(fn):
    

    pars = []
    par_names = pyLike.StringVector()
    fn.getParamNames(par_names)

    for pname in par_names:

        par = fn.getParam(pname)
        bounds = par.getBounds()
        perr = par.error() if par.isFree() else np.nan
        pars += [dict(name=pname,
                      value=par.getValue(),
                      error=perr,
                      min=bounds[0],
                      max=bounds[1],
                      free=par.isFree(),
                      scale=par.getScale())]

    return pars
525500
def make_function3(self, node, is_lambda, nested=1, code_node=None):
    

    # For Python 3.3, the evaluation stack in MAKE_FUNCTION is:

    # * default argument objects in positional order
    # * pairs of name and default argument, with the name just below
    #   the object on the stack, for keyword-only parameters
    # * parameter annotation objects
    # * a tuple listing the parameter names for the annotations
    #   (only if there are ony annotation objects)
    # * the code associated with the function (at TOS1)
    # * the qualified name of the function (at TOS)

    # For Python 3.0 .. 3.2 the evaluation stack is:
    # The function object is defined to have argc default parameters,
    # which are found below TOS.
    # * first come positional args in the order they are given in the source,
    # * next come the keyword args in the order they given in the source,
    # * finally is the code associated with the function (at TOS)
    #
    # Note: There is no qualified name at TOS

    # MAKE_CLOSURE adds an additional closure slot

    # In Python 3.6 stack entries change again. I understand
    # 3.7 changes some of those changes. Yes, it is hard to follow
    # and I am sure I haven't been able to keep up.

    # Thank you, Python.

    def build_param(ast, name, default):
        """build parameters:
            - handle defaults
            - handle format tuple parameters
        """
        if self.version >= 3.6:
            value = default
        else:
            value = self.traverse(default, indent='')
        maybe_show_tree_param_default(self.showast, name, value)
        result = '%s=%s' % (name,  value)

        # The below can probably be removed. This is probably
        # a holdover from days when LOAD_CONST erroneously
        # didn't handle LOAD_CONST None properly
        if result[-2:] == '= ':	# default was 'LOAD_CONST None'
            result += 'None'

        return result

    # MAKE_FUNCTION_... or MAKE_CLOSURE_...
    assert node[-1].kind.startswith('MAKE_')

    # Python 3.3+ adds a qualified name at TOS (-1)
    # moving down the LOAD_LAMBDA instruction
    if 3.0 <= self.version <= 3.2:
        lambda_index = -2
    elif 3.03 <= self.version:
        lambda_index = -3
    else:
        lambda_index = None

    args_node = node[-1]

    annotate_dict = {}

    # Get a list of tree nodes that constitute the values for the "default
    # parameters"; these are default values that appear before any *, and are
    # not to be confused with keyword parameters which may appear after *.
    args_attr = args_node.attr

    if isinstance(args_attr, tuple) or (self.version >= 3.6 and isinstance(args_attr, list)):
        if len(args_attr) == 3:
            pos_args, kw_args, annotate_argc  = args_attr
        else:
            pos_args, kw_args, annotate_argc, closure  = args_attr

            i = -4
            kw_pairs = 0
            if closure:
                # FIXME: fill in
                i -= 1
            if annotate_argc:
                # Turn into subroutine and DRY with other use
                annotate_node = node[i]
                if annotate_node == 'expr':
                    annotate_node = annotate_node[0]
                    annotate_name_node = annotate_node[-1]
                    if annotate_node == 'dict' and annotate_name_node.kind.startswith('BUILD_CONST_KEY_MAP'):
                        types = [self.traverse(n, indent='') for n in annotate_node[:-2]]
                        names = annotate_node[-2].attr
                        l = len(types)
                        assert l == len(names)
                        for i in range(l): annotate_dict[names[i]] = types[i]
                        pass
                    pass
                i -= 1
            if kw_args:
                kw_node = node[i]
                if kw_node == 'expr':
                    kw_node = kw_node[0]
                if kw_node == 'dict':
                    kw_pairs = kw_node[-1].attr


        # FIXME: there is probably a better way to classify this.
        have_kwargs = node[0].kind.startswith('kwarg') or node[0] == 'no_kwargs'
        if len(node) >= 4:
            lc_index = -4
        else:
            lc_index = -3
            pass

        if (3.0 <= self.version <= 3.3 and len(node) > 2 and
                node[lambda_index] != 'LOAD_LAMBDA' and
                (have_kwargs or node[lc_index].kind != 'load_closure')):

            # Find the index in "node" where the first default
            # parameter value is located. Note this is in contrast to
            # key-word arguments, pairs of (name, value), which appear after "*".
            # "default_values_start" is this location.
            default_values_start = 0
            if node[0] == 'no_kwargs':
                default_values_start += 1
            # args are after kwargs; kwargs are bundled as one node
            if node[default_values_start] == 'kwargs':
                default_values_start += 1
            defparams = node[default_values_start:default_values_start+args_node.attr[0]]
        else:
            if self.version < 3.6:
                defparams = node[:args_node.attr[0]]
                kw_args  = 0
            else:
                defparams = []
                # FIXME: DRY with code below
                default, kw_args, annotate_argc = args_node.attr[0:3]
                if default:
                    expr_node = node[0]
                    if node[0] == 'pos_arg':
                        expr_node = expr_node[0]
                    assert expr_node == 'expr', "expecting mkfunc default node to be an expr"
                    if (expr_node[0] == 'LOAD_CONST' and
                        isinstance(expr_node[0].attr, tuple)):
                        defparams = [repr(a) for a in expr_node[0].attr]
                    elif expr_node[0] in frozenset(('list', 'tuple', 'dict', 'set')):
                        defparams =  [self.traverse(n, indent='') for n in expr_node[0][:-1]]
                else:
                    defparams = []
                pass
    else:
        if self.version < 3.6:
            defparams = node[:args_node.attr]
            kw_args  = 0
        else:
            default, kw_args, annotate, closure = args_node.attr
            if default:
                expr_node = node[0]
                if node[0] == 'pos_arg':
                    expr_node = expr_node[0]
                assert expr_node == 'expr', "expecting mkfunc default node to be an expr"
                if (expr_node[0] == 'LOAD_CONST' and
                    isinstance(expr_node[0].attr, tuple)):
                    defparams = [repr(a) for a in expr_node[0].attr]
                elif expr_node[0] in frozenset(('list', 'tuple', 'dict', 'set')):
                    defparams =  [self.traverse(n, indent='') for n in expr_node[0][:-1]]
            else:
                defparams = []

            i = -4
            kw_pairs = 0
            if closure:
                # FIXME: fill in
                annotate = node[i]
                i -= 1
            if annotate_argc:
                # Turn into subroutine and DRY with other use
                annotate_node = node[i]
                if annotate_node == 'expr':
                    annotate_node = annotate_node[0]
                    annotate_name_node = annotate_node[-1]
                    if annotate_node == 'dict' and annotate_name_node.kind.startswith('BUILD_CONST_KEY_MAP'):
                        types = [self.traverse(n, indent='') for n in annotate_node[:-2]]
                        names = annotate_node[-2].attr
                        l = len(types)
                        assert l == len(names)
                        for i in range(l): annotate_dict[names[i]] = types[i]
                        pass
                    pass
                i -= 1
            if kw_args:
                kw_node = node[i]
                if kw_node == 'expr':
                    kw_node = kw_node[0]
                if kw_node == 'dict':
                    kw_pairs = kw_node[-1].attr
        pass

    if lambda_index and is_lambda and iscode(node[lambda_index].attr):
        assert node[lambda_index].kind == 'LOAD_LAMBDA'
        code = node[lambda_index].attr
    else:
        code = code_node.attr

    assert iscode(code)
    scanner_code = Code(code, self.scanner, self.currentclass)

    # add defaults values to parameter names
    argc = code.co_argcount
    paramnames = list(scanner_code.co_varnames[:argc])

    # defaults are for last n parameters, thus reverse
    paramnames.reverse();
    defparams.reverse()

    try:
        ast = self.build_ast(scanner_code._tokens,
                             scanner_code._customize,
                             is_lambda = is_lambda,
                             noneInNames = ('None' in code.co_names))
    except (ParserError, ParserError2) as p:
        self.write(str(p))
        if not self.tolerate_errors:
            self.ERROR = p
        return

    if self.version >= 3.0:
        if self.version < 3.6:
            kw_pairs = args_node.attr[1]
    else:
        kw_pairs = 0

    # build parameters
    params = []
    if defparams:
        for i, defparam in enumerate(defparams):
            params.append(build_param(ast, paramnames[i], defparam))

        params += paramnames[i+1:]
    else:
        params = paramnames

    params.reverse() # back to correct order

    if code_has_star_arg(code):
        if self.version > 3.0:
            params.append('*%s' % code.co_varnames[argc + kw_pairs])
        else:
            params.append('*%s' % code.co_varnames[argc])
        argc += 1

    # dump parameter list (with default values)
    if is_lambda:
        self.write("lambda ", ", ".join(params))
        # If the last statement is None (which is the
        # same thing as "return None" in a lambda) and the
        # next to last statement is a "yield". Then we want to
        # drop the (return) None since that was just put there
        # to have something to after the yield finishes.
        # FIXME: this is a bit hoaky and not general
        if (len(ast) > 1 and
            self.traverse(ast[-1]) == 'None' and
            self.traverse(ast[-2]).strip().startswith('yield')):
            del ast[-1]
            # Now pick out the expr part of the last statement
            ast_expr = ast[-1]
            while ast_expr.kind != 'expr':
                ast_expr = ast_expr[0]
            ast[-1] = ast_expr
            pass
    else:
        # FIXME: add annotations here
        self.write("(", ", ".join(params))
    # self.println(indent, '#flags:\t', int(code.co_flags))

    ends_in_comma = False
    if kw_args > 0:
        if not (4 & code.co_flags):
            if argc > 0:
                self.write(", *, ")
            else:
                self.write("*, ")
            pass
        else:
            self.write(", ")
        ends_in_comma = True

        # FIXME: this is not correct for 3.5. or 3.6 (which works different)
        # and 3.7?
        if 3.0 <= self.version <= 3.2:
            kwargs = node[0]
            last = len(kwargs)-1
            i = 0
            for n in node[0]:
                if n == 'kwarg':
                    self.write('%s=' % n[0].pattr)
                    self.preorder(n[1])
                    if i < last:
                        self.write(', ')
                        ends_in_comma = True
                        pass
                    else:
                        ends_in_comma = False
                    pass
                i += 1
                pass
            pass
        elif self.version <= 3.5:
            # FIXME this is not qute right for 3.5
            for n in node:
                if n == 'pos_arg':
                    continue
                elif self.version >= 3.4 and not (n.kind in ('kwargs', 'no_kwargs', 'kwarg')):
                    continue
                else:
                    self.preorder(n)
                    ends_in_comma = False
                break
        elif self.version >= 3.6:
            # argc = node[-1].attr
            # co = node[-3].attr
            # argcount = co.co_argcount
            # kwonlyargcount = co.co_kwonlyargcount

            free_tup = annotate_dict = kw_dict = default_tup = None
            fn_bits = node[-1].attr
            index = -4  # Skip over:
                        #  MAKE_FUNCTION,
                        #  LOAD_CONST qualified name,
                        #  LOAD_CONST code object
            if fn_bits[-1]:
                free_tup = node[index]
                index -= 1
            if fn_bits[-2]:
                annotate_dict = node[index]
                index -= 1
            if fn_bits[-3]:
                kw_dict = node[index]
                index -= 1
            if fn_bits[-4]:
                default_tup = node[index]

            if kw_dict == 'expr':
                kw_dict = kw_dict[0]

            # FIXME: handle free_tup, annotate_dict, and default_tup
            if kw_dict:
                assert kw_dict == 'dict'
                defaults = [self.traverse(n, indent='') for n in kw_dict[:-2]]
                names = eval(self.traverse(kw_dict[-2]))
                assert len(defaults) == len(names)
                sep = ''
                # FIXME: possibly handle line breaks
                for i, n in enumerate(names):
                    self.write(sep)
                    self.write("%s=%s" % (n, defaults[i]))
                    sep = ', '
                    ends_in_comma = False
                    pass
                pass
        pass

    if code_has_star_star_arg(code):
        if argc > 0 and not ends_in_comma:
            self.write(', ')
        self.write('**%s' % code.co_varnames[argc + kw_pairs])

    if is_lambda:
        self.write(": ")
    else:
        self.write(')')
        if annotate_dict and 'return' in annotate_dict:
            self.write(' -> %s' % annotate_dict['return'])
        self.println(":")

    if len(code.co_consts) > 0 and code.co_consts[0] is not None and not is_lambda: # ugly
        # docstring exists, dump it
        print_docstring(self, self.indent, code.co_consts[0])

    scanner_code._tokens = None # save memory
    assert ast == 'stmts'

    all_globals = find_all_globals(ast, set())
    globals, nonlocals = find_globals_and_nonlocals(ast, set(),
                                                    set(), code, self.version)

    for g in sorted((all_globals & self.mod_globs) | globals):
        self.println(self.indent, 'global ', g)

    for nl in sorted(nonlocals):
        self.println(self.indent, 'nonlocal ', nl)

    self.mod_globs -= all_globals
    has_none = 'None' in code.co_names
    rn = has_none and not find_none(ast)
    self.gen_source(ast, code.co_name, scanner_code._customize, is_lambda=is_lambda,
                    returnNone=rn)
    scanner_code._tokens = None; scanner_code._customize = None
368724
function handleOperation(handlers, mode, checkArity, req, res, done) {
  // parse path:
  // - first part is the operation name
  // - the following components of the path are used as arguments
  const parsedParts = parsePath(req);
  if (parsedParts[0].length === 0) {
    done(new ModofunError(403, 'NoOperation', 'Operation must be specified!'));
    return;
  }
  const [operation, ...args] = parsedParts;

  if (operation && handlers.hasOwnProperty(operation)) {
    // the stack of operation specific middleware
    let operationMiddleware = [];
    // operation handler
    let operationHandler = handlers[operation];

    if (Array.isArray(operationHandler)) {
      // if an array is passed, add operation specific middleware
      // last item in the array should be the operation handler
      operationMiddleware = operationHandler.slice(0, -1);
      operationHandler = operationHandler[operationHandler.length-1];

    } else if (typeof operationHandler !== 'function') {
      // otherwise return internal error
      done(new ModofunError(500, 'InvalidConfig', 'Handler must be a function or array'));
      return;
    }

    // call middleware stack with same req/res context
    runMiddlewareStack(operationMiddleware, req, res, (err) => {
      if (err) {
        done(err);
        return;
      }
      try {
        // call handler function
        if (mode === FUNCTION_MODE) {
          invokeFunctionHandler(operationHandler, args, checkArity, req, res, done);
        } else {
          invokeHTTPHandler(operationHandler, args, req, res, done);
        }
      } catch(err) {
        done(err);
      }
    });

  } else {
    // fail if requested operation cannot be resolved
    done(new ModofunError(404, 'NotFound', `No handler for: ${operation}`));
    return;
  }
}
1173751
function tupleToArray(tuple) {
  if(isFunction(tuple)) {
    return function(x) {
      const m = tuple(x)

      if(!isFunction(m.tupleLength)) {
        throw new TypeError('tupleToArray: Tuple returning function required')
      }

      return m.toArray()
    }
  }

  if(isFunction(tuple.tupleLength)) {
    return tuple.toArray()
  }

  throw new TypeError('tupleToArray: Tuple or Tuple returning function required')
}
405485
function make() {
    // create a map of all flow functions wrapped by _make
    const makeFnMap = {};
    Object.keys(fnMap).forEach(function (key) {
      makeFnMap[key] = _make(fnMap[key]);
    });
    return makeFnMap;

    // takes a function and wraps it so that execution is 'postponed'
    function _make(fn) {
      // the user calls this function, e.g. flw.make.series(...)
      return function madeFunction(fns, context, returnKey) {
        if (typeof context === 'string') {
          returnKey = context; context = {};
        }
        // this function is consumed by flw
        return function flowFunction(context, cb) {
          // when passed from a flw flow it's called with a premade context
          // if called directly, create a new context
          if (cb === undefined && typeof context === 'function') {
            cb = context;
            context = {};
            _checkContext(context);
          }

          if (typeof cb !== 'function') {
            throw new Error('flw: .make - cb !== function');
          }
          return fn(fns, context, returnKey, cb);
        };
      };
    }
  }
1115132
function getWrappedFunc(funcName, func, ...args) {
  const funcDefaultArgs = defaultArgs[funcName] || defaultArgs['default'];
  const allArgs = funcDefaultArgs.concat(args);

  return function(...allArgs) {
    const boomArgs = _.take(allArgs, funcDefaultArgs.length);
    let result =  func.call(null, ...boomArgs);
    for (var i = 0; i < args.length; i++) {
      let currArgVal = allArgs[i + funcDefaultArgs.length];
      const argDef = args[i];
      // Check if we need to use the defaults
      if (currArgVal === undefined){
        // Run the function from the args def
        if (_.isFunction(argDef.default)) {
          result.output.payload[argDef.name] = argDef.default();
        // Add the default value to result
        } else if (argDef.default) {
          result.output.payload[argDef.name] = argDef.default;
        }
        // Add the passed value to result
      } else {
        result.output.payload[argDef.name] = currArgVal;
      }
    }
    return result;
  };
}
804269
def call_fn(fn, arglist, env):
  """"""
  if isinstance(fn, framework.LazyFunction):
    # The following looks complicated, but this is necessary because you can't
    # construct closures over the loop variable directly.
    thunks = [(lambda thunk: lambda: framework.eval(thunk, env))(th) for th in arglist.values]
    return fn(*thunks)

  evaled_args = framework.eval(arglist, env)
  if isinstance(fn, framework.EnvironmentFunction):
    return fn(*evaled_args, env=env)

  return fn(*evaled_args)
172791
def build_operation_chain(stack)
      empty_op = EmptyOperation.new(nil)

      stack.reverse.reduce(empty_op) do |next_op, current_op|
        klass, args, block = current_op

        if Class === klass
          klass.new(next_op, *args, &block)
        elsif Proc === klass
          lambda do |env|
            next_op.call(klass.call(env, *args))
          end
        else
          raise StandardError, "Invalid operation, doesn't respond to `call`: #{klass.inspect}"
        end
      end
    end
949207
def __parse(self, function_meta):
        
        self._func = get_mapping_function(
            function_meta["func_name"],
            self.functions_mapping
        )
        self.func_name = self._func.__name__
        self._args = prepare_lazy_data(
            function_meta.get("args", []),
            self.functions_mapping,
            self.check_variables_set
        )
        self._kwargs = prepare_lazy_data(
            function_meta.get("kwargs", {}),
            self.functions_mapping,
            self.check_variables_set
        )

        if self.func_name == "load_csv_file":
            if len(self._args) != 1 or self._kwargs:
                raise exceptions.ParamsError("P() should only pass in one argument!")
            self._args = [self._args[0]]
        elif self.func_name == "get_os_environ":
            if len(self._args) != 1 or self._kwargs:
                raise exceptions.ParamsError("ENV() should only pass in one argument!")
            self._args = [self._args[0]]
1102246
function parseArgs() {
    var args = Array.prototype.slice.call(arguments);

    var ret = {
        query: args[0],
        params: [],
        options: {},
        callback: undefined,
        endCallback: undefined
    };

    args.shift();

    // If specified, params must be an array
    if (args[0] instanceof Array) {
        ret.params = args[0];
        args.shift();
    }

    // If specified, options must be a non-Function object
    if (! (args[0] instanceof Function)) {
        ret.options = args[0];
        args.shift();
    }

    ret.callback = args[0];
    ret.endCallback = args[1];

    if (ret.query === undefined || ret.callback === undefined) {
        throw new Error('query and callback are required');
    }

    return ret;
}
373053
def get_global_vars(func):
    
    closure = getclosurevars(func)
    if closure['nonlocal']:
        raise TypeError("Can't launch a job with closure variables: %s" %
                        closure['nonlocals'].keys())
    globalvars = dict(modules={},
                      functions={},
                      vars={})
    for name, value in closure['global'].items():
        if inspect.ismodule(value):  # TODO: deal FUNCTIONS from closure
            globalvars['modules'][name] = value.__name__
        elif inspect.isfunction(value) or inspect.ismethod(value):
            globalvars['functions'][name] = value
        else:
            globalvars['vars'][name] = value

    return globalvars
48600
def p_expr_function(p):
    ''
    p[0] = ast.Closure(p[4], p[6], p[8], p[2], lineno=p.lineno(1))