Exemplo n.º 1
0
    def testApplication(self):
        """Test function application across states."""
        self.assertEqual(
            superposition.superposition(2, 4),
            superposition.state_apply(superposition.superposition(1, 2),
                                      lambda x: x * 2))

        # As everything working on states, this should also work on scalars.
        applied = superposition.state_apply(5, lambda x: x * 2)
        self.assertTrue(superposition.state_eq(10, applied))
Exemplo n.º 2
0
    def testApplication(self):
        """Test function application across states."""
        self.assertEqual(
            superposition.superposition(2, 4),
            superposition.state_apply(
                superposition.superposition(1, 2),
                lambda x: x * 2))

        # As everything working on states, this should also work on scalars.
        applied = superposition.state_apply(5, lambda x: x * 2)
        self.assertTrue(superposition.state_eq(10, applied))
Exemplo n.º 3
0
    def get(self, key, complete=False):
        """Returns value of the key, or a superposition thereof.

        Out of the get_ functions, this is almost always the one you want.

        Getting a basic value:
        ======================

        Use key in form of Component.attribute. For example, "Process/pid" or
        "User/username". Same as calling entity[key]:

        entity["Process/pid"]  # PID of the process.

        What if the value is an entity:
        ===============================

        This method automatically recognizes attributes that reference other
        entities, looks them up and returns them. For example:

        entity["Process/parent"]  # Returns the parent process entity.
        entity["Process/parent"]["Process/pid"]  # PID of the parent.

        What if I want all the child processes (Inverse Lookup):
        ========================================================

        You can call entity.get_referencing_entities if you want to be explicit.

        Alternatively, prepend the key with a '&' for inverse lookup of a N:1
        assocation.

        For example:

        entity["&Process/parent"]  # Returns processes of which this process is
                                   # (Child processes).

        entity["&Handle/process"]  # Returns all handles this process has open.

        In most cases, this is unnecessary and aliases can be used instead.

        For example:

        entity["&Handle/process"]  # Is already aliased in definitions as:
        entity["Process/handles"]

        entity["&Process/parent"]  # Is already aliased in definitions as:
        entity["Process/children"]

        When does this return more than one value:
        ==========================================

        1) When doing an inverse lookup.
        2) When the value we find is a superposition.

        In both cases, a superposition is returned. Remember that superpositions
        proxy the [] operator, returning more superpositions. For example:

        # To return the pids of all child processes:
        entity["&Process/parent"]["Process/pid"]

        You can request more than one key in a single call:
        ===================================================

        This is identical to the behavior of [] on python dictionaries:

        entity["Process/pid", "Process/command"]  # is the same as calling:
        (entity["Process/pid"], entity["Process/command"])

        You can also request a multi-level path into the object:
        ========================================================

        The path separator is '->' and is used as follows:

        entity["Process/handles"]["Handle/resource"]  # Is the same as:
        entity["Process/handles->Handle/resource]

        This is merely syntax sugar to make specifying rendering output easier.
        """
        # If we get called with [x, y] python will pass us the keys as a tuple
        # of (x, y). The following behaves identically to dict.
        if isinstance(key, tuple):
            return [self.get(_key, complete) for _key in key]

        # If we get called with a Component/attribute->Component/attribute
        # we treat -> as path separator and the whole key as path into the
        # object.
        if "->" in key:
            # This works recursively.
            key, rest = key.split("->", 1)
            subresult = self.get(key=key, complete=complete)
            if not subresult:
                return None

            return superposition.state_apply(
                subresult,
                lambda x: x.get(key=rest, complete=complete))

        # The & sigil denotes reverse lookup.
        if key.startswith("&"):
            entities = self.get_referencing_entities(key[1:],
                                                     complete=complete)
            return superposition.meld(*list(entities))

        # The raw result could be None, a superposition or just a scalar.
        value = self.get_raw(key)
        if value is None:
            return obj.NoneObject(
                "Entity '%s' has no results for key '%s'." % (self, key))

        # Redirection.
        if isinstance(value, entity_component.Alias):
            return self.get(value.alias, complete=complete)

        typedesc = self.reflect_type(key)
        if typedesc.type_name == "Entity":
            entities = self.manager.find_by_identity(value, complete=complete)
            return superposition.meld(*list(entities))

        return value
