[PyObjC-svn] r2182 - in trunk/pyobjc/pyobjc-framework-CFNetwork: . Doc Lib/CFNetwork Modules PyObjCTest

[email protected]
Newsgroups gmane.comp.python.pyobjc.cvs
Message-ID <[email protected]>
Author: ronaldoussoren
Date: Thu Apr 30 09:40:35 2009
New Revision: 2182

Log:
* Finish API bindings for CFNetwork
* Ensure all tests pass 
  TestCFProxySupport.testManual fails during 'python setup.py test',
  but passes when run manually. I haven't debugged the issue yet.
* Documentation reflects that we have full API coverage for
  this framework
* Make the docstring in setup.py more useful.


Added:
   trunk/pyobjc/pyobjc-framework-CFNetwork/Modules/
   trunk/pyobjc/pyobjc-framework-CFNetwork/Modules/_manual.m
   trunk/pyobjc/pyobjc-framework-CFNetwork/Modules/pyobjc-api.h   (contents, props changed)
   trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/proxy.pac
Modified:
   trunk/pyobjc/pyobjc-framework-CFNetwork/   (props changed)
   trunk/pyobjc/pyobjc-framework-CFNetwork/Doc/api-notes-CFNetwork.txt
   trunk/pyobjc/pyobjc-framework-CFNetwork/Lib/CFNetwork/PyObjC.bridgesupport
   trunk/pyobjc/pyobjc-framework-CFNetwork/Lib/CFNetwork/__init__.py
   trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfhost.py
   trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfnetservices.py
   trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfnetworkdiagnostics.py
   trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfproxysupport.py
   trunk/pyobjc/pyobjc-framework-CFNetwork/setup.py

Modified: trunk/pyobjc/pyobjc-framework-CFNetwork/Doc/api-notes-CFNetwork.txt
==============================================================================
--- trunk/pyobjc/pyobjc-framework-CFNetwork/Doc/api-notes-CFNetwork.txt	(original)
+++ trunk/pyobjc/pyobjc-framework-CFNetwork/Doc/api-notes-CFNetwork.txt	Thu Apr 30 09:40:35 2009
@@ -4,15 +4,10 @@
 
 * ``CFNetworkExecuteProxyAutoConfigurationScript`` and ``CFNetworkExecuteProxyAutoConfigurationURL``
 
-  These functions are not yet supported because they require a manually written proxy function.
-
-* ``CFHostGetAddressing``
-
-   This proxy crashes python in the unittests, I haven't debugged the issue yet and it may be 
-   caused by bad use of this function in the tests.
+  The ``context`` argument can be an arbitrary Python object.
 
 * ``CFHostSetClient``
 
-  This API is not yet supported from Python because they require a manually written proxy function.
+  The ``context`` argument can be an arbitrary Python object.
 
 

Modified: trunk/pyobjc/pyobjc-framework-CFNetwork/Lib/CFNetwork/PyObjC.bridgesupport
==============================================================================
--- trunk/pyobjc/pyobjc-framework-CFNetwork/Lib/CFNetwork/PyObjC.bridgesupport	(original)
+++ trunk/pyobjc/pyobjc-framework-CFNetwork/Lib/CFNetwork/PyObjC.bridgesupport	Thu Apr 30 09:40:35 2009
@@ -9,12 +9,14 @@
   <cftype name='CFNetServiceBrowserRef' type='^{__CFNetServiceBrowser=}' type64='^{__CFNetServiceBrowser=}' gettypeid_func='CFNetServiceBrowserGetTypeID'/>
   <cftype name='CFNetServiceMonitorRef' type='^{__CFNetServiceMonitor=}' type64='^{__CFNetServiceMonitor=}' gettypeid_func='CFNetServiceMonitorGetTypeID'/>
   <cftype name='CFNetServiceRef' type='^{__CFNetService=}' type64='^{__CFNetService=}' gettypeid_func='CFNetServiceGetTypeID'/>
+  <constant name='kCFStreamErrorDomainMach' type='i' />
   <constant name='kCFStreamErrorDomainFTP' type='i' />
   <constant name='kCFStreamErrorDomainSOCKS' type='i' />
   <constant name='kCFStreamErrorDomainSSL' type='i' />
   <constant name='kCFStreamErrorDomainHTTP' type='i' />
   <constant name='kCFStreamErrorDomainNetDB' type='i' />
   <constant name='kCFStreamErrorDomainSystemConfiguration' type='i' />
+  <constant name='kCFStreamErrorDomainNetServices' type='i' />
   <constant name='kCFProxyTypeKey' type='^{__CFString=}' />
   <constant name='kCFProxyHostNameKey' type='^{__CFString=}' />
   <constant name='kCFProxyPortNumberKey' type='^{__CFString=}' />
