[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pypy-dev
Subject:    [pypy-dev] _scproxy module and tweaks for osx
From:       Dan Colish <dcolish () gmail ! com>
Date:       2011-02-28 17:51:22
Message-ID: 237B76A5746A4108B33E98626E152D15 () gmail ! com
[Download RAW message or body]

I've been playing with a few ideas on OSX to get the build to be more stable. \
Attached is a patch that does this, but it is far from complete. There are still bugs \
in the way that frameworks are used when the final Makefile is created. In addition, \
there are problems with libintl that I'd like to be a little more pragmatic about. \
The _scproxy module itself works with the framework hardcoded fixes.

Anyway, I'd appreciate some feedback and also so thoughts on how best to deal with \
various build environments on OSX.

-- Dan


["stable-scproxy.diff" (application/octet-stream)]

comparing with ssh://hg@bitbucket.org/pypy/pypy
searching for changes
changeset:   42255:fb341cb97ce8
tag:         tip
parent:      42253:a8c4588929dd
user:        Dan Colish <dcolish@gmail.com>
date:        Thu Feb 24 00:28:46 2011 -0800
summary:     Add support for the OSX specific _scproxy module although frameworks are \
hard coded, it builds correctly now

diff -r a8c4588929dd -r fb341cb97ce8 pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py	Thu Feb 24 02:23:28 2011 +0100
+++ b/pypy/config/pypyoption.py	Thu Feb 24 00:28:46 2011 -0800
@@ -59,6 +59,9 @@
     # The _locale module is needed by site.py on Windows
     default_modules["_locale"] = None
 
+if sys.platform == 'darwin':
+    working_modules["_scproxy"] = None
+
 if sys.platform == "sunos5":
     del working_modules['mmap']   # depend on ctypes, can't get at c-level 'errono'
     del working_modules['rctime'] # depend on ctypes, missing tm_zone/tm_gmtoff
diff -r a8c4588929dd -r fb341cb97ce8 pypy/module/_scproxy/__init__.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pypy/module/_scproxy/__init__.py	Thu Feb 24 00:28:46 2011 -0800
@@ -0,0 +1,21 @@
+from pypy.interpreter.mixedmodule import MixedModule
+import sys
+
+if sys.platform != 'darwin':
+    raise Exception("You cant run this outside of osx")
+
+
+class Module(MixedModule):
+    """A demo built-in module based on rffi."""
+    interpleveldefs = {
+        '_get_proxies': 'interp_scproxy.get_proxies',
+        '_get_proxy_settings': 'interp_scproxy.get_proxy_settings',
+    }
+
+    appleveldefs = {
+    }
+
+    def startup(self, space):
+        from pypy.module._scproxy.interp_state import get
+        MixedModule.startup(self, space)
+        get(space).startup(space)
diff -r a8c4588929dd -r fb341cb97ce8 pypy/module/_scproxy/interp_scproxy.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pypy/module/_scproxy/interp_scproxy.py	Thu Feb 24 00:28:46 2011 -0800
@@ -0,0 +1,72 @@
+from pypy.rpython.lltypesystem import rffi
+from pypy.module._scproxy.interp_state import (
+    CFArrayRef,
+    CFIndex,
+    CFNumberRef,
+    CFTypeRef,
+    CFArrayGetCount,
+    CFArrayGetValueAtIndex,
+    CFDictionaryGetValue,
+    CFRelease,
+    SCDynamicStoreCopyProxies,
+    cfnum_to_int,
+    cfstring2str,
+    get,
+    set_proxy,
+)
+
+
+def get_proxies(space):
+    proxyDict = SCDynamicStoreCopyProxies(rffi.NULL)
+    result = {}
+    result.update(set_proxy(space, "http", proxyDict,
+                            get(space).kSCPropNetProxiesHTTPEnable,
+                            get(space).kSCPropNetProxiesHTTPProxy,
+                            get(space).kSCPropNetProxiesHTTPPort))
+    result.update(set_proxy(space, "https", proxyDict,
+                            get(space).kSCPropNetProxiesHTTPSEnable,
+                            get(space).kSCPropNetProxiesHTTPSProxy,
+                            get(space).kSCPropNetProxiesHTTPSPort))
+    result.update(set_proxy(space, "ftp", proxyDict,
+                            get(space).kSCPropNetProxiesFTPEnable,
+                            get(space).kSCPropNetProxiesFTPProxy,
+                            get(space).kSCPropNetProxiesFTPPort))
+    result.update(set_proxy(space, "gopher", proxyDict,
+                            get(space).kSCPropNetProxiesGopherEnable,
+                            get(space).kSCPropNetProxiesGopherProxy,
+                            get(space).kSCPropNetProxiesGopherPort))
+
+    w_result = space.newdict()
+    for key, w_value in result.items():
+        space.setitem(w_result, space.wrap(key), w_value)
+    return w_result
+
+
+def get_proxy_settings(space):
+    proxyDict = SCDynamicStoreCopyProxies(rffi.NULL)
+    result = {}
+    key = rffi.cast(rffi.VOIDP,
+                    get(space).kSCPropNetProxiesExcludeSimpleHostnames)
+    aNum = CFDictionaryGetValue(proxyDict, key)
+
+    if aNum and cfnum_to_int(rffi.cast(CFNumberRef, aNum)):
+        result['exclude_simple'] = space.wrap(True)
+    else:
+        result['exclude_simple'] = space.wrap(False)
+
+    key = rffi.cast(rffi.VOIDP, get(space).kSCPropNetProxiesExceptionsList)
+    exceptions_array = rffi.cast(CFArrayRef,
+                                 CFDictionaryGetValue(proxyDict, key))
+    count = rffi.cast(rffi.INT, CFArrayGetCount(exceptions_array))
+    exceptions = []
+
+    for x in range(count):
+        idx = rffi.cast(CFIndex, x)
+        cfvalue = CFArrayGetValueAtIndex(exceptions_array, idx)
+        exceptions.append(cfstring2str(cfvalue))
+    result['exceptions'] = space.newtuple([space.wrap(x) for x in exceptions])
+
+    w_result = space.newdict()
+    for key, w_value in result.items():
+        space.setitem(w_result, space.wrap(key), w_value)
+    return w_result
diff -r a8c4588929dd -r fb341cb97ce8 pypy/module/_scproxy/interp_state.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pypy/module/_scproxy/interp_state.py	Thu Feb 24 00:28:46 2011 -0800
@@ -0,0 +1,151 @@
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.rpython.lltypesystem.rffi import llexternal
+from pypy.rpython.tool import rffi_platform as platform
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
+
+
+class CConfig(object):
+    __compilation_info__ = ExternalCompilationInfo(
+        includes=['SystemConfiguration.h'],
+        include_dirs=['/System/Library/Frameworks/SystemConfiguration.framework/Headers/'],
 +        frameworks=['CoreFoundation', 'SystemConfiguration'])
+
+platform.configure(CConfig)
+
+eci = CConfig.__compilation_info__
+
+
+CFAllocatorRef = rffi.COpaquePtr('CFAllocatorRef')
+CFArrayRef = rffi.COpaquePtr('CFArrayRef')
+CFDictionaryRef = rffi.COpaquePtr('CFDictionaryRef')
+CFIndex = rffi.COpaquePtr('CFIndex')
+CFNumberRef = rffi.COpaquePtr('CFNumberRef')
+CFStringRef = rffi.COpaquePtr('CFStringRef')
+CFTypeRef = rffi.COpaquePtr('CFTypeRef')
+
+CFArrayGetCount = llexternal('CFArrayGetCount',
+                             [CFArrayRef],
+                             CFIndex, compilation_info=eci)
+CFArrayGetValueAtIndex = llexternal('CFArrayGetValueAtIndex',
+                                    [CFArrayRef,
+                                     CFIndex],
+                                    CFStringRef,
+                                    compilation_info=eci)
+CFDictionaryGetValue = llexternal('CFDictionaryGetValue',
+                                  [CFDictionaryRef,
+                                   rffi.VOIDP],
+                                  rffi.VOIDP, compilation_info=eci)
+CFNumberCreateInt = llexternal('CFNumberCreate',
+                               [CFAllocatorRef,
+                                rffi.INT, rffi.VOIDP],
+                               CFNumberRef,
+                               compilation_info=eci)
+CFNumberGetValue = llexternal('CFNumberGetValue',
+                              [CFNumberRef, rffi.INT,
+                               rffi.VOIDP],
+                              rffi.INT, compilation_info=eci)
+CFRelease = llexternal('CFRelease', [CFTypeRef], rffi.VOIDP,
+                       compilation_info=eci)
+CFStringCreateWithCString = llexternal('CFStringCreateWithCString',
+                                       [CFAllocatorRef, rffi.CCHARP, rffi.INT],
+                                       CFStringRef, compilation_info=eci)
+CFStringGetCStringPtr = llexternal('CFStringGetCStringPtr',
+                                   [CFStringRef, rffi.INT],
+                                   rffi.CCHARP,
+                                   compilation_info=eci)
+SCDynamicStoreCopyProxies = llexternal(
+    'SCDynamicStoreCopyProxies', [rffi.VOIDP],
+    CFDictionaryRef, compilation_info=eci)
+
+
+def cfstring2charp(cfstr):
+    return CFStringGetCStringPtr(cfstr, 0)
+
+
+def cfstring2str(cfstr):
+    return rffi.charp2str(CFStringGetCStringPtr(cfstr, 0))
+
+
+def str2cfstring(pystr):
+    with rffi.scoped_str2charp(pystr) as charp:
+        allocator = rffi.cast(CFAllocatorRef, rffi.NULL)
+        return CFStringCreateWithCString(allocator, charp, 0)
+
+
+def cfnum_to_int(val_cref):
+    with lltype.scoped_alloc(rffi.INTP.TO, 1) as result_p:
+        CFNumberGetValue(val_cref, 9,
+                         rffi.cast(rffi.VOIDP, result_p))
+        res_p = rffi.cast(rffi.INTP, result_p)
+        final_val = rffi.cast(lltype.Signed, res_p[0])
+        return final_val
+
+
+def int_to_cfnum(val):
+    with lltype.scoped_alloc(rffi.INTP.TO, 1) as val_p:
+        val_p[0] = rffi.cast(rffi.INT, val)
+        return CFNumberCreateInt(
+            rffi.cast(CFAllocatorRef, rffi.NULL), 3,
+            rffi.cast(rffi.VOIDP, val_p))
+
+
+def set_proxy(space, proto, proxyDict, enabledKey, hostKey, portKey):
+    py_proxies = {}
+    aNum = CFDictionaryGetValue(proxyDict,
+                                rffi.cast(rffi.VOIDP, enabledKey))
+
+    if aNum and cfnum_to_int(rffi.cast(CFNumberRef, aNum)):
+        host_key = rffi.cast(rffi.VOIDP, hostKey)
+        port_key = rffi.cast(rffi.VOIDP, portKey)
+        hostString = CFDictionaryGetValue(proxyDict, host_key)
+        aNum = rffi.cast(CFNumberRef,
+                         CFDictionaryGetValue(proxyDict, port_key))
+        if hostString:
+            hoststr = cfstring2str(rffi.cast(CFStringRef,
+                                             hostString))
+            if aNum:
+                aNum = rffi.cast(CFNumberRef, aNum)
+                py_proxies[proto] = space.wrap("http://%s:%d" % (
+                        hoststr, cfnum_to_int(aNum)))
+            else:
+                py_proxies[proto] = space.wrap("http://%s" % hoststr)
+    return py_proxies
+
+
+class Cache(object):
+    def __init__(self, space):
+        self.str2cfstring = str2cfstring
+
+    def startup(self, space):
+        self.kSCPropNetProxiesHTTPEnable = get(space).str2cfstring(
+            'HTTPEnable')
+        self.kSCPropNetProxiesHTTPProxy = get(space).str2cfstring(
+            'HTTPProxy')
+        self.kSCPropNetProxiesHTTPPort = get(space).str2cfstring(
+            'HTTPPort')
+        self.kSCPropNetProxiesHTTPSEnable = get(space).str2cfstring(
+            'HTTPSEnable')
+        self.kSCPropNetProxiesHTTPSProxy = get(space).str2cfstring(
+            'HTTPSProxy')
+        self.kSCPropNetProxiesHTTPSPort = get(space).str2cfstring(
+            'HTTPSPort')
+        self.kSCPropNetProxiesFTPEnable = get(space).str2cfstring(
+            'FTPEnable')
+        self.kSCPropNetProxiesFTPProxy = get(space).str2cfstring(
+            'FTPProxy')
+        self.kSCPropNetProxiesFTPPort = get(space).str2cfstring(
+            'FTPPort')
+        self.kSCPropNetProxiesGopherEnable = get(space).str2cfstring(
+            'GopherEnable')
+        self.kSCPropNetProxiesGopherProxy = get(space).str2cfstring(
+            'GopherProxy')
+        self.kSCPropNetProxiesGopherPort = get(space).str2cfstring(
+            'GopherPort')
+        self.kSCPropNetProxiesExcludeSimpleHostnames = get(space).str2cfstring(
+            'ExcludeSimpleHostnames')
+        self.kSCPropNetProxiesExceptionsList = get(space).str2cfstring(
+            'ExceptionsList')
+
+
+def get(space):
+    return space.fromcache(Cache)
diff -r a8c4588929dd -r fb341cb97ce8 pypy/module/_scproxy/test/__init__.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pypy/module/_scproxy/test/__init__.py	Thu Feb 24 00:28:46 2011 -0800
@@ -0,0 +1,1 @@
+#
diff -r a8c4588929dd -r fb341cb97ce8 pypy/module/_scproxy/test/test_scproxy.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pypy/module/_scproxy/test/test_scproxy.py	Thu Feb 24 00:28:46 2011 -0800
@@ -0,0 +1,23 @@
+from pypy.conftest import gettestobjspace
+
+
+class AppTestSCProxy(object):
+    def setup_class(cls):
+        space = gettestobjspace(usemodules=['_scproxy'])
+        cls.space = space
+
+    def test_get_proxy_settings(self):
+        import _scproxy
+        proxy_settings = _scproxy._get_proxy_settings()
+        assert isinstance(proxy_settings, dict)
+        assert 'exceptions' in proxy_settings.keys()
+        assert 'exclude_simple' in proxy_settings.keys()
+        assert isinstance(proxy_settings['exclude_simple'], bool)
+        assert isinstance(proxy_settings['exceptions'], tuple)
+        # this should always be in there
+        assert "*.local" in proxy_settings['exceptions']
+
+    def test_get_proxies(self):
+        import _scproxy
+        proxies = _scproxy._get_proxies()
+        assert proxies == {}
diff -r a8c4588929dd -r fb341cb97ce8 pypy/rlib/rlocale.py
--- a/pypy/rlib/rlocale.py	Thu Feb 24 02:23:28 2011 +0100
+++ b/pypy/rlib/rlocale.py	Thu Feb 24 00:28:46 2011 -0800
@@ -13,23 +13,18 @@
         self.message = message
 
 HAVE_LANGINFO = sys.platform != 'win32'
-HAVE_LIBINTL  = sys.platform != 'win32'
-libraries = []
+HAVE_LIBINTL  = sys.platform != ('win32' and 'darwin')
+
 
 if HAVE_LIBINTL:
     try:
-        platform.verify_eci(ExternalCompilationInfo(includes=['libintl.h'],
-                                                    libraries=['intl']))
-        libraries.append('intl')
+        platform.verify_eci(ExternalCompilationInfo(includes=['libintl.h']))
     except platform.CompilationError:
-        try:
-            platform.verify_eci(ExternalCompilationInfo(includes=['libintl.h']))
-        except platform.CompilationError:
-            HAVE_LIBINTL = False
+        HAVE_LIBINTL = False
+
 
 class CConfig:
     includes = ['locale.h', 'limits.h', 'ctype.h']
-    libraries = libraries
 
     if HAVE_LANGINFO:
         includes += ['langinfo.h']
@@ -37,8 +32,10 @@
         includes += ['libintl.h']
     if sys.platform == 'win32':
         includes += ['windows.h']
+    if sys.platform == 'darwin':
+        includes += ['xlocale.h']
     _compilation_info_ = ExternalCompilationInfo(
-        includes=includes, libraries=libraries
+        includes=includes,
     )
     HAVE_BIND_TEXTDOMAIN_CODESET = platform.Has('bind_textdomain_codeset')
     lconv = platform.Struct("struct lconv", [
diff -r a8c4588929dd -r fb341cb97ce8 pypy/rlib/test/test_rlocale.py
--- a/pypy/rlib/test/test_rlocale.py	Thu Feb 24 02:23:28 2011 +0100
+++ b/pypy/rlib/test/test_rlocale.py	Thu Feb 24 00:28:46 2011 -0800
@@ -37,7 +37,7 @@
     assert isinstance(grouping, str)
 
 def test_libintl():
-    if sys.platform not in ("linux2", "darwin"):
+    if sys.platform not in ("linux2"):
         py.test.skip("there is (maybe) no libintl here")
     _gettext = external('gettext', [rffi.CCHARP], rffi.CCHARP)
     res = _gettext("1234")
diff -r a8c4588929dd -r fb341cb97ce8 pypy/translator/platform/darwin.py
--- a/pypy/translator/platform/darwin.py	Thu Feb 24 02:23:28 2011 +0100
+++ b/pypy/translator/platform/darwin.py	Thu Feb 24 00:28:46 2011 -0800
@@ -1,4 +1,3 @@
-
 import py, os
 from pypy.translator.platform import posix
 
@@ -9,8 +8,8 @@
     cflags = ('-O3', '-fomit-frame-pointer', '-mmacosx-version-min=10.4')
     standalone_only = ('-mdynamic-no-pic',)
     shared_only = ()
-
-    so_ext = 'so'
+    so_prefixes = ['lib']
+    so_ext = 'dylib'
 
     # NOTE: GCC 4.2 will fail at runtime due to subtle issues, possibly
     # related to GC roots. Using LLVM-GCC or Clang will break the build.
@@ -28,7 +27,7 @@
         return (list(self.shared_only)
                 + ['-dynamiclib', '-undefined', 'dynamic_lookup']
                 + args)
-    
+
     def _preprocess_include_dirs(self, include_dirs):
         res_incl_dirs = list(include_dirs)
         res_incl_dirs.append('/usr/local/include') # Homebrew
@@ -78,14 +77,20 @@
             response_file = relto.bestrelpath(response_file)
         return ["-Wl,-exported_symbols_list,%s" % (response_file,)]
 
+
 class Darwin_i386(Darwin):
     name = "darwin_i386"
-    link_flags = ('-arch', 'i386', '-mmacosx-version-min=10.4')
+    link_flags = ('-arch', 'i386', '-mmacosx-version-min=10.4',
+                  '-framework SystemConfiguration',
+                  '-framework CoreFoundation')
     cflags = ('-arch', 'i386', '-O3', '-fomit-frame-pointer',
               '-mmacosx-version-min=10.4')
 
+
 class Darwin_x86_64(Darwin):
     name = "darwin_x86_64"
-    link_flags = ('-arch', 'x86_64', '-mmacosx-version-min=10.4')
+    link_flags = ('-arch', 'x86_64', '-mmacosx-version-min=10.4',
+                  '-framework SystemConfiguration',
+                  '-framework CoreFoundation')
     cflags = ('-arch', 'x86_64', '-O3', '-fomit-frame-pointer',
               '-mmacosx-version-min=10.4')



_______________________________________________
pypy-dev@codespeak.net
http://codespeak.net/mailman/listinfo/pypy-dev

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic