Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #38152 > unrolled thread

Re: autoflush on/off

Started byJabba Laci <jabba.laci@gmail.com>
First post2013-02-05 01:09 +0100
Last post2013-02-05 12:59 +0100
Articles 3 — 3 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: autoflush on/off Jabba Laci <jabba.laci@gmail.com> - 2013-02-05 01:09 +0100
    Re: autoflush on/off Ulrich Eckhardt <ulrich.eckhardt@dominolaser.com> - 2013-02-05 09:04 +0100
      Re: autoflush on/off Piet van Oostrum <piet@vanoostrum.org> - 2013-02-05 12:59 +0100

#38152 — Re: autoflush on/off

FromJabba Laci <jabba.laci@gmail.com>
Date2013-02-05 01:09 +0100
SubjectRe: autoflush on/off
Message-ID<mailman.1342.1360023018.2939.python-list@python.org>
Hi,

Thanks for the answers. I like the context manager idea but setting
the sys.stdout back to the original value doesn't work.

Example:

class Unbuff(object):
    def __init__(self):
        self.stdout_bak = sys.stdout

    def __enter__(self):
        sys.stdout.flush()
        sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

    def __exit__(self, exc_type, exc_val, exc_tb):
        sys.stdout = self.stdout_bak

####

with Unbuff():
        for i in range(5):
            sys.stdout.write('.')
            sleep(.5)
#
sys.stdout.write('EXIT')    # provokes an error


The problem is in __exit__ when sys.stdout is pointed to the old
value. sys.stdout.write doesn't work from then on. Output:

.....close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr

Laszlo


> Write a context manager class. See Library manual, 4.11. Context Manager
> Types. The __enter__ method would be much like the above except that is
> should save the old stdout object 'oldstdout = sys.stdout' instead of
> fiddling with 'autoflush_on'. Then __exit__ would simply be 'sys.stdout =
> oldstdout'. Drop autoflush_on.  Your context manager should not care about
> the existing buffering other than to restore it on exit. Saving and
> restoring the existing stdout object does that.
>
> --
> Terry Jan Reedy
>
> --
> http://mail.python.org/mailman/listinfo/python-list

[toc] | [next] | [standalone]


#38177

FromUlrich Eckhardt <ulrich.eckhardt@dominolaser.com>
Date2013-02-05 09:04 +0100
Message-ID<a1r6u9-78o.ln1@satorlaser.homedns.org>
In reply to#38152
Am 05.02.2013 01:09, schrieb Jabba Laci:
> I like the context manager idea

There is a helper library for constructing context managers, see 
http://docs.python.org/2/library/contextlib.html. That would have made 
your code even shorter.



> setting the sys.stdout back to the original value doesn't work.
[...]
> The problem is in __exit__ when sys.stdout is pointed to the old
> value. sys.stdout.write doesn't work from then on. Output:
>
> .....close failed in file object destructor:
> sys.excepthook is missing
> lost sys.stderr

Argh! Yes, the newly-created file object takes ownership of the 
filedescriptor. Once done with it, it invokes close() on it, making it 
unusable for the original sys.stdout.

Okay, other approach: I believe that the only function regularly called 
on sys.stdout is write(). Just write a replacement that forwards the 
data to the original, followed by a call to flush. If you are ambitious, 
forward any other call to sys.stdout directly by catching attribute 
lookup (__getattribute__) in your class.

Good luck!

Uli

[toc] | [prev] | [next] | [standalone]


#38183

FromPiet van Oostrum <piet@vanoostrum.org>
Date2013-02-05 12:59 +0100
Message-ID<m2zjzjas3o.fsf@cochabamba.vanoostrum.org>
In reply to#38177
Ulrich Eckhardt <ulrich.eckhardt@dominolaser.com> writes:

> Am 05.02.2013 01:09, schrieb Jabba Laci:

>> setting the sys.stdout back to the original value doesn't work.
> [...]
>> The problem is in __exit__ when sys.stdout is pointed to the old
>> value. sys.stdout.write doesn't work from then on. Output:
>>
>> .....close failed in file object destructor:
>> sys.excepthook is missing
>> lost sys.stderr
>
> Argh! Yes, the newly-created file object takes ownership of the
> filedescriptor. Once done with it, it invokes close() on it, making it
> unusable for the original sys.stdout.

That can be solved with a dup.

import os, sys

class Unbuff(object):
    def __enter__(self):
        sys.stdout.flush()
        self.stdout_bak = sys.stdout
        sys.stdout = os.fdopen(os.dup(sys.stdout.fileno()), 'w', 0)

    def __exit__(self, exc_type, exc_val, exc_tb):
        sys.stdout = self.stdout_bak

-- 
Piet van Oostrum <piet@vanoostrum.org>
WWW: http://pietvanoostrum.com/
PGP key: [8DAE142BE17999C4]

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web