Lisandro Dalcin wrote:
On Thu, May 7, 2009 at 11:10 AM, Robert <[email protected]> wrote:
On Windows in distutils/distutils.cfg MingW is set instead of VC
default

[build]
compiler = mingw32


works well with extensions, including setup.py-method for building
Cython modules. But it fails with pyximport method.
Is this a bug - or how to tell using the MingW compiler?


I would not say it is a bug, but rather a consequence of the
implementation of pyximport.

Likely a call to  "dist.parse_config_files()" should be added just
before "dist.parse_command_line()" in pyximport/pyxbuild.py

However, if you do this, a "setup.cfg" file will be parse if present
in $PWD... This could be seen as a gotcha, or as a feature...


Thanks,

in attachment my patch so far to:

* only load the global distutils.cfg
* extend the .pyxbld scheme for enabling custom setup() args
* speed up import pyximport;pyximport.install() for use in auto startup files (by late imports). It was quite slowing down python startup crucially.

Maybe its interesting for sb else too, or for general.
Didn't find into http://trac.cython.org/cython_trac/ so far.

Robert
Only in .: __init__.pyc
diff -u ../pyximport.orig\pyxbuild.py .\pyxbuild.py
--- ../pyximport.orig\pyxbuild.py       Fri Apr 03 01:52:00 2009
+++ .\pyxbuild.py       Fri May 08 11:39:52 2009
@@ -6,7 +6,6 @@
 import os
 import sys
 
-import distutils
 from distutils.dist import Distribution
 from distutils.errors import DistutilsArgError, DistutilsError, CCompilerError
 from distutils.extension import Extension
@@ -16,11 +15,10 @@
     HAS_CYTHON = True
 except ImportError:
     HAS_CYTHON = False
-import shutil
 
 DEBUG = 0
 def pyx_to_dll(filename, ext = None, force_rebuild = 0,
-               build_in_temp=False, pyxbuild_dir=None):
+               build_in_temp=False, pyxbuild_dir=None, setup_args={}):
     """Compile a PYX file to a DLL and return the name of the generated .so 
        or .dll ."""
     assert os.path.exists(filename), "Could not find %s" % 
os.path.abspath(filename)
@@ -46,7 +44,11 @@
         args.append("--force")
     if HAS_CYTHON and build_in_temp:
         args.append("--pyrex-c-in-temp")
-    dist = Distribution({"script_name": None, "script_args": args})
+    sargs=setup_args.copy()
+    sargs.update(
+        {"script_name": None,
+         "script_args": args + setup_args.get("script_args",[])} )
+    dist = Distribution(sargs)
     if not dist.ext_modules:
         dist.ext_modules = []
     dist.ext_modules.append(ext)
@@ -55,6 +57,13 @@
     build = dist.get_command_obj('build')
     build.build_base = pyxbuild_dir
 
+    # use global distutils.cfg only
+    cfgfiles = []
+    sys_dir = os.path.dirname(sys.modules['distutils'].__file__)
+    sys_file = os.path.join(sys_dir, "distutils.cfg")
+    if os.path.isfile(sys_file):
+        cfgfiles.append(sys_file)
+    dist.parse_config_files(cfgfiles)   # distutils/distutils.cfg; not 
./pydistutils.cfg; ./setup.cfg; 
     try:
         ok = dist.parse_command_line()
     except DistutilsArgError:
Only in .: pyxbuild.py.opt
Only in .: pyxbuild.pyc
Only in .: pyxi.patch
diff -u ../pyximport.orig\pyximport.py .\pyximport.py
--- ../pyximport.orig\pyximport.py      Fri Apr 03 01:52:00 2009
+++ .\pyximport.py      Fri May 08 12:03:42 2009
@@ -14,6 +14,22 @@
 sitecustomize.py with only those two lines at
 /usr/local/lib/python2.3/site-packages/sitecustomize.py .
 
+A custom distutils.core.Extension instance and setup() args
+(Distribution) for for the build can be defined by a <modulename>.pyxbld
+file like:
+
+# examplemod.pyxbdl
+def make_ext(modname, pyxfilename):
+    from distutils.extension import Extension
+    return Extension(name = modname,
+                     sources=[pyxfilename, 'hello.c'],
+                     include_dirs=['/myinclude'] )
+def make_setup_args():
+    return dict(script_args=["--compiler=mingw32"])
+
+Extra dependencies can be defined by a <modulename>.pyxdep .
+See README.
+
 Since Cython 0.11, the :mod:`pyximport` module also has experimental
 compilation support for normal Python modules.  This allows you to
 automatically run Cython on every .pyx and .py module that Python
