Coder Perfect

Python’s mkdir -p functionality [duplicate]

Problem

Is there a way to acquire functionality from Python that is equivalent to mkdir -p on the shell? Other than a system call, I’m seeking for a solution. I’m confident the code isn’t more than 20 lines long, and I’m wondering whether it’s previously been written?

Asked by Setjmp

Solution #1

Use pathlib.Path.mkdir in Python 3.5:

import pathlib
pathlib.Path("/tmp/path/to/desired/directory").mkdir(parents=True, exist_ok=True)

Python 3.5 introduced the exist ok argument.

Unless mode is provided and the existing directory has different permissions than the intended ones, OSError is raised as before: os.makedirs has an optional third argument exist ok that, when True, enables the mkdir -p functionality—unless mode is provided and the existing directory has different permissions than the intended ones; in that case, OSError is raised as previously:

import os
os.makedirs("/tmp/path/to/desired/directory", exist_ok=True)

You may use os.makedirs and ignore the error in previous versions of Python:

import errno    
import os

def mkdir_p(path):
    try:
        os.makedirs(path)
    except OSError as exc:  # Python ≥ 2.5
        if exc.errno == errno.EEXIST and os.path.isdir(path):
            pass
        # possibly handle other errno cases here, otherwise finally:
        else:
            raise

Answered by tzot

Solution #2

That’s the case in Python >=3.2.

os.makedirs(path, exist_ok=True)

Use @tzot’s answer in prior versions.

Answered by Fred Foo

Solution #3

This is less difficult than catching the exception:

import os
if not os.path.exists(...):
    os.makedirs(...)

Disclaimer This method necessitates two system calls and is more prone to race problems in certain contexts and conditions. If you’re writing something more complex than a basic throwaway script that runs in a controlled environment, you’re better off using the acceptable solution, which only takes one system call.

UPDATE 2012-07-27

I’m tempted to delete my answer, but I believe the comment thread below contains useful information. As a result, I’m turning it into a wiki.

Answered by 5 revs, 2 users 97%

Solution #4

I recently came across the following distutils.dir util.mkpath:

In [17]: from distutils.dir_util import mkpath

In [18]: mkpath('./foo/bar')
Out[18]: ['foo', 'foo/bar']

Answered by auraham

Solution #5

If the file already exists, mkdir -p returns an error:

$ touch /tmp/foo
$ mkdir -p /tmp/foo
mkdir: cannot create directory `/tmp/foo': File exists

As a tweak to the prior ideas, if os.path.isdir returns False, re-raise the exception (when checking for errno.EEXIST).

(Update) See also this very similar question; I agree with the approved solution (and caveats), however instead of os.path.exists, I would propose os.path.isdir.

(Update) The whole function would be as follows, as suggested in the comments:

import os
def mkdirp(directory):
    if not os.path.isdir(directory):
        os.makedirs(directory) 

Answered by Jacob Gabrielson

Post is based on https://stackoverflow.com/questions/600268/mkdir-p-functionality-in-python