示例#1
0
文件: __init__.py 项目: bddppq/tvm
    def wrapped_func(func, *args, **kwargs): #pylint: disable=missing-docstring
        from .util import _is_tvm_arg_types
        if _is_tvm_arg_types(args):
            src = _pruned_source(func)
            closure_vars = inspect.getclosurevars(func).nonlocals
            closure_vars.update(inspect.getclosurevars(func).globals)
            return source_to_op(src, args, func.__globals__, closure_vars)

        from .runtime import _enter_hybrid_runtime, _restore_runtime
        intersect = _enter_hybrid_runtime(func)
        value = func(*args, **kwargs)
        _restore_runtime(func, intersect)
        return value
示例#2
0
def _resolve_imports(func):
    ''' determine any modules the function might be using
    we cannot determine what possible closures do '''
    cv = inspect.getclosurevars(func)
    candidates = (key for key in cv.globals if inspect.ismodule(cv.globals[key]))
    module_names = [key for key in candidates if key in sys.modules]
    return module_names
示例#3
0
文件: scene.py 项目: yy/manim
    def __deepcopy__(self, clone_from_id):
        cls = self.__class__
        result = cls.__new__(cls)
        clone_from_id[id(self)] = result
        for k, v in self.__dict__.items():
            if k in ["renderer", "time_progression"]:
                continue
            if k == "camera_class":
                setattr(result, k, v)
            setattr(result, k, copy.deepcopy(v, clone_from_id))

        # Update updaters
        for mobject in self.mobjects:
            cloned_updaters = []
            for updater in mobject.updaters:
                # Make the cloned updater use the cloned Mobjects as free variables
                # rather than the original ones. Analyzing function bytecode with the
                # dis module will help in understanding this.
                # https://docs.python.org/3/library/dis.html
                # TODO: Do the same for function calls recursively.
                free_variable_map = inspect.getclosurevars(updater).nonlocals
                cloned_co_freevars = []
                cloned_closure = []
                for i, free_variable_name in enumerate(
                        updater.__code__.co_freevars):
                    free_variable_value = free_variable_map[free_variable_name]

                    # If the referenced variable has not been cloned, raise.
                    if id(free_variable_value) not in clone_from_id:
                        raise Exception(
                            f"{free_variable_name} is referenced from an updater "
                            "but is not an attribute of the Scene, which isn't "
                            "allowed.")

                    # Add the cloned object's name to the free variable list.
                    cloned_co_freevars.append(free_variable_name)

                    # Add a cell containing the cloned object's reference to the
                    # closure list.
                    cloned_closure.append(
                        types.CellType(clone_from_id[id(free_variable_value)]))

                cloned_updater = types.FunctionType(
                    updater.__code__.replace(
                        co_freevars=tuple(cloned_co_freevars)),
                    updater.__globals__,
                    updater.__name__,
                    updater.__defaults__,
                    tuple(cloned_closure),
                )
                cloned_updaters.append(cloned_updater)
            clone_from_id[id(mobject)].updaters = cloned_updaters
        return result
示例#4
0
def _cast_detection_model(model, device):
    # check model is an instance of one of the meta arch
    from detectron2.export.caffe2_modeling import Caffe2MetaArch
    from detectron2.modeling import META_ARCH_REGISTRY

    if isinstance(model, Caffe2MetaArch):
        model._wrapped_model = _cast_detection_model(model._wrapped_model, device)
        return model

    assert isinstance(model, tuple(META_ARCH_REGISTRY._obj_map.values()))
    model.to(device)
    # cast normalizer separately
    if hasattr(model, "normalizer") and not (
        hasattr(model, "pixel_mean") and hasattr(model, "pixel_std")
    ):
        pixel_mean = inspect.getclosurevars(model.normalizer).nonlocals["pixel_mean"]
        pixel_std = inspect.getclosurevars(model.normalizer).nonlocals["pixel_std"]
        pixel_mean = pixel_mean.to(device)
        pixel_std = pixel_std.to(device)
        model.normalizer = lambda x: (x - pixel_mean) / pixel_std
    return model
示例#5
0
def no_globals(*funcs):
    '''Warn about global variables in functions, a common source of problems'''
    import inspect
    NoGlobalVars = True
    for func in funcs:
        for gname, gvalue in inspect.getclosurevars(func).globals.items():
            if not inspect.ismodule(gvalue) and not inspect.isfunction(gvalue):
                print(
                    'Warning: You appear to be using global variable "{}" in function "{}"'
                    .format(gname, func.__name__))
                NoGlobalVars = False
    assert NoGlobalVars, 'Use only parameters and local variables in your functions'
