Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

logging.FileHandler diff Py2 v Py3

149 views
Skip to first unread message

Skip Montanaro

unread,
Apr 3, 2018, 11:15:16 AM4/3/18
to
I've encountered a problem in an application I'm porting from Python
2.7 to 3.6. The logginng.FileHandler class likes "/dev/stderr" as a
destination in Python 2, but complains in Python 3.

Python 2.7.14:

>>> import logging
>>> logging.FileHandler("/dev/stderr")
<logging.FileHandler object at 0x7fbbba9bbdd0>

Python 3.6.4:

>>> import logging
>>> logging.FileHandler("/dev/stderr")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/skip/miniconda3/envs/python3/lib/python3.6/logging/__init__.py",
line 1030, in __init__
StreamHandler.__init__(self, self._open())
File "/home/skip/miniconda3/envs/python3/lib/python3.6/logging/__init__.py",
line 1059, in _open
return open(self.baseFilename, self.mode, encoding=self.encoding)
OSError: [Errno 29] Illegal seek

I can see how to work around the error, pass mode="w" when passing
/dev/{stdout,stderr} to the constructor. Shouldn't that bit of
ugliness be hidden in the logging module?

Skip

Peter Otten

unread,
Apr 3, 2018, 12:55:11 PM4/3/18
to
I think the culprit is io.open() rather than the logging module. Why does

>>> io.open("/dev/stderr", "a")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 29] Illegal seek

even try to seek()?

Paul Moore

unread,
Apr 3, 2018, 1:05:11 PM4/3/18
to
On 3 April 2018 at 17:54, Peter Otten <__pet...@web.de> wrote:
> I think the culprit is io.open() rather than the logging module. Why does
>
>>>> io.open("/dev/stderr", "a")
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> OSError: [Errno 29] Illegal seek
>
> even try to seek()?

Because it's append mode so it needs to go to the end?

Paul

Peter Otten

unread,
Apr 3, 2018, 2:19:35 PM4/3/18
to
I expected that to be handled by the C library, and in C there is no error:

$ cat open_stderr_in_appendmode.c
#include <stdio.h>

main()
{
FILE * stderr = fopen("/dev/stderr", "a");
if (stderr == 0)
{
printf("failed\n");
}
else
{
printf("succeded\n");
fprintf(stderr, "\nthis goes to stderr\n");
fclose(stderr);
}
}
$ gcc open_stderr_in_appendmode.c
$ ./a.out
succeded

this goes to stderr

The same goes for Py2's built-in and codecs.open():

$ python
Python 2.7.6 (default, Nov 23 2017, 15:49:48)
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> import io
>>> with open("/dev/stderr", "a") as f: f.write("works\n")
...
works
>>> with codecs.open("/dev/stderr", "a") as f: f.write("works\n")
...
works
>>> with io.open("/dev/stderr", "a") as f: f.write("works\n")
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 29] Illegal seek
>>>

So io.open() really seems to do its own thing, and differently.

Skip Montanaro

unread,
Apr 3, 2018, 5:08:07 PM4/3/18
to
>
> >> I think the culprit is io.open() rather than the logging module. Why
> does
>

Thanks, Peter. It never even occurred to me to look at the source code
around the call. I saw open() and thought "built-in open". I forgot that
the io package supplanted a bunch of lower level i/o.

I'll poke around a little and maybe open a bug report if I can't find any
explanation for the change in behavior.

Skip

>

Skip Montanaro

unread,
Apr 5, 2018, 3:42:25 PM4/5/18
to
> I'll poke around a little and maybe open a bug report if I can't find any
> explanation for the change in behavior.

Turns out to be a known problem with a bit of history:

https://bugs.python.org/issue27805

Skip
0 new messages