コード例 #1
0
    def default_key(func, *nargs, **kwargs):
        parts = [func.__module__]
        argnames = py23.get_function_arg_names(func)

        if argnames:
            if argnames[0] == "cls":
                cls_ = nargs[0]
                parts.append(cls_.__name__)
                nargs = nargs[1:]
            elif argnames[0] == "self":
                cls_ = nargs[0].__class__
                parts.append(cls_.__name__)
                nargs = nargs[1:]

        parts.append(func.__name__)

        value = ('.'.join(parts), nargs, tuple(sorted(kwargs.items())))

        # make sure key is hashable. We don't strictly need it to be, but this
        # is a way of hopefully avoiding object types that are not ordered (these
        # would give an unreliable key). If you need to key on unhashable args,
        # you should provide your own `key` functor.
        #
        _ = hash(value)  # noqa

        return repr(value)
コード例 #2
0
ファイル: forward.py プロジェクト: wwfxuk/rez
def command(opts, parser, extra_arg_groups=None):
    from rez.config import config
    from rez.utils.platform_ import platform_
    from rez.exceptions import RezSystemError
    from rez.vendor import yaml
    from rez.vendor.yaml.error import YAMLError
    from rez.utils import py23
    import os.path

    # we don't usually want warnings printed in a wrapped tool. But in cases
    # where we do (for debugging) we leave a backdoor - setting $REZ_QUIET=0
    # will stop this warning suppression.
    if "REZ_QUIET" not in os.environ:
        config.override("quiet", True)

    yaml_file = os.path.abspath(opts.YAML)

    cli_args = opts.ARG
    for arg_group in (extra_arg_groups or []):
        cli_args.extend(arg_group)

    if platform_.name == "windows" and yaml_file.lower().endswith(".cmd"):
        with open(yaml_file) as f:
            content = "\n".join(f.readlines()[4:])  # strip batch script
    else:
        with open(yaml_file) as f:
            content = f.read()

    try:
        doc = yaml.load(content, Loader=yaml.FullLoader)
    except YAMLError as e:
        raise RezSystemError("Invalid executable file %s: %s" %
                             (yaml_file, str(e)))

    func_name = doc["func_name"]
    nargs = doc.get("nargs", [])
    kwargs = doc.get("kwargs", {})

    if isinstance(doc["module"], basestring):
        # refers to a rez module
        from rez.backport.importlib import import_module
        namespace = "rez.%s" % doc["module"]
        module = import_module(namespace)
    else:
        # refers to a rez plugin module
        from rez.plugin_managers import plugin_manager
        plugin_type, plugin_name = doc["module"]
        module = plugin_manager.get_plugin_module(plugin_type, plugin_name)

    target_func = getattr(module, func_name)
    func_args = py23.get_function_arg_names(target_func)

    if "_script" in func_args:
        kwargs["_script"] = yaml_file
    if "_cli_args" in func_args:
        kwargs["_cli_args"] = cli_args

    target_func(*nargs, **kwargs)
コード例 #3
0
ファイル: serialise.py プロジェクト: fnaum/rez
    def _process(value):
        if isinstance(value, dict):
            for k, v in value.items():
                value[k] = _process(v)

            return value
        elif isfunction(value):
            func = value

            if hasattr(func, "_early"):
                # run the function now, and replace with return value
                #

                # make a copy of the func with its own globals, and add 'this'
                import types
                fn = types.FunctionType(func.__code__,
                                        func.__globals__.copy(),
                                        name=func.__name__,
                                        argdefs=func.__defaults__,
                                        closure=func.__closure__)

                # apply globals
                fn.__globals__["this"] = EarlyThis(data)
                fn.__globals__.update(get_objects())

                # execute the function
                args = py23.get_function_arg_names(func)

                if len(args) not in (0, 1):
                    raise ResourceError("@early decorated function must "
                                        "take zero or one args only")
                if args:
                    # this 'data' arg support isn't needed anymore, but I'm
                    # supporting it til I know nobody is using it...
                    #
                    value_ = fn(data)
                else:
                    value_ = fn()

                # process again in case this is a function returning a function
                return _process(value_)

            elif hasattr(func, "_late"):
                return SourceCode(func=func,
                                  filepath=filepath,
                                  eval_as_function=True)

            elif func.__name__ in package_rex_keys:
                # if a rex function, the code has to be eval'd NOT as a function,
                # otherwise the globals dict doesn't get updated with any vars
                # defined in the code, and that means rex code like this:
                #
                # rr = 'test'
                # env.RR = '{rr}'
                #
                # ..won't work. It was never intentional that the above work, but
                # it does, so now we have to keep it so.
                #
                return SourceCode(func=func,
                                  filepath=filepath,
                                  eval_as_function=False)

            else:
                # a normal function. Leave unchanged, it will be stripped after
                return func
        else:
            return value