5

Context: I am using shutil.rmtree(delDir, ignore_errors = False, onerror = readOnlyErrorHandler) to delete a directory tree that holds readonly files:

Annoyence: PyLint (inside VS Code) marks the raise command inside my readOnlyErrorHandler function as

  • 'The raise statement is not inside an except clause' by pylint (misplaced-bare-raise).

Question: Is there a way around getting this warning without disabling linting for the whole file?

def readOnlyErrorHandler(func, path, exc_info):
  import errno
  if func in (os.rmdir, os.unlink, os.remove) and exc_info[1].errno == errno.EACCES:
    print (f"Retry '{func.__name__}' after chmod 0o777 on '{path}'")
    os.chmod(path, 0o777) 
    func(path)
  else:
    # marked as 'The raise statement is not inside an except clause' 
    # by pylint(misplaced-bare-raise)
    raise  # purpose: rethrow the other errors that brought me here

System: Windows, Python 3.6.3

Test with:

from stat import S_IREAD, S_IRGRP, S_IROTH
import os
import shutil

path = "./some/path/to/files/"

# create read only files:
os.makedirs(path, exist_ok=True) 
for fn in ["one.txt","two.txt"]:
    filename = os.path.join(path, fn)
    with open(filename, "w") as f:
        f.write("read only")
    os.chmod(filename, S_IREAD|S_IRGRP|S_IROTH)

# try to delete files
# fails: shutil.rmtree(path)
# works
shutil.rmtree(path, ignore_errors=False, onerror=readOnlyErrorHandler)
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • 1
    why not `raise ValueError` (or some specific error to your liking)? `raise` alone is meant to reraise the currently caught exception (there is no such exception in your example...). – hiro protagonist Jul 09 '19 at 06:03
  • @hiro I would like to "rethrow" the error that brought me into this function. Taking the information of it from `exc_info` - but that does not work using raise alone. Repackaging exc_info into my error and throwing that sounds ok - I look into it – Patrick Artner Jul 09 '19 at 06:19
  • oh, sorry, did not get that. now i see what you mean... – hiro protagonist Jul 09 '19 at 06:21
  • 1
    @PatrickArtner: While it’s certainly a reasonable implementation strategy; I don’t think it’s part of `rmtree`’s **interface** that the exception it caught is still active during the error handler call. – Davis Herring Jul 09 '19 at 06:28
  • 1
    what about `raise exc_info[1]` then? or `raise exc_info[0]("exception from readOnlyErrorHandler")`? – hiro protagonist Jul 09 '19 at 06:29

1 Answers1

3

you have all the information about the exception that occurred in exc_info. in this case exc_info will be something like

(
    <class 'FileNotFoundError'>, 
    FileNotFoundError(2, 'No such file or directory'), 
    <traceback object at 0x7fae2a66a0c8>
)

so you could either re-raise the exception with

raise exc_info[1]

or customize the error messsge (but keep the type of the exception):

raise exc_info[0]("exception from readOnlyErrorHandler")
hiro protagonist
  • 44,693
  • 14
  • 86
  • 111