0

This code processes directories. It first tries to rename the directory to check if it is in use.

for d in reldir:
    os.rename(d, os.path.join(d + '_'))
    # if original directory name exists, skip to next d
    os.rename(os.path.join(d + '_'), d)

However, the behavior is the problem. I need it to stop processing the directory if the rename fails (not stop the whole script as it currently does). Directories that are not in use are processed correctly. How do I make it skip a directory in use? On batch I could just do exit /b in the for loop. I prefer no output for these skipped directories.

This is the error I get when directory is in use:

Traceback (most recent call last):
  File "D:/SYSTEM/CODING/PYTHON/import.py", line 49, in <module>
    os.rename(d, os.path.join(d + '_'))
PermissionError: [WinError 5] Access is denied: 'Dir1' -> 'Dir1_'

Process finished with exit code 1
Bricktop
  • 533
  • 3
  • 22
  • 1
    How do you know a directory is "in use"? What platform are you running on? – John Szakmeister Sep 07 '19 at 09:43
  • Windows. I have no better method than to try and rename the directory. If you know of a better one please let me know – Bricktop Sep 07 '19 at 09:46
  • 1
    What error do you get when you try and rename it under Windows? – John Szakmeister Sep 07 '19 at 09:47
  • @bigdataolddriver no argument there. Error added to original question – Bricktop Sep 07 '19 at 09:50
  • 1
    try except and final is the way to your original question , as @MrFuppes answered – James Li Sep 07 '19 at 09:51
  • @Bricktop: you could use `os.access(p, os.W_OK)` to see if you can write to the path. however, that doesn't tell you if *any* process is currently accessing the path... can't think of a clean method in Python right now to do that. – FObersteiner Sep 07 '19 at 09:51
  • @MrFuppes I can't imagine a dir could be in use in a way that would prevent writing to it from another process. – Bricktop Sep 07 '19 at 09:53
  • @Bricktop alright, if that satisfies your need - added to my answer. – FObersteiner Sep 07 '19 at 09:57
  • 2
    Right. So, what I was getting at is that there really isn't a good way to see whether something is in use or not. And as pointed about by bigdataolddriver, checking ahead of time is not really helpful as someone could come in and start manipulating things after you have checked--especially on Windows. Windows also has to deal with virus scanners messing stuff up, and they often open the file to scan it and prevent you from operating on it. Some tools go through a lot of pain to make it work well (for instance, Subversion) to deal with that pain. – John Szakmeister Sep 07 '19 at 09:57
  • 1
    Here's what I was referring to in the above comment (Subversion's WIN32_RETRY_LOOP): http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/io.c?revision=1865520&view=markup#l132 – John Szakmeister Sep 07 '19 at 09:58
  • 1
    comment deleted to avoid flaming. AFAIK, windows do not provide a formal way to prevent from "use" a certain directory. the better way in your situation may be a fail-retry-overtime-die manner. – James Li Sep 07 '19 at 10:18
  • 1
    extend: try processing - catch exception to retry - if fails more than certain times - report as timeout - all remaing directories timed out - whole script dies – James Li Sep 07 '19 at 10:27

1 Answers1

1

you could use try / except. However, I should add that I'm with @bigdataolddriver (comments on question) that the method of just renaming a directory seems pretty rude to check if the directory is in use by any process.

for d in reldir:
    try:
        os.rename(d, os.path.join(d + '_'))
    except PermissionError: # directory in use, try unsuccessful
        continue # skip to next iteration
    # do something else if try was successful

If you just need to check if you can write to the directory, use

for d in reldir:
    if os.access(d, os.W_OK):
        # do something

On checking if a file is in use, read e.g. here.

FObersteiner
  • 22,500
  • 8
  • 42
  • 72
  • Can a process really lock an entire directory from being written into? – Bricktop Sep 07 '19 at 09:58
  • not sure! maybe a virus scanner - see JohnSzakmeister's comment under your question – FObersteiner Sep 07 '19 at 10:00
  • 1
    @Bricktop I just scanned a directory with McAfee and `os.access(d, os.W_OK)` still evaluated to `True`. One sample doesn't indicate anything but I'd *assume* a virus scanner on windows would not lock a whole directory. I'd use the os.access method and see if I run into troubles. Then you can still fall back to the rename method. – FObersteiner Sep 07 '19 at 10:29