file.close()

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Hallvard B Furuseth

    #16
    Re: file.close()

    Francois Pinard wrote:[color=blue]
    > For one, I systematically avoid cluttering my code with unneeded `close'.[/color]

    What happens if close fails during GC? Will it still raise an
    exception? If so, the exception could happen at an unfortunate place in
    the code.

    Um. Explicit close does raise an exception if it fails, right?

    --
    Hallvard

    Comment

    • Paul Rubin

      #17
      Re: file.close()

      bokr@oz.net (Bengt Richter) writes:[color=blue][color=green]
      > >"done" here is a generic method that gets called on exiting a "with"
      > >block.[/color]
      > First reaction == +1, but some questions...
      >
      > 1) Is f.done() really necessary? I.e., doesn't an explicit del f
      > take care of it if the object has been coded with a __del__
      > method? I.e., the idea was to get the effect of CPython's
      > immediate effective del on ref count going to zero, right?[/color]

      The ref count might not be zero. Something inside the "with" block
      might make a new reference and leave it around.
      [color=blue]
      > 2) how about with two files (or other multiple resources)?
      >
      > with f1,f2 = file('f1'), file('f2'):
      > [do stuff with f1 & f2]
      >
      > What is the canonical expansion?[/color]

      I think f1.done and f2.done should both get called.
      [color=blue]
      > Also, what about the attribute version, i.e.,
      >
      > ob.f = file(frob)
      > try:
      > [do stuff with ob.f]
      > finally:
      > del ob.f # calls f.__del__, which calls/does f.close()
      >
      > I.e., ob.f = something could raise an exception (e.g., a read-only property)
      > *after* file(frob) has succeeded. So I guess the easiest would be to limit
      > the left hand side to plain names...[/color]

      The assignment should be inside the try. If I had it on the outside
      before, that was an error.

      Comment

      • Bengt Richter

        #18
        Re: file.close()

        On 25 Jul 2003 13:35:49 -0700, Paul Rubin <http://phr.cx@NOSPAM.i nvalid> wrote:
        [color=blue]
        >bokr@oz.net (Bengt Richter) writes:[color=green][color=darkred]
        >> >"done" here is a generic method that gets called on exiting a "with"
        >> >block.[/color]
        >> First reaction == +1, but some questions...
        >>
        >> 1) Is f.done() really necessary? I.e., doesn't an explicit del f
        >> take care of it if the object has been coded with a __del__
        >> method? I.e., the idea was to get the effect of CPython's
        >> immediate effective del on ref count going to zero, right?[/color]
        >
        >The ref count might not be zero. Something inside the "with" block
        >might make a new reference and leave it around.
        >[/color]
        Aha. In that case, is the del just a courtesy default action?
        [color=blue][color=green]
        >> 2) how about with two files (or other multiple resources)?
        >>
        >> with f1,f2 = file('f1'), file('f2'):
        >> [do stuff with f1 & f2]
        >>
        >> What is the canonical expansion?[/color]
        >
        >I think f1.done and f2.done should both get called.[/color]
        Consistently ;-)
        [color=blue]
        >[color=green]
        >> Also, what about the attribute version, i.e.,
        >>
        >> ob.f = file(frob)
        >> try:
        >> [do stuff with ob.f]
        >> finally:
        >> del ob.f # calls f.__del__, which calls/does f.close()
        >>
        >> I.e., ob.f = something could raise an exception (e.g., a read-only property)
        >> *after* file(frob) has succeeded. So I guess the easiest would be to limit
        >> the left hand side to plain names...[/color]
        >
        >The assignment should be inside the try. If I had it on the outside
        >before, that was an error.[/color]

        Really? Don't you want a failing f = file(frob) exception to skip the finally,
        since f might not even be bound to anything in that case?

        The trouble I was pointing to is having two possible causes for exception, and only
        one of them being of relevance to the file resource.

        Maybe if you wanted to go to the trouble, it could be split something like

        with ob.f = file(frob):
        [do stuff with ob.f]

        becoming

        _tmp = file(frob)
        try:
        ob.f = _tmp
        [ do stuff with ob.f ]
        finally:
        _tmp.done()
        del _tmp
        del ob.f

        Not sure about the order. Plain ob.f.done() would not guarantee a call to _tmp.done(),
        since ob could refuse to produce f, and f could be a wrapper produced during ob.f = _tmp,
        and it might not have a __del__ method etc etc. _tmp is just for some internal temp binding.

        Regards,
        Bengt Richter

        Comment

        • Dennis Lee Bieber

          #19
          Re: file.close()

          Hallvard B Furuseth fed this fish to the penguins on Friday 25 July
          2003 12:51 pm:

          [color=blue]
          > Um. Explicit close does raise an exception if it fails, right?
          >[/color]

          [wulfraed@beasti e wulfraed]$ python
          Python 2.2 (#1, Nov 5 2002, 15:43:24)
          [GCC 2.96 20000731 (Mandrake Linux 8.2 2.96-0.76mdk)] on linux-i386
          Type "help", "copyright" , "credits" or "license" for more information.[color=blue][color=green][color=darkred]
          >>> f = file("t.t","w")
          >>> f.close()
          >>> f.close()
          >>> f[/color][/color][/color]
          <closed file 't.t', mode 'w' at 0x809dc88>[color=blue][color=green][color=darkred]
          >>> del f
          >>> f.close()[/color][/color][/color]
          Traceback (most recent call last):
          File "<stdin>", line 1, in ?
          NameError: name 'f' is not defined[color=blue][color=green][color=darkred]
          >>>[/color][/color][/color]

          Looks like it doesn't care... As long as the file /had/ been opened
          first (doesn't look like the interactive interpreter collected f until
          the del either).


          --[color=blue]
          > =============== =============== =============== =============== == <
          > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
          > wulfraed@dm.net | Bestiaria Support Staff <
          > =============== =============== =============== =============== == <
          > Bestiaria Home Page: http://www.beastie.dm.net/ <
          > Home Page: http://www.dm.net/~wulfraed/ <[/color]

          Comment

          • Erik Max Francis

            #20
            Re: file.close()

            Dennis Lee Bieber wrote:
            [color=blue]
            > Hallvard B Furuseth fed this fish to the penguins on Friday 25 July
            > 2003 12:51 pm:
            >[color=green]
            > > Um. Explicit close does raise an exception if it fails, right?[/color]
            >[/color]
            ...[color=blue]
            > Looks like it doesn't care... As long as the file /had/ been
            > opened
            > first (doesn't look like the interactive interpreter collected f until
            > the del either).[/color]

            I don't think you've demonstrated that; all you've shown is that builtin
            Python file objects make file closing idempotent. You haven't
            demonstrated a case where there actually is an I/O error that occurs
            when .close gets called. In particular, I _really_ don't know what you
            meant to show with this snippet, as it really has nothing to do with
            files at all:
            [color=blue][color=green][color=darkred]
            > >>> f[/color][/color]
            > <closed file 't.t', mode 'w' at 0x809dc88>[color=green][color=darkred]
            > >>> del f
            > >>> f.close()[/color][/color]
            > Traceback (most recent call last):
            > File "<stdin>", line 1, in ?
            > NameError: name 'f' is not defined[/color]

            --
            Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
            __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
            / \ He who knows how to be poor knows everything.
            \__/ Jules Michelet

            Comment

            • Jeff Epler

              #21
              Re: file.close()

              On Sun, Jul 27, 2003 at 04:31:19PM -0700, Erik Max Francis wrote:[color=blue]
              > You haven't
              > demonstrated a case where there actually is an I/O error that occurs
              > when .close gets called.[/color]

              What makes you believe that a Python file object's "close" can never error?
              "close" corresponds to the fclose() function of the C standard library,
              and the manpages have plenty to say on the subject (see below).

              I just created a small filesystem (1000 1k blocks, over half of which
              was used by filesystem overhead) and got Python to do this:[color=blue][color=green][color=darkred]
              >>> f = open("/mnt/tmp/x", "w")
              >>> f.write("x" * (453*1024+511))
              >>> f.close()[/color][/color][/color]
              Traceback (most recent call last):
              File "<stdin>", line 1, in ?
              IOError: [Errno 28] No space left on device

              Curiously enough, this doesn't even print the 'Exception in __del__ ignored' message:[color=blue][color=green][color=darkred]
              >>> f = open("/mnt/tmp/x", "w")
              >>> f.write("x" * (453*1024+511))
              >>> del f[/color][/color][/color]
              even though the failed stdio fclose must still have been called.

              stdio buffering kept the last few bytes of the f.write() from actually
              being sent to the disk, but the f.close() call must dump them to the disk,
              at which time the "disk full" condition is actually seen. While I had
              to contrive this situation for this message, it's exactly the kind of
              thing that will to happen to you when your software is at the customer's
              site and you've left for a month in rural Honduras where there aren't
              any easily-accessible phones, let alone easy internet access.

              Jeff

              [from `man fclose']
              RETURN VALUE
              Upon successful completion 0 is returned. Otherwise, EOF is returned
              and the global variable errno is set to indicate the error. In either
              case any further access (including another call to fclose()) to the
              stream results in undefined behaviour.
              [...]
              The fclose function may also fail and set errno for any of the errors
              specified for the routines close(2), write(2) or fflush(3).

              [from `man close']
              ERRORS
              EBADF fd isn’t a valid open file descriptor.

              EINTR The close() call was interrupted by a signal.

              EIO An I/O error occurred.

              [from `man write']
              ERRORS
              EBADF fd is not a valid file descriptor or is not open for writing.

              EINVAL fd is attached to an object which is unsuitable for writing.

              EFAULT buf is outside your accessible address space.

              EFBIG An attempt was made to write a file that exceeds the implementa-
              tion-defined maximum file size or the process’ filesize limit,
              or to write at a position past than the maximum allowed offset.

              EPIPE fd is connected to a pipe or socket whose reading end is closed.
              When this happens the writing process will also receive aSIG-
              PIPE signal. (Thus, the write return value is seen only ifthe
              program catches, blocks or ignores this signal.)

              EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and the
              write would block.

              EINTR The call was interrupted by a signal before any data was writ-
              ten.

              ENOSPC The device containing the file referred to by fd has no room for
              the data.

              EIO A low-level I/O error occurred while modifying the inode.

              Other errors may occur, depending on the object connected to fd.

              [from `man fflush']
              ERRORS
              EBADF Stream is not an open stream, or is not open for writing.

              The function fflush may also fail and set errno for any of the errors
              specified for the routine write(2).



              Comment

              • Erik Max Francis

                #22
                Re: file.close()

                Jeff Epler wrote:
                [color=blue]
                > On Sun, Jul 27, 2003 at 04:31:19PM -0700, Erik Max Francis wrote:
                >[color=green]
                > > You haven't
                > > demonstrated a case where there actually is an I/O error that occurs
                > > when .close gets called.[/color]
                >
                > What makes you believe that a Python file object's "close" can never
                > error?
                > "close" corresponds to the fclose() function of the C standard
                > library,
                > and the manpages have plenty to say on the subject (see below).[/color]

                I never made any such claim. I was simply countering someone _else_
                making that claim, who used a Python session snippet to try to
                demonstrate it, that they had demonstrated no such thing. He simply
                called the close method twice, which had gave no indication of what he
                was looking for.

                --
                Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
                __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
                / \ What do women want?
                \__/ Sigmund Freud

                Comment

                • Dennis Lee Bieber

                  #23
                  Re: file.close()

                  Erik Max Francis fed this fish to the penguins on Sunday 27 July 2003
                  08:24 pm:
                  [color=blue]
                  > demonstrate it, that they had demonstrated no such thing. He simply
                  > called the close method twice, which had gave no indication of what he
                  > was looking for.
                  >[/color]

                  Which I will blame upon my long history on a system/language where
                  closing a closed file /does/ generate an error...

                  --[color=blue]
                  > =============== =============== =============== =============== == <
                  > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
                  > wulfraed@dm.net | Bestiaria Support Staff <
                  > =============== =============== =============== =============== == <
                  > Bestiaria Home Page: http://www.beastie.dm.net/ <
                  > Home Page: http://www.dm.net/~wulfraed/ <[/color]

                  Comment

                  Working...