fix up circular cimports related to the sockaddr type, and touch up endpoint/getaddrinfo a bit
authorTero Marttila <terom@fixme.fi>
Fri, 25 Sep 2009 21:34:04 +0300
changeset 49 e2f79e68418a
parent 48 ee7ade660c0b
child 50 da394bb715af
fix up circular cimports related to the sockaddr type, and touch up endpoint/getaddrinfo a bit
qmsk/net/socket/_address.pxd
qmsk/net/socket/_address.pyx
qmsk/net/socket/address.pxd
qmsk/net/socket/address.pyx
qmsk/net/socket/af_inet.pxd
qmsk/net/socket/af_inet.pyx
qmsk/net/socket/af_inet6.pxd
qmsk/net/socket/af_inet6.pyx
qmsk/net/socket/af_unix.pxd
qmsk/net/socket/af_unix.pyx
qmsk/net/socket/sctp.pyx
qmsk/net/socket/socket.pyx
setup.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmsk/net/socket/_address.pxd	Fri Sep 25 21:34:04 2009 +0300
@@ -0,0 +1,42 @@
+"""
+    Internal module to keep the abstract sockaddr types out of the address module, which must contain backreferences to
+    the concrete implementations.
+"""
+
+cimport qmsk.net.socket.platform as platform
+
+cdef class sockaddr :
+    """
+        A network-level socket address
+        
+        XXX: not abstract enough. Functions/properties like getnameinfo/addr/port do not work for e.g. sockaddr_un
+
+        >>> sockaddr().family
+        0
+        >>> sockaddr().port
+        Traceback (most recent call last):
+          ...
+        NotImplementedError
+        >>> sockaddr().getnameinfo()
+        Traceback (most recent call last):
+          ...
+        NotImplementedError
+    """
+    
+    # address family
+    # XXX: this should be a class constant! It's part of our type safety!
+    cdef readonly platform.sa_family_t family
+
+    cdef void _init_family (self, platform.sa_family_t family = ?)
+
+    # get the sockaddr/socklen
+    # each of these can be NULL to ignore it
+    cdef int _get_sockaddr (self, platform.sockaddr **sa_ptr, platform.socklen_t *sa_len) except -1
+
+    cdef platform.sockaddr* _get_sockaddr_ptr (self) except NULL
+    cdef platform.socklen_t _get_sockaddr_len (self) except -1
+    
+    # set the sockaddr, socklen must match
+    cdef int _set_sockaddr (self, platform.sockaddr *sa, size_t sa_len) except -1
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmsk/net/socket/_address.pyx	Fri Sep 25 21:34:04 2009 +0300
@@ -0,0 +1,97 @@
+
+
+cdef class sockaddr :
+    cdef void _init_family (self, platform.sa_family_t family=platform.AF_UNSPEC) :
+        self.family = family
+
+    # XXX:use size_t
+    cdef int _get_sockaddr (self, platform.sockaddr **sa_ptr, platform.socklen_t *sa_len) except -1 :
+        """
+            Get the sockaddr pointer and sockaddr length for this address
+        """ 
+
+        raise NotImplementedError()
+
+    cdef platform.sockaddr* _get_sockaddr_ptr (self) except NULL :
+        """
+            Get the sockaddr pointer
+        """
+
+        cdef platform.sockaddr *sa
+        cdef platform.socklen_t sa_len
+
+        self._get_sockaddr(&sa, &sa_len)
+
+        return sa
+    
+    cdef platform.socklen_t _get_sockaddr_len (self) except -1 :
+        """
+            Get the sockaddr len
+        """
+
+        cdef platform.sockaddr *sa
+        cdef platform.socklen_t sa_len
+
+        self._get_sockaddr(&sa, &sa_len)
+
+        return sa_len
+
+    cdef int _set_sockaddr (self, platform.sockaddr *sa, size_t sa_len) except -1 :
+        """
+            Set the sockaddr value for this address; sa_len must match!
+        """
+
+        raise NotImplementedError()
+
+    def getnameinfo (self) :
+        """
+            Returns a (host, serv) tuple for this address à la getnameinfo
+
+            >>> addr = sockaddr_in()
+            >>> assert addr.getnameinfo() == (addr.addr, str(addr.port))
+        """
+
+        cdef platform.sockaddr *sa
+        cdef platform.socklen_t sa_len
+
+        # XXX: take as args?
+        cdef int flags = platform.NI_NUMERICHOST | platform.NI_NUMERICSERV
+        
+        # get our abstract sockaddr
+        self._get_sockaddr(&sa, &sa_len)
+
+        # get nice text format
+        return platform.getnameinfo(sa, sa_len, flags)
+
+    property addr :
+        """
+            The ASCII literal network address
+        """
+
+        def __get__ (self) :
+            """
+                Default implmentation using getnameinfo()
+            """
+
+            addr, port = self.getnameinfo()
+
+            return addr
+
+    property port :
+        """
+            The integer port number
+        """
+
+        def __get__ (self) :
+            """
+                Default implementation using getnameinfo() and int()
+            """
+
+            addr, port = self.getnameinfo()
+
+            return int(port)
+    
+    def __repr__ (self) :
+        return "sockaddr(%d, %s, %d)" % (self.family, self.addr, self.port)
+
+
--- a/qmsk/net/socket/address.pxd	Tue Sep 01 00:08:02 2009 +0300
+++ b/qmsk/net/socket/address.pxd	Fri Sep 25 21:34:04 2009 +0300
@@ -6,43 +6,9 @@
         endpoint    - human-readable network address, corresponding to multiple sockaddr's
 """
 
-cimport qmsk.net.libc as libc
-
 cimport qmsk.net.socket.platform as platform
 
-cdef class sockaddr :
-    """
-        A network-level socket address
-        
-        XXX: not abstract enough. Functions/properties like getnameinfo/addr/port do not work for e.g. sockaddr_un
-
-        >>> sockaddr().family
-        0
-        >>> sockaddr().port
-        Traceback (most recent call last):
-          ...
-        NotImplementedError
-        >>> sockaddr().getnameinfo()
-        Traceback (most recent call last):
-          ...
-        NotImplementedError
-    """
-    
-    # address family
-    # XXX: this should be a class constant! It's part of our type safety!
-    cdef readonly platform.sa_family_t family
-
-    cdef void _init_family (self, platform.sa_family_t family = ?)
-
-    # get the sockaddr/socklen
-    # each of these can be NULL to ignore it
-    cdef int _get_sockaddr (self, platform.sockaddr **sa_ptr, platform.socklen_t *sa_len) except -1
-
-    cdef platform.sockaddr* _get_sockaddr_ptr (self) except NULL
-    cdef platform.socklen_t _get_sockaddr_len (self) except -1
-    
-    # set the sockaddr, socklen must match
-    cdef int _set_sockaddr (self, platform.sockaddr *sa, size_t sa_len) except -1
+from qmsk.net.socket._address cimport sockaddr
 
 # build a sockaddr from the given sockaddr struct, based on sa_family
 cdef sockaddr build_sockaddr (platform.sockaddr *sa, size_t sa_len)
@@ -82,17 +48,13 @@
 
 cdef class endpoint :
     """
