4

I'm supposed to ask the user to enter a directory and if the directory doesn't exist, we tell them and then make a directory for them.

This is my code so far. It acts in the same way whether or not the directory whose path is entered actually exists. This occurs when using pathlib on windows. Bug Reported Issue35692

import pathlib
from pathlib import Path

def directory():

    p = Path(input("Enter file path: "))

    if p.exists:

        print('Exists')

        return p

    else:

        print('Directory does not exist. Making directory for you.')

        p.mkdir()



directory()
Accelerate
  • 65
  • 1
  • 6
  • Eh? A proper answer to "how does mkdir work" would dive into syscalls and filesystem design, but it seems unlikely that that's what you really want to know. – Charles Duffy Jul 19 '17 at 22:55
  • @CharlesDuffy My bad, I should have worded my title differently. – Accelerate Jul 19 '17 at 22:56
  • @CharlesDuffy Hm, I tried what you said and entered an invalid directory, but for some reason my first half of the code seems to say everything exists. Do you know what's wrong with it? – Accelerate Jul 19 '17 at 22:59
  • Mkdir() has a parameter that you kinda have to pass to it. Python might allow you not to but you definitely need to name the directory to make it. – Erich Jul 19 '17 at 23:04
  • 1
    @Accelerate, `p.exists` isn't calling a function named `exists`; it returns a reference to the function itself; since that reference is neither `None`, `False`, `0`, etc. (and doesn't have a `__bool__` method to say otherwise), it evaluates as true in a boolean context. (I'm guessing you're coming from the Ruby world, where `object.funcname` calls the function called `funcname`? That's not true here; it *returns a handle on* that function, and you need to call it, as `object.funcname()`, to actually get it to be invoked). – Charles Duffy Jul 19 '17 at 23:07
  • Related: [Why do function objects evaluate to true in Python?](https://stackoverflow.com/questions/12697338/why-do-function-objects-evaluate-to-true-in-python) – Charles Duffy Jul 19 '17 at 23:16
  • This is not duplicate of any question. this issues is genuine. Please remove it from duplicate here's the official link https://bugs.python.org/issue35692 – Santhosh Dhaipule Chandrakanth Oct 22 '19 at 07:30
  • I have raised an issue as well on the github https://github.com/python/pythondotorg/issues/1519 – Santhosh Dhaipule Chandrakanth Oct 22 '19 at 11:22
  • Use `os` instead `os.path.isdir("/home/el")` for directory and `os.path.exists("/home/el/myfile.txt")` for file source [How to find if directory exists in Python](https://stackoverflow.com/questions/8933237/how-to-find-if-directory-exists-in-python?#answer-8933290) – Santhosh Dhaipule Chandrakanth Dec 04 '19 at 12:39

2 Answers2

6

Because you have to call the .exists method. See:

>>> p = pathlib.Path("/Users/juan")
>>> p.exists # this just returns the method object
<bound method Path.exists of PosixPath('/Users/juan')>
>>> p.exists()
True

Method/function objects always evaluate to True, hence why you are always seeing that the path exists.

juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
0

The mkdir you are using is this one in pathlib (some of the comments were assuming os.mkdir)

Path.mkdir(mode=0o777, parents=False, exist_ok=False)
Create a new directory at this given path. If mode is given, it is combined with the process’ umask value to determine the file mode and access flags. If the path already exists, FileExistsError is raised.

If parents is true, any missing parents of this path are created as needed; they are created with the default permissions without taking mode into account (mimicking the POSIX mkdir -p command).

If parents is false (the default), a missing parent raises FileNotFoundError.

If exist_ok is false (the default), FileExistsError is raised if the target directory already exists.

If exist_ok is true, FileExistsError exceptions will be ignored (same behavior as the POSIX mkdir -p command), but only if the last path component is not an existing non-directory file.

Changed in version 3.5: The exist_ok parameter was added.

It should work fine without parameters if you provide a valid path.

Note if you want to check if it exists, you'll need to call the exists() method - don't forget the ()

However, it's not a great approach, because someone else could make the directory(or a file) at that path between when you check for it and when you get around to creating it. This is called a race condition.

It's better to wrap the mkdir in a try/except and let the OS tell you if there's a problem. There are a lot more possibilities for exceptions than just already existing. eg.

def directory():

    p = Path(input("Enter file path: "))
    try:
        p.mkdir()
        print('Directory does not exist. Making directory for you.')
    except IOError as ex:
        print('Couldn't create directory', ex)
John La Rooy
  • 295,403
  • 53
  • 369
  • 502