Commits

Bob Ippolito committed c39bf97

- Fixed some spelling errors (mostly the word usefull)
- Use objc.platform instead of sys.platform
- Removed namespace pollution from "from Foundation import *"
- Added linker semantics emulation: objc.pathForFramework will return the
full path for a framework as it would be linked to with respect to
environment variables or whatever other means is appropriate on the platform.
Only dyld semantics are emulated right now.
This is to support objc.loadBundle usage.
- Changed objc.loadBundle usage in wrappers that have link-time associations
to use bundle_identifier instead of a static path. This is to support
internal Apple use, but probably also applies to development against a SDK.
bundle_path usage has been changed to use objc.pathForFramework when not
on MACOSX and when the framework is not already linked in.
(requested by bbum)

Comments (0)

Files changed (19)

Lib/AddressBook/__init__.py

 """
 
 # Load the AddressBook bundle, and gather all classes defined there
-import objc
+import objc as _objc
 
 # AddressBook.framework has a dependency on AppKit.framework. Make sure we
-# load AppKit ourselfes, otherwise we might not load the custom wrappers for it.
-import AppKit
-del AppKit
-
-objc.loadBundle("AddressBook", globals(), bundle_path="/System/Library/Frameworks/AddressBook.framework")
+# load AppKit ourselves, otherwise we might not load the custom wrappers for it.
+import AppKit as _AppKit
 
 from _AddressBook import *
+if _objc.platform == 'MACOSX':
+    _objc.loadBundle(
+        "AddressBook",
+        globals(),
+        bundle_identifier='com.apple.AddressBook.framework',
+    )
+else:
+    _objc.loadBundle(
+        "AddressBook",
+        globals(),
+        bundle_path=_objc.pathForFramework(
+            "/System/Library/Frameworks/AddressBook.framework",
+        ),
+    )
 
 import protocols  # no need to export these, just register with PyObjC
 
 # Define useful utility methods here
 
-objc.setSignatureForSelector('NSImagePickerController', 'setTarget:selector:userInfo:', 'v@:@:i')
+_objc.setSignatureForSelector('NSImagePickerController', 'setTarget:selector:userInfo:', 'v@:@:i')
 
 # Not entirely correct...
-objc.setSignatureForSelector('ABAuthenticationInfo', 'appliesToRequest:', 'c@:@')
-objc.setSignatureForSelector('ABAuthenticationInfo', 'applyToRequest:', 'c@:@')
-objc.setSignatureForSelector('ABDAVQuery', 'buildRequest', '@@:')
-objc.setSignatureForSelector('ABPerson', 'encodedDataForValue:charsetName:', '@@:@o^@')
-
-del objc
+_objc.setSignatureForSelector('ABAuthenticationInfo', 'appliesToRequest:', 'c@:@')
+_objc.setSignatureForSelector('ABAuthenticationInfo', 'applyToRequest:', 'c@:@')
+_objc.setSignatureForSelector('ABDAVQuery', 'buildRequest', '@@:')
+_objc.setSignatureForSelector('ABPerson', 'encodedDataForValue:charsetName:', '@@:@o^@')

Lib/AppKit/__init__.py

 documentation for details on how to use these functions and classes.
 """
 
-import Foundation
 import _AppKitSignatures
 import objc as _objc
 
 from _AppKit import *
 
 # Load the Cocoa bundle, and gather all classes defined there
-_objc.loadBundle("AppKit", globals(), bundle_path="/System/Library/Frameworks/AppKit.framework")
+if _objc.platform == 'MACOSX':
+    _objc.loadBundle(
+        "AppKit",
+        globals(),
+        bundle_identifier='com.apple.AppKit',
+    )
+else:
+    _objc.loadBundle(
+        "AppKit",
+        globals(),
+        bundle_path=_objc.pathForFramework(
+            "/System/Library/Frameworks/AppKit.framework",
+        ),
+    )
 _objc.recycleAutoreleasePool()
 
 