-        A network-level socket endpoint. This is the level that humans mostly work with, but the tricky bit is that
-        an endpoint can map to more than one sockaddr...
+        XXX: silly abstraction, just use the getaddrinfo function
 
-        Hence, endpoints are stored as human-readable hostname/service strings, which are then translated to sockaddrs
-        using getaddrinfo.
-
-        >>> from __future__ import absolute_import; import socket as _socket
+        >>> from qmsk.net.socket.constants import *
         >>> e = endpoint('127.0.0.1', 80)
         >>> str(e)
         'hostname=127.0.0.1, service=80'
-        >>> res = e.getaddrinfo(_socket.AF_UNSPEC, _socket.SOCK_STREAM)
+        >>> res = e.getaddrinfo(AF_UNSPEC, SOCK_STREAM)
         >>> len(res)
         1
         >>> str(res[0])
@@ -100,7 +62,7 @@
         >>> e = endpoint('2001::5', 80)
         >>> str(e)
         'hostname=2001::5, service=80'
-        >>> res = e.getaddrinfo(_socket.AF_UNSPEC, _socket.SOCK_STREAM)
+        >>> res = e.getaddrinfo(AF_UNSPEC, SOCK_STREAM)
         >>> len(res)
         1
         >>> str(res[0])
--- a/qmsk/net/socket/address.pyx	Tue Sep 01 00:08:02 2009 +0300
+++ b/qmsk/net/socket/address.pyx	Fri Sep 25 21:34:04 2009 +0300
@@ -1,104 +1,13 @@
 cimport qmsk.net.libc as libc
 cimport qmsk.net.py as py
 
