Ejemplo n.º 1
0
    def test_replace_non_leaf_node_types(self):
        # keep the previous type as we want to restore it
        OldDependNode = nt.DependNode

        nold = nt.Network()
        assert str(nold).startswith("network")

        # overwriting the foundation of all nodes will not change anything
        # for existing node types, as they have bound the previous type already.
        class DependNode(nt.Node):
            """This type cannot do anything, we have removed functionality"""
            def __str__(self):
                return 'me_as_string'

        # END custom DependNode

        assert str(nold).startswith('network')

        # new instances still use the default implementation
        nnew = nt.Network()
        assert str(nnew).startswith('network')

        # also we cannot instatiate it explicitly as we are not inheriting
        # from the type that MRV wants to create, Network
        self.failUnlessRaises(TypeError, DependNode, nnew.object())

        # we could get away with this, but we clean it up anyway
        nt.removeCustomType(DependNode)
        nt.addCustomType(OldDependNode)

        # MONKEY PATCHING
        #################
        # The only way to get custom method implementation directly into the non-leaf
        # node types is monkey patching, hence existing methods will be overwritten
        # with your implementation
        # Using the dict for retrieval as one would get class methods otherwise, these
        # check for the actual type passed in which would fail in our case.
        old_str = nt.DependNode.__dict__['__str__']
        nt.DependNode.__str__ = DependNode.__dict__['__str__']

        assert str(nold) == 'me_as_string'
        # undo our changes
        nt.DependNode.__str__ = old_str
Ejemplo n.º 2
0
	def test_replace_non_leaf_node_types(self):
		# keep the previous type as we want to restore it
		OldDependNode = nt.DependNode
		
		nold = nt.Network()
		assert str(nold).startswith("network")
		
		# overwriting the foundation of all nodes will not change anything 
		# for existing node types, as they have bound the previous type already.
		class DependNode(nt.Node):
			"""This type cannot do anything, we have removed functionality"""
			def __str__(self):
				return 'me_as_string'
		# END custom DependNode
		
		assert str(nold).startswith('network')
		
		# new instances still use the default implementation
		nnew = nt.Network()
		assert str(nnew).startswith('network')
		
		# also we cannot instatiate it explicitly as we are not inheriting 
		# from the type that MRV wants to create, Network
		self.failUnlessRaises(TypeError, DependNode, nnew.object())
		
		# we could get away with this, but we clean it up anyway
		nt.removeCustomType(DependNode)
		nt.addCustomType(OldDependNode)
		
		
		# MONKEY PATCHING
		#################
		# The only way to get custom method implementation directly into the non-leaf  
		# node types is monkey patching, hence existing methods will be overwritten
		# with your implementation
		# Using the dict for retrieval as one would get class methods otherwise, these
		# check for the actual type passed in which would fail in our case.
		old_str = nt.DependNode.__dict__['__str__']
		nt.DependNode.__str__ = DependNode.__dict__['__str__']
		
		assert str(nold) == 'me_as_string'
		# undo our changes
		nt.DependNode.__str__ = old_str