@@ -391,7 +393,7 @@
     <arg type='^{__CFString=}' />
   </function>
   <function name='CFHostGetAddressing'>
-    <retval type='^{__CFArray=}' already_cfretained='true' />
+    <retval type='^{__CFArray=}' />
     <arg type='^{__CFHost=}' />
     <arg type='o^B' />
   </function>
@@ -433,16 +435,16 @@
   <function name='CFNetDiagnosticCopyNetworkStatusPassively'>
     <retval type='l' />
     <arg type='^{__CFNetDiagnostic=}' />
-    <arg type='^^{__CFString}' />
+    <arg type='^^{__CFString}' type_modifier='o' />
   </function>
   <function name='CFNetDiagnosticCreateWithStreams'>
-    <retval type='^{__CFNetDiagnostic=}' />
+    <retval type='^{__CFNetDiagnostic=}' already_cfretained='true' />
     <arg type='^{__CFAllocator=}' />
     <arg type='^{__CFReadStream=}' />
     <arg type='^{__CFWriteStream=}' />
   </function>
   <function name='CFNetDiagnosticCreateWithURL'>
-    <retval type='^{__CFNetDiagnostic=}' />
+    <retval type='^{__CFNetDiagnostic=}' already_cfretained='true' />
     <arg type='^{__CFAllocator=}' />
     <arg type='^{__CFURL=}' />
   </function>
@@ -648,20 +650,6 @@
   <function name='CFNetworkCopySystemProxySettings'>
     <retval type='^{__CFDictionary=}' already_cfretained='true' />
   </function>
-  <function name='CFNetworkExecuteProxyAutoConfigurationScript'>
-    <retval type='^{__CFRunLoopSource=}' />
-    <arg type='^{__CFString=}' />
-    <arg type='^{__CFURL=}' />
-    <arg type='^?' />
-    <arg type='^{?=i^v^?^?^?}' type64='^{?=i^v^?^?^?}' />
-  </function>
-  <function name='CFNetworkExecuteProxyAutoConfigurationURL'>
-    <retval type='^{__CFRunLoopSource=}' />
-    <arg type='^{__CFURL=}' />
-    <arg type='^{__CFURL=}' />
-    <arg type='^?' />
-    <arg type='^{?=i^v^?^?^?}' type64='^{?=i^v^?^?^?}' />
-  </function>
   <function name='CFReadStreamCreateForHTTPRequest'>
     <retval type='^{__CFReadStream=}' already_cfretained='true' />
     <arg type='^{__CFAllocator=}' />

Modified: trunk/pyobjc/pyobjc-framework-CFNetwork/Lib/CFNetwork/__init__.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-CFNetwork/Lib/CFNetwork/__init__.py	(original)
+++ trunk/pyobjc/pyobjc-framework-CFNetwork/Lib/CFNetwork/__init__.py	Thu Apr 30 09:40:35 2009
@@ -18,3 +18,5 @@
 
 def CFSocketStreamSOCKSGetErrorSubdomain(err):
     return (err.error >> 16) & 0xFFFF
+
+from CFNetwork._manual import *

Modified: trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfhost.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfhost.py	(original)
+++ trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfhost.py	Thu Apr 30 09:40:35 2009
@@ -48,11 +48,6 @@
 
         CFHostUnscheduleFromRunLoop(v, rl, kCFRunLoopDefaultMode)
 
-        # XXX: This fails and I don't have time to debug right now
-        #self.failUnlessArgHasType(CFHostGetAddressing, 1, 'o^' + objc._C_NSBOOL)
-        #lst, ok = CFHostGetAddressing(t, None)
-        #self.failUnlessIsInstance(lst, CFArrayRef)
-        #self.failUnlessIsInstance(ok, bool)
 
         self.failUnlessArgHasType(CFHostGetNames, 1, 'o^' + objc._C_NSBOOL)
         lst, ok = CFHostGetNames(v, None)
@@ -61,8 +56,37 @@
 
         
     def testCallbacks(self):
-        self.fail("CFHostSetClient")
+        lst = []
+        ctx = object()
+        def callback(host, typeinfo, error, ctx):
+            lst.append([host, typeinfo, error, ctx])
 