示例#6
0
def test_wrap_r_function(is_method):
    r_code = 'function(x, y=FALSE, z="abc") TRUE'
    parameter_names = ('self', 'x', 'y', 'z') if is_method else ('x', 'y', 'z')
    r_func = robjects.r(r_code)
    foo = robjects.functions.wrap_r_function(r_func,
                                             'foo',
                                             is_method=is_method)
    assert inspect.getclosurevars(foo).nonlocals['r_func'].rid == r_func.rid
    assert tuple(foo.__signature__.parameters.keys()) == parameter_names
    if not is_method:
        res = foo(1)
        assert res[0] is True
示例#7
0
def replace_class_closure(func, class_):
    """
    functions defined within classes that use super() are given
    a __class__ closure variable which is how the super() magic works.
    However, this messes up methods when they are attached to a diferent
    class.
    """
    closurevars = inspect.getclosurevars(func)
    assert '__class__' in closurevars.nonlocals

    new_func = types.FunctionType(func.__code__, func.__globals__,
                                  closure=(make_cell(class_),))
    return new_func
示例#8
0
def function_by_value_reducer(fun):
    cl_vars = inspect.getclosurevars(fun)
    code = marshal.dumps(fun.__code__)
    basic_def = (fun.__name__, fun.__qualname__, code, fun.__closure__)
    global_refs = dict(cl_vars.globals)
    get_global_references_from_nested_code(fun.__code__, fun.__globals__,
                                           global_refs)
    fun_context = {
        'global_refs': global_refs,
        'defaults': fun.__defaults__,
        'kwdefaults': fun.__kwdefaults__
    }
    return function_unpickle, basic_def, fun_context, None, None, set_funcion_state
示例#9
0
    def __init__(self, mapping_func, clamp):
        self.mapping_func = mapping_func
        self.clamp = clamp
        tree = util.get_ast(mapping_func).body[0]

        closure_vars = inspect.getclosurevars(mapping_func)
        for var, value in closure_vars.nonlocals.items():
            value = ast.parse(str(value)).body[0].value
            tree = util.inline_variable(var, value, tree)

        self.ast = tree
        self.ndim = len(self.ast.args.args)
        self.shape = mapping_func(*[1 for _ in range(self.ndim)])
示例#10
0
    def __deepcopy__(self, memo):
        cls = self.__class__
        result = cls.__new__(cls)
        memo[id(self)] = result
        for k, v in self.__dict__.items():
            if type(v) in [FrameServer, Event, Camera]:
                continue
            setattr(result, k, copy.deepcopy(v, memo))

        # Update updaters
        for mobject in self.mobjects:
            cloned_updaters = []
            for updater in mobject.updaters:
                # Make the cloned updater use the cloned Mobjects as free variables
                # rather than the original ones.
                # TODO: The the same for function calls recursively.
                free_variable_map = inspect.getclosurevars(updater).nonlocals
                cloned_co_freevars = []
                cloned_closure = []
                for i, free_variable_name in enumerate(
                        updater.__code__.co_freevars):
                    free_variable_value = free_variable_map[free_variable_name]
                    if isinstance(free_variable_value, Mobject):
                        random_name = get_random_name(free_variable_map)

                        # Put the cloned Mobject in the function's scope.
                        free_variable_map[random_name] = memo[id(
                            free_variable_value)]

                        # Add the cloned Mobject's name to the free variable list.
                        cloned_co_freevars.append(random_name)

                        # Add a cell containing the cloned Mobject's reference to the
                        # closure list.
                        cloned_closure.append(
                            types.CellType(memo[id(free_variable_value)]))
                    else:
                        cloned_co_freevars.append(free_variable_name)
                        cloned_closure.append(updater.__closure__[i])

                cloned_updater = types.FunctionType(
                    updater.__code__.replace(
                        co_freevars=tuple(cloned_co_freevars)),
                    updater.__globals__,
                    updater.__name__,
                    updater.__defaults__,
                    tuple(cloned_closure),
                )
                cloned_updaters.append(cloned_updater)
            memo[id(mobject)].updaters = cloned_updaters
        return result
