Ticket #1442: endpoints4.diff

File endpoints4.diff, 25.7 KB (added by rwall, 10 years ago)

A diff against endpoints-1442 addressing most of radix's review points.

  • twisted/test/test_endpoints.py

     
     1from zope.interface import implements, Interface
     2
    13from twisted.trial import unittest
    24from twisted.internet import (defer, error, interfaces, reactor,
    35                              _sslverify as sslverify)
     
    24from twisted.internet.address import IPv4Address, UNIXAddress
    3 from twisted.internet.protocol import ClientFactory, Protocol, ServerFactory
    4 from twisted.internet.endpoints import (TCPEndpoint, UNIXEndpoint)
     5from twisted.internet.protocol import ClientFactory, Protocol
     6from twisted.internet.endpoints import (TCPServerEndpoint, TCPClientEndpoint,
     7                                        SSLTCPServerEndpoint,
     8                                        SSLTCPClientEndpoint,
     9                                        UNIXServerEndpoint, UNIXClientEndpoint)
    510from twisted.test.test_sslverify import makeCertificate
    611
    7 class ServerProtocol(Protocol):
    8     def connectionMade(self):
    9         self.factory.onConnectionMade.callback(self)
    1012
    11     def connectionLost(self, *a):
    12         self.factory.onConnectionLost.callback(self)
    13 
    14 class ClientProtocol(Protocol):
     13class TestProtocol(Protocol):
     14    """I am a protocol whose only function is to callback deferreds on my
     15    factory when I am connected and when I am disconnected.
     16    """
     17   
    1518    def connectionMade(self):
     
    2023    def connectionLost(self, *a):
    2124        self.factory.onConnectionLost.callback(self)
    2225
    23 class MyServerFactory(ServerFactory):
    24     protocol = ServerProtocol
    25    
    26     def __init__(self):
    27         self.onConnectionMade = defer.Deferred()
    28         self.onConnectionLost = defer.Deferred()
    2926
    30 class MyClientFactory(ClientFactory):
    31     protocol = ClientProtocol
     27class TestFactory(ClientFactory):
     28    """I am a simple factory to be used both when connecting and listening. I
     29    contain two deferreds which are called back when my protocol connects and
     30    disconnects.
     31    """
    3232   
     33    protocol = TestProtocol
     34   
    3335    def __init__(self):
    3436        self.onConnectionMade = defer.Deferred()
    3537        self.onConnectionLost = defer.Deferred()
    3638
     39
    3740class PortAndConnectorCleanerUpper(unittest.TestCase):
     41    """I am a base class for Endpoint testcases. I clean up all the Ports and
     42    Connectors used in subclass test methods (provided that I know about them).
     43    When a subclass creates a server, the resulting Port should be appended to
     44    my list of listeningPorts.
     45    When my subclasses create a client, the resulting connector should be
     46    appended to my list of clientConnectors.
     47    """
     48   
    3849    def setUp(self):
     50        """Setup my fresh lists for listeningPorts and clientConnections"""
    3951        self.listeningPorts = []
    4052        self.clientConnections = []
    4153   
    4254    def tearDown(self):
     55        """Stoplistening on all Ports and disconnect all connectors"""
    4356        map(lambda p: p.stopListening(), self.listeningPorts)
    4457        map(lambda c: c.disconnect(), self.clientConnections)
    4558
     59
     60class IEndpointTestCase(Interface):
     61    """I provide methods for creating servers / clients and server / client
     62    endpoints"""
     63   
     64    def createServer(factory):
     65        """Create a server
     66       
     67        @param factory: A provider of I{IProtocolFactory}
     68        """
     69
     70    def createClient(address, factory):
     71        """Create a client
     72       
     73        @param address: A provider of I{IAddress}
     74        @param factory: A provider of I{IProtocolFactory}
     75        """
     76       
     77    def createServerEndpoint(address=None):
     78        """Create an ServerEndpoint.
     79       
     80        @param address: An optional provider of I{IAddress}. If omitted a
     81        suitable free address will be chosen.
     82        """
     83
     84    def createClientEndpoint(address):
     85        """Create an ClientEndpoint.
     86       
     87        @param address: A provider of I{IAddress} to which the endpoint will be
     88        required to connect.
     89        """
     90
     91
    4692class EndpointTestCaseMixin(object):
     93    """Generic test methods to be mixed into all EndpointTest classes. Classes
     94    that mix me in, should provide IEndpointTestCase"""
     95   
    4796    def test_EndpointConnectSuccess(self):
    48         """Test that Endpoint can connect and returns a deferred who
     97        """Test that a client Endpoint can connect and returns a deferred who
    4998        gets called back with a protocol instance.
    5099        """
    51         sf = MyServerFactory()
     100        sf = TestFactory()
    52101        p = self.createServer(sf)
    53102        addr = p.getHost()
    54         ep = self.createEndpoint(addr)
    55         cf = MyClientFactory()
    56         d = ep.connect(reactor, cf)
     103        ep = self.createClientEndpoint(addr)
     104        cf = TestFactory()
     105        d = ep.connect(cf)
    57106        self.assertTrue(isinstance(d, defer.Deferred))
    58107        def onConnectSuccess(proto):
    59108            self.assertTrue(interfaces.IProtocol.providedBy(proto))
     
    65114        """Test that if an Endpoint tries to connect to a none
    66115        listening port that it gets a ConnectError failure.
    67116        """
    68         p = self.createServer(MyServerFactory())
     117        p = self.createServer(TestFactory())
    69118        addr = p.getHost()
    70119        p.loseConnection()
    71120
    72         ep = self.createEndpoint(addr)
    73         d = ep.connect(reactor, MyClientFactory())
     121        ep = self.createClientEndpoint(addr)
     122        d = ep.connect(TestFactory())
    74123        self.failUnlessFailure(d, error.ConnectError)
    75124        return d
    76125   
     
    78127        """Test that Endpoint can listen and returns a deferred that
    79128        gets called back with a port instance.
    80129        """
    81         ep = self.createEndpoint()
    82         sf = MyServerFactory()
    83         d = ep.listen(reactor, sf)
     130        ep = self.createServerEndpoint()
     131        sf = TestFactory()
     132        d = ep.listen(sf)
    84133        self.assertTrue(isinstance(d, defer.Deferred))
    85134        def onListenSuccess(port):
    86135            self.assertTrue(interfaces.IListeningPort.providedBy(port))
     
    88137            return port.getHost()
    89138        d.addCallback(onListenSuccess)
    90139        def connectTo(addr):
    91             self.createClient(addr, MyClientFactory())
     140            self.createClient(addr, TestFactory())
    92141        d.addCallback(connectTo)
    93142        return defer.gatherResults([sf.onConnectionMade, d])
    94143
     
    96145        """Test that if Endpoint tries to listen on an already listening
    97146        port, that a CannotListenError failure is errbacked.
    98147        """
    99         p = self.createServer(MyServerFactory())
     148        p = self.createServer(TestFactory())
    100149        addr = p.getHost()
    101         ep = self.createEndpoint(addr)
    102         d = ep.listen(reactor, MyServerFactory())
     150        ep = self.createServerEndpoint(addr)
     151        d = ep.listen(TestFactory())
    103152        self.failUnlessFailure(d, error.CannotListenError)
    104153        return d
    105154
     155
    106156class TCPEndpointsTestCase(PortAndConnectorCleanerUpper, EndpointTestCaseMixin):
     157    """Tests for TCP Endpoints"""
     158   
     159    implements(IEndpointTestCase)
     160   
    107161    def createServer(self, factory):
    108162        p = reactor.listenTCP(0, factory)
    109163        self.listeningPorts.append(p)
     
    114168        self.clientConnections.append(c)
    115169        return c
    116170
    117     def createEndpoint(self, address=None):
    118         if not address:
     171    def createServerEndpoint(self, address=None):
     172        if address is None:
    119173            address = IPv4Address("TCP", "localhost", 0)
    120         return TCPEndpoint(address.host, address.port)
     174        return TCPServerEndpoint(reactor, address.port)
    121175
     176    def createClientEndpoint(self, address):
     177        return TCPClientEndpoint(reactor, address.host, address.port)
     178
     179
    122180class SSLEndpointsTestCase(PortAndConnectorCleanerUpper, EndpointTestCaseMixin):
     181    """Tests for SSL Endpoints"""
    123182   
     183    implements(IEndpointTestCase)
     184   
    124185    def setUpClass(self):
     186        """Set up client and server SSL contexts for use later."""
    125187        self.sKey, self.sCert = makeCertificate(
    126188            O="Server Test Certificate",
    127189            CN="server")
     
    142204        self.clientConnections.append(c)
    143205        return c
    144206
    145     def createEndpoint(self, address=None):
    146         if not address:
     207    def createServerEndpoint(self, address=None):
     208        if address is None:
    147209            address = IPv4Address("TCP", "localhost", 0)
    148         return TCPEndpoint(address.host, address.port,
    149                            sslContextFactory=self.clientSSLContext)
    150        
     210        return SSLTCPServerEndpoint(reactor, address.port,
     211                                    self.clientSSLContext)
    151212
     213    def createClientEndpoint(self, address):
     214        return SSLTCPClientEndpoint(reactor, address.host, address.port,
     215                                    self.clientSSLContext)
     216
     217
    152218class UNIXEndpointsTestCase(PortAndConnectorCleanerUpper, EndpointTestCaseMixin):
     219    """Tests for UnixSocket Endpoints"""
     220   
     221    implements(IEndpointTestCase)
     222   
    153223    def createServer(self, factory):
    154224        p = reactor.listenUNIX(self.mktemp(), factory)
    155225        self.listeningPorts.append(p)
     
    160230        self.clientConnections.append(c)
    161231        return c
    162232
    163     def createEndpoint(self, address=None):
    164         if not address:
     233    def createServerEndpoint(self, address=None):
     234        if address is None:
    165235            address = UNIXAddress(self.mktemp())
    166         return UNIXEndpoint(address.name)
     236        return UNIXServerEndpoint(reactor, address.name)
     237
     238    def createClientEndpoint(self, address=None):
     239        return UNIXClientEndpoint(reactor, address.name)
  • twisted/test/test_address.py

     
     1import re
     2
     3from twisted.trial import unittest
     4from twisted.internet.address import IPv4Address, UNIXAddress
     5
     6
     7class AddressTestCaseMixin(object):
     8    def test_AddressComparison(self):
     9        """Test that two different address instances, sharing the same
     10        properties are considered equal."""
     11        self.assertEquals(self.buildAddress(), self.buildAddress())
     12
     13    def test_StringRepresentation(self):
     14        """Test that when addresses are converted to strings, they adhere to a
     15        standard pattern. Not sure if it's worth it, but seemed like a bit of
     16        fun and demonstrates an inconsistency with UNIXAddress.__str__
     17        """
     18        addr = self.buildAddress()
     19        pattern = "".join([
     20           "^",
     21           "([^\(]+Address)", # class name,
     22           "\(",       # opening bracket,
     23           "([^)]+)",  # arguments,
     24           "\)",       # closing bracket,
     25           "$"
     26        ])
     27        m = re.match(pattern, str(addr))
     28        self.assertNotEqual(None, m,
     29                            "%s does not match the standard __str__ pattern "
     30                            "ClassName(arg1, arg2, etc)" % str(addr))
     31        self.assertEqual(addr.__class__.__name__, m.group(1))
     32       
     33        args = [x.strip() for x in m.group(2).split(",")]
     34        self.assertEqual(len(args), len(self.addressArgSpec))
     35        def checkArg(arg, argSpec):
     36            self.assertEqual(argSpec[1] % getattr(addr, argSpec[0]), arg)
     37        map(checkArg, args, self.addressArgSpec)
     38
     39
     40class IPv4AddressTestCaseMixin(AddressTestCaseMixin):
     41    def setUpClass(self):
     42        self.addressArgSpec = (("type", "%s"), ("host", "%r"), ("port", "%d"))
     43
     44
     45class IPv4AddressTCPTestCase(unittest.TestCase, IPv4AddressTestCaseMixin):
     46    def buildAddress(self):
     47        return IPv4Address("TCP", "127.0.0.1", 0)
     48
     49
     50class IPv4AddressUDPTestCase(unittest.TestCase, IPv4AddressTestCaseMixin):
     51    def buildAddress(self):
     52        return IPv4Address("UDP", "127.0.0.1", 0)
     53
     54
     55class UNIXAddressTestCase(unittest.TestCase, AddressTestCaseMixin):
     56    def setUpClass(self):
     57        self._socketAddress = self.mktemp()
     58        self.addressArgSpec = (("name", "%r"),)
     59       
     60    def buildAddress(self):
     61        return UNIXAddress(self._socketAddress)
  • twisted/internet/endpoints.py

     
    11# -*- test-case-name: twisted.test.test_endpoints -*-
    22
    3 from zope.interface import implements, providedBy, directlyProvides
     3from zope.interface import implements
    44
    55from twisted.internet import interfaces
    6 from twisted.internet import defer, protocol
     6from twisted.internet import defer
    77from twisted.internet.protocol import ClientFactory, Protocol
    88
     9
    910class _WrappingProtocol(Protocol):
    1011    """I wrap another protocol in order to notify my user when a connection has
    1112    been made.
     
    2324        """
    2425       
    2526        self.wrappedProtocol.makeConnection(self.transport)
    26         self.factory.deferred.callback(self.wrappedProtocol)
     27        self.factory.onFirstConnection.callback(self.wrappedProtocol)
    2728       
    2829    def dataReceived(self, data):
    2930        return self.wrappedProtocol.dataReceived(data)
     
    3233        return self.wrappedProtocol.connectionLost(reason)
    3334       
    3435class _WrappingFactory(ClientFactory):
     36    """I wrap a factory in order to wrap the protocols it builds."""
    3537    protocol = _WrappingProtocol
    3638
    3739    def __init__(self, wrappedFactory):
     40        """
     41        @param wrappedFactory: A provider of I{IProtocolFactory} whose
     42        buildProtocol method will be called and whose resulting protocol will be
     43        wrapped.
     44        """
    3845        self.wrappedFactory = wrappedFactory
    39         self.deferred = defer.Deferred()
     46        self.onFirstConnection = defer.Deferred()
    4047
    4148    def buildProtocol(self, addr):
    4249        try:
    4350            proto = self.wrappedFactory.buildProtocol(addr)
    4451        except:
    45             self.deferred.errback()
     52            self.onFirstConnection.errback()
    4653        else:
    4754            return self.protocol(self, proto)
    4855
    4956    def clientConnectionFailed(self, connector, reason):
    50         self.deferred.errback(reason)
     57        self.onFirstConnection.errback(reason)
    5158
    5259
    53 class TCPEndpoint(object):
    54     implements(interfaces.IClientEndpoint, interfaces.IServerEndpoint)
     60class TCPServerEndpoint(object):
     61    """I am a TCP server endpoint."""
     62   
     63    implements(interfaces.IServerEndpoint)
    5564
    56     def __init__(self, host, port, connectArgs={}, listenArgs={},
    57                  sslContextFactory=None):
     65    def __init__(self, reactor, port, listenArgs={}):
    5866        """
    59         @param host: A hostname, used only when connecting
    60         @param port: The port number, used both when connecting and listening
    61         @param connectArgs: An optional dict of keyword args that will be passed
    62         to L{twisted.internet.interfaces.IReactorTCP.connectTCP}
     67        @param reactor: The reactor
     68        @param port: The port number used listening
    6369        @param listenArgs: An optional dict of keyword args that will be passed
    6470        to L{twisted.internet.interfaces.IReactorTCP.listenTCP}
    65         @param sslContextFactory: An optional instance of
    66         L{twisted.internet._sslverify.OpenSSLCertificateOptions}. If given, it
    67         makes L{connect} and L{listen} use the corresponding methods from
    68         L{twisted.internet.interfaces.IReactorSSL}
    6971        """
     72        self.reactor = reactor
     73        self.port = port
     74        self.listenArgs = dict(backlog=50, interface='')
     75        self.listenArgs.update(listenArgs)
     76
     77    def listen(self, serverFactory):
     78        wf = _WrappingFactory(serverFactory)
     79        return defer.execute(self.reactor.listenTCP, self.port, wf,
     80                             **self.listenArgs)
     81
     82
     83class TCPClientEndpoint(object):
     84    """I am a TCP client endpoint."""
     85   
     86    implements(interfaces.IClientEndpoint)
     87
     88    def __init__(self, reactor, host, port, connectArgs={}):
     89        """
     90        @param reactor: The reactor
     91        @param host: A hostname, used when connecting
     92        @param port: The port number, used when connecting
     93        @param connectArgs: An optional dict of keyword args that will be passed
     94        to L{twisted.internet.interfaces.IReactorTCP.connectTCP}
     95        """
     96        self.reactor = reactor
    7097        self.host = host
    7198        self.port = port
    7299        self.connectArgs = dict(timeout=30, bindAddress=None)
    73100        self.connectArgs.update(connectArgs)
     101       
     102    def connect(self, clientFactory):
     103        wf = _WrappingFactory(clientFactory)
     104        d = defer.execute(self.reactor.connectTCP, self.host, self.port, wf,
     105                          **self.connectArgs)
     106        d.addCallback(lambda _: wf.onFirstConnection)
     107        return d
     108
     109
     110class SSLTCPServerEndpoint(object):
     111    """I am an SSL secured TCP server endpoint."""
     112   
     113    implements(interfaces.IServerEndpoint)
     114
     115    def __init__(self, reactor, port, sslContextFactory, listenArgs={}):
     116        """
     117        @param reactor: The reactor
     118        @param port: The port number used listening
     119        @param sslContextFactory: An instance of
     120        L{twisted.internet._sslverify.OpenSSLCertificateOptions}.
     121        @param listenArgs: An optional dict of keyword args that will be passed
     122        to L{twisted.internet.interfaces.IReactorTCP.listenTCP}
     123        """
     124        self.reactor = reactor
     125        self.port = port
     126        self.sslContextFactory = sslContextFactory
    74127        self.listenArgs = dict(backlog=50, interface='')
    75128        self.listenArgs.update(listenArgs)
     129
     130    def listen(self, serverFactory):
     131        wf = _WrappingFactory(serverFactory)
     132        return defer.execute(self.reactor.listenSSL, self.port, wf,
     133                             contextFactory=self.sslContextFactory,
     134                             **self.listenArgs)
     135
     136
     137class SSLTCPClientEndpoint(object):
     138    """I am an SSL secured TCP client endpoint."""
     139   
     140    implements(interfaces.IClientEndpoint)
     141
     142    def __init__(self, reactor, host, port, sslContextFactory, connectArgs={}):
     143        """
     144        @param reactor: The reactor
     145        @param host: A hostname, used when connecting
     146        @param port: The port number, used when connecting
     147        @param sslContextFactory: An instance of
     148        L{twisted.internet._sslverify.OpenSSLCertificateOptions}.
     149        @param connectArgs: An optional dict of keyword args that will be passed
     150        to L{twisted.internet.interfaces.IReactorTCP.connectTCP}
     151        """
     152        self.reactor = reactor
     153        self.host = host
     154        self.port = port
    76155        self.sslContextFactory = sslContextFactory
     156        self.connectArgs = dict(timeout=30, bindAddress=None)
     157        self.connectArgs.update(connectArgs)
    77158       
    78     def connect(self, reactor, clientFactory):
     159    def connect(self, clientFactory):
    79160        wf = _WrappingFactory(clientFactory)
    80         connectArgs = self.connectArgs
    81         connectMethod = reactor.connectTCP
    82         if self.sslContextFactory:
    83             connectMethod = reactor.connectSSL
    84             connectArgs["contextFactory"] = self.sslContextFactory
    85            
    86         d = defer.execute(connectMethod, self.host, self.port, wf, **connectArgs)
     161        d = defer.execute(self.reactor.connectSSL, self.host, self.port, wf,
     162                          contextFactory=self.sslContextFactory,
     163                          **self.connectArgs)
     164        d.addCallback(lambda _: wf.onFirstConnection)
     165        return d
    87166
    88         d.addCallback(lambda _: wf.deferred)
    89167
    90         return d
     168class UNIXServerEndpoint(object):
     169    """I am a UnixSocket server endpoint"""
     170   
     171    implements(interfaces.IServerEndpoint)
    91172
    92     def listen(self, reactor, serverFactory):
     173    def __init__(self, reactor, address, listenArgs={}):
     174        """
     175        @param reactor: The reactor
     176        @param address: The path to the Unix socket file, used when listening
     177        @param listenArgs: A dict of keyword args that will be passed to
     178        L{twisted.internet.interfaces.IReactorUNIX.listenUNIX}
     179        """
     180        self.reactor = reactor
     181        self.address = address
     182        self.listenArgs = dict(backlog=50, mode=0666, wantPID=0)
     183        self.listenArgs.update(listenArgs)
     184
     185    def listen(self, serverFactory):
    93186        wf = _WrappingFactory(serverFactory)
    94         listenArgs = self.listenArgs
    95         listenMethod = reactor.listenTCP
    96         if self.sslContextFactory:
    97             listenMethod = reactor.listenSSL
    98             listenArgs["contextFactory"] = self.sslContextFactory
    99         return defer.execute(listenMethod, self.port, wf, **listenArgs)
     187        return defer.execute(self.reactor.listenUNIX, self.address, wf,
     188                             **self.listenArgs)
    100189
    101 class UNIXEndpoint(object):
    102     implements(interfaces.IClientEndpoint, interfaces.IServerEndpoint)
    103190
    104     def __init__(self, address, connectArgs={}, listenArgs={}):
     191class UNIXClientEndpoint(object):
     192    """I am a UnixSocket client endpoint"""
     193   
     194    implements(interfaces.IClientEndpoint)
     195
     196    def __init__(self, reactor, address, connectArgs={}):
    105197        """
    106         @param address: The path to the Unix socket file, used both when
    107         connecting and listening
     198        @param reactor: The reactor
     199        @param address: The path to the Unix socket file, used when connecting
    108200        @param connectArgs: A dict of keyword args that will be passed to
    109201        L{twisted.internet.interfaces.IReactorUNIX.connectUNIX}
    110         @param listenArgs: A dict of keyword args that will be passed to
    111         L{twisted.internet.interfaces.IReactorUNIX.listenUNIX}
    112202        """
    113 
     203        self.reactor = reactor
    114204        self.address = address
    115205        self.connectArgs = dict(timeout=30, checkPID=0)
    116206        self.connectArgs.update(connectArgs)
    117         self.listenArgs = dict(backlog=50, mode=0666, wantPID=0)
    118         self.listenArgs.update(listenArgs)
    119207
    120     def connect(self, reactor, clientFactory):
     208    def connect(self, clientFactory):
    121209        wf = _WrappingFactory(clientFactory)
    122         d = defer.execute(reactor.connectUNIX, self.address, wf,
     210        d = defer.execute(self.reactor.connectUNIX, self.address, wf,
    123211                          **self.connectArgs)
    124212
    125         d.addCallback(lambda _: wf.deferred)
     213        d.addCallback(lambda _: wf.onFirstConnection)
    126214
    127215        return d
    128 
    129     def listen(self, reactor, serverFactory):
    130         wf = _WrappingFactory(serverFactory)
    131         return defer.execute(reactor.listenUNIX, self.address, wf,
    132                              **self.listenArgs)
  • twisted/internet/interfaces.py

     
    1818
    1919    Default implementations are in L{twisted.internet.address}.
    2020    """
    21    
    22     def buildEndpoint():
    23         """
    24         @return: an instance providing both L{IClientEndpoint} and L{IServerEndpoint}
    25         """
    2621
    2722
    2823### Reactor Interfaces
     
    13031298class IClientEndpoint(Interface):
    13041299    """Object that represents a remote endpoint that we wish to connect to.
    13051300    """
    1306     def connect(reactor, clientFactory):
     1301    def connect(clientFactory):
    13071302        """
    1308         @param reactor: The reactor
    13091303        @param clientFactory: A provider of L{IProtocolFactory}
    13101304        @return: A L{Deferred} that results in an L{IProtocol} upon successful
    13111305        connection otherwise a L{ConnectError}
     
    13151309    """Object representing an endpoint where we will listen for connections.
    13161310    """
    13171311
    1318     def listen(callable):
     1312    def listen(serverFactory):
    13191313        """
    1320         @param reactor: The reactor
    13211314        @param serverFactory: A provider of L{IProtocolFactory}
    13221315        @return: A L{Deferred} that results in an L{IListeningPort} or an
    13231316        L{CannotListenError}
  • twisted/internet/address.py

     
    99from zope.interface import implements
    1010
    1111from twisted.internet.interfaces import IAddress
    12 from twisted.internet.endpoints import TCPEndpoint, UNIXEndpoint
    1312
     13
    1414class IPv4Address(object):
    1515    """
    1616    Object representing an IPv4 socket endpoint.
     
    3636        self.port = port
    3737        self._bwHack = _bwHack
    3838
    39     def buildEndpoint(self):
    40         if self.type == "TCP":
    41             return TCPEndpoint(self.host, self.port)
    42         else:
    43             raise NotImplementedError
    44 
    4539    def __getitem__(self, index):
    4640        warnings.warn("IPv4Address.__getitem__ is deprecated.  Use attributes instead.",
    4741                      category=DeprecationWarning, stacklevel=2)
     
    7973        self.name = name
    8074        self._bwHack = _bwHack
    8175
    82     def buildEndpoint(self):
    83         return UNIXEndpoint(self.name)
    84 
    8576    def __getitem__(self, index):
    8677        warnings.warn("UNIXAddress.__getitem__ is deprecated.  Use attributes instead.",
    8778                      category=DeprecationWarning, stacklevel=2)
     
    9687        if isinstance(other, tuple):
    9788            return tuple(self) == other
    9889        elif isinstance(other, UNIXAddress):
    99             try:
    100                 return os.path.samefile(self.name, other.name)
    101             except OSError:
    102                 pass
     90            # First do the simple thing and check to see if the names are the
     91            # same. If not, and the paths exist, check to see if they point to
     92            # the same file.
     93            if self.name == other.name:
     94                return True
     95            else:
     96                try:
     97                    return os.path.samefile(self.name, other.name)
     98                except OSError:
     99                    pass
    103100        return False
    104101
    105102    def __str__(self):
    106         return 'UNIXSocket(%r)' % (self.name,)
     103        return 'UNIXAddress(%r)' % (self.name,)
    107104
    108105
    109106# These are for buildFactory backwards compatability due to