+        host = CFHostCreateWithName(None, u"www.python.org")
+        CFHostSetClient(host, callback, ctx)
+
+        rl = CFRunLoopGetCurrent()
+        CFHostScheduleWithRunLoop(host, rl, kCFRunLoopDefaultMode)
+
+        ok, err = CFHostStartInfoResolution(host, kCFHostAddresses, None)
+        self.failUnless(ok)
+        self.failUnlessIsInstance(ok, bool)
+        self.failUnlessIsInstance(err, CFStreamError)
+
+        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 2.0, True)
+
+        CFHostUnscheduleFromRunLoop(host, rl, kCFRunLoopDefaultMode)
+        self.failUnlessEqual(len(lst), 1)
+        self.failUnlessIsInstance(lst[0][0], CFHostRef)
+        self.failUnlessIsInstance(lst[0][1], (int, long))
+        self.failUnlessIsInstance(lst[0][2], CFStreamError)
+        self.failUnless(lst[0][3] is ctx)
+
+        self.failIfResultIsCFRetained(CFHostGetAddressing)
+        self.failUnlessArgHasType(CFHostGetAddressing, 1, 'o^Z')
+        lst, ok = CFHostGetAddressing(host, None)
+        self.failUnlessIsInstance(lst, CFArrayRef)
+        self.failUnlessIsInstance(lst[0], CFDataRef)
+        self.failUnlessIsInstance(ok, bool)
 
 
 

Modified: trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfnetservices.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfnetservices.py	(original)
+++ trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfnetservices.py	Thu Apr 30 09:40:35 2009
@@ -52,10 +52,13 @@
 
         self.failUnlessResultIsBOOL(CFNetServiceRegisterWithOptions)
         self.failUnlessArgIsOut(CFNetServiceRegisterWithOptions, 2)
-        self.fall("CFNetServiceRegisterWithOptions")
-
-
 
+        ok, err = CFNetServiceRegisterWithOptions(serv, kCFNetServiceFlagNoAutoRename, None)
+        self.failUnlessIsInstance(ok, bool)
+        if ok:
+            self.failUnlessEqual(err, None)
+        else:
+            self.failUnlessIsInstance(err, CFStreamError)
 
 
 if __name__ == "__main__":

Modified: trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfnetworkdiagnostics.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfnetworkdiagnostics.py	(original)
+++ trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfnetworkdiagnostics.py	Thu Apr 30 09:40:35 2009
@@ -3,9 +3,10 @@
 
 class TestCFNetwork (TestCase):
     def testTypes(self):
-        # Test fails because the type seems to be registered when the 
-        # first instance is created ...
-        self.failUnlessIsCFType(CFNetDiagnosticRef)
+        # XXX: CFNetDiagnosticsRef is not actually a proper type
+        # in Leopard, the result turns out to be a CFDictionaryRef...
+        #self.failUnlessIsCFType(CFNetDiagnosticRef)
+        pass
 
     def testConstants(self):
         self.failUnlessEqual(kCFNetDiagnosticNoErr, 0)
@@ -23,21 +24,21 @@
         self.failUnlessIsInstance(rd, CFReadStreamRef)
         self.failUnlessIsInstance(wr, CFWriteStreamRef)
 
-        ref = CFNetDiagnosticCreateWithStreams(None, rs, ws)
-        self.failUnlessIsInstance(ref, CFNetDiagnosticRef)
+        ref = CFNetDiagnosticCreateWithStreams(None, rd, wr)
+        self.failUnlessIsInstance(ref, objc.objc_object) #CFNetDiagnosticRef)
 
         self.failUnlessResultIsCFRetained(CFNetDiagnosticCreateWithURL)
-        ref = CFNetDiagnosticCreateWithURL(None, ref)
-        self.failUnlessIsInstance(ref, CFNetDiagnosticRef)
+        ref = CFNetDiagnosticCreateWithURL(None, CFURLCreateWithString(None, u"http://www.apple.com/", None))
+        self.failUnlessIsInstance(ref, objc.objc_object) #CFNetDiagnosticRef)
 
         CFNetDiagnosticSetName(ref, u"hello world")
 
         sts = CFNetDiagnosticDiagnoseProblemInteractively(ref)
-        self.failUnlesssIsInstance(sts, (int, long))
+        self.failUnlessIsInstance(sts, (int, long))
 
         self.failUnlessArgIsOut(CFNetDiagnosticCopyNetworkStatusPassively, 1)
         sts, descr = CFNetDiagnosticCopyNetworkStatusPassively(ref, None)
-        self.failUnlesssIsInstance(sts, (int, long))
+        self.failUnlessIsInstance(sts, (int, long))
         self.failUnlessIsInstance(descr, unicode)
 
 if __name__ == "__main__":