示例#11
0
def analyze(target: CallableFunction) -> Node:
    """Analyze specified target and return a Node representation.

    Args:
        target (CallableFunction): async function to analyze.

    Returns:
        (Node): a node instance representation of target function
    """

    nonlocals = getclosurevars(target).nonlocals

    def _analyze_property(p):
        """Return a tuple (name, value) or (name, function name) as property."""
        value = nonlocals[p] if p in nonlocals else None
        return p, value.__name__ if value and callable(value) else value

    def _analyze_edges(egde_name):
        """Lookup children node from egde_name local var."""
        value = None
        if egde_name in nonlocals and nonlocals[egde_name]:
            edge = nonlocals[egde_name]
            # it could be a collection of node
            if hasattr(edge, "__iter__"):
                value = list(map(analyze, edge))
            else:  # or a single node
                value = [analyze(edge)]
        return (egde_name, value)

    if hasattr(target, "__node_metadata"):
        # its a node construct.
        node = target.__node_metadata
        if not isinstance(node, NodeMetadata):
            raise RuntimeError(
                f'attr __node_metadata of {target} is not a NodeMetadata!')
        return Node(
            name=node.name,
            properties=list(map(_analyze_property, node.properties)),
            edges=list(
                filter(lambda p: p is not None, map(_analyze_edges,
                                                    node.edges))),
        )

    # simple function
    return Node(
        name=target.__name__.lstrip("_")
        if hasattr(target, "__name__") else "anonymous",
        properties=list(map(_analyze_property, nonlocals.keys())),
        edges=[],
    )
示例#12
0
def _inline_modules(fn, modules, constants):
    if sys.version_info.major == 2:
        return None
    cvs = inspect.getclosurevars(fn)
    for mk in cvs.globals.keys():
        gv = cvs.globals[mk]
        if isinstance(gv, types.ModuleType):
            modules[mk] = gv.__name__
        elif hasattr(gv, '__module__') and gv.__module__ != '__main__':
            modules[mk] = gv.__name__, gv.__module__
        elif type(gv) == str or type(gv) == int or type(gv) == float or type(gv) == bool:
            constants[mk] = gv
        else:
            raise TypeError("Unsupported global closure {} type {} in {}".format(mk, gv, fn))
示例#13
0
def test_precedence(order, allclose):
    closure_vars = inspect.getclosurevars(allclose)
    overrides = closure_vars.nonlocals["overrides"]
    assert len(overrides) == 1

    pairs = get_vector_pairs(order, order * 2, np.random.RandomState(6))
    if order in (1, 2):
        assert overrides[0] == dict(atol=order, rtol=order * 2)
        for x, y, close in pairs:
            assert allclose(y, x) == close
    else:
        assert overrides[0] == dict(atol=2, rtol=4)
        x, y, _ = pairs[0]
        assert not allclose(y, x)
示例#14
0
文件: core.py 项目: kyouko-taiga/stew
    def _rewrite_fn(self, fn):
        # Rewrite the operation so that its if statements are wrapped within a
        # matching context.
        node = ast.parse(_unindent(inspect.getsource(fn)))
        node = _RewriteOperation().visit(node)

        src = astunparse.unparse(node)
        exec(compile(src, filename='', mode='exec'))

        self._fn = locals()['_fn']
        update_wrapper(self._fn, fn)
        self._fn.__qualname__ = fn.__qualname__
        self._fn._original = fn
        self._fn._nonlocals = inspect.getclosurevars(self._fn._original).nonlocals
示例#15
0
def get_currently_executing_function_call_arguments(
        include_module_name: bool = False,
        include_caller_names: bool = False,
        **kwargs) -> dict:
    cf: FrameType = currentframe()
    fb: FrameType = cf.f_back
    argvs: ArgInfo = getargvalues(fb)
    fc: CodeType = fb.f_code
    cur_func_obj: Callable = [
        referer for referer in get_referrers(fc)
        if getattr(referer, "__code__", None) is fc
        and getclosurevars(referer).nonlocals.items() <= fb.f_locals.items()
    ][0]
    cur_mod = getmodule(cur_func_obj)
    sig: Signature = signature(cur_func_obj)
    params: dict = {}
    var_positional: dict = {}
    var_keyword: dict = {}
    for key, param in sig.parameters.items():
        val: Any = argvs.locals[key]
        params[key] = val
        if param.kind == Parameter.VAR_POSITIONAL:
            var_positional[key] = val
        elif param.kind == Parameter.VAR_KEYWORD:
            var_keyword[key] = val
    bound_args: BoundArguments = sig.bind(**params)
    call_args: OrderedDict = bound_args.arguments

    call_args_dict: dict = dict(call_args)

    for key, value in var_positional.items():
        call_args_dict[key] = value

    for key, value in var_keyword.items():
        call_args_dict.pop(key)
        call_args_dict.update(value)

    if include_module_name:
        call_args_dict.update({"module_name": cur_mod.__name__})

    if not include_caller_names:
        if call_args.get("cls"):
            call_args_dict.pop("cls", None)
        if call_args.get("self"):
            call_args_dict.pop("self", None)

    call_args_dict.update(**kwargs)

    return call_args_dict
