Scripts/findPython
==================

* :download:`Download example <findPython.py>`

...


findPython.py
.............

.. sourcecode:: python

    #!/usr/bin/pythonw
    """
    Find the library name for the current Python interpreter
    """
    import objc
    from Foundation import NSBundle
    
    
    def S(*args):
        return b"".join(args)
    
    
    # these are void*
    NSSymbol = b"I"
    NSModule = b"I"
    
    FUNCTIONS = [
        ("NSIsSymbolNameDefined", S(objc._C_BOOL, objc._C_CHARPTR)),
        ("NSLookupAndBindSymbol", S(NSSymbol, objc._C_CHARPTR)),
        ("NSModuleForSymbol", S(NSModule, NSSymbol)),
        ("NSLibraryNameForModule", S(objc._C_CHARPTR, NSModule)),
    ]
    
    
    def libraryNameForSymbol(symbol):
        bndl = NSBundle.bundleWithPath_("/System/Library/Frameworks/System.framework")
        d = {}
        objc.loadBundleFunctions(bndl, d, FUNCTIONS)
        for fn, _sig in FUNCTIONS:
            if fn not in d:
                raise ValueError(f"Couldn't find function {fn}")
        symbol = b"_" + symbol
        if not d["NSIsSymbolNameDefined"](symbol):
            # symbol not defined
            return None
        sym = d["NSLookupAndBindSymbol"](symbol)
        if not sym:
            raise ValueError(f"Couldn't bind symbol {symbol!r}")
        mod = d["NSModuleForSymbol"](sym)
        if not mod:
            raise ValueError(f"Couldn't find module for symbol {symbol!r}")
        return d["NSLibraryNameForModule"](mod)
    
    
    if __name__ == "__main__":
        print(libraryNameForSymbol(b"Py_Initialize"))

