Running Python in Xcode: Step by Step

As I’m preparing for a project that will involve Python programming, I need to get up to speed with at least a basic level of Python mastery. However, I’m not a big fan of using the interactive Python REPL, or whatever it is actually called:

screen-shot-2016-12-04-at-11-37-21-am

I decided to use Xcode instead, and I’m finding it a much better solution for my needs:

screen-shot-2016-12-03-at-8-31-15-pm

Here’s the steps I took to set up this project:

Step 1: Install Python 3.5

If you run python -V at the command line, macOS reports “Python 2.7.10”, or at least it does on my system. Bzzt. I want 3.5.2, which is the most recent non-beta release, and dates to June of this year.

I grabbed my installer from the Python.org downloads page: https://www.python.org/downloads/release/python-352/

Step 2: Locate python3

I use tcsh, so where python3 reports /usr/local/bin/python3. The location is surely the same for you, but I don’t know what the equivalent for where is in bash.

Step 3: Create an Xcode project

File > New > Project > Cross-platform > External Build System > Next.

screen-shot-2016-12-04-at-11-44-06-am

Enter a name (e.g. Python), and enter the path from Step 2 into the “Build Tool” line. Click Next.

screen-shot-2016-12-04-at-11-44-43-am

Navigate to whatever location you like, and click Create.

Step 4. Create a Python file

Choose File > New,  select macOS > Other > Empty. Click  Next.

screen-shot-2016-12-04-at-11-48-04-am

You should already be in your project’s top level folder. If not, go there. Name your file Whatever.py, choosing whatever name you like. I went with Work.py. Make sure the “add to target Python” box is checked. Click Create.

screen-shot-2016-12-04-at-11-49-43-am

Step 5. Edit your Run Scheme

The Xcode default should have the Run scheme selected:

cap

Click and hold on the Python target in the jump bar. Select Edit Scheme…

screen-shot-2016-12-04-at-11-50-56-am-2

The Run scheme displays, with the Info tab selected.

Step 6. Choose the Executable

I warn you now that this step is going to be delicate, fragile, and stupid. That’s because Xcode, for whatever reason, will not let you use the symbolic link at /usr/local/bin/python3. I don’t know why.

In the Info tab. Select “Other” from the Executable pop-up list. A file selection dialog appears.

cap

 

Return to the terminal. Type: open /usr/local/bin. Select python3 and control-click/right-click. Select Show Original. This will probably be named python3.5. It’s not a symbolic link but unfortunately Xcode continues to be fussy about allowing you to select it as your executable because of the period in its name. Sigh.

Drag python3.5 onto the file dialog and click Choose, if you’re allowed to. If so, great. If not, you need to work around Xcode: create a hard link and then drag the link onto the dialog.

% ln python3.5 python35

I know, I know. Ew. But it’s better than copying, or worse, renaming the file. And no, symbolic links don’t seem to work here. Better solution? Let me know.

Finally, uncheck “Debug executable”. You don’t want to debug the Python language itself.

screen-shot-2016-12-04-at-12-05-26-pm

Step 7. Add Launch Arguments

Now, click the Arguments tab. Click + under “Arguments Passed On Launch” and type $(SRCROOT)/ followed by the name of the Python file you created in Step 4.

screen-shot-2016-12-04-at-12-07-02-pm

Step 8. Test it out.

Click Close to dismiss the scheme editor. Enter a program (don’t forget all those colons and tabs) and run it:

screen-shot-2016-12-04-at-12-38-05-pm

It’s a very odd thing to be jumping into Python with a Swift background. Clearly Swift has inherited a lot of Python genes. It also feels sinful to use such lax typing without compiler oversight. That said, my first experiences in Python can wait for another day and another post. More to follow.

22 Comments

  • You can use ‘which’ in bash to find the location of python3

    • You can use `which` in tcsh too, but it points to the library not the preferred entry point of /usr/local/bin. I much prefer using the right path, especially with Daniel’s suggestion of editing the scheme file by hand.

    • Also, Sierra does have Python 3.4 installed, if you’re happy with that instead of 3.5:

      $ which python
      /Library/Frameworks/Python.framework/Versions/2.7/bin/python
      $ which python3
      /Library/Frameworks/Python.framework/Versions/3.4/bin/python3

      • My Sierra install does not have Python 3.anything installed. And the actual Python installation is does have is in /System/Library/Frameworks/Python.framework

  • Xcode is not as grumpy about the symbolic link being used as it pretends to be. Set up the Executable in the scheme in any old way, just to get a value in there. First, quit Xcode. Then hand-edit the appropriate .xcscheme file from deep within your project file hierarchy. Find the exectuable referenced in the file and change the pertinent attribute to something like:

    FilePath = “/usr/local/bin/python3”

    Now reopen Xcode and build and run the project, seeing that it has manged just fine to “run” /usr/local/bin/python3 for you.

    Enjoy!

    • Hand-editing the xcscheme XML file doesn’t exactly suggest a non-grump Xcode. I’m more picturing Xcode snickering to itself, with “gotcha again!”

      (But thank you!)

      (p.s. Tested, works great.)

      • Yes, Xcode is laughing at us, but at least we may have the last laugh 😉

  • I discovered that if any of the folders in the path to the project contain spaces that it would barf when running. Once I removed the spaces then all was well.

    • Hi Steve – I think this will be alleviated by putting quotation marks around the argument in Xcode. So instead of $(SRCROOT)/Work.py, try “$(SRCROOT)/Work.py”.

  • Also, as you pointed out you probably don’t want to “debug python” literally, but what you might be interested in is invoking the Python’s built in debugger module as a part of your “run” scheme. Before the $(SRCROOT) based python file reference in the Arguments, add an entry for “-m pdb”. Now when you run python to run your script it will drop you into the Python debugger. Only problem is this doesn’t seem to play well with Xcode’s built in console, so check the option under “Options” in the scheme editor, to select Terminal instead of Xcode as the running console.

    • Nice!

    • Awesome! I really like this!

  • You might want to take a look at the PyCharm IDE if you’re going to be doing a lot of Python programming. There’s a free community edition.

  • hey. What if I wanted to work with python libraries? Can i still work with them in Xcode?

  • But why so much pain? Get PyCharm from Jetbrains and brew a couple of Pythons and just use it.

  • Another vote for PyCharm. Being able to step through your code in the debugger and run snippets of code is great for figuring out what is really going on.

    For the python package manager I use Anaconda. Virtual environments are great if you need different sets of libraries for different projects.

    Jupyter notebooks are the equivalent to playgrounds. (You can install Jupyter with anaconda.)

  • I tried this trick but with Free Pascal compiler (from freepascal.org), instead of Python, but it didn’t work. When I tried to run a pascal program, the Xcode error window said “posix_spawn failed (error code: 86)”. Could you help me please? Thank you.

    • Try editing the xcscheme file as Danield recommends in the comments.

      • Have done that, too. But still got no luck. Same error. 🙁

  • Would make more sense to spend the time setting up Atom – similar to Sublime – where you get autocomplete, debugging, etc.

  • Using your info I am able to use python/x-code. However I ran into a ‘ ident’ problem. Somehow the editor of x-code ‘reformats’ my python files. So when I execute I get python -errors regarding ‘ ident”s…

  • If I try to run a python file, Xcode runs the work.py file which we linked as arguments again and again, instead of the python file which I want to run. Please find me a solution.