@@ -34,14 +50,9 @@
 import os
 import glob
 import imp
-import pyxbuild
-from distutils.dep_util import newer
-from distutils.extension import Extension
-
-try:
-    import hashlib
-except ImportError:
-    import md5 as hashlib
+##import pyxbuild  # changed: late import for speed
+##from distutils.dep_util import newer
+##from distutils.extension import Extension
 
 mod_name = "pyximport"
 
@@ -64,30 +75,43 @@
     "Load a pyrex file given a name and filename."
 
 def get_distutils_extension(modname, pyxfilename):
-    extra = "_" + hashlib.md5(open(pyxfilename).read()).hexdigest()  
+#    try:
+#        import hashlib
+#    except ImportError:
+#        import md5 as hashlib
+#    extra = "_" + hashlib.md5(open(pyxfilename).read()).hexdigest()  
 #    modname = modname + extra
-    extension_mod = handle_special_build(modname, pyxfilename)
+    extension_mod,setup_args = handle_special_build(modname, pyxfilename)
     if not extension_mod:
+        from distutils.extension import Extension
         extension_mod = Extension(name = modname, sources=[pyxfilename])
-    return extension_mod
+    return extension_mod,setup_args
 
 def handle_special_build(modname, pyxfilename):
     special_build = os.path.splitext(pyxfilename)[0] + PYXBLD_EXT
-
-    if not os.path.exists(special_build): 
-        ext = None
-    else:
-        globls = {}
-        locs = {}
+    ext = None
+    setup_args={}
+    if os.path.exists(special_build): 
+        # globls = {}
+        # locs = {}
         # execfile(special_build, globls, locs)
         # ext = locs["make_ext"](modname, pyxfilename)
         mod = imp.load_source("XXXX", special_build, open(special_build))
-        ext = mod.make_ext(modname, pyxfilename)
-        assert ext and ext.sources, ("make_ext in %s did not return Extension" 
-                                     % special_build)
+        make_ext = getattr(mod,'make_ext')
+        if make_ext:
+            ext = make_ext(modname, pyxfilename)
+            assert ext and ext.sources, ("make_ext in %s did not return 
Extension" 
+                                         % special_build)
+        make_setup_args = getattr(mod,'make_setup_args')
+        if make_setup_args:
+            setup_args = make_setup_args()
+            assert isinstance(setup_args,dict), ("make_setup_args in %s did 
not return a dict" 
+                                         % special_build)
+        assert set or setup_args, ("neither make_ext nor make_setup_args %s" 
+                                         % special_build)
         ext.sources = [os.path.join(os.path.dirname(special_build), source) 
                        for source in ext.sources]
-    return ext
+    return ext, setup_args
 
 def handle_dependencies(pyxfilename):
     dependfile = os.path.splitext(pyxfilename)[0] + PYXDEP_EXT
@@ -116,6 +140,7 @@
         # the pyx file, 'touch' the pyx file so that distutils will
         # be tricked into rebuilding it.
         for file in files:
+            from distutils.dep_util import newer
             if newer(file, pyxfilename):
                 print "Rebuilding because of ", file
                 filetime = os.path.getmtime(file)
@@ -127,11 +152,13 @@
         "Path does not exist: %s" % pyxfilename)
     handle_dependencies(pyxfilename)
 
-    extension_mod = get_distutils_extension(name, pyxfilename)
+    extension_mod,setup_args = get_distutils_extension(name, pyxfilename)
 
+    import pyxbuild
     so_path = pyxbuild.pyx_to_dll(pyxfilename, extension_mod,
                                   build_in_temp=True,
-                                  pyxbuild_dir=pyxbuild_dir)
+                                  pyxbuild_dir=pyxbuild_dir,
+                                  setup_args=setup_args )
     assert os.path.exists(so_path), "Cannot find: %s" % so_path
 
     junkpath = os.path.join(os.path.dirname(so_path), name+"_*")
@@ -171,10 +198,10 @@
             print "SEARCHING", fullname, package_path
         if '.' in fullname:
             mod_parts = fullname.split('.')
-            package = '.'.join(mod_parts[:-1])
+            #package = '.'.join(mod_parts[:-1])
             module_name = mod_parts[-1]
         else:
-            package = None
+            #package = None
             module_name = fullname
         pyx_module_name = module_name + self.extension
         # this may work, but it returns the file content, not its path
Only in .: pyximport.py.opt
Only in .: pyximport.pyc
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to