I was working on the setup.py
for pymssql and was annoyed by the distutils.ccompiler.CCompiler.has_function
function — because it checks whether a C function exists by creating a very simple C program and invoking the compiler and linker and the compiler and linker may emit warnings and errors if the function doesn’t exist and then this shows up in the output of python setup.py install
, etc. so it can confuse users and make users think that something is wrong when there really isn’t. Here’s an example of what I’m talking about:
$ python setup.py install /var/folders/nk/8f8f6wjn7v3b9cb2gjqf6vph0000gp/T/clock_gettimeZdbS70.c:1:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int] main (int argc, char **argv) { ^~~~ /var/folders/nk/8f8f6wjn7v3b9cb2gjqf6vph0000gp/T/clock_gettimeZdbS70.c:2:5: warning: implicit declaration of function 'clock_gettime' is invalid in C99 [-Wimplicit-function-declaration] clock_gettime(); ^ 2 warnings generated. ld: library not found for -lrt clang: error: linker command failed with exit code 1 (use -v to see invocation)
I don’t want users to see linker errors when they install the package and think that something is wrong. This is perfectly normal that -lrt
didn’t work — this is on Mac OS X and it doesn’t have an rt
library and we just detected that so that we don’t try to use it. The user doesn’t need to see these errors though, as it could confuse them.
So I looked for a way to not have the compiler errors displayed on stderr.
I found:
- Stack Overflow: Disabling output when compiling with distutils
- The setup.py from Mercurial (referenced in above Stack Overflow post) has a
hasfunction
function that implements a simplified version ofdistutils.ccompiler.CCompiler.has_function
. But it’s limited — for example you can’t pass alibraries
parameter to it, which happens to be a feature I needed. - Python issue 15805: Add stdout redirection tool to contextlib – some folks in the early stages of talking about adding stuff to the standard library to redirect stdout/stderr
It seemed silly to have to reimplement logic in distutils for compiling code when all we want to do is just suppress error output by redirecting stderr. I thought one could simply call the distutils stuff inside a context manager that redirects stderr.
This is what I came up with — a context manager called stdchannel_redirected
:
Here’s how I use it:
with stdchannel_redirected(sys.stderr, os.devnull): if compiler.has_function('clock_gettime', libraries=['rt']): libraries.append('rt')
I used this in the setup.py
of pymssql — see this commit.
I suspect that this probably exists out there in some other form, so I tweeted about it. Let me know if you know a better way…
Some rumblings about adding context managers for stdout/stderr redirection to the standard library: Python issue 15805: Add stdout redirection tool to contextlib
Pingback: Python:Disabling output when compiling with distutils – IT Sprite
Hi Marc,
Thanks for taking the time to write up your findings. I use it to suppress output from some introspection code that wraps exiv2 — it’s very useful! What license is your snippet under? GPL3 or LGPL?
Damon
The code is public domain. Do what you please.
Pingback: Temporarily Redirect stdout/stderr – PythonCharm
Pingback: Suppress stdout / stderr print from Python functions
Pingback: Temporarily Redirect stdout/stderr - Magenaut
Pingback: Redirigir temporalmente stdout/stderr - Fallosweb.com