![](https://secure.gravatar.com/avatar/3d5a540f00cbb2cc4e09ae5913fa781a.jpg?s=120&d=mm&r=g)
Oh, here's an example of how easy it is to autoconfigure Python extensions now. This is taken from examples/mxdatetime_setup.py; here're the essentials 'run()' method of the "config_mxDateTime" command class: def run (self): have = {} have['strftime'] = self.check_func('strftime', ['time.h']) have['strptime'] = self.check_func('strptime', ['time.h']) have['timegm'] = self.check_func('timegm', ['time.h']) define = [] undef = [] for name in have.keys(): # ('strftime', 'strptime', 'timegm'): macro_name = 'HAVE_' + string.upper(name) if have[name]: define.append((macro_name, None)) else: undef.append(macro_name) Note that the bulk of the code is the bureaucracy of figuring out which macros to define, ie. generateing HAVE_STRFTIME and friends. Obviously this could (and should) be taken care of by the standard "config" command; we'll get there! Here's the output of "setup.py config" (very noisy because --noisy and --dump-source are both enabled by default for now): running config compiling '_configtest.c': #include <time.h> int main () { strftime; } gcc -c -g -O2 -fPIC _configtest.c -o _configtest.o gcc _configtest.o -o _configtest success! removing: _configtest.c _configtest.o _configtest compiling '_configtest.c': #include <time.h> int main () { strptime; } gcc -c -g -O2 -fPIC _configtest.c -o _configtest.o _configtest.c: In function `main': _configtest.c:4: `strptime' undeclared (first use in this function) _configtest.c:4: (Each undeclared identifier is reported only once _configtest.c:4: for each function it appears in.) failure. removing: _configtest.c _configtest.o compiling '_configtest.c': #include <time.h> int main () { timegm; } gcc -c -g -O2 -fPIC _configtest.c -o _configtest.o gcc _configtest.o -o _configtest success! removing: _configtest.c _configtest.o _configtest macros to define: [('HAVE_STRFTIME', None), ('HAVE_TIMEGM', None)] macros to undefine: ['HAVE_STRPTIME'] Note that ('HAVE_STRFTIME', None) means "-DHAVE_STRFTIME" -- i.e. define the macro without any particular value. No, I don't know why 'strptime()' isn't showing up, but at least it demonstrates a failure case. Greg -- Greg Ward - geek-on-the-loose gward@python.net http://starship.python.net/~gward/ Save energy: be apathetic.
![](https://secure.gravatar.com/avatar/12362ecee4672f1dd2d641ce5b4eca14.jpg?s=120&d=mm&r=g)
Greg Ward wrote:
Oh, here's an example of how easy it is to autoconfigure Python extensions now. This is taken from examples/mxdatetime_setup.py; here're the essentials 'run()' method of the "config_mxDateTime" command class:
def run (self): have = {} have['strftime'] = self.check_func('strftime', ['time.h']) have['strptime'] = self.check_func('strptime', ['time.h']) have['timegm'] = self.check_func('timegm', ['time.h'])
define = [] undef = [] for name in have.keys(): # ('strftime', 'strptime', 'timegm'): macro_name = 'HAVE_' + string.upper(name) if have[name]: define.append((macro_name, None)) else: undef.append(macro_name)
Note that the bulk of the code is the bureaucracy of figuring out which macros to define, ie. generateing HAVE_STRFTIME and friends. Obviously this could (and should) be taken care of by the standard "config" command; we'll get there!
Here's the output of "setup.py config" (very noisy because --noisy and --dump-source are both enabled by default for now):
running config compiling '_configtest.c': #include <time.h>
int main () { strftime; } gcc -c -g -O2 -fPIC _configtest.c -o _configtest.o gcc _configtest.o -o _configtest success! removing: _configtest.c _configtest.o _configtest compiling '_configtest.c': #include <time.h>
int main () { strptime; } gcc -c -g -O2 -fPIC _configtest.c -o _configtest.o _configtest.c: In function `main': _configtest.c:4: `strptime' undeclared (first use in this function) _configtest.c:4: (Each undeclared identifier is reported only once _configtest.c:4: for each function it appears in.) failure. removing: _configtest.c _configtest.o compiling '_configtest.c': #include <time.h>
int main () { timegm; } gcc -c -g -O2 -fPIC _configtest.c -o _configtest.o gcc _configtest.o -o _configtest success! removing: _configtest.c _configtest.o _configtest macros to define: [('HAVE_STRFTIME', None), ('HAVE_TIMEGM', None)] macros to undefine: ['HAVE_STRPTIME']
Note that ('HAVE_STRFTIME', None) means "-DHAVE_STRFTIME" -- i.e. define the macro without any particular value. No, I don't know why 'strptime()' isn't showing up, but at least it demonstrates a failure case.
Because it will only show up if the _XOPEN_SOURCE symbol is defined before including time.h -- weird, I know, but that's gcc... it may be worthwhile to provide such defines to the config functions in some way (or to make them default for gcc in the compiler class, e.g. always define _GNU_SOURCE which enables all of GNU CC's features). -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/
![](https://secure.gravatar.com/avatar/3df7a0217dacea2884ae569429392b5f.jpg?s=120&d=mm&r=g)
Hi, I noticed the following Traceback with bdist_rpm command: Traceback (innermost last): File "setup.py", line 120, in ? data_files = [('share/locale/de/LC_MESSAGES', File "/usr/lib/python1.5/site-packages/distutils/core.py", line 112, in setup dist.run_commands () File "setup.py", line 47, in run_commands self.run_command (cmd) File "/usr/lib/python1.5/site-packages/distutils/dist.py", line 788, in run_command cmd_obj.run () File "/usr/lib/python1.5/site-packages/distutils/command/install.py", line 474, in run outputs[counter] = outputs[counter][root_len:] TypeError: unsliceable object Bad exit status from /var/tmp/rpm-tmp.56627 (%install) error: command 'rpm' failed with exit status 1 Reason is that file_util.py:copy_file does not return the copyied file name any more (it used to I think) but instead a boolean value for successful copying. This is not good because it breaks the get_outputs() functions of install commands (see the above traceback). For example get_outputs() of install_data looks like [0, 0, 0]. I suggest that you change back to the old behaviour: if copy_file fails, throw an exception else return target file name (even if you copied nothing because the target file was newer) Bastian Kleineidam
![](https://secure.gravatar.com/avatar/3d5a540f00cbb2cc4e09ae5913fa781a.jpg?s=120&d=mm&r=g)
On 22 June 2000, Bastian Kleineidam said:
I noticed the following Traceback with bdist_rpm command: Traceback (innermost last): [...] File "/usr/lib/python1.5/site-packages/distutils/command/install.py", line 474, in run outputs[counter] = outputs[counter][root_len:] TypeError: unsliceable object Bad exit status from /var/tmp/rpm-tmp.56627 (%install) error: command 'rpm' failed with exit status 1
Reason is that file_util.py:copy_file does not return the copyied file name any more (it used to I think) but instead a boolean value for successful copying.
~#@!$^~@#@#%!#^$#! My mistake: I got confused over copy_file's interface, obviously.
I suggest that you change back to the old behaviour: if copy_file fails, throw an exception else return target file name (even if you copied nothing because the target file was newer)
That assumes that I changed the interface to return boolean arbitrarily. I did not: I believe there is code that depends on it returning boolean. And now there is also code that depends on it returning the output filename. Damn! Time to grep the source for copy_file and see how it's *really* used... (and also time to write those regression tests!) Greg -- Greg Ward - nerd gward@python.net http://starship.python.net/~gward/ A man wrapped up in himself makes a very small package.
![](https://secure.gravatar.com/avatar/3d5a540f00cbb2cc4e09ae5913fa781a.jpg?s=120&d=mm&r=g)
On 22 June 2000, I spoke too soon:
That assumes that I changed the interface to return boolean arbitrarily. I did not: I believe there is code that depends on it returning boolean. And now there is also code that depends on it returning the output filename. Damn! Time to grep the source for copy_file and see how it's *really* used...
Well, from poking through the CVS logs, it appears that 'copy_file()' has *always* returned boolean. And from scanning the source, it appears that no code actually expects it to return boolean -- the only bits that pays attention to the return value are my recent additions that use 'copy_file()'s supposed string return value to build list of files copied. So, Bastian's patch is exactly the right thing. (Except you forgot to fix the docstring! Don't worry, I did it.) Applied, checked in, and now maybe things will work again. Greg -- Greg Ward - geek-at-large gward@python.net http://starship.python.net/~gward/ The NSA. We care: we listen to our customers.
![](https://secure.gravatar.com/avatar/3df7a0217dacea2884ae569429392b5f.jpg?s=120&d=mm&r=g)
Hello, apply this patch to make copy_file return the target file instead of 0/1: diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/file_util.py distutils/distutils/file_util.py --- distutils.orig/distutils/file_util.py Sat May 20 18:05:34 2000 +++ distutils/distutils/file_util.py Thu Jun 22 02:27:45 2000 @@ -123,7 +123,7 @@ if update and not newer (src, dst): if verbose: print "not copying %s (output up-to-date)" % src - return 0 + return dst try: action = _copy_action[link] @@ -137,7 +137,7 @@ print "%s %s -> %s" % (action, src, dst) if dry_run: - return 1 + return dst # On a Mac, use the native file copy routine if os.name == 'mac': @@ -171,7 +171,7 @@ if preserve_mode: os.chmod (dst, S_IMODE (st[ST_MODE])) - return 1 + return dst # copy_file ()
![](https://secure.gravatar.com/avatar/3df7a0217dacea2884ae569429392b5f.jpg?s=120&d=mm&r=g)
Hello, the bdist_win command did not call self.reinitialize_command. Patch follows. Bastian Kleineidam diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/command/bdist_wininst.py distutils/distutils/command/bdist_wininst.py --- distutils.orig/distutils/command/bdist_wininst.py Tue Jun 27 03:24:38 2000 +++ distutils/distutils/command/bdist_wininst.py Tue Jun 27 10:22:09 2000 @@ -70,9 +70,11 @@ # options on it! (The option we set, 'root', is so that we can do # a proper "fake install" using this install command object.) install = self.distribution.get_command_obj('install') + self.reinitialize_command(install) install.root = self.bdist_dir install_lib = self.distribution.get_command_obj('install_lib') + self.reinitialize_command(install_lib) install_lib.compile = 0 install_lib.optimize = 0
participants (3)
-
Bastian Kleineidam
-
Greg Ward
-
M.-A. Lemburg