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.