-from qmsk.net.socket.address cimport *
+#from qmsk.net.socket.address cimport *
+
+cimport qmsk.net.libc as libc
 
 cimport qmsk.net.socket.platform as platform
 
-cdef class sockaddr :
-    cdef void _init_family (self, platform.sa_family_t family=platform.AF_UNSPEC) :
-        self.family = family
-
-    # XXX:use size_t
-    cdef int _get_sockaddr (self, platform.sockaddr **sa_ptr, platform.socklen_t *sa_len) except -1 :
-        """
-            Get the sockaddr pointer and sockaddr length for this address
-        """ 
-
-        raise NotImplementedError()
-
-    cdef platform.sockaddr* _get_sockaddr_ptr (self) except NULL :
-        """
-            Get the sockaddr pointer
-        """
-
-        cdef platform.sockaddr *sa
-        cdef platform.socklen_t sa_len
-
-        self._get_sockaddr(&sa, &sa_len)
-
-        return sa
-    
-    cdef platform.socklen_t _get_sockaddr_len (self) except -1 :
-        """
-            Get the sockaddr len
-        """
-
-        cdef platform.sockaddr *sa
-        cdef platform.socklen_t sa_len
-
-        self._get_sockaddr(&sa, &sa_len)
-
-        return sa_len
-
-    cdef int _set_sockaddr (self, platform.sockaddr *sa, size_t sa_len) except -1 :
-        """
-            Set the sockaddr value for this address; sa_len must match!
-        """
-
-        raise NotImplementedError()
-
-    def getnameinfo (self) :
-        """
-            Returns a (host, serv) tuple for this address à la getnameinfo
-
-            >>> addr = sockaddr_in()
-            >>> assert addr.getnameinfo() == (addr.addr, str(addr.port))
-        """
-
-        cdef platform.sockaddr *sa
-        cdef platform.socklen_t sa_len
-
-        # XXX: take as args?
-        cdef int flags = platform.NI_NUMERICHOST | platform.NI_NUMERICSERV
-        
-        # get our abstract sockaddr
-        self._get_sockaddr(&sa, &sa_len)
-
-        # get nice text format
-        return platform.getnameinfo(sa, sa_len, flags)
-
-    property addr :
-        """
-            The ASCII literal network address
-        """
-
-        def __get__ (self) :
-            """
-                Default implmentation using getnameinfo()
-            """
-
-            addr, port = self.getnameinfo()
-
-            return addr
-
-    property port :
-        """
-            The integer port number
-        """
-
-        def __get__ (self) :
-            """
-                Default implementation using getnameinfo() and int()
-            """
-
-            addr, port = self.getnameinfo()
-
-            return int(port)
-    
-    def __repr__ (self) :
-        return "sockaddr(%d, %s, %d)" % (self.family, self.addr, self.port)
-
+# concrete sockaddr implementation types
 # mapping of AF -> sockaddr, user-modifyable
 cimport qmsk.net.socket.af_inet, qmsk.net.socket.af_inet6
 
@@ -226,7 +135,7 @@
         Look up given hostname/service using the given socket parameters, and return a sequence of addrinfo objects.
             
             hostname        - internet address/hostname to look up, or None (for INADDR_ANY/localhost, see AI_PASSIVE)
-            service         - port/service to use, or None (for ephemeral)
+            service         - port/service to use, or None (for ephemeral). Should be given as a string
             family          - address family to use, one of AF_*. May be AF_UNSPEC.
             socktype        - socket type to use, one of SOCK_*.
             protocol        - protocol to use, one of IPPROTO_* or zero to pick the default protocol for the given
@@ -267,6 +176,10 @@
         _hostname = hostname
     
     if service is not None :
+        # XXX: also accept integer port number?
+        if isinstance(service, int) :
+            service = str(service)
+
         _service = service
 
     # operate!
--- a/qmsk/net/socket/af_inet.pxd	Tue Sep 01 00:08:02 2009 +0300
+++ b/qmsk/net/socket/af_inet.pxd	Fri Sep 25 21:34:04 2009 +0300
@@ -2,8 +2,8 @@
     AF_INET-specific stuff
 """
 
-from qmsk.net.socket.address cimport *
-
+from qmsk.net.socket._address cimport sockaddr
+cimport qmsk.net.socket.platform as platform
 
 cdef class sockaddr_in (sockaddr) :
     """
