Twisted python:将kwarg通过组件系统传递给工厂的正确方法

时间:2013-10-02 01:15:11

标签: python twisted kwargs

我需要使用super将kwarg传递给我相当于FingerFactoryFromService的父类。

我知道我实际上正在将kwarg传递给IFingerFactory,因为这也是我传递最终在 init FingerFactoryFromService中的服务的地方,我可以理解它在组件系统的某个地方被绊倒了但我想不出任何其他方式。

我一直得到的错误是

exceptions.TypeError: 'test' is an invalid keyword argument for this function

我的virtualenv中的代码版本是:

pip (1.4.1)
setuptools (1.1.6)
Twisted (13.1.0)
wsgiref (0.1.2)
zope.interface (4.0.5)

这是一个显示问题的手指教程的缩减示例:

from twisted.protocols import basic

from twisted.application import internet, service
from twisted.internet import protocol, reactor, defer
from twisted.python import components
from zope.interface import Interface, implements  # @UnresolvedImport


class IFingerService(Interface):

    def getUser(user):  # @NoSelf
        """
        Return a deferred returning a string.
        """

    def getUsers():  # @NoSelf
        """
        Return a deferred returning a list of strings.
        """


class IFingerFactory(Interface):

    def getUser(user):  # @NoSelf
        """
        Return a deferred returning a string.
        """

    def buildProtocol(addr):  # @NoSelf
        """
        Return a protocol returning a string.
        """


def catchError(err):
    return "Internal error in server"


class FingerProtocol(basic.LineReceiver):

    def lineReceived(self, user):
        d = self.factory.getUser(user)
        d.addErrback(catchError)

        def writeValue(value):
            self.transport.write(value + '\r\n')
            self.transport.loseConnection()
        d.addCallback(writeValue)


class FingerService(service.Service):

    implements(IFingerService)

    def __init__(self, filename):
        self.filename = filename
        self.users = {}

    def _read(self):
        self.users.clear()
        for line in file(self.filename):
            user, status = line.split(':', 1)
            user = user.strip()
            status = status.strip()
            self.users[user] = status
        self.call = reactor.callLater(30, self._read)  # @UndefinedVariable

    def getUser(self, user):
        print user
        return defer.succeed(self.users.get(user, "No such user"))

    def getUsers(self):
        return defer.succeed(self.users.keys())

    def startService(self):
        self._read()
        service.Service.startService(self)

    def stopService(self):
        service.Service.stopService(self)
        self.call.cancel()


class FingerFactoryFromService(protocol.ServerFactory):

    implements(IFingerFactory)

    protocol = FingerProtocol

    #def __init__(self, srv):
    def __init__(self, srv, test=None):
        self.service = srv
        ## I need to call super here because my equivalent of ServerFactory requires 
        ## a kwarg but this cutdown example doesnt so I just assign it to a property
        # super(FingerFactoryFromService, self).__init__(test=test)
        self.test_thing = test or 'Default Something'

    def getUser(self, user):
        return self.service.getUser(user)

components.registerAdapter(FingerFactoryFromService,
                           IFingerService,
                           IFingerFactory)

application = service.Application('finger')
serviceCollection = service.IServiceCollection(application)

finger_service = FingerService('/etc/passwd')
finger_service.setServiceParent(serviceCollection)

#line_finger_factory = IFingerFactory(finger_service)
line_finger_factory = IFingerFactory(finger_service, test='Something')
line_finger_server = internet.TCPServer(1079, line_finger_factory)
line_finger_server.setServiceParent(serviceCollection)  

1 个答案:

答案 0 :(得分:1)

这与组件系统无关。您要做的是覆盖Factory的buildProtocol方法,如下所示:

https://twistedmatrix.com/documents/current/core/howto/servers.html#auto9