I came up with a method that seems to work quite well.
First download the source version of python that you want to use from the official site. Extract the archive somewhere. I am using Python 3.4.2. Adjust the commands in your system for the specific version that you are using.
Create the assembly directory that you will use for this version of python for development. The entire directory should not contain spaces to ensure that bash correctly interprets strings (#!). I used /Users/myaccount/development/python/devbuild/python3.4.2 .
Go to the extracted Python directory and run the following commands:
./configure --prefix="/Users/myaccount/development/python/devbuild/python3.4.2" make make install
This will install python in the development directory. Configure the Python path to use the correct directory:
export PYTHONPATH="/Users/myaccount/development/python/devbuild/python3.4.2/lib/python3.4/site-packages/"
Go to the python bin directory ( /Users/myaccount/development/python/devbuild/python3.4.2/bin ) and use pip3 there to install any modules you need. The $PYTHONPATH parameter ensures that the modules are installed in the correct site-packages directory.
Find a convenient home for the PyObjC repository and clone it there. Then check the tag for the latest version and install it, making sure your $PYTHONPATH is still correct:
hg clone https:
Whenever you need to update python modules, just make sure you use the correct python python and $PYTHONPATH .
Now add python to your Xcode project.
Drag /Users/myaccount/development/python/devbuild/python3.4.2 into the Xcode project, setting it so that you donβt need to copy items if necessary, and create a link to the folder.
Add /Users/myaccount/development/python/devbuild/python3.4.2/include/python3.4m to the Header Search Paths setting in the Xcode Build Settings project. Not sure if there is a way to do this as a generalized step, just to find the directory specified in the directory we just added.
Drag the library `/Users/myaccount/development/python/devbuild/python3.4.2/lib/libpython3.4m.a to the Xcode project, setting it as a link without copying.
Now you can use the code from the scriptbook tutorial repository for beginners of the Nerd ranch with a few changes.
Plugin Manager code will require the NSString extension to work with wchar_t strings, which seem to be similar to the Python APIs:
@interface NSString (WcharEncodedString) - (wchar_t*) getWideString; @end @implementation NSString (WcharEncodedString) - (wchar_t*) getWideString { const char* tmp = [self cStringUsingEncoding:NSUTF8StringEncoding]; unsigned long buflen = strlen(tmp) + 1; wchar_t* buffer = malloc(buflen * sizeof(wchar_t)); mbstowcs(buffer, tmp, buflen); return buffer; } @end
The Python header should be included as follows:
#include "Python.h"
The following code must be run before Py_Initialize() is called in order to install the correct python, PYTHONPATH, and PYTHONHOME executable, as suggested by Zorg on this other issue.
NSString* executablePath = [[NSBundle mainBundle] pathForResource:@"python3.4" ofType:nil inDirectory:@"python3.4.2/bin"]; Py_SetProgramName([executablePath getWideString]); NSString* pythonDirectory = [[NSBundle mainBundle] pathForResource:@"python3.4" ofType:nil inDirectory:@"python3.4.2/lib"]; Py_SetPath([pythonDirectory getWideString]); Py_SetPythonHome([pythonDirectory getWideString]);
Finally, the python path must be extended in the PluginExecutor.py file to include various subdirectories of the high-level lib path. Add the following code to the top of the Plugin Executor file:
import sys from os import walk path = sys.path.copy() for p in path: for root,dirs,files in walk(p): if p is not root: sys.path.append(root)
I will post updates if everything starts to break down, but for now this seems like a working solution.