Exemplo n.º 4
0
    def coerce(self, value):
        if value == None:
            return None

        decoder = lambda s: str(s).decode("utf-8", "ignore")
        return superposition.state_apply(value, decoder)
Exemplo n.º 5
0
    def get(self, key, complete=False):
        """Returns value of the key, or a superposition thereof.

        Out of the get_ functions, this is almost always the one you want.

        Getting a basic value:
        ======================

        Use key in form of Component.attribute. For example, "Process/pid" or
        "User/username". Same as calling entity[key]:

        entity["Process/pid"]  # PID of the process.

        What if the value is an entity:
        ===============================

        This method automatically recognizes attributes that reference other
        entities, looks them up and returns them. For example:

        entity["Process/parent"]  # Returns the parent process entity.
        entity["Process/parent"]["Process/pid"]  # PID of the parent.

        What if I want all the child processes (Inverse Lookup):
        ========================================================

        You can call entity.get_referencing_entities if you want to be explicit.

        Alternatively, prepend the key with a '&' for inverse lookup of a N:1
        assocation.

        For example:

        entity["&Process/parent"]  # Returns processes of which this process is
                                   # (Child processes).

        entity["&Handle/process"]  # Returns all handles this process has open.

        In most cases, this is unnecessary and aliases can be used instead.

        For example:

        entity["&Handle/process"]  # Is already aliased in definitions as:
        entity["Process/handles"]

        entity["&Process/parent"]  # Is already aliased in definitions as:
        entity["Process/children"]

        When does this return more than one value:
        ==========================================

        1) When doing an inverse lookup.
        2) When the value we find is a superposition.

        In both cases, a superposition is returned. Remember that superpositions
        proxy the [] operator, returning more superpositions. For example:

        # To return the pids of all child processes:
        entity["&Process/parent"]["Process/pid"]

        You can request more than one key in a single call:
        ===================================================

        This is identical to the behavior of [] on python dictionaries:

        entity["Process/pid", "Process/command"]  # is the same as calling:
        (entity["Process/pid"], entity["Process/command"])

        You can also request a multi-level path into the object:
        ========================================================

        The path separator is '->' and is used as follows:

        entity["Process/handles"]["Handle/resource"]  # Is the same as:
        entity["Process/handles->Handle/resource]

        This is merely syntax sugar to make specifying rendering output easier.
        """
        # If we get called with [x, y] python will pass us the keys as a tuple
        # of (x, y). The following behaves identically to dict.
        if isinstance(key, tuple):
            return [self.get(_key, complete) for _key in key]

        # If we get called with a Component/attribute->Component/attribute
        # we treat -> as path separator and the whole key as path into the
        # object.
        if "->" in key:
            # This works recursively.
            key, rest = key.split("->", 1)
            subresult = self.get(key=key, complete=complete)
            if not subresult:
                return None

            return superposition.state_apply(
                subresult, lambda x: x.get(key=rest, complete=complete))

        # The & sigil denotes reverse lookup.
        if key.startswith("&"):
            entities = self.get_referencing_entities(key[1:],
                                                     complete=complete)
            return superposition.meld(*list(entities))

        # The raw result could be None, a superposition or just a scalar.
        value = self.get_raw(key)
        if value is None:
            return obj.NoneObject("Entity '%s' has no results for key '%s'." %
                                  (self, key))

        # Redirection.
        if isinstance(value, entity_component.Alias):
            return self.get(value.alias, complete=complete)

        if isinstance(value, entity_component.Component):
            return CurriedComponent(self, value)

        typedesc = self.reflect_type(key)
        if typedesc.type_name == "Entity":
            entities = self.manager.find_by_identity(value, complete=complete)
            return superposition.meld(*list(entities))

        return value