Index: Doc/library/os.rst =================================================================== --- Doc/library/os.rst (revision 83045) +++ Doc/library/os.rst (working copy) @@ -1126,17 +1126,19 @@ Availability: Unix, Windows. -.. function:: makedirs(path[, mode]) +.. function:: makedirs(path[, mode][, exist_ok=False]) .. index:: single: directory; creating single: UNC paths; and os.makedirs() Recursive directory creation function. Like :func:`mkdir`, but makes all - intermediate-level directories needed to contain the leaf directory. Throws - an :exc:`error` exception if the leaf directory already exists or cannot be - created. The default *mode* is ``0o777`` (octal). On some systems, *mode* - is ignored. Where it is used, the current umask value is first masked out. + intermediate-level directories needed to contain the leaf directory. If + the directory already exists, throws an :exc:`OSError` exception if + *exist_ok* is Flase, otherwise no exception is thrown. If the directory + cannot be created, throws an :exc:`error` exception. The default *mode* + is ``0o777`` (octal). On some systems, *mode* is ignored. Where it is + used, the current umask value is first masked out. .. note:: Index: Lib/os.py =================================================================== --- Lib/os.py (revision 83045) +++ Lib/os.py (working copy) @@ -119,13 +119,14 @@ # Super directory utilities. # (Inspired by Eric Raymond; the doc strings are mostly his) -def makedirs(name, mode=0o777): - """makedirs(path [, mode=0o777]) +def makedirs(name, mode=0o777, exist_ok=False): + """makedirs(path [, mode=0o777][, exist_ok=False]) Super-mkdir; create a leaf directory and all intermediate ones. Works like mkdir, except that any intermediate path segment (not - just the rightmost) will be created if it does not exist. This is - recursive. + just the rightmost) will be created if it does not exist. If the + target directory already exists, throws an OSError if exist_ok is + False, otherwise no exception is thrown. This is recursive. """ head, tail = path.split(name) @@ -133,14 +134,18 @@ head, tail = path.split(head) if head and tail and not path.exists(head): try: - makedirs(head, mode) + makedirs(head, mode, exist_ok) except OSError as e: # be happy if someone already created the path if e.errno != errno.EEXIST: raise if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists return - mkdir(name, mode) + try: + mkdir(name, mode) + except OSError as e: + if not (e.errno == errno.EEXIST and exist_ok): + raise def removedirs(name): """removedirs(path) Index: Lib/test/test_os.py =================================================================== --- Lib/test/test_os.py (revision 83045) +++ Lib/test/test_os.py (working copy) @@ -609,6 +609,14 @@ 'dir5', 'dir6') os.makedirs(path) + def test_exist_ok(self): + base = support.TESTFN + path = os.path.join(support.TESTFN, 'dir1') + os.makedirs(path) + self.assertRaises(OSError, os.makedirs, path) + self.assertRaises(OSError, os.makedirs, path, exist_ok=False) + os.makedirs(path, exist_ok=True) + def tearDown(self): path = os.path.join(support.TESTFN, 'dir1', 'dir2', 'dir3', 'dir4', 'dir5', 'dir6')