Example #1
0
    def _lookup(self, namespace_id, follow_symrefs=True):
        """
        Description:
            Get an object in the namespace by its namespace id
        Input:
            namespace_id: id of the object to retrieve
            follow_symrefs: whether or not to try to perform a deep lookup
                deep lookups can contain other NSIDs which will be looked up in turn until
                a final value is found and returned. For this feature to be enabled, this
                node's ._nsroot attribute must also be a valid NamespaceNode-like object
                that supports a lookup() method that will be passed an NSID.

        Output:
            item if found, else NamespaceLookupError raised
        """
        log = LoggerAdapter(logger, {'name_ext': 'NamespaceNode._lookup'})
        log.debug('[{}] lookup([{}])'.format(self._nsid, namespace_id))
        obj = None

        if follow_symrefs and is_nsid_ref(namespace_id):
            value = self._lookup_symbolic_ref(namespace_id)
            return value

        else:
            #- split the NSID by path seperator (normally a dot)
            path = self._name_to_path(namespace_id)
            #- fully qualified NSID or not?
            if self._nsroot and path[0] == self._nsroot._nsid:
                #- lookup fully qualified NSIDs using the root node
                next_nsid = '.'.join(path[1:])
                return self._nsroot.lookup(next_nsid,
                                           follow_symrefs=follow_symrefs)
            else:
                #- lookup relative NSIDs iteratively from current
                obj = self
                for name in path:
                    try:
                        obj = getattr(obj, name)

                        if follow_symrefs and is_nsid_ref(obj):
                            return self._lookup_symbolic_ref(obj)

                    except AttributeError as err:
                        log.error(
                            'thewired Failed to find value for [{}] in [{}]'.
                            format(namespace_id, self._nsid))
                        raise NamespaceLookupError("{}.{}".format(
                            self._nsid, namespace_id)) from err

            return obj
Example #2
0
    def _lookup_symbolic_ref(self, ref, follow_symrefs=True):
        """
        Description:
            lookup a value in starting from NSROOT, instead of a value in this namespace
            node. (if nsroot is not set, we lookup from this node.)
        Input:
            ref: the symbolic reference to lookup
            follow: whether to follow links that lead to links or not
        """
        log = LoggerAdapter(logger,
                            {'name_ext': 'NamspaceNode._lookup_symbolic_ref'})
        if self._nsroot is None:
            nsroot = self

        else:
            nsroot = self._nsroot

        log.debug("nsid ref: {}".format(ref))
        #- strip the prefix
        nsid = get_nsid_from_ref(ref)
        ref = nsroot._lookup(nsid)

        if follow_symrefs:
            while is_nsid_ref(ref):
                log.debug("nsid ref: {}".format(ref))
                nsid = get_nsid_from_ref(ref)
                ref = nsroot._lookup(nsid)
            #- ref no longer an nsid ref

        return ref
Example #3
0
    def get_addendum(self, nsid=None, implementor=None, *args, **kwargs):
        """
        Description:
            addendums can be callables or strings
            this wraps the differences up

        Input:
            nsid: nsid of the implementor to get the addendum for
            implementor: implementor object to get the addendum for
            *args: ignored
            **kwargs: passed to the ParametizedCall object if this is a dynamic addendum
                type
        """
        log = LoggerAdapter(logger,
                            {'name_ext': 'AddendumFormatter.get_addendum'})
        log.debug("Entering")
        log.debug("args: {}".format(args))
        log.debug("kwargs: {}".format(kwargs))

        if implementor and self.key:
            log.debug("Getting key function")
            key_func = self.get_key_func()
            key = key_func(implementor)
        else:
            key = None
        log.debug("key: {}".format(key))

        log.debug("_addendums: {}".format(self._addendums))
        addendums = list()
        for addendum in self._addendums:
            if is_nsid_ref(addendum):
                log.debug("Dereferencing addendum: {}".format(addendum))
                addendum = self.nsroot._lookup(addendum)

            if isinstance(addendum, collections.Mapping):
                log.debug("Found mapping addendum")
                if ParametizedCall.is_param_call_map(addendum):
                    log.debug("Found Parametized Call addendum")
                    method_name, params = ParametizedCall.get_params(
                        addendum, **kwargs)
                    addendum = ParametizedCall(self.nsroot, method_name,
                                               params)
                    log.debug("Instantiated ParametizedCall")

            if callable(addendum):
                log.debug("Calling addendum w/ key: {}".format(key))
                addendums.append(
                    addendum(nsid=nsid, implementor=implementor, key=key))
            else:
                log.debug("Using bare addendum text: {}".format(addendum))
                addendums.append(addendum)

        final_addendum = ''.join(addendums)
        log.debug("final addendum: {}".format(final_addendum))
        log.debug("Exiting")
        return final_addendum
Example #4
0
 def get_key_func(self):
     """
     Description:
         key methods are possibly NSIDs, so we may have to look them up at run time.
     """
     if self.key:
         if is_nsid_ref(self.key):
             key_func = self.nsroot._lookup(self.key)
             return key_func
     else:
         return None
Example #5
0
    def deref_sequence_items(self, seq):
        """
        Description:
            dereference everything in a sequence
        """
        dref_seq = list()
        for item in seq:
            if is_nsid_ref(item):
                item = self.nsroot._lookup_symbolic_ref(item,
                                                        follow_symrefs=True)
            dref_seq.append(item)

        return dref_seq
Example #6
0
    def make_addendum(self,
                      nsid=None,
                      implementor=None,
                      key=None,
                      need_key=True):
        """
        Description:
            create the addendum dynamically from the parameter map
            Inter-namespace symbolic references are all deferenced

        Input:
            nsid: ignored;
            implementor: ignored;
            key: sub key to use in the parameterized dict
                generally per-implementor object specific

            need_key: boolean to control raising KeyError if provided key does not exist
                in the addendum param map

        Output:
            a string suitable for use in an Addendum provider
        """

        log = LoggerAdapter(logger,
                            {'name_ext': 'ParametizedCall.make_addendum'})
        unpack_str = ''
        for k, v in self.params.items():

            #- dereference symbolic ref values
            if is_nsid_ref(v):
                log.debug("Dereferencing symbolic ref: {}".format(v))
                v = self.nsroot._lookup_symbolic_ref(v, follow_symrefs=True)
                log.debug("deref: {}".format(v))

            #- dereference sequence items
            if isinstance(v, collections.Sequence) and not isinstance(v, str):
                v = self.stringify_sequence(v, key=key)
                unpack_str += '{} = {}, '.format(k, v)
                continue

            if isinstance(v, collections.Mapping) and key is not None:
                try:
                    v = v[key]
                    #unpack_str += '{} = {}, '.format(k,v[key])
                except KeyError as err:
                    #- subkey not present
                    msg = "Subkey '{}' not present; not using".format(key)
                    log.debug(msg)
                    if need_key:
                        raise

            if isinstance(v, str):
                unpack_str += '{} = \'{}\', '.format(k, v)
            else:
                #- immediate non-string value
                unpack_str += '{} = {}, '.format(k, v)

        #- chop off last ", "
        unpack_str = unpack_str[0:-2]

        addendum = '.' + self.method_name + '(' + unpack_str + ')'
        log.debug("returning addendum: {}".format(addendum))
        return addendum