Thoughts on iOS Python

If you search for “python” on the iOS App Store, you’ll get a lot of hits, but if you filter out the teaching apps, the IDEs, the documentation apps, and the ones with lots of one-star reviews, you’ll be left with just a handful of apps:

I use Python for two things:

  1. Automation scripting for general computer use. On the Mac, the standard libraries are often all I need, and whatever added libraries become necessary are usually written in Python itself. On iOS, it’s usually helpful to have specialty modules for connecting to the clipboard, the Photos library, calendars, and so on.
  2. Numerical and data analysis for my job. Here, I rely on several modules—NumPy, SciPy, Pandas, SymPy, Matplotlib—that are written mainly in other languages and have Python interfaces.

My opinions on Pythonista and Pyto are informed by these uses.


When Pythonista came out several years ago, it was really good at the first thing but not so good at the second. That changed slightly a few years ago when Pythonista 3 was released. It included Numpy, SymPy, and Matplotlib, which was a step in the right direction but not enough for me to be able to use it for most of my work.1

Because as nice as it is to have NumPy, SymPy, and Matplotlib, I really need Pandas and SciPy. So I still need a Mac for work scripts. I have, however, developed a workflow in which I do a fair amount of work on an iPad that’s being used largely as a smart terminal. With Textastic on one side of Split View and Prompt on the other, I can edit scripts on my Mac and run them without having to be at my desk. In fact, Split View was the feature that got me to buy an iPad in the first place.

As for automation, Pythonista has unfortunately moved from being a great app to being a frustrating one, largely because it sat around for a couple of years with no updates whatsoever. And those years coincided with the ascent of Workflow/Shortcuts. Pythonista didn’t get worse during these years, but the world of iOS automation moved on and Pythonista didn’t move with it. It’s greatest value as an automation tool now would be if it we could use it to handle the computation that Shortcuts really isn’t good at.

As I mentioned in one of my ROT13 posts a few months ago, simple two-way communication with Shortcuts is essential nowadays to being a good iOS automation citizen, and Pythonista just doesn’t have it. It’s still limping along with the clipboard and URL schemes (and a limited version of URL schemes, at that).

But there is hope for Pythonista. Last week, an update appeared out of nowhere, and although the new features don’t address the app’s most serious weaknesses, there may be a light at the end of the tunnel. There’s now a keyboard module for running scripts from a special Pythonista keyboard.

Pythonista keyboard

And there’s a shortcuts module that does very little right now, but…

The shortcuts module provides utilities for Pythonista URLs that can be used to launch the app, and run or open scripts. You can also launch the Shortcuts app (and run shortcuts) using this module, but support for “native” Python shortcuts in the Shortcuts app is planned for a future version of Pythonista.

Let’s hope that future version of Pythonista isn’t another two years away.


What’s exciting about Pyto is the libraries it comes with. Among the ones I use the most for work, the only one missing is SymPy, and since I have that in Pythonista, it’s not a terrible loss. So now I can do most of my work natively on the iPad, a big jump forward.

What’s not so exciting about Pyto is everything else.

The editor is a mess. It doesn’t understand how matching characters are supposed to work. If for example, I type

a = sin(

it adds the closing parenthesis and puts the cursor between them.

a = sin(|)

So far, so good. But when I finish typing in the argument and then type the closing parenthesis (because I’ve been typing for 45 years and closing parentheses is a habit—also, it’s easier than typing the right cursor key), it doesn’t jump past the closing parenthesis that’s already there—like every other editor that does matching characters—it just adds the typed parenthesis and leaves the cursor between the two.

a = sin(pi/6)|)

Of lesser concern, but still annoying, Pyto insists on a 4-character indent if you’re using tabs. I know PEP 8 says to use 4-character indentation, but I’m not working in a team and PEP 8 isn’t the boss of me. Except when I’m typing in Pyto.

Perhaps more disturbing than the editor is Pyto’s confusing and limited Shortcuts support. Pythonista has the excuse that it was developed long before Workflow/Shortcuts was around—Pyto doesn’t. Here’s the documentation:

Pyto provides Shortcuts for running scripts and code. Shortcuts will open Pyto to execute the code and it’s not possible to retrieve the result. See x-callback URLs for getting callbacks.

Run Code with Arguments will execute the given code with the given arguments. Code can be executed in app or without leaving Shortcuts. If you uncheck Run In App, the Shortcut will return the output of the code (stdout + stderr). When Run In App is unchecked, the code will only have access to the standard library and stdin cannot be sent.

Run Script with Arguments will execute the given script with the given arguments. Note that Script is a file, and Shortcuts doesn’t provide a way to pick a file as a value. So the only ways to have a valid value passed to this Shortcut are by sharing a file with the Share Sheet and passing the input or by picking each time a script with the Get file system Shortcut.

I think it was Dennis Ritchie who said he’d sometimes rewrite his code for Unix commands because writing the man page—and having to explain how the command currently worked—made him embarrassed. Pyto’s developer could use some embarrassment when it comes to Shortcuts interaction.

Even Pyto’s best feature, its expanded library, isn’t perfect. Weirdly, the very first thing I tried after installing Pyto was code like this:

from scipy.stats import binom

print(binom.pmf(4, 5, .5))

and it crashed. In fact, the binomial pmf function has crashed every time I’ve invoked it, except when the first two arguments are equal. The closely related hypergeometric pmf function doesn’t crash, nor do the binomial or hypergeometric cdf functions. As I said, weird.

While the crash is a little bothersome, I can work around it if necessary. More bothersome is that the developer hasn’t replied to my bug report in the week since I sent it.


Because only modules written entirely in Python can be installed by the user, the number of non-native libraries that come with an iOS Python app determines how broadly useful the app can be. That’s why, despite its many flaws, I have hopes for Pyto and don’t regret buying it. Giving me the ability to write the kinds of scripts I need to for work covers up a lot of shortcomings.

And seeing Pythonista back in development again has made me cautiously optimistic about it again. The developer clearly knows he needs to get on the Shortcuts bandwagon if he wants his app to be a significant player in the iOS automation world again. I think a lot of ground has been lost to Scriptable.

My dream would be for these two apps get into a competition with each other. If that happened, I might be able to put off learning JavaScript for another decade.

  1. I certainly have used Pythonista for work, especially when I’ve needed to make random selections in the field for sampling and testing. The random module is in the standard library and has always been a part of Pythonista. I’ve used it many times in short scripts to prove that I’m not cherry picking the samples. And it’s great to use Pythonista’s interactive console with SymPy when I’m out of the office and need to do some quick algebra without making stupid errors.