示例#16
0
def _get_loader_details(hook) -> tuple:
    """Return the loader_details for a given FileFinder closure

    :param hook: FileFinder closure
    :returns: loader_details tuple
    """
    try:
        namespace = inspect.getclosurevars(hook)
    except TypeError as err:
        raise ValueError from err

    try:
        return namespace.nonlocals["loader_details"]
    except KeyError as err:
        raise ValueError from err
    def can_process(self, view):
        if inspect.isclass(view):
            for func in self._get_method_decorators(view.dispatch):
                if 'user_passes_test' not in (func.__name__, func.__qualname__.split('.')[0]):
                    continue

                test_func = inspect.getclosurevars(func).nonlocals['test_func']
                if test_func.__name__ == 'check_perms':
                    return True

        elif inspect.isfunction(view):
            # Unwrap the function and look for the has_perms property.
            return self._has_func_decorator(view, 'has_perms')

        return False
    def _get_operation_spec(handler):
        closure_vars = inspect.getclosurevars(handler)
        description = closure_vars.nonlocals.get('description', '')
        payload_schema = closure_vars.nonlocals.get('payload_schema')
        response_schema = closure_vars.nonlocals.get('response_schema')
        success_response_code = closure_vars.nonlocals.get(
            'success_response_code')

        openApiConverter = OpenAPIConverter(OPEN_API_VERSION, lambda s: None,
                                            None)

        request_body = {}
        response = {}

        if payload_schema:
            payload_schema_dict = openApiConverter.schema2jsonschema(
                payload_schema)

            request_body = dict(requestBody=dict(
                description=payload_schema.__name__,
                content={'application/json': {
                    'schema': payload_schema_dict
                }}))

        if response_schema:
            response_schema_dict = openApiConverter.schema2jsonschema(
                response_schema)

            response = {
                f'{success_response_code}': {
                    'description': 'success',
                    'content': {
                        'application/json': {
                            'schema': response_schema_dict
                        }
                    }
                }
            }
        else:
            response = {f'{success_response_code}': ''}

        return {
            'description': description,
            'responses': {
                **response
            },
            **request_body
        }
示例#19
0
    def default(self, obj):
        """
        This method is used to serialize objects to JSON format.

        If obj is a function, then it will return a dict with two keys : 'code', for the code source, and 'nonlocals' for all nonlocalsvalues. (including nonlocals functions, that will be serialized as this is recursive.)
        if obj is a np.darray, it converts it into a list.
        if obj is an object with __dict__ attribute, it returns its __dict__.
        Else, will let the JSONEncoder do the stuff, and throw an error if the type is not suitable for JSONEncoder.

        Parameters
        ----------
        obj : Any
            Arbitrary object to convert

        Returns
        -------
        Any
            Python object that JSON encoder will recognize

        """
        if not (isinstance(obj, ModuleType)) and isinstance(
            obj, (MethodType, FunctionType)
        ):
            cvars = inspect.getclosurevars(obj)
            cvardict = {**copy.copy(cvars.globals), **copy.copy(cvars.nonlocals)}
            for i in list(cvardict):
                # NOTE : All module types objects are removed, because otherwise it throws ValueError: Circular reference detected if not. TODO
                if isinstance(cvardict[i], ModuleType):
                    del cvardict[i]
            return self._check_iterable(
                {"code": inspect.getsource(obj), "nonlocals": cvardict}
            )
        elif isinstance(obj, np.ndarray):
            if obj.size > 1000:
                obj = np.resize(obj, (100, 100))
                return f"TRUNCATED ARRAY: {repr(obj)}"
            # We return the repr and not a list to avoid the JsonEncoder to iterate over it.
            return repr(obj)
        elif hasattr(obj, "__dict__"):
            temp = getattr(obj, "__dict__")
            # MappingProxy is not supported by the Json Encoder
            if isinstance(temp, MappingProxyType):
                return dict(temp)
            return self._check_iterable(temp)
        elif isinstance(obj, np.uint8):
            return int(obj)

        return f"Unsupported type for serializing -> {str(type(obj))}"