Modified: trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfproxysupport.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfproxysupport.py	(original)
+++ trunk/pyobjc/pyobjc-framework-CFNetwork/PyObjCTest/test_cfproxysupport.py	Thu Apr 30 09:40:35 2009
@@ -1,5 +1,6 @@
 from PyObjCTools.TestSupport import *
 from CFNetwork import *
+import os
 
 SCRIPT="""
 function FindProxyForURL(url, host) {
@@ -36,9 +37,60 @@
 
 
     @min_os_level('10.5')
-    def testUnsupported(self):
-        self.fail("CFNetworkExecuteProxyAutoConfigurationScript") # Manual wrapper needed
-        self.fail("CFNetworkExecuteProxyAutoConfigurationURL") # Manual wrapper needed
+    def testManual(self):
+        lst = []
+        ctx = object()
+        def callback(ctx, proxies, error):
+            lst.append([ctx, proxies, error])
+
+        url = CFURLCreateWithString(None, "http://www.apple.com/", None)
+        
+        rls = CFNetworkExecuteProxyAutoConfigurationScript(
+                SCRIPT, url, callback, ctx)
+        self.failUnlessIsInstance(rls, CFRunLoopSourceRef)
+
+        rl = CFRunLoopGetCurrent()
+        CFRunLoopAddSource(rl, rls,  kCFRunLoopCommonModes)
+
+        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0, True)
+
+        CFRunLoopRemoveSource(rl, rls,  kCFRunLoopCommonModes)
+
+        self.failIfEqual(len(lst), 0)
+        self.failUnless(lst[0][0] is ctx)
+        self.failUnlessIsInstance(lst[0][1], CFArrayRef)
+        self.failUnlessEqual(lst[0][2],  None)
+
+        lst[:] = []
+        scriptURL = CFURLCreateWithFileSystemPath(
+                None,
+                os.path.join(os.path.dirname(__file__), "proxy.pac"),
+                kCFURLPOSIXPathStyle,
+                False)
+
+        rls = CFNetworkExecuteProxyAutoConfigurationURL(
+                scriptURL, url, callback, ctx)
+        self.failUnlessIsInstance(rls, CFRunLoopSourceRef)
+
+        CFRunLoopAddSource(rl, rls,  kCFRunLoopCommonModes)
+
+        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0, True)
+
+        CFRunLoopRemoveSource(rl, rls,  kCFRunLoopCommonModes)
+
+        #print lst
+
+        self.failIfEqual(len(lst), 0)
+        self.failUnless(lst[0][0] is ctx)
+        if lst[0][2] is None:
+            self.failUnlessIsInstance(lst[0][1], CFArrayRef)
+            self.failUnlessEqual(lst[0][2],  None)
+
+        else:
+            self.failUnlessEqual(lst[0][1],  None)
+            self.failUnlessIsInstance(lst[0][2], CFErrorRef)
+
+
         
 
     @min_os_level('10.5')

Modified: trunk/pyobjc/pyobjc-framework-CFNetwork/setup.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-CFNetwork/setup.py	(original)
+++ trunk/pyobjc/pyobjc-framework-CFNetwork/setup.py	Thu Apr 30 09:40:35 2009
@@ -1,5 +1,11 @@
 ''' 
-Wrappers for framework 'CFNetwork'. 
+PyObjC wrappers for the framework "CFNetwork", part of "CoreServices" on 
+MacOSX.
+
+The CFNetwork framework provides a library of abstractions for networking
+protocols. The most interesting bits for Python programmers are the
+API's for working with proxy autoconfiguration and the API's for networking
+diagnotics.
 
 These wrappers don't include documentation, please check Apple's documention
 for information on how to use this framework and PyObjC's documentation
@@ -9,7 +15,7 @@
 import ez_setup
 ez_setup.use_setuptools()
 
-from setuptools import setup
+from setuptools import setup, Extension
 try:
     from PyObjCMetaData.commands import extra_cmdclass, extra_options
 except ImportError:
@@ -35,8 +41,14 @@
     ],
     dependency_links = [],
     package_data = { 
-        '': ['*.xml'] 
+        '': ['*.bridgesupport'] 
     },
+    ext_modules = [
+        Extension("CFNetwork._manual",
+            ["Modules/_manual.m"],
+            extra_link_args=['-framework', 'CoreServices'],
+        ),
+    ],
     test_suite='PyObjCTest',
     cmdclass = extra_cmdclass,
     options = extra_options('CFNetwork'),

------------------------------------------------------------------------------
Register Now & Save for Velocity, the Web Performance & Operations 
Conference from O'Reilly Media. Velocity features a full day of 
expert-led, hands-on workshops and two days of sessions from industry 
leaders in dedicated Performance & Operations tracks. Use code vel09scf 
and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.