There are a couple potential reasons for this.
1)
You told it to delete directories only (-type d), and those directories still have files inside them.
2)
Your directories only contain other directories, so the -type d will take care of the contents issue. However you are using OS-X, which is largely based on FreeBSD, and the FreeBSD find by default will process the directory before its contents.
However the -depth option exists to solve this problem by telling find to process the directory after its contents.
find ~ -name __pycache__ -type d -ls -delete -depth
This issue does not exist on linux because the -delete option implicitly enables -depth.
FreeBSD man 1 find:
-depth Always true; same as the non-portable -d option. Cause find to
perform a depth-first traversal, i.e., directories are visited in
post-order and all entries in a directory will be acted on before
the directory itself. By default, find visits directories in
pre-order, i.e., before their contents. Note, the default is not
a breadth-first traversal.
GNU man 1 find:
-depth Process each directory's contents before the directory itself. The -delete
action also implies -depth.
find ~ -path '*/__pycache__*' -delete, or probablyfind ~ -path '*/__pycache__/*' -o -name __pycache__ -deleteto be safe. – naught101 Aug 24 '16 at 01:18find ~ \( -path '*/__pycache__/*' -o -name __pycache__ \) -deleteas and has precedence over or. – Stéphane Chazelas Aug 24 '16 at 11:36