[Tutor] Cannot fix OSError

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Fri Jan 30 21:26:10 EST 2004



On Sat, 31 Jan 2004, Nick Lunt wrote:

> Hi Folks,
>
> this is my first posting to the list, although I have been snooping for
> a couple of weeks ;)
>
> I've recently started to learn Python and so far I'm having great fun.
>
> Anyway, here's my problem, first off here's the program:
>
> # code
> import tarfile, sys, os
>
> if len(sys.argv) <= 2:
>         print 'Error:', sys.argv[0], ' <tarfile.tar> <list of files>
>         sys.exit(1)
>
> tfile = sys.argv[1]
>
> totar = []
> for f in sys.argv[2:]:
>         if os.access(f, os.R_OK): # NOTE1
>                 totar.append(f)
>         else:
>                 print 'Could not access', f, 'to tar'
>
>
> tf = tarfile.TarFile(tfile, 'w')
> for f in totar:
>         tf.add(f)
>
> tf.close
>
> # end code



Hmmm... there are a few lines that need to be fixed, but I don't see yet
how they would contribute to the bug.  *grin*


The last statement:

> tf.close

needs to include the open and close parens: functions fire off only in the
presence of parentheses.




> I could trap it in a try/except OSError block, but I'd like to know why
> the line NOTE1 does not simply cause the program to skip the unreadable
> file and continue ?
>
> From the python interpreter 'os.access('/file/i/cant/read', os.R_OK)'
> returns False so I expected my 'if' on line NOTE1 to sort that out.


Agreed; from the code, I don't see anything else wrong with it...


Oh!  Here is one possibility: the files listed in sys.argv[2:] may be
directories.  It's possible that tarfile.TarFile.add() can take in either
directories or filenames.  That is, the directory

    /etc

might be listed in sys.argv[2:], and technically speaking, '/etc' is
completely readable.  But if tarfile recursively dives into a directory,
it might run into:

    /etc/skel/tmp

and run into problems tarring that file.  The test for readability in the
code you've written only looks at the files explicitely listed on the
command line.


The documentation of tarfile.TarFile.add() in:

    http://www.python.org/doc/lib/module-tarfile.html

does imply that it will recursively dive into directories.  Does this make
sense?



Here's a slightly revised version of the code, where the
readability-filtering is doing in a separate function:


###
import tarfile, sys, os

def main():
    if len(sys.argv) <= 2:
        print 'Error:', sys.argv[0], ' <tarfile.tar> <list of files>
        sys.exit(1)
    tfile = sys.argv[1]
    totar = filter_for_readables(sys.argv[2:])

    tf = tarfile.TarFile(tfile, 'w')
    for f in totar:
        tf.add(f)
    tf.close()


def filter_for_readables(files):
    filtered_files = []
    for f in files:
        if os.access(f, os.R_OK):
            filtered_files.append(f)
        else:
            print 'Could not access', f, 'to tar'
    return filtered_files


if __name__ == '__main__':
    main()
###



The function reorganization here isn't just for show, but should make it
easier to test and experiment with the code, since you'll be able to do
things like:

###
>>> import tar
>>> tar.filter_for_readables(some_file)
###

from the interactive interpreter.


Anyway, to fix the bug, you may need to take some precautions and expand
out every directory name in sys.argv[2:] to the actual files that you want
to tar up.  That is, you may need to process sys.argv[2:] so that tarfile
doesn't dive into directories on its own.

The os.walk() function may be helpful for you:

    http://www.python.org/doc/lib/module-tarfile.html


If you have more questions, please feel free to ask.  Good luck!




More information about the Tutor mailing list