✎ Quills
Last updated:
Importing Quills can be tricky because it is a compiled module, it is not necessarily installed in a location that Mac OS X searches by default, and it supports a variety of architectures and Python versions.
See the architecture page for full details on library design decisions.
Creating a Script That Imports Quills
There are actually a few ways to run Quills-based scripts:
- Directly add to MacTelnet.app/Contents/MacOS/RunMacTelnet.py; this is not recommended for a script of any complexity, but it is a quick way to experiment with the Quills API. What you add is obviously executed automatically when MacTelnet starts up! The file has several embedded comments to guide you.
- Or, copy the MacTelnet.app/Contents/MacOS/MacTelnet and MacTelnet.app/Contents/MacOS/RunMacTelnet.py scripts, which already contain some magic for locating the Quills libraries from Python, and adapt them to suit your needs. This approach (or a manual one based on the information below) is required if you want your script to run completely outside MacTelnet, such as when you invoke it from the Finder or the Apple Terminal.
- Or, invoke your Python script from a MacTelnet window (such as one running a shell), which invokes an additional copy of MacTelnet as a child of the current one. The big advantage of this approach is that your Python script is simple: just import and Quills is found for you. But the downside is that the script is not portable: it will not run outside a MacTelnet window unless its environment dependencies have been resolved.
Any of the short-cuts above will work, but more details on the specific runtime requirements are provided here, for completeness.
Quills is partly compiled (see Architecture), so you must make sure both the compiled and Python parts are found.
There are two important locations:
- Library path. The dynamic linker must find the bulk of the compiled Quills library. This is platform-specific:
- Quills.framework/Versions/A is PowerPC-only and used for Panther (which has no universal binaries)
- Quills.framework/Versions/B is universal and used for both Tiger and Leopard
- Module path. The Python interpreter must find the Python interface to Quills. By Python convention, this requires
a pure Python interface Quills.py and a _Quills.so at the same location. These files are small, but a set must
exist for every combination of Mac OS X system:
- Quills.framework/Versions/A/lib/python2.3 - PowerPC-only (Panther)
- Quills.framework/Versions/B/lib/python2.3.5 - universal binary (Tiger)
- Quills.framework/Versions/B/lib/python2.5 - universal binary (Leopard)
The library path can be found in a couple of ways (run man dyld for more information on linker search paths):
- Set the DYLD_LIBRARY_PATH environment variable (or an equivalent) before the Python interpreter that imports Quills begins (i.e. use the parent shell). This is why MacTelnet is split into MacTelnet and RunMacTelnet.py.
- Or, use install privilege to put Quills.framework into /Library/Frameworks, the location that the compiled Python interface will use by default.
The module path can also be found in a few ways:
- Set the PYTHONPATH environment variable before the Python interpreter that imports Quills begins (i.e. use the parent shell).
- Or, change the sys.path in your Python script to include the appropriate directory, before you import.
- Or, use install privilege to put the appropriate copy of Quills.py and _Quills.so in a location that Python searches by default. Where this is depends on how Python was built, but it is often a place like /usr/local/lib/pythonX.Y, where X.Y is the base Python version. Since this only saves you from typing one extra line in your Python scripts, you may not want to go to this effort!
Using install privilege to resolve the two paths above is certainly simpler for the script writer, but it introduces a dependency that users of your program must resolve: namely, they must also ensure Quills is installed in all the right places on their computers. To remain portable, MacTelnet.app does not use this approach.