There are also a couple of CFFI-based libraries that I wrote, which have been linked in the other post. It seems that I never made a proper post on the forums about them, so I'll do that here:
The first one is cffipp (found in my pythonista-c-utils repo), which adds a proper C preprocessor to CFFI. By default CFFI's C parsing understands almost no C preprocessing features (only simple constant
#defines are supported). This library adds support for all important C preprocessor directives and features, which makes it possible to load standard iOS headers into CFFI (as long as they are pure C, such as Core Foundation). The repo includes patched versions of a few headers, to make them compatible with CFFI and improve parsing performance.
Unfortunately, cffipp is now quite outdated - I wrote it three years ago based on CFFI 1.6 and the headers for iOS 9. The CFFI and header patches include a lot of copied code, so updating it to newer CFFI and iOS SDK versions would take a bit of work. If anyone is interested in using this, let me know, I might be able to get it updated.
The second library is objc-cffi, which is basically a CFFI-based version of
objc_utilwith a few extra convenience features. This library is fairly incomplete - although it has a few features that
objc_utildoesn't (introspection, better automatic type detection for methods) it's missing some very important features for practical use (class definitions, block support, collection syntax).
I also found out quite soon that CFFI is not well suited as the base for this library. To interact with the Objective-C runtime I need to create a lot of types dynamically, which is very slow with CFFI, because every type needs to be constructed as C source code and then parsed by CFFI. I also ran into name collision issues, because every FFI object has a single namespace and does not allow multiple definitions (the Objective-C runtime sometimes returns different type information for the same type, depending on context).
Around this time I also started contributing to rubicon-objc, which has also been mentioned a few times on this forum - it's basically
objc_util, but not Pythonista-specific (also works on Mac and other platforms with Objective-C). I've ported most of objc-cffi's convenience features over to rubicon-objc now, and I'm still working on improving rubicon-objc, so I would definitely recommend that over objc-cffi.
This is in response to the questions/replies from @cvp and @JonB in https://forum.omz-software.com/topic/5660/install-pymunk-on-pythonista-get-cffi-error about how to use CFFI in Pythonista. I'm putting it in a separate thread since it's not really relevant to the original question (getting a specific library working in Pythonista).
For context: CFFI is a library for calling C code from Python. It has a similar purpose as ctypes, with one big difference being that CFFI lets you write type and function declarations using standard C syntax, without having to "translate" them to another syntax/API first as with ctypes.
By default, CFFI uses its own custom C extension to call C code, and also has various features that make use of a proper C preprocessor/compiler. Of course this doesn't work by default on Pythonista, since there is no C toolchain and you can't compile or load custom extension modules. However, in addition to the default C extension backend, CFFI also includes a ctypes-based pure-Python backend (
cffi.backend_ctypes.CTypesBackend), which works in Pythonista, with no modifications needed to CFFI itself.
The installation process is very straightforward: you download the source and copy the
site-packages, as with any other module. We can safely ignore the C parts, since we don't use them. (You can probably also install CFFI via Stash, but I haven't tried it.) Once it's installed, you can create an
FFIobject with the ctypes backend like this:
import cffi.backend_ctypes ffi = cffi.FFI(backend=cffi.backend_ctypes.CTypesBackend())
After that, you can use the
ffiobject as you normally would - see the CFFI docs. Note that the docs sometimes refer to different modes of operation for CFFI (ABI/API and in-line/out-of-line). Only in-line ABI mode can be used with the ctypes backend in Pythonista, all other modes require a working C compiler.
Unfortunately, this often doesn't help with getting CFFI-based libraries to work on Pythonista - in many cases these libraries rely on third-party or custom C code that isn't available in Pythonista. CFFI is simply the interface between Python and C, so even if you have CFFI working it won't be of any use without the C libraries that you want to call.
That's not to say that CFFI is of no use in Pythonista. Almost everything that you can do with ctypes can also be done with CFFI, and usually with a much nicer and more convenient API, which makes it very useful for calling C APIs (Unix/iOS and CPython).
@T451f The bottom row of Pythonista's extended keyboard uses the system standard shortcut bar (where in other apps you have buttons for undo, redo, cut, copy, paste). Check in your iOS keyboard settings (in the Settings app, not in Pythonista) that you have the shortcut bar enabled.
@cvp I think the second keyboard row is only available on old iOS versions (iOS 10 and below IIRC) because of technical reasons. If your iOS version is newer than that, you can't use the second keyboard row.
You can use the following commands in the Pythonista 3 Python console to copy the folder back:
>>> import os, shutil >>> shutil.copytree(os.path.expanduser("~/Documents/foldername"), os.path.expanduser("~/../Documents/foldername"))
foldernameis the name of the folder you want to copy (assuming that it's in the root of Pythonista 3's local files). You can also use
shutil.copytreeif you want to move the folder rather than copy it (which may be a good idea if it's very big).
By the way, is there any reason in particular why you're still using Pythonista 2? Pythonista 3 supports both Python 2 and 3, so there's generally no need for Pythonista 2 if you have Pythonista 3. In fact Pythonista 2 can no longer be bought on the App Store and won't receive any more updates.
Warning: Unfortunately, this module no longer works on iOS 11 and later because the underlying APIs have been removed from iOS.
I don't think
sys.displayhookwould be very helpful here - it only affects how the final evaluated object is displayed, it does not change anything about how the typed-in Python code is executed. In particular,
If you want to affect
sys.stdoutwith a custom file-like object.
If you want to affect the code execution even more than that, you're probably better off writing your own REPL, perhaps based on the standard
codemodule or simply
eval. This lets you run the entered code in a different environment (by passing a dict to
eval) and you can even analyze and modify the code before it gets run (although that might be overkill depending on what you want to do).
There are two possibilities I can think of:
- Do you have a file called
numpy.pyin Pythonista? If so, you need to rename it - otherwise
import numpy as npwill import your
numpy.pyand not the standard
- Try restarting Pythonista (swipe up from the bottom of the screen to open the app switcher, then swipe Pythonista upwards to close it, then reopen the app). It is possible that the
numpymodule isn't loaded completely; this can happen if you stop your script while the
import numpystatement is running. By restarting Pythonista, you can bring the Python environment back into a clean state.
- Do you have a file called
Normal Markdown doesn't have any native syntax for underlining -
__underline__produces underline, i. e. bold text. In standard Markdown,
__bold__is equivalent to
_italic_is the same as
Chat applications like Discord, Slack and Mattermost support syntax that is similar to normal Markdown, but isn't completely compatible (they include some custom features that don't exist in Markdown, and don't understand all standard Markdown syntax). Discord's underline feature is an example of that.