def test_make_validator():
    def func():
        ...

    key = "foo"
    params = {"bar": "xy", "baz": (1, -1)}

    name, validator = make_validator(func, key, **params).popitem()
    assert isinstance(validator, classmethod)
    assert name == func.__name__
    assert getclosurevars(validator.__func__).nonlocals["params"] == params
    assert hasattr(validator, "__validator_config__")
    assert validator.__validator_config__[0] == (key, )  # validated key

    name, root_validator = make_validator(func, "", **params).popitem()
    assert hasattr(root_validator, "__root_validator_config__")
示例#21
0
    def _has_method_decorator(self, function, func_name):
        """
        Checks if a function with the name `func_name` (str) is present within the
        ``@method_decorator`` on the provided function.
        """
        closures = inspect.getclosurevars(function).nonlocals
        if 'decorators' in closures:
            for func in closures['decorators']:
                if func.__name__ == func_name or func.__qualname__.split(
                        '.')[0] == func_name:
                    return True

        if 'method' in closures:
            return self._has_method_decorator(closures['method'], func_name)

        return False
示例#22
0
def get_bindable(obj, base):
    """
    attr : dict of inspect.Attribute
    base : type

    Returns a obj/function that can properly be moved to another
    class. Largely this deals with Python 3 and super() binding
    the class via a closure.
    """
    if not isinstance(obj, types.FunctionType):
        return obj

    closurevars = getclosurevars(obj)
    if '__class__' in closurevars.nonlocals:
        obj = replace_class_closure(obj, base)
    return obj
示例#23
0
def _inspect_func_serialization(base_obj, depth, parent, failure_set):
    """Adds the first-found non-serializable element to the failure_set."""
    assert inspect.isfunction(base_obj)
    closure = inspect.getclosurevars(base_obj)
    found = False
    if closure.globals:
        _printer.print(
            f"Detected {len(closure.globals)} global variables. "
            "Checking serializability..."
        )

        with _printer.indent():
            for name, obj in closure.globals.items():
                serializable, _ = inspect_serializability(
                    obj,
                    name=name,
                    depth=depth - 1,
                    _parent=parent,
                    _failure_set=failure_set,
                )
                found = found or not serializable
                if found:
                    break

    if closure.nonlocals:
        _printer.print(
            f"Detected {len(closure.nonlocals)} nonlocal variables. "
            "Checking serializability..."
        )
        with _printer.indent():
            for name, obj in closure.nonlocals.items():
                serializable, _ = inspect_serializability(
                    obj,
                    name=name,
                    depth=depth - 1,
                    _parent=parent,
                    _failure_set=failure_set,
                )
                found = found or not serializable
                if found:
                    break
    if not found:
        _printer.print(
            f"WARNING: Did not find non-serializable object in {base_obj}. "
            "This may be an oversight."
        )
    return found
示例#24
0
def decipher_done_callback(done_callback):
    closure = inspect.getclosurevars(done_callback).nonlocals
    state = f"progress: {closure['nfinished']}/{closure['nfuts']}"
    future = closure["outer"]
    print(future, state)
    children = closure["children"]
    for child in children:
        if child.done():
            # resolved, exception, cancelled
            if child.cancelled():
                print(child, "cancelled")
            elif child.exception():
                print(child, child.exception())
            else:
                print(child, child.result())
        else:
            print(child, "pending")
示例#25
0
 def __init__(self,
              environment: Environment,
              function: FunctionType,
              globals_: Dict[str, Any] = None) -> None:
     """Construct a parser."""
     self.environment = environment
     self.function = function
     _, self.line_offset = inspect.getsourcelines(function)
     self.filename: str = inspect.getfile(function)
     self.block_map: Dict[Block, Constant] = {}
     if globals_ is None:
         free_vars = inspect.getclosurevars(function)  # type: ignore
         assert isinstance(free_vars.builtins, Dict)
         globals_ = free_vars.builtins
         globals_.update(free_vars.globals)
         globals_.update(free_vars.nonlocals)
     self.globals_ = globals_
