TypeError while checking for permissions with os.access() on windows xp

Dave Angel davea at ieee.org
Sat Aug 22 19:36:12 CEST 2009


ryniek90 wrote:
> <div class="moz-text-flowed" style="font-family: -moz-fixed">
>> First, some nitpicking: Include the whole traceback when posting about
>> errors please.  Don't write "if some_boolean_expression != True:"
>> instead prefer "if not some_boolean_expression:".  Also, in your code
>> "except (Except), ex: return ex" the parentheses are redundant,
>> there's no "Except" Exception (unless you created one yourself) and
>> why are you catching and returning the Exception object?  (Also,
>> what's that "sys.exit(0)" doing in there? And why exit with 0 if there
>> was a problem? Exit code 0 means "no problem".)
>>
>>
>> Second, from what you've said backup_dest must be None:
>>
>>  
>>>>> import os
>>>>> os.access(None, os.W_OK)
>>>>>         
>>
>> Traceback (most recent call last):
>>   File "<pyshell#1>", line 1, in <module>
>>     os.access(None, os.W_OK)
>> TypeError: coercing to Unicode: need string or buffer, NoneType found
>>
>>   
>
> No, backup_dest is destination for backup. It's this variable: 
> *backup_dest = self.__backup_dest* .
> *self.__backup_dest = os.getenv('HOME')*  -  as you can see, 
> self.__backup_dest is a reference to the home directory which is a 
> string. Then backup_dest is a reference to the variable 
> self.__backup_dest. But that second reference seems to be recognised 
> as a NoneType ??
>
> I'm using optparse in my script (that code for checking for permission 
> is a part of my backup script).
>
> Maybe i post my complete code:
> "
> #!/usr/bin/env python
> #-*- coding: utf-8 -*-
> #MyBackUper
>
> import os, sys, tarfile
> import datetime
> from optparse import OptionParser
>
>
> class Except(Exception):
>    pass
>
>
> class Packer(Except):
>
>    def __init__(self):
>        self.__backup_dest = os.getenv('HOME')
>        __current_time = datetime.datetime.today().strftime('%Y-%m-%d 
> %H:%M:%S')
>        Except.__init__(self)
>
>    def doc_note(self):
>
>        print """
>
>        DOCUMENTATION
>
>        'Backuper' is a script for doing backups.
>        You can backup with it single files or whole directories.
>        For available commands type 'backuper.py -h' or 'backuper.py 
> --help'.
>
>        Using it is simple:
>
>        - to backup single file, type:
>        'backuper.py -f FILE_PATH BCKP_NAME [DEST_PATH]',
>        where 'FILE_PATH' is exact path to prefered file which you want 
> to backup and 'BCKP_NAME' is the name for backup output file. Default 
> 'DEST_PATH' is placed in home directory, it can't be changed. 
> 'BCKP_NAME' must be given;
>
>        - to backup whole directory, type:
>        'backuper.py -d DIR_PATH BCKP_NAME [DEST_PATH]', where 
> 'DIR_PATH' is exact path to prefered directory, which you want to 
> backup and 'BCKP_NAME' is the name for backup output file. Default 
> 'DEST_PATH' is placed in home directory, it can't be changed. 
> 'BCKP_NAME' must be given;
>
>        """
>
>    def __check_set_perm(self, rd_obj_path, backup_dest):
>
>        try:
>
>            if os.path.exists(rd_obj_path):
>                if not os.access(rd_obj_path, os.R_OK):
>                    print "Have no permissions on [%s] for reading 
> operation.\nTrying to set them..." % os.path.split(rd_obj_path)[1]
>                    if not os.path.isdir(rd_obj_path):
>                        os.chmod(rd_obj_path, stat.S_IREAD)
>                    else:
>                        for root, dirs, files in os.walk(rd_obj_path):
>                            for f in files:
>                                os.chmod(os.path.join(root, f), 
> stat.S_IREAD)
>                    print "Get permissions for reading on [%s] 
> successfully." % os.path.split(rd_obj_path)[1]
>                else:
>                    print "Have permissions on [%s] for reading." % 
> os.path.split(rd_obj_path)[1]
>
>                if not os.access(backup_dest, os.W_OK):
>                    print "Have no permissions on [%s] for writing 
> operation.\nTrying to set them..." % os.path.split(backup_dest)[1]
>                    os.chmod(backup_dest, stat.S_IWRITE)
>                    print "Get permissions for reading on [%s] 
> successfully." % os.path.split(backup_dest)[1]
>                else:
>                    print "Have permissions on [%s] for writing." % 
> os.path.split(backup_dest)[1]
>            else:
>                return "Can't find specified path - [%s]." % rd_obj_path
>                sys.exit(1)
>
>        except (Except), ex:
>            return ex
>
>
>    def backup_file(self, rd_obj_path, bkp_obj_name):
>
>        try:
>
>            if os.name == "nt":
>                rd_obj_path = rd_obj_path.replace('~/', '%s\\' % 
> os.getenv('HOME')).replace('\\', '\\\\')
>                backup_dest = self.__backup_dest
>                print "Checking permissions for reading and writing..."
>                self.__check_set_perm(rd_obj_path, backup_dest)
>                backup_obj = tarfile.open("%s\\%s(%s).tar.bz2" % 
> (backup_dest, bkp_obj_name, __current_time), 'w:bz2')
>
>            else:
>                rd_obj_path = rd_obj_path.replace('~/', '%s/' % 
> os.getenv('HOME'))
>                backup_dest = self.__backup_dest
>                print "Checking permissions for reading and writing..."
>                self.__check_set_perm(rd_obj_path, backup_dest)
>                backup_obj = tarfile.open("%s/%s(%s).tar.bz2" % 
> (backup_dest, bkp_obj_name, __current_time), 'w:bz2')
>
>            print "Preparing for backup [%s]..." % 
> os.path.split(rd_obj_path)[1]
>            print "Starting backup..."
>            read_obj = open(rd_obj_path, 'rb')
>            print "Now adding [%s]..." % os.path.split(rd_obj_path)[1]
>            backup_obj.add(read_obj.read())
>            read_obj.close(), backup_obj.close()
>            print "Backup [%s] made successfully. :-)" % 
> os.path.split(backup_dest)[1]
>
>        except (Except), ex:
>            return ex
>
>    def backup_dir(self, rd_obj_path, bkp_obj_name):
>
>        try:
>
>            if os.name == "nt":
>                rd_obj_path = rd_obj_path.replace('~/', '%s\\' % 
> os.getenv('HOME')).replace('\\', '\\\\')
>                backup_dest = self.__backup_dest
>                print "Checking permissions for reading and writing..."
>                self.__check_set_perm(rd_obj_path, backup_dest)
>                backup_obj = tarfile.open("%s\\%s(%s).tar.bz2" % 
> (backup_dest, bkp_obj_name, __current_time), 'w:bz2')
>
>            else:
>                rd_obj_path = rd_obj_path.replace('~/', '%s/' % 
> os.getenv('HOME'))
>                backup_dest = self.__backup_dest
>                print "Checking permissions for reading and writing..."
>                self.__check_set_perm(rd_obj_path, backup_dest)
>                backup_obj = tarfile.open("%s/%s(%s).tar.bz2" % 
> (backup_dest, bkp_obj_name, __current_time), 'w:bz2')
>
>            print "Preparing for backup '%s'..." % 
> os.path.split(rd_obj_path)[1]
>            print "Gathering files for backup..."
>            path_list = []
>            for root, dirs, files in os.walk(rd_obj_path):
>                for f in files:
>                    path_list.append(os.path.join(root, f))
>            print "Starting backup..."
>            for p in path_list:
>                fl = open(p, 'rb')
>                print "Now adding [%s] from [%s] directory" % 
> (os.path.split(p)[1], os.path.split(p)[0])
>                backup_obj.add(fl.read())
>                fl.close()
>                print "Added [%s] successfully" % os.path.split(p)[1]
>            backup_obj.close()
>            print "Backup [%s] made successfully. :-)" % 
> os.path.split(backup_dest)[1]
>
>        except (Except), ex:
>            return ex
>
>
> class ParseIt(object):
>
>    def __init__(self):
>        self.__initial = True
>
>    _usage = "usage: %prog [options] Arg1 Arg2"
>    parser = OptionParser(_usage)
>    parser.add_option("-f", "--file", action="store", type="string", 
> dest="filename", help="Make backup of a single file", 
> metavar="FILE_PATH CKP_NAME", nargs=2)
>    parser.add_option("-d", "--dir", action="store", type="string", 
> dest="dirname", help="Recursively backup a whole directory", 
> metavar="DIR_PATH BCKP_NAME", nargs=2)
>    parser.add_option("-i", "--info", dest="info_note", 
> action="store_true", help="Show script's documentation")
>
>    (options, args) = parser.parse_args()
>
> def main_meth():
>    paq = Packer()
>    pars = ParseIt()
>    if pars.options.filename:
>        paq.backup_file(pars.options.filename[0], 
> pars.options.filename[1])
>    elif pars.options.dirname:
>        paq.backup_dir(pars.options.dirname[0], pars.options.dirname[1])
>    elif pars.options.info_note:
>        paq.doc_note()
>
>
> if __name__ == "__main__":
>    main_meth()
>
> "
>
>
>
> </div>
>
I don't know why you didn't immediately add a print statement just 
before the failing os.access(), once you saw the error message.  You 
could have printed out both the formal parameter and the instance attribute.

Simple explanation:  you probably don't have an environment variable 
named "HOME".  I don't either, on Windows.  You need to test for that, 
and put some error handling, so the lack of an environment variable 
won't crash your program.

 > Then backup_dest is a reference to the variable self.__backup_dest. 
But that second reference seems to be recognised as a NoneType ??

backup_dest is a local variable which is a reference to whatever object 
self.__backup_dest referenced.  That could be a very different thing.  
But in this case the subtlety isn't important -- they're both 
referencing None, which is the object returned by os.getenv() when the 
requested environment variable doesn't exist.

DaveA




More information about the Python-list mailing list