-# Define usefull utility methods here
+# Define useful utility methods here
 NSClassForName = _objc.lookUpClass
 
 # The used to be defined here as pure python functions, these aliasses
 # are left here for backward compatibility.
-NSMakePoint = Foundation.NSMakePoint
-NSMakeSize = Foundation.NSMakeSize
-NSMakeRect = Foundation.NSMakeRect
-
-del Foundation
+from Foundation import NSMakePoint, NSMakeSize, NSMakeRect
 
 import protocols  # no need to export these, just register with PyObjC
 
-# NSView doesn't declares, but does not implement this method. This
+# NSView declares, but does not implement this method. This
 # additional protocol is needed to ensure that python implementations of
 # the method pick up the right signature.
 protocols.NSWindowPrinting = _objc.informal_protocol(
 # (informal) protocols exported for b/w compatibility
 #
 from protocols import NSAccessibility, NSChangeSpelling, NSColorPickingCustom, \
-                       NSColorPickingDefault, NSComboBoxCellDataSource, NSComboBoxDataSource, \
-                       NSDraggingDestination, NSDraggingInfo, NSDraggingSource, \
-                       NSIgnoreMisspelledWords, NSInputServerMouseTracker, NSMenuValidation, \
-                       NSOutlineViewDelegate, NSOutlineViewDataSource, NSServicesRequests, \
-                       NSTableViewDelegate, NSTableDataSource, NSToolTipOwner, \
-                       NSToolbarItemValidation, NSToolbarDelegate, NSUserInterfaceValidations, \
-                       NSValidatedUserInterfaceItem, NSApplicationDelegate, NSTextViewDelegate
-
+                      NSColorPickingDefault, NSComboBoxCellDataSource, \
+                      NSComboBoxDataSource, NSDraggingDestination, \
+                      NSDraggingInfo, NSDraggingSource, \
+                      NSIgnoreMisspelledWords, NSInputServerMouseTracker, \
+                      NSMenuValidation, NSOutlineViewDelegate, \
+                      NSOutlineViewDataSource, NSServicesRequests, \
+                      NSTableViewDelegate, NSTableDataSource, NSToolTipOwner, \
+                      NSToolbarItemValidation, NSToolbarDelegate, \
+                      NSUserInterfaceValidations, \
+                      NSValidatedUserInterfaceItem, NSApplicationDelegate, \
+                      NSTextViewDelegate

Lib/ExceptionHandling/__init__.py

 """
 
 # Load the ExceptionHandling bundle, and gather all classes defined there
-import objc
-
-objc.loadBundle("ExceptionHandling", globals(), bundle_path="/System/Library/Frameworks/ExceptionHandling.framework")
+import objc as _objc
 
 from _ExceptionHandling import *
-del objc
+if _objc.platform == 'MACOSX':
+    _objc.loadBundle(
+        "ExceptionHandling",
+        globals(),
+        bundle_identifier='com.apple.AppKit',
+    )
+else:
+    _objc.loadBundle(
+        "ExceptionHandling",
+        globals(),
+        bundle_path=_objc.pathForFramework(
+            "/System/Library/Frameworks/ExceptionHandling.framework",
+        ),
+    )
 
 import protocols  # no need to export these, just register with PyObjC
 

Lib/Foundation/__init__.py

 import objc as _objc
-import sys
-
 from _Foundation import *
 
-
 NSClassFromString = _objc.lookUpClass
 
 # Do something smart to collect Foundation classes...
 
-NSBundle = _objc.lookUpClass('NSBundle')
+if _objc.platform == 'MACOSX':
+    _objc.loadBundle(
+        'Foundation',
+        globals(),
+        bundle_identifier='com.apple.Foundation',
+    )
+else:
+    _objc.loadBundle(
+        'Foundation',
+        globals(),
+        bundle_path=_objc.pathForFramework(
+            '/System/Library/Frameworks/Foundation.framework',
+        ),
+    )
 
-_objc.loadBundle("Foundation", globals(), bundle_path="/System/Library/Frameworks/Foundation.framework")
+def _initialize():
+    import sys, os
+    if 'PYOBJCFRAMEWORKS' in os.environ:
+        paths = os.environ['PYOBJCFRAMEWORKS'].split(":")
+        count = 0
+        for path in paths:
+            bundle = NSBundle.bundleWithPath_(path)
+            bundle.principalClass()
+            sys.path.insert(count, str(bundle.resourcePath()))
+            count = count + 1
 
-import os
-import sys
-if 'PYOBJCFRAMEWORKS' in os.environ:
-    paths = os.environ['PYOBJCFRAMEWORKS'].split(":")
-    count = 0
-    for path in paths:
-        bundle = NSBundle.bundleWithPath_(path)
-        bundle.principalClass()
-        sys.path.insert(count, str(bundle.resourcePath()))
-        count = count + 1
+            initPath = bundle.pathForResource_ofType_( "Init", "py")
+            if initPath:
+                execfile(initPath, globals(), locals())
 
-        initPath = bundle.pathForResource_ofType_( "Init", "py")
-        if initPath:
-            execfile(initPath, globals(), locals())
-
-# Install an observer callback in the current CFRunLoop that will
-# automatically release and acquire the Global Interpreter Lock
-# when needed. This is needed so other Python threads get a chance
-# to run while we're inside the event loop.
-#
-# The autoGIL module is only present when using Python 2.2 on MacOS X
-import sys
-if sys.version_info[:2] == (2, 2):
-    try:
-        import autoGIL
-    except ImportError:
-        pass
-    else:
-        autoGIL.installAutoGIL()
+    # Install an observer callback in the current CFRunLoop that will
+    # automatically release and acquire the Global Interpreter Lock
+    # when needed. This is needed so other Python threads get a chance
+    # to run while we're inside the event loop.
+    #
+    # The autoGIL module is only present when using Python 2.2 on MacOS X
+    if sys.version_info[:2] == (2, 2):
+        try:
+            import autoGIL
+        except ImportError:
+            pass
+        else:
+            autoGIL.installAutoGIL()
+_initialize()
 
 import protocols  # no need to export these, just register with PyObjC
 
 #
 # (informal) protocols eported for b/w compatibility
 #
-from protocols import NSConnectionDelegateMethods, NSDistantObjectRequestMethods, \
+from protocols import NSConnectionDelegateMethods, \
+                      NSDistantObjectRequestMethods, \
                       NSCopyLinkMoveHandler, NSKeyedArchiverDelegate, \
                       NSKeyedUnarchiverDelegate, NSNetServiceDelegateMethods, \
                       NSNetServiceBrowserDelegateMethods, NSPortDelegateMethods
-

Lib/Foundation/test/test_nsarray.py

         self.assertRaises(ValueError, NSArray.arrayWithObjects_count_, ('a','b'), 3)
 
     def test_arrayByAddingObjects_count_(self):
-        if sys.platform != 'darwin' and not hasattr(NSArray, 'arrayByAddingObjects_count_'): return
+        if objc.platform != 'MACOSX' and not hasattr(NSArray, 'arrayByAddingObjects_count_'): return
 
         a = NSArray.arrayWithArray_(('a', 'b', 'c'))
         self.assertEquals(a, ('a', 'b', 'c'))
 
 
     def testReplaceObjects(self):
-        if sys.platform == 'darwin' or hasattr(NSMutableArray, 'replaceObjectsInRange_withObjects_count_'):
+        if objc.platform == 'MACOSX' or hasattr(NSMutableArray, 'replaceObjectsInRange_withObjects_count_'):
 
             a = NSMutableArray.arrayWithArray_(range(4))
             self.assertEquals(a, (0, 1, 2, 3))
         a = NSMutableArray.arrayWithArray_(range(10))
         self.assertEquals(a, (0, 1, 2, 3, 4, 5, 6, 7, 8, 9))
         
-        if sys.platform == 'darwin' or hasattr(a, 'sortUsingFunction_context_range_'):
+        if objc.platform == 'MACOSX' or hasattr(a, 'sortUsingFunction_context_range_'):
             def cmpfunc(l, r, c):
                 return -cmp(l,r)
 
         a = NSMutableArray.arrayWithArray_(range(10))
         self.assertEquals(a, (0, 1, 2, 3, 4, 5, 6, 7, 8, 9))
 
-        if sys.platform == 'darwin' or hasattr(a, 'sortUsingFunction_context_range_'):
+        if objc.platform == 'MACOSX' or hasattr(a, 'sortUsingFunction_context_range_'):
             def cmpfunc(l, r, c):
                 return -cmp(l,r)
 
         o = NSArray.arrayWithArray_(range(4))
         self.assertRaises(TypeError, o.getObjects_)
         self.assertRaises(TypeError, o.getObjects_range_, (1,2))
-        if sys.platform == 'darwin' or hasattr(o, 'apply_context_'):
+        if objc.platform == 'MACOSX' or hasattr(o, 'apply_context_'):
             self.assertRaises(TypeError, o.apply_context_, lambda x, y:None, 0)
 
 if __name__ == '__main__':

Lib/Foundation/test/test_nsnumber.py

 </plist>
 """
 
-if sys.platform == 'darwin':
+if objc.platform == 'MACOSX':
     class TestPropList (unittest.TestCase):
         #Test if numbers are stored properly in property-list. The most 
         #important part of the testcase are boolean values.

Lib/Foundation/test/test_osxcasts.py

 from Foundation import *
 
 try:
-    # These tests are only usefull on MacOS X when using MacPython
+    # These tests are only useful on MacOS X when using MacPython
     from Carbon.CF import *
 
 

Lib/InterfaceBuilder/__init__.py

 """
 
 # Load the AddressBook bundle, and gather all classes defined there
-import objc 
+import objc as _objc
 
-import AppKit
-del AppKit
+import AppKit as _AppKit
+from _InterfaceBuilder import *
 
-objc.loadBundle("InterfaceBuilder", globals(), bundle_path="/System/Library/Frameworks/InterfaceBuilder.framework")
-
-del objc
-from _InterfaceBuilder import *
+if _objc.platform == 'MACOSX':
+    _objc.loadBundle(
+        "InterfaceBuilder",
+        globals(),
+        bundle_identifier='com.apple.InterfaceBuilderFramework',
+    )
+else:
+    _objc.loadBundle(
+        "InterfaceBuilder",
+        globals(),
+        bundle_path=_objc.pathForFramework(
+            "/System/Library/Frameworks/InterfaceBuilder.framework",
+        ),
+    )
 
 import protocols  # no need to export these, just register with PyObjC
 

Lib/PreferencePanes/__init__.py

 """
 
 # Load the PreferencePanes bundle, and gather all classes defined there
-import objc 
-
-import AppKit
-del AppKit
-
-objc.loadBundle("PreferencePanes", globals(), bundle_path="/System/Library/Frameworks/PreferencePanes.framework")
-
-del objc
+import objc as _objc
+import AppKit as _AppKit
 from _PreferencePanes import *
 
-# Define usefull utility methods here
+if _objc.platform == 'MACOSX':
+    _objc.loadBundle(
+        "PreferencePanes",
+        globals(),
+        bundle_identifier='com.apple.frameworks.preferencepanes',
+    )
+else:
+    _objc.loadBundle(
+        "PreferencePanes",
+        globals(),
+        bundle_path=_objc.pathForFramework(
+            "/System/Library/Frameworks/PreferencePanes.framework",
+        ),
+    )
+
+# Define useful utility methods here

Lib/PyObjCTools/__init__.py

 """
 Various utility modules
 
-This package provides a number of usefull utility modules.
+This package provides a number of useful utility modules.
 
 Conversion      -- Tools for converting between Python and Objective-C objects.
 NibClassBuilder -- Tools for working with class definitions in 
     "Next Interface Builder" files ("nibs")
-Signals         -- Signal handling functions that are usefull during development
+Signals         -- Signal handling functions that are useful during development
 pluginbuilder   -- bundlebuilder extension for build plugin bundles in Python
 """

Lib/ScreenSaver/__init__.py

 
 
 # Load the ScreenSaver framework, and gather all classes defined there
-import objc
+import objc as _objc
 
-import AppKit
-del AppKit
+import AppKit as _AppKit
 
 # Custom method signature (undocumented class, this is a guess)
-objc.setSignatureForSelector("ScreenSaverUserInfo", "loginUserName:andID:", "v@:o^@o^I")
+_objc.setSignatureForSelector("ScreenSaverUserInfo", "loginUserName:andID:", "v@:o^@o^I")
 
-objc.loadBundle("ScreenSaver", globals(), bundle_path="/System/Library/Frameworks/ScreenSaver.framework")
+_objc.loadBundle(
+    "ScreenSaver",
+    globals(),
+    bundle_path=_objc.pathForFramework(
+        "/System/Library/Frameworks/ScreenSaver.framework",
+    ),
+)
 
-del objc
 # NOTE: One MacOSX 10.2.4 the framework doesn't define constants,
 # therefore there is no _ScreenSaver module.
 
-# Define usefull utility methods here
+# Define useful utility methods here

Lib/SecurityInterface/__init__.py

 """
 
 # Load the SecurityInterface bundle, and gather all classes defined there
-import objc
+import objc as _objc
 
 # For some reason SecurityFoundation.framework is currently documented as being
 # part of SecurityInterface.
-objc.loadBundle("SecurityInterface", globals(), bundle_path="/System/Library/Frameworks/SecurityFoundation.framework")
-
-objc.loadBundle("SecurityInterface", globals(), bundle_path="/System/Library/Frameworks/SecurityInterface.framework")
-
 from _SecurityInterface import *
-del objc
+if _objc.platform == 'MACOSX':
+    _objc.loadBundle(
+        "SecurityInterface",
+        globals(),
+        bundle_identifier='com.apple.securityinterface',
+    )
+    _objc.loadBundle(
+        "SecurityInterface",
+        globals(),
+        bundle_identifier='com.apple.securityfoundation',
+    )
+else:
+    _objc.loadBundle(
+        "SecurityInterface",
+        globals(),
+        bundle_path=_objc.pathForFramework(
+            "/System/Library/Frameworks/SecurityFoundation.framework",
+        )
+    )
+    _objc.loadBundle(
+        "SecurityInterface",
+        globals(),
+        bundle_path=_objc.pathForFramework(
+            "/System/Library/Frameworks/SecurityInterface.framework",
+        ),
+    )
 
 import protocols  # no need to export these, just register with PyObjC
 

Lib/WebKit/__init__.py

 documentation for details on how to use these functions and classes.
 """
 
-import AppKit
-del AppKit
+import AppKit as _AppKit
 import objc as _objc
 
 # We first register special methods signatures with the runtime. The module
 from _WebKit import *
 
 # Load the Cocoa bundle, and gather all classes defined there
-_objc.loadBundle("WebKit", globals(), bundle_path="/System/Library/Frameworks/WebKit.framework")
+
+if _objc.platform == 'MACOSX':
+    _objc.loadBundle(
+        "WebKit",
+        globals(),
+        bundle_identifier='com.apple.WebKit',
+    )
+else:
+    _objc.loadBundle(
+        "WebKit",
+        globals(),
+        bundle_path=_objc.pathForFramework(
+            "/System/Library/Frameworks/WebKit.framework",
+        ),
+    )
 _objc.recycleAutoreleasePool()
 
 import protocols  # no need to export these, just register with PyObjC
 
 _objc.setSignatureForSelector('NSJavaVirtualMachine', 'versionRangeFromString:lower:upper:', 'v@:r*o^Io^I')
-del _objc

Lib/objc/__init__.py

 ##
 ## Disable gc -- blows up w/Python 2.2.0
 ##
-import sys
-if sys.version_info[:3] == (2,2,0):
+import sys as _sys
+if _sys.version_info[:3] == (2,2,0):
+    import warnings
+    warnings.warn(
+        "Python 2.2.0's garbage collector crashes when used with PyObjC, disabling.  Python 2.3 or later is highly recommended.",
+        RuntimeWarning,
+    )
     import gc
     gc.disable()
 
 del gl, nm, _objc, x
 
 
-# Add usefull utility functions below
-
+# Add useful utility functions below
+if platform == 'MACOSX':
+    from _dyld import *
+else:
+    from _gnustep import *
 
 class _runtime:
     """
     Return the main bundle for the named plugin. This should be used
     in combination with ``PyObjCTools.pluginbuilder``.
     """
-    cls = 'PyObjC_Bundle_' + pluginName 
-    return runtime.NSBundle.bundleForClass_(getattr(runtime, cls))
+    cls = 'PyObjC_Bundle_' + pluginName
+    return lookUpClass('NSBundle').bundleForClass_(lookUpClass(cls))
 
 from _convenience import CONVENIENCE_METHODS, CLASS_METHODS
 
 # is ugly, but it is also something that would be very
 # hard to avoid...
 
-del sys
-
 def classAddMethod(cls, name, method):
     """
     Add a single method to a class. 'name' is the ObjC selector
     import types
 
     if isinstance(method, selector):
-        sel = selector(method.callable, 
-                    selector=name, 
-                    signature=method.signature, 
+        sel = selector(method.callable,
+                    selector=name,
+                    signature=method.signature,
                     isClassMethod=method.isClassMethod)
     else:
         sel = selector(method, selector=name)
 
 ######
 # Backward compatibility stuff
-# (depricated functionality)
+# (deprecated functionality)
 
 def recycle_autorelease_pool():
     """Depricated: Use recycleAutoreleasePool"""

Lib/objc/_dyld.py

+from __future__ import generators
+"""
+dyld emulation
+"""
+
+__all__ = [
+    'dyld_framework', 'dyld_library', 'dyld_find', 'pathForFramework',
+    'infoForFramework',
+]
+
+import os
+from _framework import infoForFramework
+
+# These are the defaults as per man dyld(1)
+#
+DEFAULT_FRAMEWORK_FALLBACK = ':'.join([
+    os.path.expanduser("~/Library/Frameworks"),
+    "/Library/Frameworks",
+    "/Network/Library/Frameworks",
+    "/System/Library/Frameworks",
+])
+
+DEFAULT_LIBRARY_FALLBACK = ':'.join([
+    os.path.expanduser("~/lib"),
+    "/usr/local/lib",
+    "/lib",
+    "/usr/lib",
+])
+
+def ensure_utf8(s):
+    """Not all of PyObjC understands unicode paths very well yet"""
+    if isinstance(s, unicode):
+        return s.encode('utf8')
+    return s
+
+def injectSuffixes(iterator):
+    suffix = os.environ.get('DYLD_IMAGE_SUFFIX', None)
+    if suffix is None:
+        return iterator
+    def _inject(iterator=iterator,suffix=suffix):
+        for path in iterator:
+            if path.endswith('.dylib'):
+                yield path[:-6] + suffix + '.dylib'
+            else:
+                yield path + suffix
+            yield path
+    return _inject()
+
+def dyld_framework(filename, framework_name, version=None):
+    """Find a framework using dyld semantics"""
+    filename = ensure_utf8(filename)
+    framework_name = ensure_utf8(framework_name)
+    version = ensure_utf8(version)
+
+    def _search():
+        spath = os.environ.get('DYLD_FRAMEWORK_PATH', None)
+        if spath is not None:
+            for path in spath.split(':'):
+                if version:
+                    yield os.path.join(
+                        path, framework_name+'.framework',
+                        'Versions', version, framework_name
+                    )
+                else:
+                    yield os.path.join(
+                        path, framework_name+'.framework', framework_name
+                    )
+        yield filename
+        spath = os.environ.get(
+            'DYLD_FALLBACK_FRAMEWORK_PATH', DEFAULT_FRAMEWORK_FALLBACK
+        )
+        for path in spath.split(':'):
+            if version:
+                yield os.path.join(
+                    path, framework_name+'.framework', 'Versions',
+                    version, framework_name
+                )
+            else:
+                yield os.path.join(
+                    path, framework_name+'.framework', framework_name
+                )
+    
+    
+    for f in injectSuffixes(_search()):
+        if os.path.exists(f):
+            return f
+    # raise ..
+    raise ValueError, "Framework %s could not be found" % (framework_name,)
+
+def dyld_library(filename, libname):
+    """Find a dylib using dyld semantics"""
+    filename = ensure_utf8(filename)
+    libname = ensure_utf8(libname)
+    def _search():
+        spath = os.environ.get('DYLD_LIBRARY_PATH', None)
+        if spath is not None:
+            for path in spath.split(':'):
+                yield os.path.join(path, libname)
+        yield filename
+        spath = os.environ.get(
+            'DYLD_FALLBACK_LIBRARY_PATH', DEFAULT_LIBRARY_FALLBACK
+        )
+        for path in spath.split(':'):
+            yield os.path.join(path, libname)
+    for f in injectSuffixes(_search()):
+        if os.path.exists(f):
+            return f
+    raise ValueError, "dylib %s could not be found" % (filename,)
+
+def dyld_find(filename):
+    """Generic way to locate a dyld framework or dyld"""
+    # if they passed in a framework directory, not a mach-o file
+    # then go ahead and look where one would expect to find the mach-o
+    filename = ensure_utf8(filename)
+    if os.path.isdir(filename):
+        filename = os.path.join(
+            filename,
+            os.path.basename(filename)[:-len(os.path.splitext(filename)[-1])]
+        )
+    filename = os.path.realpath(filename)
+    res = infoForFramework(filename)
+    if res:
+        framework_loc, framework_name, version = res
+        return dyld_framework(filename, framework_name, version)
+    else:
+        return dyld_library(filename, os.path.basename(filename))
+
+def pathForFramework(path):
+    fpath, name, version = infoForFramework(dyld_find(path))
+    return os.path.join(fpath, name+'.framework')

Lib/objc/_framework.py

+"""
+Generic framework path manipulation
+"""
+
+import re
+__all__ = ['infoForFramework']
+
+# This regexp should find:
+#   \1 - framework location
+#   \2 - framework name
+#   \3 - framework version (optional)
+#
+FRAMEWORK_RE = re.compile(
+    r"""(^.*)(?:^|/)(\w+).framework(?:/(?:Versions/([^/]+)/)?\2$)?"""
+)
+
+def infoForFramework(filename):
+    """returns (location, name, version) or None"""
+    is_framework = FRAMEWORK_RE.findall(filename)
+    if not is_framework:
+        return None
+    return is_framework[-1]

Lib/objc/_gnustep.py

+from __future__ import generators
+
+__all__ = ['pathForFramework', 'infoForFramework']
+#
+# TODO - I have no idea what the semantics are for GNUStep ..
+#
+from _framework import infoForFramework
+
+def pathForFramework(path):
+    return path

Lib/objc/test/test_leaks.py

 import unittest
 import objc
 
-# Most usefull systems will at least have 'NSObject'.
+# Most useful systems will at least have 'NSObject'.
 NSObject = objc.lookUpClass('NSObject')
 NSMutableArray = objc.lookUpClass('NSMutableArray')
 

Lib/objc/test/test_subclass.py

 import sys
 import types
 
-# Most usefull systems will at least have 'NSObject'.
+# Most useful systems will at least have 'NSObject'.
 NSObject = objc.lookUpClass('NSObject')
 
 class TestSubclassing(unittest.TestCase):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.