I don't see that there is a function in the library that mimic the behavior of 'mkdir -p'. If 'makedirs' is used, it will generate an error if the file already exists. There are some functions available on the website to close the gap. But I'd prefer this is in the library. Is there any plan to add a function that mimic the behavior of 'mkdir -p'? http://code.activestate.com/recipes/82465-a-friendly-mkdir/ -- Regards, Peng
On 17/07/2010 23:03, Peng Yu wrote:
I don't see that there is a function in the library that mimic the behavior of 'mkdir -p'. If 'makedirs' is used, it will generate an error if the file already exists. There are some functions available on the website to close the gap. But I'd prefer this is in the library. Is there any plan to add a function that mimic the behavior of 'mkdir -p'?
Presumably a new keyword argument could be added to os.makedirs. Could you raise a feature request on the python bug tracker, preferably with patch and tests of course! It would be worth searching to see if there is an existing feature request for this, and if so you can add a comment to it. All the best, Michael Foord -- http://www.ironpythoninaction.com/
On 17/07/2010 11:03 PM, Peng Yu wrote:
I don't see that there is a function in the library that mimic the behavior of 'mkdir -p'. If 'makedirs' is used, it will generate an error if the file already exists. There are some functions available on the website to close the gap. But I'd prefer this is in the library. Is there any plan to add a function that mimic the behavior of 'mkdir -p'?
If I were you I'd ping Tarek who's taken ownership of the shutil module. It would go there if it went anywhere. That said, it's not clear just how far the stdlib should go to mimic every switch and option of shell commands... TJG
On Sun, Jul 18, 2010 at 11:30 AM, Tim Golden <mail@timgolden.me.uk> wrote:
On 17/07/2010 11:03 PM, Peng Yu wrote:
I don't see that there is a function in the library that mimic the behavior of 'mkdir -p'. If 'makedirs' is used, it will generate an error if the file already exists. There are some functions available on the website to close the gap. But I'd prefer this is in the library. Is there any plan to add a function that mimic the behavior of 'mkdir -p'?
If I were you I'd ping Tarek who's taken ownership of the shutil module. It would go there if it went anywhere.
That said, it's not clear just how far the stdlib should go to mimic every switch and option of shell commands...
Well, it really should have behaved like mkdir -p in the first place. Eric Raymond submitted the code ages ago, and at the time I wasn't familiar with mkdir -p, otherwise, I would have made him change it. I believe every single use of os.mkdirs() I've made goes something like this: if not os.path.exists(x): os.mkdirs(x) or perhaps like this: try: os.mkdirs(x) except os.error: pass (Though the latter masks a bunch of other rare but possible failure modes -- often this is in throw-away code though where it doesn't matter or the next line will raise an exception that's good enough to diagnose the situation anyway.) -- --Guido van Rossum (python.org/~guido)
Tim Golden wrote:
That said, it's not clear just how far the stdlib should go to mimic every switch and option of shell commands...
I don't think it's a matter of mimicking switches just because they're there. The operation of "make sure this directory and all its parents exist" is very commonly required, e.g. when installing software. It makes sense to have it easily available. -- Greg
Agree. Through searching for existing issues, I found there isn't any such request. And I will submit one. The '-p' option of shell's mkdir has tow functions: 1, create parents directories if not exists, 2, suppress "File exists" error if the target has already exists. What we need is the second function. So I think both os.mkdir() and os.makedirs() should add a keyword argument to suppress the "OSError: [Errno 17] File exists". So we can remove many "try...except..." codes surround os.mkdir() and os.makedirs() as Greg said, "The operation of 'make sure this directory and all its parents exist' is very commonly required" -- Ray Allen Best wishes!
See http://bugs.python.org/issue9299 On Mon, Jul 19, 2010 at 1:16 PM, Ray Allen <ysj.ray@gmail.com> wrote:
Agree. Through searching for existing issues, I found there isn't any such request. And I will submit one.
The '-p' option of shell's mkdir has tow functions: 1, create parents directories if not exists, 2, suppress "File exists" error if the target has already exists. What we need is the second function. So I think both os.mkdir() and os.makedirs() should add a keyword argument to suppress the "OSError: [Errno 17] File exists". So we can remove many "try...except..." codes surround os.mkdir() and os.makedirs() as Greg said, "The operation of 'make sure this directory and all its parents exist' is very commonly required"
-- Ray Allen Best wishes!
-- Ray Allen Best wishes!
Sorry, I don't know what is the "no constant arguments" guideline refers to. Could you give me some more explanation? By the way, I feel adding separate functions is not quiet worthy for such a function. On Tue, Jul 20, 2010 at 7:11 AM, Greg Ewing <greg.ewing@canterbury.ac.nz>wrote:
Ray Allen wrote:
I think both os.mkdir() and os.makedirs() should add a keyword argument to
suppress the "OSError: [Errno 17] File exists".
This could be seen as violating the "no constant arguments" guideline. Maybe separate function would be better?
-- Greg _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/ysj.ray%2Bpython-dev%40gma...
-- Ray Allen Best wishes!
On Tue, 20 Jul 2010 06:49:44 pm 岳帅杰 wrote:
Sorry, I don't know what is the "no constant arguments" guideline refers to. Could you give me some more explanation?
It refers to the guideline that you shouldn't have a single function with two (or more) different behaviour and an argument that does nothing but select between them. Here is a toy example: def change_case(s, make_upper=True): if make_upper: return s.upper() else: return s.lower()
By the way, I feel adding separate functions is not quiet worthy for such a function.
I tend to agree. Perhaps all we need is a recipe in the docs: try: os.makedirs(path) except OSError, e: if e.errno != 17: raise I think that's all it takes to get the behaviour wanted without any false negatives, and four lines is short enough to use in-place, or if you prefer it's easy enough to wrap it in a function in your own module. Not everything needs to be a built-in. I'm -0 on adding an argument to os.makedirs, +0 on adding a variant function to os, and +0.5 on adding the variant to the shutil module. -- Steven D'Aprano
On Tue, Jul 20, 2010 at 11:09 PM, Steven D'Aprano <steve@pearwood.info> wrote:
I'm -0 on adding an argument to os.makedirs, +0 on adding a variant function to os, and +0.5 on adding the variant to the shutil module.
shutil seems like the place for it to me. The subtlety of getting the error suppression correct makes it worth implementing this once and for all I think. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On 20/07/2010 14:43, Nick Coghlan wrote:
On Tue, Jul 20, 2010 at 11:09 PM, Steven D'Aprano<steve@pearwood.info> wrote:
I'm -0 on adding an argument to os.makedirs, +0 on adding a variant function to os, and +0.5 on adding the variant to the shutil module.
shutil seems like the place for it to me. The subtlety of getting the error suppression correct makes it worth implementing this once and for all I think.
Really - so we have two almost identical functions with slightly different behaviour in different standard library modules? Aren't the Python APIs for working with files and paths confused enough already. That seems crazy to me and a switch on os.makedirs much more sensible. Michael
Cheers, Nick.
On 7/20/2010 12:49 PM, Michael Foord wrote:
On 20/07/2010 14:43, Nick Coghlan wrote:
On Tue, Jul 20, 2010 at 11:09 PM, Steven D'Aprano<steve@pearwood.info> wrote:
I'm -0 on adding an argument to os.makedirs, +0 on adding a variant function to os, and +0.5 on adding the variant to the shutil module. shutil seems like the place for it to me. The subtlety of getting the error suppression correct makes it worth implementing this once and for all I think.
Really - so we have two almost identical functions with slightly different behaviour in different standard library modules? Aren't the Python APIs for working with files and paths confused enough already. That seems crazy to me and a switch on os.makedirs much more sensible.
Guido has twice approved changing os.makedirs. First 2 1/2 years ago in http://bugs.python.org/msg58924 from http://bugs.python.org/issue1675 and recently in this thread http://mail.python.org/pipermail/python-dev/2010-July/102027.html which lead to http://bugs.python.org/issue9299 Both issues have a patch and I reviewed their major similarities and minor differences in http://bugs.python.org/msg110770 -- Terry Jan Reedy
Michael Foord <fuzzyman@voidspace.org.uk> wrote:
On 20/07/2010 14:43, Nick Coghlan wrote:
On Tue, Jul 20, 2010 at 11:09 PM, Steven D'Aprano<steve@pearwood.info> wrote:
I'm -0 on adding an argument to os.makedirs, +0 on adding a variant function to os, and +0.5 on adding the variant to the shutil module.
shutil seems like the place for it to me. The subtlety of getting the error suppression correct makes it worth implementing this once and for all I think.
Really - so we have two almost identical functions with slightly different behaviour in different standard library modules? Aren't the Python APIs for working with files and paths confused enough already. That seems crazy to me and a switch on os.makedirs much more sensible.
Yep, me too. Bill
Michael
Cheers, Nick.
-- http://www.ironpythoninaction.com/
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/janssen%40parc.com
On 20Jul2010 17:49, Michael Foord <fuzzyman@voidspace.org.uk> wrote: | On 20/07/2010 14:43, Nick Coghlan wrote: | >On Tue, Jul 20, 2010 at 11:09 PM, Steven D'Aprano<steve@pearwood.info> wrote: | >>I'm -0 on adding an argument to os.makedirs, +0 on adding a variant | >>function to os, and +0.5 on adding the variant to the shutil module. | >shutil seems like the place for it to me. The subtlety of getting the | >error suppression correct makes it worth implementing this once and | >for all I think. | | Really - so we have two almost identical functions with slightly | different behaviour in different standard library modules? Three if you count os.mkdir itself as well. | Aren't | the Python APIs for working with files and paths confused enough | already. That seems crazy to me and a switch on os.makedirs much | more sensible. +1 from me. Hasn't the BDFL blessed this particular suggestion too? Disclaimer: I am _not_ a dev. Cheers, -- Cameron Simpson <cs@zip.com.au> DoD#743 http://www.cskk.ezoshosting.com/cs/ I am not a free man, I am a number. - Beirne Konarski <beirnek@summitis.com>
On Tue, Jul 20, 2010 at 11:35 PM, Cameron Simpson <cs@zip.com.au> wrote:
On 20Jul2010 17:49, Michael Foord <fuzzyman@voidspace.org.uk> wrote: | On 20/07/2010 14:43, Nick Coghlan wrote: | >On Tue, Jul 20, 2010 at 11:09 PM, Steven D'Aprano<steve@pearwood.info> wrote: | >>I'm -0 on adding an argument to os.makedirs, +0 on adding a variant | >>function to os, and +0.5 on adding the variant to the shutil module. | >shutil seems like the place for it to me. The subtlety of getting the | >error suppression correct makes it worth implementing this once and | >for all I think. | | Really - so we have two almost identical functions with slightly | different behaviour in different standard library modules?
Three if you count os.mkdir itself as well.
| Aren't | the Python APIs for working with files and paths confused enough | already. That seems crazy to me and a switch on os.makedirs much | more sensible.
+1 from me. Hasn't the BDFL blessed this particular suggestion too?
Now I have. :-) -1 on a new function (despite the constant-argument guideline) and +1 on a flag. If it weren't for backwards compatibility I'd just change os.makedirs() to act like mkdir -p period, but the last opportunity we had for that was Python 3.0. -- --Guido van Rossum (python.org/~guido)
On Tue, 20 Jul 2010, Steven D'Aprano wrote:
I tend to agree. Perhaps all we need is a recipe in the docs:
try: os.makedirs(path) except OSError, e: if e.errno != 17: raise
What if the path or a parent of it already exists as a file? If one has requested -p I believe one typically wants this to be an error. And I assume that one would not use the literal 17 in production code. Isaac Morland CSCF Web Guru DC 2554C, x36650 WWW Software Specialist
I'd go with putting it in shutil. We could also add a function there that wraps up the recipe in issue 9311 to work around the quirks of os.access on FreeBSD (and possibly other platforms). -- R. David Murray www.bitdance.com
On 07/27/2010 06:18 PM, Alexander Belopolsky wrote:
On Tue, Jul 20, 2010 at 10:20 AM, R. David Murray<rdmurray@bitdance.com> wrote:
I'd go with putting it in shutil.
+1
I would also call it shutil.mktree which will go well with shutil.rmtree next to it.
Note that mktree is not analogous to rmtree - while rmtree removes a directory tree beneath a specified directory, mktree would only create a single "branch", not an entire tree. I'd imagine a mktree function to accept a data structure describing the tree to be created. If you're going for a short name distinctive from mkdir, I propose mksubdirs.
I believe, in design purpose, the os.mkdir() is to match the system call "mkdir()" exactly, the os.makedirs() is a "Super-mkdir", it provides extra convenience for using when we want to create directories. This is the case makedirs() should deal with. A new function maybe confused with makedirs(). I think os.makedirs() should go to shutil, but we have missed the right time. On Wed, Jul 28, 2010 at 3:29 PM, Hrvoje Niksic <hrvoje.niksic@avl.com>wrote:
On 07/27/2010 06:18 PM, Alexander Belopolsky wrote:
On Tue, Jul 20, 2010 at 10:20 AM, R. David Murray<rdmurray@bitdance.com> wrote:
I'd go with putting it in shutil.
+1
I would also call it shutil.mktree which will go well with shutil.rmtree next to it.
Note that mktree is not analogous to rmtree - while rmtree removes a directory tree beneath a specified directory, mktree would only create a single "branch", not an entire tree. I'd imagine a mktree function to accept a data structure describing the tree to be created.
If you're going for a short name distinctive from mkdir, I propose mksubdirs.
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/ysj.ray%2Bpython-dev%40gma...
-- Ray Allen Best wishes!
On 7/28/2010 4:42 AM, Ray Allen wrote:
I believe, in design purpose, the os.mkdir() is to match the system call "mkdir()" exactly, the os.makedirs() is a "Super-mkdir", it provides extra convenience for using when we want to create directories. This is the case makedirs() should deal with.
After discussion with Guido, the patch on the tracker leaves makedir alone and catches the exception, or not, in makedirs. -- Terry Jan Reedy
Hrvoje Niksic writes:
single "branch", not an entire tree. I'd imagine a mktree function to accept a data structure describing the tree to be created.
-1 on mktree for that reason.
If you're going for a short name distinctive from mkdir, I propose mksubdirs.
A little more accurate might be mkpath, but I'd be happy with either. And of course in Unix jargon "path" is ambiguous.
On 28/07/2010 11:53, Greg Ewing wrote:
Hrvoje Niksic wrote:
mktree would only create a single "branch", not an entire tree.
Maybe mkbranch, then?
Seeing as we already have a decision to add this functionality to os.makedirs as a switch and not to create a new function, this bikeshedding seems particularly pointless. http://mail.python.org/pipermail/python-dev/2010-July/102132.html All the best, Michael -- http://www.ironpythoninaction.com/ http://www.voidspace.org.uk/blog READ CAREFULLY. By accepting and reading this email you agree, on behalf of your employer, to release me from all obligations and waivers arising from any and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and acceptable use policies (”BOGUS AGREEMENTS”) that I have entered into with your employer, its partners, licensors, agents and assigns, in perpetuity, without prejudice to my ongoing rights and privileges. You further represent that you have the authority to release me from any BOGUS AGREEMENTS on behalf of your employer.
On Tue, Jul 20, 2010 at 9:09 AM, Steven D'Aprano <steve@pearwood.info> wrote:
It refers to the guideline that you shouldn't have a single function with two (or more) different behaviour and an argument that does nothing but select between them.
In particular, when that argument is almost never given a variable value, but is specified using a constant at the call site. -Fred -- Fred L. Drake, Jr. <fdrake at gmail.com> "A storm broke loose in my mind." --Albert Einstein
On 07/20/2010 10:43 AM, Fred Drake wrote:
On Tue, Jul 20, 2010 at 9:09 AM, Steven D'Aprano<steve@pearwood.info> wrote:
It refers to the guideline that you shouldn't have a single function with two (or more) different behaviour and an argument that does nothing but select between them.
In particular, when that argument is almost never given a variable value, but is specified using a constant at the call site.
I was thinking it should have been two functions, but I realized there is more subtleties involved than simply just reusing a directory that already exists. One possibility might be... mkdir(path [, allow=None, mode=0777]) Where None can be replaced with one or more of the following. 'exists' dir can already exist (with same permissions as mode) 'case' dir case can be different. (Windows) 'files' dir can have files in it. ... or a string containing the initials. It doesn't fall under the single constant rule if done this way. Ron
On 07/20/2010 11:47 AM, Ron Adam wrote:
On 07/20/2010 10:43 AM, Fred Drake wrote:
On Tue, Jul 20, 2010 at 9:09 AM, Steven D'Aprano<steve@pearwood.info> wrote:
It refers to the guideline that you shouldn't have a single function with two (or more) different behaviour and an argument that does nothing but select between them.
In particular, when that argument is almost never given a variable value, but is specified using a constant at the call site.
I was thinking it should have been two functions, but I realized there is more subtleties involved than simply just reusing a directory that already exists.
One possibility might be...
mkdir(path [, allow=None, mode=0777])
Where None can be replaced with one or more of the following.
'exists' dir can already exist (with same permissions as mode) 'case' dir case can be different. (Windows) 'files' dir can have files in it.
Add 'path', Complete path as -p option does.
... or a string containing the initials.
It doesn't fall under the single constant rule if done this way.
Ron
On Tue, Jul 20, 2010 at 12:47 PM, Ron Adam <rrr@ronadam.com> wrote:
It doesn't fall under the single constant rule if done this way.
If the value for 'allow' were almost always given as a constant, this would be an argument for three functions instead of one. The guideline has little to do with the type of the value, but the number of possible values ("small") and whether they're normally given as constants in the code. If there's more than one, and combinations then to vary, then keeping them as args makes sense. Also, if we don't know what we want the functionality to be, as you suggest, then worry about that is premature. :-) Let's decide on the required functionality first.
On 07/20/2010 12:00 PM, Fred Drake wrote:
On Tue, Jul 20, 2010 at 12:47 PM, Ron Adam<rrr@ronadam.com> wrote:
It doesn't fall under the single constant rule if done this way.
If the value for 'allow' were almost always given as a constant, this would be an argument for three functions instead of one.
The guideline has little to do with the type of the value, but the number of possible values ("small") and whether they're normally given as constants in the code.
If there's more than one, and combinations then to vary, then keeping them as args makes sense.
Also, if we don't know what we want the functionality to be, as you suggest, then worry about that is premature. :-) Let's decide on the required functionality first.
That makes sense. :-) Another things that comes to mind, is it may make sense to choose either strict, and have args to *allow* different cases, or to choose lenient, and have args to *restrict* different cases. That keeps it somewhat less confusing, and doesn't require memorization to remember what the mixed mode default might be. (Unless we use a single combination 99% of the time, then that probably *should* be the default.) Ron
Steven D'Aprano wrote:
Perhaps all we need is a recipe in the docs:
try: os.makedirs(path) except OSError, e: if e.errno != 17: raise
I don't like writing code that depends on particular errno values, because I don't trust it to work cross- platform. Also it seems suboptimal to require people to use a recipe like this to get the behaviour that is wanted in the overwhelming majority of cases. I don't see what would be so bad about adding a new function for this. Think of it as correcting the mistake of not making makedirs() behave this way from the beginning. -- Greg
I don't see what would be so bad about adding a new
function for this. Think of it as correcting the mistake of not making makedirs() behave this way from the beginning. If you want to add a new function, then what its name should be? I guess it should be too similar as existing ones. It's confusing for using because they have similar names and do the same major things except exception. For users it's easier to remember one function than tow. If we want to correct a mistake, it's better not to import another mistake. I don't like writing code that depends on particular errno values, because I don't trust it to work cross- platform. I think in this case, the errno is generate by c standard library, which can be seen as cross-platform.
-- Greg
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/ysj.ray%2Bpython-dev%40gma...
-- Ray Allen Best wishes!
Ray Allen wrote:
I think in this case, the errno is generate by c standard library, which can be seen as cross-platform.
But I'm never sure how standard the actual error numbers are, though. I tend to think of them as coming from Unix-land, and thus fair game for getting screwed around with on Windows. Am I worrying too much? -- Greg
Greg Ewing <greg.ewing@canterbury.ac.nz> writes:
Ray Allen wrote:
I think in this case, the errno is generate by c standard library, which can be seen as cross-platform.
But I'm never sure how standard the actual error numbers are, though.
You can use them by name, and in fact I strongly recommend it: import os import errno try: os.makedirs(path) except OSError, exc: if exc.errno != errno.EEXIST: raise
I tend to think of them as coming from Unix-land, and thus fair game for getting screwed around with on Windows. Am I worrying too much?
There are some that differ between different OSen, true. Using them by name avoids dealing with *different* numbers (since the ‘errno’ module's attributes will use the same name for semantically the same error), leaving only the problem of errors that are *missing* on some platforms. EEXIST is common to all of them though, AFAIK. -- \ “Sittin' on the fence, that's a dangerous course / You can even | `\ catch a bullet from the peace-keeping force” —Dire Straits, | _o__) _Once Upon A Time In The West_ | Ben Finney
Hey folks, On 21 July 2010 10:37, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Steven D'Aprano wrote:
Perhaps all we need is a recipe in the docs:
try: os.makedirs(path) except OSError, e: if e.errno != 17: raise
I don't like writing code that depends on particular errno values, because I don't trust it to work cross- platform.
I use errno.EEXIST instead of a magic number. later, -- Clinton Roy Software Engineer Global Change Institute University of Queensland humbug.org.au - Brisbane Unix Group clintonroy.wordpress.com - Blog flickr.com/photos/croy/ - Photos
岳帅杰 wrote:
Sorry, I don't know what is the "no constant arguments" guideline refers to. Could you give me some more explanation?
It's a rule of thumb that Guido says he uses when designing an API. If in the majority of use cases for a proposed function, one of its arguments would always be a constant that chooses between two or more different behaviours, then it would probably be better to have separate functions for each of the behaviours. -- Greg
participants (21)
-
Alexander Belopolsky
-
Ben Finney
-
Bill Janssen
-
Cameron Simpson
-
Clinton Roy
-
Fred Drake
-
Greg Ewing
-
Guido van Rossum
-
Hrvoje Niksic
-
Isaac Morland
-
Michael Foord
-
Nick Coghlan
-
Peng Yu
-
R. David Murray
-
Ray Allen
-
Ron Adam
-
Stephen J. Turnbull
-
Steven D'Aprano
-
Terry Reedy
-
Tim Golden
-
岳帅杰