def test_FunctionBuilder_add_arg(): fb = FunctionBuilder('return_five', doc='returns the integer 5', body='return 5') f = fb.get_func() assert f() == 5 fb.add_arg('val') f = fb.get_func() assert f(val='ignored') == 5 with pytest.raises(ValueError) as excinfo: fb.add_arg('val') excinfo.typename == 'ExistingArgument' fb = FunctionBuilder('return_val', doc='returns the value', body='return val') broken_func = fb.get_func() with pytest.raises(NameError): broken_func() fb.add_arg('val', default='default_val') better_func = fb.get_func() assert better_func() == 'default_val' assert better_func('positional') == 'positional' assert better_func(val='keyword') == 'keyword'
def test_FunctionBuilder_modify(): fb = FunctionBuilder('return_five', doc='returns the integer 5', body='return 5') f = fb.get_func() assert f() == 5 fb.varkw = 'kw' f_kw = fb.get_func() assert f_kw(ignored_arg='ignored_val') == 5
def _method_factory(self, pid): """Create a custom function signature with docstring, instantiate it and pass it to a wrapper which will actually call the process. Parameters ---------- pid: str Identifier of the WPS process. Returns ------- func A Python function calling the remote process, complete with docstring and signature. """ process = self._processes[pid] required_inputs_first = sorted(process.dataInputs, key=sort_inputs_key) input_names = [] # defaults will be set to the function's __defaults__: # A tuple containing default argument values for those arguments that have defaults, # or None if no arguments have a default value. defaults = [] for inpt in required_inputs_first: input_names.append(sanitize(inpt.identifier)) if inpt.minOccurs == 0 or inpt.defaultValue is not None: default = inpt.defaultValue if inpt.dataType != "ComplexData" else None defaults.append(utils.from_owslib(default, inpt.dataType)) defaults = tuple(defaults) if defaults else None body = dedent(""" inputs = locals() inputs.pop('self') return self._execute('{pid}', **inputs) """).format(pid=pid) func_builder = FunctionBuilder( name=sanitize(pid), doc=utils.build_process_doc(process), args=["self"] + input_names, defaults=defaults, body=body, filename=__file__, module=self.__module__, ) self._inputs[pid] = {} if hasattr(process, "dataInputs"): self._inputs[pid] = OrderedDict( (i.identifier, i) for i in process.dataInputs) self._outputs[pid] = {} if hasattr(process, "processOutputs"): self._outputs[pid] = OrderedDict( (o.identifier, o) for o in process.processOutputs) func = func_builder.get_func() return func
def _method_factory(self, pid): """Create a custom function signature with docstring, instantiate it and pass it to a wrapper which will actually call the process. Parameters ---------- pid: str Identifier of the WPS process. Returns ------- func A Python function calling the remote process, complete with docstring and signature. """ process = self._processes[pid] input_defaults = OrderedDict() for inpt in process.dataInputs: iid = sanitize(inpt.identifier) default = getattr(inpt, "defaultValue", None) if inpt.dataType != 'ComplexData' else None input_defaults[iid] = utils.from_owslib(default, inpt.dataType) body = dedent(""" inputs = locals() inputs.pop('self') return self._execute('{pid}', **inputs) """).format(pid=pid) func_builder = FunctionBuilder( name=sanitize(pid), doc=utils.build_process_doc(process), args=["self"] + list(input_defaults), defaults=tuple(input_defaults.values()), body=body, filename=__file__, module=self.__module__, ) self._inputs[pid] = {} if hasattr(process, "dataInputs"): self._inputs[pid] = OrderedDict( (i.identifier, i) for i in process.dataInputs ) self._outputs[pid] = {} if hasattr(process, "processOutputs"): self._outputs[pid] = OrderedDict( (o.identifier, o) for o in process.processOutputs ) func = func_builder.get_func() return func
def test_FunctionBuilder_add_arg_kwonly(): fb = FunctionBuilder('return_val', doc='returns the value', body='return val') broken_func = fb.get_func() with pytest.raises(NameError): broken_func() fb.add_arg('val', default='default_val', kwonly=True) better_func = fb.get_func() assert better_func() == 'default_val' with pytest.raises(ValueError): fb.add_arg('val') assert better_func(val='keyword') == 'keyword' with pytest.raises(TypeError): assert better_func('positional') return
glom(target, spec) except GlomError as e: stack = _norm_stack(traceback.format_exc(), e) finally: traceback._some_str = _orig_some_str return stack # quick way to get a function in this file, which doesn't have a glom # package file path prefix on it. this prevents the function getting # removed in the stack flattening. from boltons.funcutils import FunctionBuilder fb = FunctionBuilder(name='_raise_exc', body='raise Exception("unique message")', args=['t']) _raise_exc = fb.get_func() # NB: if we keep this approach, eventually # boltons.funcutils.FunctionBuilder will put lines into the linecache, # and comparisons may break def test_regular_error_stack(): actual = _make_stack({'results': [{'value': _raise_exc}]}) expected = """\ Traceback (most recent call last): File "test_error.py", line ___, in _make_stack glom(target, spec) File "core.py", line ___, in glom raise err glom.core.GlomError.wrap(Exception): error raised while processing, details below.