Hacker News new | past | comments | ask | show | jobs | submit login
Python with a Cocoa GUI on MacOS (dawes.wordpress.com)
97 points by sacheendra 67 days ago | hide | past | web | favorite | 30 comments

I've used it for https://pngmini.com, and I regret it.

• Startup time is noticeably slower than native apps. Importing Cocoa makes Python parse a ton of code.

• Cocoa just doesn't fit Python's naming conventions. You get long method names with underscores where arguments should be, followed by many unlabelled arguments. The worst thing is that 1-arg methods, which otherwise look like normal Python methods, have to have an underscore suffix (`foo_`).

• All errors are runtime errors. It's a step back from ObjC, and the aforementioned writing of `[obj foo:arg]` as `obj.foo_(arg)` gets me every time. Python is also more sensitive about None than ObjC is about nil, so you need more checks and forgotten checks blow up more often.

• I wanted to do more advanced stuff with CoreAnimation and PyObjC couldn't figure out how long to retain stuff (or it was a bug somewhere). I know how to debug such problems in ObjC (and they're rare since ARC), but having Python's GC and a large framework sandwiched in between made it hard.

• The app breaks when users replace macOS's old Python with their own, which lacks PyObjC support. I don't know how common that is, but I've been getting bug reports about it.

In the end I ended up rewriting large parts in ObjC, and the remaining Python code is slow and brittle.

These days there's Swift which isn't more laborious to write than Python thanks to type inference and ARC, but has compile-time checks, non-nullable types and first-class Cocoa interface.

Interestingly enough Kivy and Beeware are attempts to create Python mobile development frameworks:



They are OK but I had trouble with Kivy’s Python 3 support and pyenv and the apps don’t look native (which is a secondary concern for most people these days, sadly, but an issue for most Mac users)

I love Beeware not only for their puns ("The IDEs of March", etc), but also for the clarity of their documentation.

Kivy is very interesting to me – I've been meaning to pick up Dusty Phillips's book about it.

PyObjC, which is what is being used here, is nice, but pretty fragile. It relies pretty much on one guy, Ronald Oussoren, who is also one of the py2app maintainers. It often lags behind the pace of macOS development.

I think PyQt is a more robust solution for GUIs, and it gives you cross-platform compatibility basically for free - although packaging is probably a bit harder.

PyQt packaging is no longer hard with https://build-system.fman.io. (I'm the author.)

Any mobile option? I sort of see pythonista on ipad can do it ... just wonder any other option of packaging gui that really cross all platforms not just desktop.

It's only for desktop for now, sorry.

That looks awesome. I do have personal concerns about GPL, though (which is why I avoid Qt - everything I do these days is either MIT or Apache licensed).

Qt itself has been LGPL for many years now, pretty sure it has been since sometime when Nokia owned it.

And it had a licensing exception for pretty much every OSI license for years before that. Anyone still talking about Qt licensing is spreading FUD from well over 15 years ago.

That looks cool, will probably give it a try.


I had a great experience with PySide2 (aka Qt for Python), although the docs still have examples in C++ (that are supposed to be in Python) sprinkled everywhere.

I’ve been doing this for a while now for small utilities, and got started on it in earnest with https://github.com/rcarmo/shelf (which I used for a long time until LinkedIn broke their APIs).

There are mainly two challenges here:

- packaging (it’s a bit tricky to sort out, and bundling a full virtualenv is the best long-term option across OS releases)

- longevity (Ronald has been maintaining PyObjC on his own dime, and Apple seems to mostly ignore everything else in favor of Swift these days)

The JavaScript bridge also works OK (I briefly considered using that instead, but the way collections are handled is hideous due to language constraints and PyObjC is so much better).

Edit: bullets

I have always been curious, what is Apple's motivation for shipping Python with macOS?

I don’t believe there’s any special motivation for including Python than what motivates the inclusion of any other of the common Unix tools such as Ruby, Git, grep, or awk.

not to mention ls, gcc, perl, httpd, and the rest of the BSD subsystem on which it is based

It’s been there forever. In fact, Apple used to have semi-official documentation on PyObjC at one point.

A bunch of system utilities are implemented against the version of Python that ships with OS X.

Grep and ask are there for POSIX compatibility, right?

The Calendar and Contacts Server that used to come with macOS Server is written in Python, I can’t think of any system utilities implemented with Python though. And once Python comes with the system (I think it has since at lest 10.4), they can’t remove it without breaking apps that depend on it.

macOS (in its NeXT-based lineage) has always come with many scripting languages (php, perl, python, ruby, applescript, awk, *sh, etc) as part of a standard unixy setup, even before Apple themselves made use of them per se in the system. While they make use of Python currently, it's there also just to enable whatever things a user or a 3rd party may build.

It was great to see a one-window BitTorrent client 14 years ago on MacOS, native GUI but lots of python underneath..

Off-topic Python question: is the use of “CapWords” / CamelCase for method names correct here? I assume this is the “prevailing style” of pyobjc or Objective C itself, and it therefore comes under the exception in PEP8.

I ask because I find the use of CamelCase like this for method names really off-putting.

It’s a byproduct of Objective C. It’s pretty common to see just about anything that provides bindings/bridges into ObjC to match the casing of the ObjC code—this is typically to help with matching and looking up relevant ObjC documentation to understand the original code better. It is off-putting, for sure.

That makes sense. It's good that PEP8 makes exceptions for such cases, I suppose, but it just looks wrong to my eye.

My general experience was that idiomatic Python generally uses snake_case for method and function names (at least, this was true of Python 2, before I stopped using python regularly)

I believe this is camelCase because of objc requirements (I’ve run into similar annoyances working on my Common Lisp bindings to cocoa.)

Every time I see Interface Builder I cringe. How Apple thinks it is a suitable way to construct GUIs is crazy to me.

How do people deal with GIL when writing GUI code in Python? Without multithreading computation will block UI.

GIL is released when a thread is waiting on a queue. One thread reads UI event queue from the OS and puts user actions into a queue, another runs your code.

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact