[Numpy-discussion] Which Python to use for Mac binaries

Ondřej Čertík ondrej.certik@gmail....
Sat Jan 5 20:21:04 CST 2013


Hi,

Currently the NumPy binaries are built using the pavement.py script,
which uses the following Pythons:

MPKG_PYTHON = {
        "2.5": ["/Library/Frameworks/Python.framework/Versions/2.5/bin/python"],
        "2.6": ["/Library/Frameworks/Python.framework/Versions/2.6/bin/python"],
        "2.7": ["/Library/Frameworks/Python.framework/Versions/2.7/bin/python"],
        "3.1": ["/Library/Frameworks/Python.framework/Versions/3.1/bin/python3"],
        "3.2": ["/Library/Frameworks/Python.framework/Versions/3.2/bin/python3"],
        "3.3": ["/Library/Frameworks/Python.framework/Versions/3.3/bin/python3"],
}

So for example I can easily create the 2.6 binary if that Python is
pre-installed on the Mac box that I am using.
On one of the Mac boxes that I am using, the 2.7 is missing, so are
3.1, 3.2 and 3.3. So I was thinking
of updating my Fabric fab file to automatically install all Pythons
from source and build against that, just like
I do for Wine.

Which exact Python do we need to use on Mac? Do we need to use the
binary installer from python.org?
Or can I install it from source? Finally, for which Python versions
should we provide binary installers for Mac?
For reference, the 1.6.2 had installers for 2.5, 2.6 and 2.7 only for
OS X 10.3. There is only 2.7 version for OS X 10.6.


Also, what is the meaning of the following piece of code in pavement.py:

def _build_mpkg(pyver):
    # account for differences between Python 2.7.1 versions from python.org
    if os.environ.get('MACOSX_DEPLOYMENT_TARGET', None) == "10.6":
        ldflags = "-undefined dynamic_lookup -bundle -arch i386 -arch
x86_64 -Wl,-search_paths_first"
    else:
        ldflags = "-undefined dynamic_lookup -bundle -arch i386 -arch
ppc -Wl,-search_paths_first"
    ldflags += " -L%s" % os.path.join(os.path.dirname(__file__), "build")

    if pyver == "2.5":
        sh("CC=gcc-4.0 LDFLAGS='%s' %s setupegg.py bdist_mpkg" %
(ldflags, " ".join(MPKG_PYTHON[pyver])))
    else:
        sh("LDFLAGS='%s' %s setupegg.py bdist_mpkg" % (ldflags, "
".join(MPKG_PYTHON[pyver])))


In particular, the last line gets executed and it then fails with:

paver dmg -p 2.6
---> pavement.dmg
---> pavement.clean
LDFLAGS='-undefined dynamic_lookup -bundle -arch i386 -arch ppc
-Wl,-search_paths_first -Lbuild'
/Library/Frameworks/Python.framework/Versions/2.6/bin/python
setupegg.py bdist_mpkg
Traceback (most recent call last):
  File "setupegg.py", line 17, in <module>
    from setuptools import setup
ImportError: No module named setuptools


The reason is (I think) that if the Python binary is called explicitly
with /Library/Frameworks/Python.framework/Versions/2.6/bin/python,
then the paths are not setup properly in virtualenv, and thus
setuptools (which is only installed in virtualenv, but not in system
Python) fails to import. The solution is to simply apply this patch:

diff --git a/pavement.py b/pavement.py
index e693016..0c637f8 100644
--- a/pavement.py
+++ b/pavement.py
@@ -449,7 +449,7 @@ def _build_mpkg(pyver):
     if pyver == "2.5":
         sh("CC=gcc-4.0 LDFLAGS='%s' %s setupegg.py bdist_mpkg" %
(ldflags, " ".join(MPKG_PYTHON[pyver])))
     else:
-        sh("LDFLAGS='%s' %s setupegg.py bdist_mpkg" % (ldflags, "
".join(MPKG_PYTHON[pyver])))
+        sh("python setupegg.py bdist_mpkg")

 @task
 def simple_dmg():


and then things work. So an obvious question is --- why do we need to
fiddle with LDFLAGS and paths to the exact Python version? Here is a
proposed simpler version of the build_mpkg() function:

def _build_mpkg(pyver):
        sh("python setupegg.py bdist_mpkg")

Thanks for any tips.

Ondrej


More information about the NumPy-Discussion mailing list