pythonpython-3.xeasygui

How to pass path variables correctly?


This looks for a file indirsavefile.txt and if found reads the single directory path stored inside to the indir variable. If that directory exists it tried to enter that directory.

If no indirsavefile.txt is found, or if the path written inside is not found, it opens a directory chooser dialog, the result of which it tries to save as the new indir variable.

import os

from os import path
indirsavefile = path.expandvars(r'%APPDATA%\lootbot\indirsavefile.txt')
print(indirsavefile)
print("proceeding to conditional...")

if os.path.isfile(indirsavefile):
    print("indirsavefile.txt found")
    # not sure what "r" is here for
    with open(indirsavefile, "r") as loadsavefile:
        indir = loadsavefile.readlines()
        print("marker1")
        if not os.path.isdir(indir):
            print("marker2")
            import easygui
            indir = print(easygui.diropenbox("Locate your DOWNLOADS directory root"))
else:
    print("indirsavefile.txt not found")
    import easygui
    indir = print(easygui.diropenbox("Locate your DOWNLOADS directory root"))
    # here save the new indir location to indirsavefile.txt

print("resulting indir location is:")
print(indir)
print("proceed to enter directory...")

os.chdir(indir)
print("Current working directory is",os.getcwd())

There are some extraneous print statements to help me track down bugs, sorry about that. When the savefile is found, I get this

Traceback (most recent call last):
  File "D:/SYSTEM/CODING/PYTHON/import.py", line 14, in <module>
    if not os.path.isdir(indir):
TypeError: _isdir: path should be string, bytes or os.PathLike, not list
C:\Users\Administrator\AppData\Roaming\lootbot\indirsavefile.txt
proceeding to conditional...
indirsavefile.txt found
marker1

Process finished with exit code 1

And when the file is not found

C:\Users\Administrator\AppData\Roaming\lootbot\indirsavefile.txt
proceeding to conditional...
indirsavefile.txt not found
E:\IMPORT
Traceback (most recent call last):
resulting indir location is:
  File "D:/SYSTEM/CODING/PYTHON/import.py", line 28, in <module>
None
    os.chdir(indir)
proceed to enter directory...
TypeError: chdir: path should be string, bytes or os.PathLike, not NoneType

Process finished with exit code 1

How do I pass a directory variable to os.path.isdir and os.chdir, and from easygui.diropenbox into a variable?

Oh, and feel free to critique the logic and simplify


Solution

  • I get the error line 15..._isdir: path should be string, bytes or os.PathLike, not list

    This error doesn't match your code. I assume that instead of

    if not os.path.isdir(r"indir"):
    

    the real code is:

    if not os.path.isdir(indir):
    

    in which case the error is indeed to be expected, since in the previous line:

    indir = loadsavefile.readlines()
    

    file.readlines() does indeed return a list, as documented. You probably want file.readline().strip() instead (if you are sure the information you want is on the first line of course).

    TypeError: chdir: path should be string, bytes or os.PathLike, not NoneType

    This is also to be expected:

    indir = print(easygui.diropenbox("Locate your DOWNLOADS directory root"))
    

    print() does indeed return None, as also documented. You want:

    indir = easygui.diropenbox("Locate your DOWNLOADS directory root")
    print(indir)
    

    open(indirsavefile, "r")
    not sure what "r" is here for

    Err... It may start to sound like a running joke, but it's documented too ;-)

    Oh, and feel free to critique the logic and simplify

    Well, you have an obvious duplication (the call to easyguy).

    First thing first: you want to move the import statement at the top of your script (not that it changes anything technically but it's the convention and it indeed helps wrt/ maintainability)

    Then you want to avoid duplicated code:

    import easygui
    
    # ...
    
    indir = None # means: we haven't a usable value yet
    
    if os.path.isfile(indirsavefile):
        with open(indirsavefile, "r") as loadsavefile:
            indir = loadsavefile.readline().strip()
            if not os.path.isdir(indir):
                # ok, still not a usable value
                indir = None
    
    if indir is None:
        indir = easygui.diropenbox("Locate your DOWNLOADS directory root"))