示例#26
0
文件: veneer.py 项目: yuul/Scenic
def getAllGlobals(req, restrictTo=None):
	namespace = req.__globals__
	if restrictTo is not None and restrictTo is not namespace:
		return {}
	externals = inspect.getclosurevars(req)
	assert not externals.nonlocals		# TODO handle these
	globs = dict(externals.builtins)
	for name, value in externals.globals.items():
		globs[name] = value
		if inspect.isfunction(value):
			subglobs = getAllGlobals(value, restrictTo=namespace)
			for name, value in subglobs.items():
				if name in globs:
					assert value is globs[name]
				else:
					globs[name] = value
	return globs
示例#27
0
def test_validator_getter():
    # TODO: test all variations
    spec = {
        "validator": "range_check",
        "validator_params": {"min_key": "min"}
        # "validator_opts":  FIXME:
    }
    key = "foo"
    validator = _validator(key, spec)[spec["validator"]]

    # FIXME: move to test_factory
    assert isinstance(validator, classmethod)  # type
    assert validator.__validator_config__[0] == (key,)  # validated key
    # list of all keys of parent
    assert (
        getclosurevars(validator.__func__).nonlocals["params"]
        == spec["validator_params"]
    )
示例#28
0
def global_getclosurevars(f: Callable) -> inspect.ClosureVars:
    """Grab the closure over all passed function. Add all known global
    variables in as well.

    Args:
        f (Callable): The function pointer

    Returns:
        inspect.ClosureVars: Standard thing returned from `inspect.getclosurevars`,
            with the global variables added into it.
    """
    cv = inspect.getclosurevars(f)

    # Now, add all the globals that we might know about in case they are also
    # referenced inside this a nested lambda.
    cv.globals.update(f.__globals__)  # type: ignore

    return cv
示例#29
0
 def _is_abstract_hard_check(cls, obj):
     try:
         closure_vars = inspect.getclosurevars(obj)
         for value in closure_vars.builtins.values():
             if value is NotImplementedError or value is NotImplemented:
                 break
         else:
             return False
     except AttributeError:
         # can not determine - probably native or builtin code
         return False
     try:
         for instruction in dis.get_instructions(obj):
             if instruction.opname == "RAISE_VARARGS" and instruction.arg == 1:
                 return True
     except TypeError:
         pass
     return False
示例#30
0
def getAllGlobals(req, restrictTo=None):
    """Find all names the given lambda depends on, along with their current bindings."""
    namespace = req.__globals__
    if restrictTo is not None and restrictTo is not namespace:
        return {}
    externals = inspect.getclosurevars(req)
    assert not externals.nonlocals  # TODO handle these
    globs = dict(externals.builtins)
    for name, value in externals.globals.items():
        globs[name] = value
        if inspect.isfunction(value):
            subglobs = getAllGlobals(value, restrictTo=namespace)
            for name, value in subglobs.items():
                if name in globs:
                    assert value is globs[name]
                else:
                    globs[name] = value
    return globs
示例#31
0
    def default(self, obj):
        """
        This method is used to serialize objects to JSON format.

        If obj is a function, then it will return a dict with two keys : 'code', for the code source, and 'nonlocals' for all nonlocalsvalues. (including nonlocals functions, that will be serialized as this is recursive.)
        if obj is a np.darray, it converts it into a list.
        if obj is an object with __dict__ attribute, it returns its __dict__.
        Else, will let the JSONEncoder do the stuff, and throw an error if the type is not suitable for JSONEncoder.

        Parameters
        ----------
        obj : Any
            Arbitrary object to convert

        Returns
        -------
        Any
            Python object that JSON encoder will recognize

        """
        if inspect.isfunction(obj) and not isinstance(obj, ModuleType):
            cvars = inspect.getclosurevars(obj)
            cvardict = {
                **copy.copy(cvars.globals),
                **copy.copy(cvars.nonlocals)
            }
            for i in list(cvardict):
                # NOTE : All module types objects are removed, because otherwise it throws ValueError: Circular reference detected if not. TODO
                if isinstance(cvardict[i], ModuleType):
                    del cvardict[i]
            return {"code": inspect.getsource(obj), "nonlocals": cvardict}
        elif isinstance(obj, np.ndarray):
            return list(obj)
        elif hasattr(obj, "__dict__"):
            temp = getattr(obj, "__dict__")
            return self._encode_dict(temp)
        elif isinstance(obj, np.uint8):
            return int(obj)
        try:
            return json.JSONEncoder.default(self, obj)
        except TypeError:
            # This is used when the user enters an unknown type in CONFIG. Rather than throwing an error, we transform
            # it into a string "Unsupported type for hashing" so that it won't affect the hash.
            return "Unsupported type for hashing"
