Description of problem: The libvirt Python module writes to stderr on errors by default, which it should not do. Version-Release number of selected component (if applicable): 1.2.1 How reproducible: always Steps to Reproduce: Start with a an empty volume pool called "default". Then, in Python: >>> import libvirt >>> c = libvirt.open('qemu:///system') >>> p = c.storagePoolLookupByName('default') >>> p.storageVolLookupByName('foo') Actual results: The first line in the output was to stderr; generated by the library and not the REPL. libvirt: Storage Driver error : Storage volume not found: no storage vol with matching name 'foo' Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/dist-packages/libvirt.py", line 2937, in storageVolLookupByName if ret is None:raise libvirtError('virStorageVolLookupByName() failed', pool=self) libvirt.libvirtError: Storage volume not found: no storage vol with matching name 'foo' Expected results: Libaries should never write to the terminal directly. I understand that the C library does this, but also provides a way to override error handling, and this capability is passed to Python through libvirt.registerErrorHandler. This makes sense in C, since C doesn't have any other standard method for passing back complex error details. C expects you to DIY, and libvirt has done this. However, in Python, the standard Pythonic way to handle errors is with exceptions only. By the principle of least surprise, I expect all error data to be encapsulated in an exception object, and nothing written to the terminal, by default. An error condition as far as a library is concerned isn't necessarily an error for the application that uses the library. Thus, arbitrary output (from the user's perspective) to the terminal is confusing to the user. As an example: I am using storageVolLookupByName as a test to see if a named volume exists. A negative result of such a test is an error to the library, but not an error to my application. Workaround: After importing libvirt, calling: libvirt.registerErrorHandler(lambda _: None, None) turns off the default behaviour of writing to stderr. Thoughts on implementation The Python bindings could set the C libvirt API's error handler to something that simply saves the error message. When returning from an API call, it could check for a saved error message and instantiate a libvirtError object that includes this information. IMHO, the ability for the caller to set a custom error handler is less useful in Python, since the caller can always catch and handle exceptions instead. However, if you did want to maintain this ability, it would be possible to do so by storing the callback handler outside the C API, and calling it from my proposed handling above.
I totally agree that libraries should not log to stderr by default. Sadly this unfortunate design decision was made in libvirt's past and for reasons of application compatibility we cannot now change it. ie any console applications which are using libvirt and relying on this default mode of error reporting would be broken if we disabled it. Our recommendation is simply that all users of libvirt-python apply the workaround that you've suggested above of setting a no-op error callback, and then just use exceptions which already do the right thing.
My workaround broke when switching to the Python 3 bindings with: TypeError: <lambda>() takes 1 positional argument but 2 were given It seems that the callback is now being called with more arguments. My new workaround is: def noop(*args, **kwargs): pass libvirt.registerErrorHandler(noop, None)