Ejemplo n.º 3
0
    def test_replacing_default_node_types(self):
        n = nt.Network()
        sn = StorageNetworkNode.create()

        # REPLACING BUILTIN NODE TYPES
        ##############################
        # if we want to play crazy, we can make all network nodes our special
        # storage node, be replacing the existing Network node type.
        # Any instantiation will fail as if its not one of our specialized nodes,
        # but this is implementation defined of course.
        # Defining a new derived Type automatically puts it into the nt module
        OldNetwork = nt.Network

        class Network(StorageNetworkNode):
            def sayhello(self):
                print "hello"

        # yes, the official Network node is now our own one, automatically
        assert nt.Network is Network

        sn2 = nt.Node(str(sn))
        assert isinstance(sn2, StorageNetworkNode)
        assert isinstance(sn2.dataIDs(), list)

        # and it can say something
        sn2.sayhello()

        # we cannot wrap normal nodes as our initializer on StorageNetworkNode barks
        # if the vital data plug cannot be found.
        self.failUnlessRaises(TypeError, nt.Node, str(n))

        # reset the old one, we affect everything within MRV now
        nt.removeCustomType(Network)
        nt.addCustomType(OldNetwork)

        # everything back to normal - we get plain old network nodes
        sn_network = nt.Node(sn.object())
        assert type(sn_network) is OldNetwork
        assert type(sn_network) is nt.Network

        # REPLACING BUILTIN NODES PROPERLY
        ##################################
        class Network(OldNetwork, nt.StorageBase):
            def __init__(self, node):
                """Implement the initializer such that we only initialize our base
				if we have the 'data' attribute. Otherwise we keep it uninitialized, so it 
				will not be functional"""
                try:
                    super(Network, self).__init__(node)
                except TypeError:
                    pass
                # END handle input type

            def sayaloha(self):
                print "aloha"

        # END better Super-Network implementation
        assert nt.Network is Network

        # now plain network nodes will be new Network nodes, but we are allowed
        # to create them
        # NodeFromObj works as well, just to be sure
        n2 = nt.NodeFromObj(n.object())
        assert type(n2) is Network

        # as the storage base has not been initialized, we cannot do anything
        # with it. The actual point here though is that users who don't know the
        # interface will get a fully functional network node at least.
        # As we do not 'tighten' the interface, code that doesn't expect our type
        # will not get into trouble.
        self.failUnlessRaises(AttributeError, n2.dataIDs)
        assert isinstance(n2, OldNetwork)
        n2.sayaloha()

        # and storage network nodes will be 'Network' nodes whose additional
        # functions we can use
        sn2 = nt.Node(sn.object())
        assert type(sn2) is Network
        sn2.sayaloha()
        sn2.dataIDs()

        # once again, get rid of our custom type, reset the old one
        nt.removeCustomType(Network)
        nt.addCustomType(OldNetwork)
        assert nt.Network is OldNetwork
Ejemplo n.º 4
0
	def test_replacing_default_node_types(self):
		n = nt.Network()
		sn = StorageNetworkNode.create()
		
		# REPLACING BUILTIN NODE TYPES
		##############################
		# if we want to play crazy, we can make all network nodes our special
		# storage node, be replacing the existing Network node type.
		# Any instantiation will fail as if its not one of our specialized nodes, 
		# but this is implementation defined of course.
		# Defining a new derived Type automatically puts it into the nt module
		OldNetwork = nt.Network
		class Network(StorageNetworkNode):
			def sayhello(self):
				print "hello"
		# yes, the official Network node is now our own one, automatically
		assert nt.Network is Network
		
		sn2 = nt.Node(str(sn))
		assert isinstance(sn2, StorageNetworkNode)
		assert isinstance(sn2.dataIDs(), list)
		
		# and it can say something
		sn2.sayhello()
		
		# we cannot wrap normal nodes as our initializer on StorageNetworkNode barks 
		# if the vital data plug cannot be found.
		self.failUnlessRaises(TypeError, nt.Node, str(n))
		
		# reset the old one, we affect everything within MRV now
		nt.removeCustomType(Network)
		nt.addCustomType(OldNetwork)
		
		# everything back to normal - we get plain old network nodes
		sn_network = nt.Node(sn.object())
		assert type(sn_network) is OldNetwork
		assert type(sn_network) is nt.Network
		
		# REPLACING BUILTIN NODES PROPERLY
		##################################
		class Network(OldNetwork, nt.StorageBase):
			def __init__(self, node):
				"""Implement the initializer such that we only initialize our base
				if we have the 'data' attribute. Otherwise we keep it uninitialized, so it 
				will not be functional"""
				try:
					super(Network, self).__init__(node)
				except TypeError:
					pass
				# END handle input type
				
			def sayaloha(self):
				print "aloha"
				
		# END better Super-Network implementation
		assert nt.Network is Network
		
		# now plain network nodes will be new Network nodes, but we are allowed
		# to create them
		# NodeFromObj works as well, just to be sure
		n2 = nt.NodeFromObj(n.object())
		assert type(n2) is Network
		
		# as the storage base has not been initialized, we cannot do anything 
		# with it. The actual point here though is that users who don't know the
		# interface will get a fully functional network node at least.
		# As we do not 'tighten' the interface, code that doesn't expect our type
		# will not get into trouble.
		self.failUnlessRaises(AttributeError, n2.dataIDs)
		assert isinstance(n2, OldNetwork)
		n2.sayaloha()
		
		# and storage network nodes will be 'Network' nodes whose additional
		# functions we can use
		sn2 = nt.Node(sn.object())
		assert type(sn2) is Network
		sn2.sayaloha()
		sn2.dataIDs()
		
		# once again, get rid of our custom type, reset the old one 
		nt.removeCustomType(Network)
		nt.addCustomType(OldNetwork)
		assert nt.Network is OldNetwork