示例#32
0
def check(func):
    args = getargs(func.__code__)
    hints = get_type_hints(func)
    cv = getclosurevars(func)
    loc_vars = {n: Any for n in args.args}
    ret = hints.pop('return') if 'return' in hints else None
    loc_vars.update(hints)
    glob_vars = {}
    for k, v in cv.globals.items():
        if v is np:
            glob_vars[k] = NumPy()
        else:
            glob_vars[k] = defines.get(v, None) or v
    source = getsource(func)
    f_ast = parse(source).body[0]
    body = f_ast.body
    exec_lines(source, body, loc_vars, glob_vars, ret)
    defines[func] = 1
    return func
示例#33
0
def kernel(func, **kwargs):
    """Decorator to simplify generation of pystencils Assignments.

    Changes the meaning of the '@=' operator. Each line containing this operator gives a symbolic assignment
    in the result list. Furthermore the meaning of the ternary inline 'if-else' changes meaning to denote a
    sympy Piecewise.

    The decorated function may not receive any arguments, with exception of an argument called 's' that specifies
    a SymbolCreator()

    Examples:
        >>> import pystencils as ps
        >>> @kernel
        ... def my_kernel(s):
        ...     f, g = ps.fields('f, g: [2D]')
        ...     s.neighbors @= f[0,1] + f[1,0]
        ...     g[0,0]      @= s.neighbors + f[0,0] if f[0,0] > 0 else 0
        >>> f, g = ps.fields('f, g: [2D]')
        >>> assert my_kernel[0].rhs == f[0,1] + f[1,0]
    """
    source = inspect.getsource(func)
    source = textwrap.dedent(source)
    a = ast.parse(source)
    KernelFunctionRewrite().visit(a)
    ast.fix_missing_locations(a)
    gl = func.__globals__.copy()

    assignments = []

    def assignment_adder(lhs, rhs):
        assignments.append(Assignment(lhs, rhs))

    gl['_add_assignment'] = assignment_adder
    gl['_Piecewise'] = sp.Piecewise
    gl.update(inspect.getclosurevars(func).nonlocals)
    exec(compile(a, filename="<ast>", mode="exec"), gl)
    func = gl[func.__name__]
    args = inspect.getfullargspec(func).args
    if 's' in args and 's' not in kwargs:
        kwargs['s'] = SymbolCreator()
    func(**kwargs)
    return assignments
示例#34
0
        def wrapped(*args, **kwargs):
            closure = inspect.getclosurevars(f)

            # Create locals
            local_context = inspect.getcallargs(f, *args, **kwargs)

            # Create globals
            global_context = closure.globals
            global_context.update(closure.builtins)
            global_context.update(closure.nonlocals)

            # Run function Requires
            for requirement, string in zip(requires, require_strings):
                assert eval(requirement, global_context, local_context), "Requirement failed: {}. Arguments: {}".format(string, args)

            # Run argument Requires
            for argument in local_context:
                # Optional, in case you want to use mypy.
                if type_checks:
                    expected_type = f.__annotations__.get(argument)
                    if expected_type:
                        try:
                            error_message = "{arg} ({val}) is not an instance of {typ} and it should be.".format(arg=argument, val=local_context[argument], typ=expected_type)
                            assert isinstance(local_context[argument], expected_type), error_message
                        except TypeError:
                            # Because of the way the `typing` library works, it's not really feasible to check that the argument has the correct *type*.
                            # isinstance(val, Type) (where Type is defined by the `typing` library) will generate a TypeError.
                            # This is deeply unfortunate but unavoidable.
                            pass

                requirements = annotation_requirements.get(argument, ())
                compiled = compiled_annotations.get(argument, ())
                for requirement, string in zip(compiled, requirements):
                    assert eval(requirement, global_context, local_context), "Annotation requirement failed: {}. Arguments: {}".format(string, args)

            # Run Ensures
            return_value = f(*args, **kwargs)
            local_context[return_string] = return_value
            for guarantee, string in zip(ensures, ensure_strings):
                assert eval(guarantee, global_context, local_context), "Guarantee failed: {}. Return value: {}".format(string, return_value)

            return return_value