--- a/qmsk/net/socket/af_inet.pyx	Tue Sep 01 00:08:02 2009 +0300
+++ b/qmsk/net/socket/af_inet.pyx	Fri Sep 25 21:34:04 2009 +0300
@@ -1,3 +1,4 @@
+cimport qmsk.net.libc as libc
 cimport qmsk.net.py as py
 
 cdef class sockaddr_in (sockaddr) :
--- a/qmsk/net/socket/af_inet6.pxd	Tue Sep 01 00:08:02 2009 +0300
+++ b/qmsk/net/socket/af_inet6.pxd	Fri Sep 25 21:34:04 2009 +0300
@@ -2,8 +2,8 @@
     AF_INET6-specific stuff
 """
 
-from qmsk.net.socket.address cimport *
-
+from qmsk.net.socket._address cimport sockaddr
+cimport qmsk.net.socket.platform as platform
 
 cdef class sockaddr_in6 (sockaddr) :
     """
--- a/qmsk/net/socket/af_inet6.pyx	Tue Sep 01 00:08:02 2009 +0300
+++ b/qmsk/net/socket/af_inet6.pyx	Fri Sep 25 21:34:04 2009 +0300
@@ -1,3 +1,4 @@
+cimport qmsk.net.libc as libc
 cimport qmsk.net.py as py
 
 cdef class sockaddr_in6 (sockaddr) :
--- a/qmsk/net/socket/af_unix.pxd	Tue Sep 01 00:08:02 2009 +0300
+++ b/qmsk/net/socket/af_unix.pxd	Fri Sep 25 21:34:04 2009 +0300
@@ -2,7 +2,8 @@
     AF_UNIX-specific stuff
 """
 
-from qmsk.net.socket.address cimport *
+from qmsk.net.socket._address cimport sockaddr
+cimport qmsk.net.socket.platform as platform
 
 
 cdef class sockaddr_un (sockaddr) :
--- a/qmsk/net/socket/af_unix.pyx	Tue Sep 01 00:08:02 2009 +0300
+++ b/qmsk/net/socket/af_unix.pyx	Fri Sep 25 21:34:04 2009 +0300
@@ -1,5 +1,5 @@
+cimport qmsk.net.libc as libc
 cimport qmsk.net.py as py
-cimport qmsk.net.libc as libc
 
 cdef class sockaddr_un (sockaddr) :
 
--- a/qmsk/net/socket/sctp.pyx	Tue Sep 01 00:08:02 2009 +0300
+++ b/qmsk/net/socket/sctp.pyx	Fri Sep 25 21:34:04 2009 +0300
@@ -10,7 +10,6 @@
 
 """
 
-from qmsk.net.socket.sctp cimport *
 from qmsk.net.socket.address cimport sockaddr
 
 cimport qmsk.net.socket.platform as platform
--- a/qmsk/net/socket/socket.pyx	Tue Sep 01 00:08:02 2009 +0300
+++ b/qmsk/net/socket/socket.pyx	Fri Sep 25 21:34:04 2009 +0300
@@ -1,5 +1,6 @@
 from qmsk.net.socket.socket cimport *
-from qmsk.net.socket.address cimport sockaddr, build_sockaddr
+from qmsk.net.socket._address cimport sockaddr
+from qmsk.net.socket.address cimport build_sockaddr
 
 cimport qmsk.net.socket.platform as platform
 cimport qmsk.net.libc as libc, qmsk.net.py as py
--- a/setup.py	Tue Sep 01 00:08:02 2009 +0300
+++ b/setup.py	Fri Sep 25 21:34:04 2009 +0300
@@ -30,6 +30,7 @@
         cython_ext("qmsk.net.py",               ["qmsk/net/py.pyx"]),
         cython_ext("qmsk.net.socket.platform",  ["qmsk/net/socket/platform.pyx"]),
         cython_ext("qmsk.net.socket.constants", ["qmsk/net/socket/constants.pyx"]),
+        cython_ext("qmsk.net.socket._address",   ["qmsk/net/socket/_address.pyx"]),
         cython_ext("qmsk.net.socket.address",   ["qmsk/net/socket/address.pyx"]),
         cython_ext("qmsk.net.socket.socket",    ["qmsk/net/socket/socket.pyx"]),
         cython_ext("qmsk.net.socket.af_inet",   ["qmsk/net/socket/af_inet.pyx"]),