def _get_bakery_dynamic_attr(self, attname, obj, args=None, default=None): """ Allows subclasses to provide an attribute (say, 'foo') in three different ways: As a fixed class-level property or as a method foo(self) or foo(self, obj). The second argument argument 'obj' is the "subject" of the current Feed invocation. See the Django Feed documentation for details. This method was shamelessly stolen from the Feed class and extended with the ability to pass additional arguments to subclass methods. """ try: attr = getattr(self, attname) except AttributeError: return default if callable(attr) or args: args = args[:] if args else [] # Check co_argcount rather than try/excepting the function and # catching the TypeError, because something inside the function # may raise the TypeError. This technique is more accurate. try: code = six.get_function_code(attr) except AttributeError: code = six.get_function_code(attr.__call__) if code.co_argcount == 2 + len(args): # one argument is 'self' args.append(obj) return attr(*args) return attr
def __init__(self, cb, args, kwargs): self.callback = cb self.args = args or [] self.kwargs = kwargs or {} self.callback_name = cb.__name__ self.callback_filename = os.path.split(get_function_code(cb).co_filename)[-1] self.callback_lineno = get_function_code(cb).co_firstlineno + 1
def _func_type(func): """ returns if callable is a function, method or a classmethod """ argnames = six.get_function_code(func).co_varnames[:six.get_function_code(func).co_argcount] if len(argnames) > 0: if argnames[0] == 'self': return 'method' if argnames[0] == 'cls': return 'classmethod' return 'function'
def test_function_attached_as_workpace_method_has_same_metainformation_as_free_function(self): self.assertEqual(MatrixWorkspace.rebin.__name__, simpleapi.Rebin.__name__) self.assertEqual(MatrixWorkspace.rebin.__doc__, simpleapi.Rebin.__doc__) # Signature of method will have extra self argument freefunction_sig = six.get_function_code(simpleapi.rebin).co_varnames expected_method_sig = ['self'] expected_method_sig.extend(freefunction_sig) self.assertEqual(six.get_function_code(MatrixWorkspace.rebin).co_varnames, tuple(expected_method_sig))
def fix_js_args(func): '''Use this function when unsure whether func takes this and arguments as its last 2 args. It will append 2 args if it does not.''' fcode = six.get_function_code(func) fargs = fcode.co_varnames[fcode.co_argcount-2:fcode.co_argcount] if fargs==('this', 'arguments') or fargs==('arguments', 'var'): return func code = append_arguments(six.get_function_code(func), ('this','arguments')) return types.FunctionType(code, six.get_function_globals(func), func.__name__, closure=six.get_function_closure(func))
def get_func_code(func): """Returns func_code of passed callable.""" _, func = tf_decorator.unwrap(func) if callable(func): if tf_inspect.isfunction(func) or tf_inspect.ismethod(func): return six.get_function_code(func) elif hasattr(func, '__call__'): return six.get_function_code(func.__call__) else: raise ValueError('Unhandled callable, type=%s' % type(func)) else: raise ValueError('Argument must be callable')
def __eq__(self, other): if self.name != other.name: return False # Functions do not define __eq__ but func_code objects apparently do. # (If we're wrapping some other callable, they will be responsible for # defining equality on their end.) if self.body == other.body: return True else: try: return six.get_function_code(self.body) == six.get_function_code(other.body) except AttributeError: return False
def check_function_eq(func_a, func_b): """Check if two functions have the same bytecode.""" code_a = six.get_function_code(func_a) code_b = six.get_function_code(func_b) # check the equality of the bytecode code_equality = all([getattr(code_a, prop) == getattr(code_b, prop) for prop in _FUNCTION_EQUALITY_PROPERTIES]) # check the equality of the function function_equality = all([func(func_b) == func(func_b) for func in _FUNCTION_EQUALITY_METHODS]) return all([code_equality, function_equality])
def repl(self): while True: input = six.moves.input('> ') input = shlex.split(input) command = input[0] if command == 'quit': break for available_command in self.COMMANDS: if command in available_command: method_name = self.COMMANDS[available_command] method = getattr(self, method_name) arg_count = six.get_function_code(method).co_argcount if len(input) != arg_count: print("Wrong argument count.") print("Expected %s" % arg_count) break try: result = method(*input[1:]) except Exception as e: print(e) else: if result is not None: print(result) break else: print("Invalid command.")
def wrapped_target(*args, **kwargs): with silk_meta_profiler(): try: func_code = six.get_function_code(target) except AttributeError: raise NotImplementedError( "Profile not implemented to decorate type %s" % target.__class__.__name__ ) line_num = func_code.co_firstlineno file_path = func_code.co_filename func_name = target.__name__ if not self.name: self.name = func_name self.profile = { "func_name": func_name, "name": self.name, "file_path": file_path, "line_num": line_num, "dynamic": self._dynamic, "start_time": timezone.now(), "request": DataCollector().request, } self._start_queries() try: result = target(*args, **kwargs) except Exception: self.profile["exception_raised"] = True raise finally: with silk_meta_profiler(): self.profile["end_time"] = timezone.now() self._finalise_queries() return result
def serialize(cust_obj): """A function to serialize custom objects passed to a model Args: cust_obj(callable): a custom layer or function to serialize Returns: a dict of the serialized components of the object""" ser_func = dict() if isinstance(cust_obj, types.FunctionType): func_code = six.get_function_code(cust_obj) func_code_d = dill.dumps(func_code).decode('raw_unicode_escape') ser_func['func_code_d'] = func_code_d ser_func['name_d'] = pickle.dumps( cust_obj.__name__).decode('raw_unicode_escape') ser_func['args_d'] = pickle.dumps( six.get_function_defaults(cust_obj)).decode('raw_unicode_escape') clos = dill.dumps( six.get_function_closure(cust_obj)).decode('raw_unicode_escape') ser_func['clos_d'] = clos ser_func['type_obj'] = 'func' else: if hasattr(cust_obj, '__module__'): # pragma: no cover cust_obj.__module__ = '__main__' ser_func['name_d'] = None ser_func['args_d'] = None ser_func['clos_d'] = None ser_func['type_obj'] = 'class' loaded = dill.dumps(cust_obj).decode('raw_unicode_escape') ser_func['func_code_d'] = loaded return ser_func
def filter_kwargs(_function, *args, **kwargs): """Given a function and args and keyword args to pass to it, call the function but using only the keyword arguments which it accepts. This is equivalent to redefining the function with an additional \*\*kwargs to accept slop keyword args. If the target function already accepts \*\*kwargs parameters, no filtering is performed. Parameters ---------- _function : callable Function to call. Can take in any number of args or kwargs """ if has_kwargs(_function): return _function(*args, **kwargs) # Get the list of function arguments func_code = six.get_function_code(_function) function_args = func_code.co_varnames[:func_code.co_argcount] # Construct a dict of those kwargs which appear in the function filtered_kwargs = {} for kwarg, value in list(kwargs.items()): if kwarg in function_args: filtered_kwargs[kwarg] = value # Call the function with the supplied args and the filtered kwarg dict return _function(*args, **filtered_kwargs)
def wrapped_target(*args, **kwargs): with silk_meta_profiler(): try: func_code = six.get_function_code(target) except AttributeError: raise NotImplementedError('Profile not implemented to decorate type %s' % target.__class__.__name__) line_num = func_code.co_firstlineno file_path = func_code.co_filename func_name = target.__name__ if not self.name: self.name = func_name self.profile = { 'func_name': func_name, 'name': self.name, 'file_path': file_path, 'line_num': line_num, 'dynamic': self._dynamic, 'start_time': timezone.now(), 'request': DataCollector().request } self._start_queries() try: result = target(*args, **kwargs) except Exception: self.profile['exception_raised'] = True raise finally: with silk_meta_profiler(): self.profile['end_time'] = timezone.now() self._finalise_queries() return result
def get_func_code(func): """Returns func_code of passed callable, or None if not available.""" _, func = tf_decorator.unwrap(func) if callable(func): if tf_inspect.isfunction(func) or tf_inspect.ismethod(func): return six.get_function_code(func) # Since the object is not a function or method, but is a callable, we will # try to access the __call__method as a function. This works with callable # classes but fails with functool.partial objects despite their __call__ # attribute. try: return six.get_function_code(func.__call__) except AttributeError: return None else: raise ValueError('Argument must be callable')
def construct_new_test_function(original_func, name, build_params): """Builds a new test function based on parameterized data. :param original_func: The original test function that is used as a template :param name: The fullname of the new test function :param build_params: A dictionary or list containing args or kwargs for the new test :return: A new function object """ new_func = types.FunctionType( six.get_function_code(original_func), six.get_function_globals(original_func), name=name, argdefs=six.get_function_defaults(original_func) ) # Support either an arg list or kwarg dict for our data build_args = build_params if isinstance(build_params, list) else [] build_kwargs = build_params if isinstance(build_params, dict) else {} # Build a test wrapper to execute with our kwargs def test_wrapper(func, test_args, test_kwargs): @functools.wraps(func) def wrapper(self): return func(self, *test_args, **test_kwargs) return wrapper return test_wrapper(new_func, build_args, build_kwargs)
def __deepcopy__(self, memo=None): """Create and return a deep copy of this instance.""" # Attempt to figure out from the method signature whether # a comparison function is expected. args = [] code = six.get_function_code(self.__class__.__init__) if any([i.endswith('__cmp') for i in code.co_varnames]): args.append(self._cmp) # Create an empty sorted dictionary. answer = self.__class__(*args) # Ensure that this object is in our memo list, in case # there is a recursive relationship. if not memo: memo = {} memo[id(self)] = answer # Deep copy the individual elements. for key, value in six.iteritems(self): answer.__setitem__( deepcopy(key, memo=memo), deepcopy(value, memo=memo), ) # Done. return answer
def parse_args(args, path, query, specials): def one_or_many(fn_, dict_, key): result = [fn_(value) for value in dict_[key]] return result[0] if len(result) == 1 else result kwargs = {} for arg, parse_fn in six.iteritems(args): if arg in specials: kwargs[arg] = specials[arg]() elif parse_fn is None: kwargs[arg] = one_or_many(lambda x: x, query, arg) elif isinstance(parse_fn, tuple): kwargs[arg] = parse_fn[DEFAULT] if arg not in query else one_or_many(parse_fn[CALLABLE], query, arg) elif isalambda(parse_fn): _code = six.get_function_code(parse_fn) closures = six.get_function_closure(parse_fn) if closures: assert len(closures) <= 1 fn = closures[0].cell_contents else: fn = eval(".".join(_code.co_names), six.get_function_globals(parse_fn)) kwargs[arg] = fn(**parse_args(get_function_args(parse_fn), path, query, specials)) else: kwargs[arg] = one_or_many(parse_fn, query, arg) return kwargs
def execute(self, streams): try: parser = PDFContentParser(streams) except PSEOF: # empty page return while 1: try: (_, obj) = parser.nextobject() except PSEOF: break if isinstance(obj, PSKeyword): name = keyword_name(obj) method = 'do_%s' % name.replace('*', '_a').replace('"', '_w').replace("'", '_q') if hasattr(self, method): func = getattr(self, method) nargs = six.get_function_code(func).co_argcount-1 if nargs: args = self.pop(nargs) logging.debug('exec: %s %r', name, args) if len(args) == nargs: func(*args) else: logging.debug('exec: %s', name) func() else: if STRICT: raise PDFInterpreterError('Unknown operator: %r' % name) else: self.push(obj) return
def _get_file_name(func): try: name = inspect.getfile(func) except AttributeError: name = get_function_code(func).co_filename return os.path.abspath(name)
def __call__ (self, fn, instance, args, kwargs): log_this = LOG.isEnabledFor (self.log_level) if self.log_enter and log_this: # Non-python methods don't have a func_code if self.log_args and hasattr (fn, "func_code"): code = six.get_function_code(fn) argnames = code.co_varnames[:code.co_argcount] x_args = args if not instance else ((instance,) + args) arg_str = ", ".join ("%s=%r" % entry for entry in list(zip (argnames, x_args)) + list(kwargs.items ())) else: # Why? arg_str = "..." LOG.log (self.log_level, "Called: %s:%s:%s (%s)", fn.__class__.__name__, getattr (fn, "__module__", "<?module?>"), getattr (fn, "__name__", "<?name?>"), arg_str) if self.log_trace: sys.settrace (self.globaltrace) tic = time.time () rc = fn (*args, **kwargs) toc = time.time () if self.log_trace: sys.settrace (None) if self.log_exit and log_this: LOG.log ( self.log_level, "Return: %s:%s:%s (...) -> %s (...) Duration: %.6f secs RC: %s", fn.__class__.__name__, getattr (fn, "__module__", "<?module?>"), getattr (fn, "__name__", "<?name?>"), inspect.currentframe ().f_back.f_code.co_name, toc - tic, rc if self.log_rc else "...") return rc
def replot(plot, agg=Count(), info=Const(val=1), shader=Id(), remove_original=True, plot_opts={}, **kwargs): """ Treat the passed plot as an base plot for abstract rendering, generate the proper Bokeh plot based on the passed parameters. This is a convenience for: > src=source(plot, ...) > <plot-type>(source=src, <params>, **ar.mapping(src)) Transfers plot title, width, height from the original plot plot -- Plot to based new plot off of remove_original -- Remove the source plot from the document (default: true) plot_opts -- Options passed directly to soure. This parameter only needs to be used if there is a name conflict bewteen target plot type and source options (see kwargs note) **kwargs -- Arugments for the plot or source as needed. If in conflict, a kwarg will be applied to the source function. If this causes incorrecte behavior, the plot arguments may be put in the plot_opts parameter instead. returns -- A new plot """ # Remove the base plot (if requested) if remove_original and plot in curdoc().context.children: curdoc().context.children.remove(plot) # Sift kwargs source_opts = {} for key in ServerDataSource().vm_props(): if key in kwargs: source_opts[key] = kwargs.pop(key) for name in get_function_code(source).co_varnames: if name in kwargs: source_opts[name] = kwargs.pop(name) # Transfer specific items from the source plot, then updates from kwargs plot_opts['plot_width'] = plot.plot_width plot_opts['plot_height'] = plot.plot_height plot_opts['title'] = plot.title plot_opts.update(kwargs) src = source(plot, agg, info, shader, **source_opts) plot_opts.update(mapping(src)) if shader.out == "image": new_plot = image(source=src, **plot_opts) elif shader.out == "image_rgb": new_plot = image_rgba(source=src, **plot_opts) elif shader.out == "multi_line": new_plot = multi_line(source=src, **plot_opts) else: raise ValueError("Unhandled output type %s" % shader.out) return new_plot
def description(self, argv0='manage.py', command=None): '''Description outputed to console''' command = command or self.__class__.__name__.lower() import inspect _help = u'' _help += u'{}\n'.format(command) if self.__doc__: _help += self._fix_docstring(self.__doc__) +'\n' else: _help += u'{}\n'.format(command) funcs = self.get_funcs() funcs.sort(key=lambda x: six.get_function_code(x[1]).co_firstlineno) for attr, func in funcs: func = getattr(self, attr) comm = attr.replace('command_', '', 1) args = inspect.getargspec(func).args[1:] args = (' [' + '] ['.join(args) + ']') if args else '' _help += "\t{} {}:{}{}\n".format( argv0, command, comm, args) if func.__doc__: _help += self._fix_docstring(func.__doc__, 2) return _help
def attach_func_as_method(name, func_obj, self_param_name, workspace_types=None): """ Adds a method to the given type that calls an algorithm using the calling object as the input workspace :param name: The name of the new method as it should appear on the type :param func_obj: A free function object that defines the implementation of the call :param self_param_name: The name of the parameter in the free function that the method's self maps to :param workspace_types: A list of string names of a workspace types. If None, then it is attached to the general Workspace type. Default=None """ def _method_impl(self, *args, **kwargs): # Map the calling object to the requested parameter kwargs[self_param_name] = self # Define the frame containing the final variable assignment # used to figure out the workspace name kwargs["__LHS_FRAME_OBJECT__"] = _inspect.currentframe().f_back # Call main function return func_obj(*args, **kwargs) # ------------------------------------------------------------------ # Add correct meta-properties for the method signature = ["self"] signature.extend(get_function_code(func_obj).co_varnames) customise_func(_method_impl, func_obj.__name__, tuple(signature), func_obj.__doc__) if workspace_types or len(workspace_types) > 0: for typename in workspace_types: cls = getattr(_api, typename) setattr(cls, name, _method_impl) else: setattr(_api.Workspace, name, _method_impl)
def add_customclassifier(self, method): if not callable(method): log.warning("Skipping non callable custom classifier %s", str(method)) return # method_name = method.im_func.func_name method_name = six.get_function_code(method).co_name self.custom_classifiers[method_name] = method.__get__(self)
def func_lineno(func): """Get the line number of a function. First looks for compat_co_firstlineno, then func_code.co_first_lineno. """ try: return six.get_function_code(func).co_firstlineno except AttributeError: return -1
def _build_new_function(func, name): code = six.get_function_code(func) func_globals = six.get_function_globals(func) func_defaults = six.get_function_defaults(func) func_closure = six.get_function_closure(func) return types.FunctionType(code, func_globals, name, func_defaults, func_closure)
def test_auto_wrap(self): from tcms.xmlrpc.api import auth func_names = getattr(auth, "__all__") for func_name in func_names: func = getattr(auth, func_name) code = six.get_function_code(func) self.assertEqual(code.co_name, "_decorator")
def get_function_arguments(func): """Return (args, kwargs) for func, excluding `self`""" code = six.get_function_code(func) defaults = six.get_function_defaults(func) or [] arg_names = [var for var in code.co_varnames[: code.co_argcount] if var != "self"] n_required = len(arg_names) - len(defaults) return arg_names[:n_required], arg_names[n_required:]
def object_build(self, node, obj): """recursive method which create a partial ast from real objects (only function, class, and method are handled) """ if obj in self._done: return self._done[obj] self._done[obj] = node for name in dir(obj): try: member = getattr(obj, name) except AttributeError: # damned ExtensionClass.Base, I know you're there ! attach_dummy_node(node, name) continue if ismethod(member): member = six.get_method_function(member) if isfunction(member): # verify this is not an imported function filename = getattr(six.get_function_code(member), 'co_filename', None) if filename is None: assert isinstance(member, object) object_build_methoddescriptor(node, member, name) elif filename != getattr(self._module, '__file__', None): attach_dummy_node(node, name, member) else: object_build_function(node, member, name) elif isbuiltin(member): if (not _io_discrepancy(member) and self.imported_member(node, member, name)): continue object_build_methoddescriptor(node, member, name) elif isclass(member): if self.imported_member(node, member, name): continue if member in self._done: class_node = self._done[member] if not class_node in node.locals.get(name, ()): node.add_local_node(class_node, name) else: class_node = object_build_class(node, member, name) # recursion self.object_build(class_node, member) if name == '__class__' and class_node.parent is None: class_node.parent = self._done[self._module] elif ismethoddescriptor(member): assert isinstance(member, object) object_build_methoddescriptor(node, member, name) elif isdatadescriptor(member): assert isinstance(member, object) object_build_datadescriptor(node, member, name) elif type(member) in _CONSTANTS: attach_const_node(node, name, member) else: # create an empty node so that the name is actually defined attach_dummy_node(node, name, member)
def object_build_function(node, member, localname): """create astroid for a living function object""" args, varargs, varkw, defaults = getargspec(member) if varargs is not None: args.append(varargs) if varkw is not None: args.append(varkw) func = build_function(getattr(member, '__name__', None) or localname, args, defaults, six.get_function_code(member).co_flags, member.__doc__) node.add_local_node(func, localname)
def for_function(cls, func, curdir=None): """Extracts the location information from the function and builds the location string (schema: "{source_filename}:{line_number}"). :param func: Function whose location should be determined. :return: FileLocation object """ func = unwrap_function(func) function_code = six.get_function_code(func) filename = function_code.co_filename line_number = function_code.co_firstlineno curdir = curdir or os.getcwd() filename = os.path.relpath(filename, curdir) return cls(filename, line_number)
def copy_func(f, name=None): """Create a copy of a function. Parameters ---------- f : function Function to copy. name : str, optional Name of new function. """ return types.FunctionType(six.get_function_code(f), six.get_function_globals(f), name or f.__name__, six.get_function_defaults(f), six.get_function_closure(f))
def test_frame_stack(): def to_code_names(frames): code_names = deque() for frame in reversed(frames): code_name = frame.f_code.co_name if code_name not in mock_code_names: break code_names.appendleft(code_name) return list(code_names) baz_frame = foo() foo_frame = baz_frame.f_back.f_back frames = frame_stack(baz_frame) assert to_code_names(frames) == ['foo', 'bar', 'baz'] # base frame. frames = frame_stack(baz_frame, base_frame=foo_frame) assert to_code_names(frames) == ['bar', 'baz'] # ignored codes. frames = frame_stack(baz_frame, ignored_codes=[ six.get_function_code(foo), six.get_function_code(baz), ]) assert to_code_names(frames) == ['bar']
def smart_repr(obj, object_list=None): """Return a repr of the object, using the object's __repr__ method. Be smart and pass the depth value if and only if it's accepted. """ # If this object's `__repr__` method has a `__code__` object *and* # the function signature contains `object_list` and `depth`, then # include the object list. # Otherwise, just call the stock repr. try: code = six.get_function_code(obj.__repr__) if all(['object_list' in obj.__repr__.__code__.co_varnames]): return obj.__repr__(object_list=object_list) except AttributeError: pass return repr(obj)
def _dictify(self, lambdaObject): lambdaResult = lambdaObject() dict = {} script = lambdaResult if isinstance(lambdaResult, str) else lambdaResult[0] language = statics.default_lambda_language if isinstance(lambdaResult, str) else lambdaResult[1] dict["script"] = script dict["language"] = language if language == "gremlin-jython" or language == "gremlin-python": if not script.strip().startswith("lambda"): script = "lambda " + script dict["script"] = script dict["arguments"] = six.get_function_code(eval(dict["script"])).co_argcount else: dict["arguments"] = -1 return _SymbolHelper.objectify("Lambda", dict)
def _get_context(func, message=None): if isinstance(func, partial): f_code = six.get_function_code(func.func) line_no = f_code.co_firstlineno filename = f_code.co_filename if not message: params = ", ".join([str(arg) for arg in func.args]) message = "partial function %s(%s)" % (func.func.__name__, params) else: f_code = six.get_function_code(func) line_no = f_code.co_firstlineno filename = f_code.co_filename if not message: if is_lambda_function(func): try: message = 'lambda defined as `{}`'.format(inspect.getsource(func).strip()) except IOError as ioerror: # We are probably in interactive python shell or debugger, # we cannot get source of the lambda. message = ("lambda (Couldn't get it's source code." "Perhaps it is defined in interactive shell.)").format(ioerror) else: message = "function %s()" % func.__name__ return f_code, line_no, filename, message
def __wrapper(func, *args, **kwargs): '''Warn the user, and then proceed.''' code = six.get_function_code(func) warnings.warn_explicit( "{:s}\n\tThis function was moved to '{:s}.{:s}' in " "librosa version {:s}." "\n\tThis alias will be removed in librosa version " "{:s}.".format(moved_from, func.__module__, func.__name__, version, version_removed), category=DeprecationWarning, filename=code.co_filename, lineno=code.co_firstlineno + 1 ) return func(*args, **kwargs)
def the_func(*args): """ Catch a hypothesis FailedHealthCheck exception and log it as a skip. """ try: func(*args) except FailedHealthCheck: func_code = six.get_function_code(func) pytest.skip( 'failed health check for %s() (%s: %s)' % \ ( func_code.co_name, func_code.co_filename, func_code.co_firstlineno ) )
def __init__(self, model, **kwargs): self.model = model self._dependencies = set() _, self.signature, self.kwargs = self._extract_signature( self.model.ode) with open(os.devnull, 'w') as f: code = get_function_code(model.ode) CodeGenerator.__init__(self, code, ostream=f) self.variables = {} self.generate() self.generate() for key, val in self.variables.items(): if val.integral is None: continue self.variables[val.integral].dependencies.update(val.dependencies)
def _build_from_function(node, name, member, module): # verify this is not an imported function try: code = six.get_function_code(member) except AttributeError: # Some implementations don't provide the code object, # such as Jython. code = None filename = getattr(code, 'co_filename', None) if filename is None: assert isinstance(member, object) object_build_methoddescriptor(node, member, name) elif filename != getattr(module, '__file__', None): attach_dummy_node(node, name, member) else: object_build_function(node, member, name)
def dictify(cls, lambda_object, writer): lambda_result = lambda_object() script = lambda_result if isinstance(lambda_result, str) else lambda_result[0] language = statics.default_lambda_language if isinstance( lambda_result, str) else lambda_result[1] out = {"script": script, "language": language} if language == "gremlin-jython" or language == "gremlin-python": if not script.strip().startswith("lambda"): script = "lambda " + script out["script"] = script out["arguments"] = six.get_function_code(eval( out["script"])).co_argcount else: out["arguments"] = -1 return GraphSONUtil.typedValue("Lambda", out)
def decorate(newfunc): if hasattr(func, 'compat_func_name'): name = func.compat_func_name else: name = func.__name__ newfunc.__dict__ = func.__dict__ newfunc.__doc__ = func.__doc__ newfunc.__module__ = func.__module__ if not hasattr(newfunc, 'compat_co_firstlineno'): newfunc.compat_co_firstlineno = six.get_function_code( func).co_firstlineno try: newfunc.__name__ = name except TypeError: # can't set func name in 2.3 newfunc.compat_func_name = name return newfunc
def named_decorator(wrapper, wrapped, decorator): """Takes a wrapper, a wrapped function and a decorator and renames the wrapper to look like wrapped@wrapper :param wrapper: wrapper returned by the decorator :type wrapper: function :param wrapped: wrapped function :type wrapped: function :param decorator: outer decorator :type decorator: function Usage:: def with_log_and_call(log_message): def wrapper(method): def inner_wrapper(*args, **kwargs): print(log_message) return method(*args, **kargs) return named_decorator(inner_wrapper, method, with_log_and_call) return wrapper """ if (getattr(wrapped, '__name__', None) is None or getattr(decorator, '__name__', None) is None): # If the wrapped function does not have a name, abort since we can't # assign a better name. This can happen if you're trying to wrap # function-like objects. return wrapper c = get_function_code(wrapper) updated_decorator_name = '{}@{}'.format( wrapped.__name__, decorator.__name__, ) code_type_args = code_type_args_for_rename(c, updated_decorator_name) code = CodeType(*code_type_args) updated_decorator = FunctionType( code, # Use our updated code object get_function_globals(wrapper), updated_decorator_name, get_function_defaults(wrapper), get_function_closure(wrapper), ) return functools.update_wrapper(updated_decorator, wrapped)
def test_func_as_str(self): name = foo.__name__ line_num = six.get_function_code(foo).co_firstlineno profile_function_or_method('tests.tests.test_dynamic_profiling', 'foo', 'test') mock_data_collector = Mock() mock_data_collector.queries = [] mock_data_collector.request = Request() with patch('silk.profiling.profiler.DataCollector', return_value=mock_data_collector) as mock_DataCollector: foo() self.assertEqual(mock_DataCollector.return_value.register_profile.call_count, 1) call_args = mock_DataCollector.return_value.register_profile.call_args[0][0] self.assertDictContainsSubset({ 'func_name': name, 'dynamic': True, 'file_path': source_file_name(), 'name': 'test', 'line_num': line_num }, call_args)
def FromModule(cls, mod): """Returns a list of all entry points in a module.""" entry_points = [] for item_name in dir(mod): item = getattr(mod, item_name) epi = cls.FromFunction(item) if epi is not None: entry_points.append(epi) # Sort by line number, as we want the functions displayed in the order in which # they were declared. entry_points.sort( key=lambda x: six.get_function_code(x.Function).co_firstlineno) return entry_points
def attach(blueprint, decorator): new_blueprint = copy.deepcopy(blueprint) new_blueprint.deferred_functions = [] for func in blueprint.deferred_functions: freevar_dict = dict( zip( six.get_function_code(func).co_freevars, map(lambda f: f.cell_contents, six.get_function_closure(func)))) rule = freevar_dict['rule'] endpoint = freevar_dict['endpoint'] view_func = freevar_dict['view_func'] options = freevar_dict['options'] decorated_view_func = decorator(view_func) if callable(view_func) and callable(decorator) \ else view_func new_blueprint.add_url_rule(rule, endpoint, decorated_view_func, **options) return new_blueprint
def test_wrapped_X(self): def wrapped(self, instance, red=None, blue=None): pass old_wrapped = wrapped # Wrap it many times and ensure that its still the right one. for _i in range(10): wrapped = self._wrapper(wrapped) func = funcutils.get_wrapped_function(wrapped) func_code = six.get_function_code(func) self.assertEqual(4, len(func_code.co_varnames)) self.assertTrue('self' in func_code.co_varnames) self.assertTrue('instance' in func_code.co_varnames) self.assertTrue('red' in func_code.co_varnames) self.assertTrue('blue' in func_code.co_varnames) self.assertEqual(old_wrapped, func)
def __init__(self, func, defaults, **kwargs): self.func = func self.code = get_function_code(func) self.defaults = defaults self.globals = get_function_globals(self.func) inputs = self._extract_signature(func) self.variables = kwargs.pop('variables', dict()) self.locals = kwargs.pop('locals', dict()) for key, val in inputs: self.variables[key] = _Variable(type='input', value=val, name=key) with open(os.devnull, 'w') as f: CodeGenerator.__init__(self, func, ostream=f) self.generate()
def _func_info(func, args): ''' introspect function's or method's full name. Returns a tuple (name, normalized_args,) with 'cls' and 'self' removed from normalized_args ''' func_type = _func_type(func) lineno = ":%s" % six.get_function_code(func).co_firstlineno if func_type == 'function': name = ".".join([func.__module__, func.__name__]) + lineno return name, args class_name = args[0].__class__.__name__ if func_type == 'classmethod': class_name = args[0].__name__ name = ".".join([func.__module__, class_name, func.__name__]) + lineno return name, args[1:]
def _is_empty_function(func, unwrap=False): """ Return True if func is considered empty. All functions with no return statement have an implicit return None - this is explicit in the code object. """ if isinstance(func, (staticmethod, classmethod, types.MethodType)): func = six.get_method_function(func) if isinstance(func, property): func = property.fget if unwrap: func = _unwrap_function(func) try: code_obj = six.get_function_code(func) except AttributeError: # This callable is something else - assume it is OK. return True # quick check if code_obj.co_code == b'd\x00\x00S' and code_obj.co_consts[0] is None: return True if code_obj.co_code == b'd\x01\x00S' and code_obj.co_consts[1] is None: return True # convert bytes to instructions instructions = _get_instructions(code_obj) if len(instructions) < 2: return True # this never happens as there is always the implicit return None which is 2 instructions assert instructions[ -1].opname == 'RETURN_VALUE' # returns TOS (top of stack) instruction = instructions[-2] if not (instruction.opname == 'LOAD_CONST' and code_obj.co_consts[instruction.arg] is None): # TOS is None return False # return is not None instructions = instructions[:-2] if len(instructions) == 0: return True # look for raise NotImplementedError if instructions[-1].opname == 'RAISE_VARARGS': # the thing we are raising should be the result of __call__ (instantiating exception object) if instructions[-2].opname == 'CALL_FUNCTION': for instr in instructions[:-2]: if instr.opname == 'LOAD_GLOBAL' and code_obj.co_names[ instr.arg] == 'NotImplementedError': return True return False
def __init__(self, target, named_parameter_types): super(Types.NamedParameterTypes, self).__init__() self._named_parameter_types = [] target_code = get_function_code(target) for index in range(target_code.co_argcount): targetparamname = target_code.co_varnames[index] if targetparamname in named_parameter_types: parameter_type = named_parameter_types[targetparamname] named_parameter_type = Types.NamedParameterType( targetparamname, parameter_type) self._named_parameter_types.append(named_parameter_type) else: self._named_parameter_types.append(None)
def _wrap_in_generator(func, source, namer, overload): """Wraps the source code in a generated function. Args: func: the original function source: the generated source code namer: naming.Namer, used for naming vars overload: config.VirtualizationConfig Returns: The generated function with a new closure variable. """ nonlocals = [] for var in six.get_function_code(func).co_freevars: # We must generate dummy vars so the generated function has the same closure # as the original function. free_template = 'var = None' nonlocal_node = templates.replace(free_template, var=var) nonlocals.extend(nonlocal_node) gen_fun_name = namer.new_symbol('gen_fun', set()) template = """ def gen_fun(overload): nonlocals program return f_name """ ret = templates.replace( template, gen_fun=gen_fun_name, nonlocals=nonlocals, overload=overload.symbol_name, program=source, f_name=func.__name__) converted_module, _ = parsing.ast_to_object(ret) outer_func = getattr(converted_module, gen_fun_name) return outer_func(overload.module)
def attach_func_as_method(name, func_obj, self_param_name, workspace_types=None): """ Adds a method to the given type that calls an algorithm using the calling object as the input workspace :param name: The name of the new method as it should appear on the type :param func_obj: A free function object that defines the implementation of the call :param self_param_name: The name of the parameter in the free function that the method's self maps to :param workspace_types: A list of string names of a workspace types. If None, then it is attached to the general Workspace type. Default=None """ def _method_impl(self, *args, **kwargs): # Map the calling object to the requested parameter kwargs[self_param_name] = self # Define the frame containing the final variable assignment # used to figure out the workspace name kwargs["__LHS_FRAME_OBJECT__"] = _inspect.currentframe().f_back # Call main function return func_obj(*args, **kwargs) # ------------------------------------------------------------------ # Add correct meta-properties for the method if hasattr(func_obj, '__signature__'): from inspect import Parameter func_parameters = list(func_obj.__signature__.parameters.values()) func_parameters.insert(0, Parameter("self", Parameter.POSITIONAL_ONLY)) signature = func_obj.__signature__.replace(parameters=func_parameters) else: signature = ['self'] signature.extend(get_function_code(func_obj).co_varnames) signature = tuple(signature) customise_func(_method_impl, func_obj.__name__, signature, func_obj.__doc__) if workspace_types or len(workspace_types) > 0: from mantid import api for typename in workspace_types: cls = getattr(api, typename) setattr(cls, name, _method_impl) else: setattr(Workspace, name, _method_impl)
def _rename_function(f, arg_num, name): """Rename the given function's name appears in the stack trace.""" func_code = six.get_function_code(f) if six.PY2: new_code = types.CodeType( arg_num, func_code.co_nlocals, func_code.co_stacksize, func_code.co_flags, func_code.co_code, func_code.co_consts, func_code.co_names, func_code.co_varnames, func_code.co_filename, name, func_code.co_firstlineno, func_code.co_lnotab, func_code.co_freevars, func_code.co_cellvars) else: new_code = types.CodeType( arg_num, 0, func_code.co_nlocals, func_code.co_stacksize, func_code.co_flags, func_code.co_code, func_code.co_consts, func_code.co_names, func_code.co_varnames, func_code.co_filename, name, func_code.co_firstlineno, func_code.co_lnotab, func_code.co_freevars, func_code.co_cellvars) return types.FunctionType(new_code, f.__globals__, name, f.__defaults__, f.__closure__)
def getnamespace(f): """Returns the complete namespace of a function. Namespace is defined here as the mapping of all non-local variables to values. This includes the globals and the closure variables. Note that this captures the entire globals collection of the function, and may contain extra symbols that it does not actually use. Args: f: User defined function. Returns: A dict mapping symbol names to values. """ namespace = dict(six.get_function_globals(f)) closure = six.get_function_closure(f) freevars = six.get_function_code(f).co_freevars if freevars and closure: for name, cell in zip(freevars, closure): namespace[name] = cell.cell_contents return namespace
def __call__(self, func): """ :param function func: This is the function which should be decorated. :return function: The function decorated to cache the values based on the arguments. """ import inspect if self._memo_target == self.MEMO_FROM_ARGSPEC: check_func = func if inspect.ismethod(check_func): check_func = check_func.im_func if not inspect.isfunction(check_func): if type(check_func) == classmethod: raise TypeError( 'To declare a classmethod with Memoize, the Memoize must be called before ' 'the classmethod\n(will work as a global cache where cls will be part of the ' 'cache-key).') else: raise TypeError('Expecting a function/method/classmethod for Memoize.') else: if 'self' in six.get_function_code(check_func).co_varnames: self._memo_target = self.MEMO_INSTANCE_METHOD else: # If it's a classmethod, it should enter here (and the cls will # be used as a part of the cache key, so, all should work properly). self._memo_target = self.MEMO_FUNCTION # Register argspec details, these are used to normalize cache keys self._argspec = self._GetArgspecObject(*inspect.getargspec(func)) # Create call wrapper, and make it look like the real function call = self._CreateCallWrapper(func) if six.PY2: call.func_name = func.func_name call.__name__ = func.__name__ call.__doc__ = func.__doc__ return call
def for_function(cls, func, curdir=None): """Extracts the location information from the function and builds the location string (schema: "{source_filename}:{line_number}"). :param func: Function whose location should be determined. :return: FileLocation object """ func = unwrap_function(func) function_code = six.get_function_code(func) filename = function_code.co_filename line_number = function_code.co_firstlineno curdir = curdir or os.getcwd() try: filename = os.path.relpath(filename, curdir) except ValueError: # WINDOWS-SPECIFIC (#599): # If a step-function comes from a different disk drive, # a relative path will fail: Keep the absolute path. pass return cls(filename, line_number)
def set_simple_func(self, func, args=()): """Set the model function to use a simple but somewhat inefficient calling convention. The function should obey the following convention:: def func(param0, param1, ..., paramN, *args): modeled_data = { do something using the parameters } return modeled_data Returns *self*. """ code = get_function_code(func) npar = code.co_argcount - len(args) pnames = code.co_varnames[:npar] def wrapper(params, *args): return func(*(tuple(params) + args)) return self.set_func(wrapper, pnames, args)
def _rename_function(f, arg_num, name): """Rename the given function's name appears in the stack trace.""" func_code = six.get_function_code(f) if sys.version_info > (3, 8, 0, "alpha", 3): # Python3.8 / PEP570 added co_posonlyargcount argument to CodeType. new_code = types.CodeType( arg_num, func_code.co_posonlyargcount, 0, func_code.co_nlocals, func_code.co_stacksize, func_code.co_flags, func_code.co_code, func_code.co_consts, func_code.co_names, func_code.co_varnames, func_code.co_filename, name, func_code.co_firstlineno, func_code.co_lnotab, func_code.co_freevars, func_code.co_cellvars) else: new_code = types.CodeType( arg_num, 0, func_code.co_nlocals, func_code.co_stacksize, func_code.co_flags, func_code.co_code, func_code.co_consts, func_code.co_names, func_code.co_varnames, func_code.co_filename, name, func_code.co_firstlineno, func_code.co_lnotab, func_code.co_freevars, func_code.co_cellvars) return types.FunctionType(new_code, f.__globals__, name, f.__defaults__, f.__closure__)
def dictify(cls, lambda_object, writer): lambda_result = lambda_object() script = lambda_result if isinstance(lambda_result, str) else lambda_result[0] language = statics.default_lambda_language if isinstance( lambda_result, str) else lambda_result[1] out = {"script": script, "language": language} if language == "gremlin-jython" or language == "gremlin-python": if not script.strip().startswith("lambda"): script = "lambda " + script out["script"] = script out["arguments"] = six.get_function_code(eval( out["script"])).co_argcount elif language == "gremlin-groovy" and "->" in script: # if the user has explicitly added parameters to the groovy closure then we can easily detect one or two # arg lambdas - if we can't detect 1 or 2 then we just go with "unknown" args = script[0:script.find("->")] out["arguments"] = 2 if "," in args else 1 else: out["arguments"] = -1 return GraphSONUtil.typedValue("Lambda", out)