<div class="gmail_quote">(cross-posting back to python-dev to finalize discussions)<br><br>2009/4/2 Guido van Rossum <span dir="ltr"><<a href="mailto:guido@python.org">guido@python.org</a>></span><br>[...]<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div><div class="h5">> The problem you report:<br>
>><br>
>>  try:<br>
>>    ...<br>
>>  except OSWinError:<br>
>>    ...<br>
>>  except OSLinError:<br>
>>    ...<br>
>><br>
><br>
> Would be solved if both OSWinError and OSLinError were always defined in<br>
> both Linux and Windows Python.  Programs could be written to catch both<br>
> OSWinError and OSLinError, except that on Linux OSWinError would never<br>
> actually be raised, and on Windows OSLinError would never occur.  Problem<br>
> solved.<br>
<br>
</div></div>Yeah, but now you'd have to generate the list of exceptions (which<br>
would be enormously long) based on the union of all errno codes in the<br>
universe.<br>
<br>
Unless you only want to do it for some errno codes and not for others,<br>
which sounds like asking for trouble.<br>
<br>
Also you need a naming scheme that works for all errnos and doesn't<br>
require manual work. Frankly, the only scheme that I can think of that<br>
could be automated would be something like OSError_ENAME.<br>
<br>
And, while OSError is built-in, I think these exceptions (because<br>
there are so many) should not be built-in, and probably not even live<br>
in the 'os' namespace -- the best place for them would be the errno<br>
module, so errno.OSError_ENAME.<br>
<div class="im"><br>
> The downsides of this?  I can only see memory, at the moment, but I might be<br>
> missing something.<br>
<br>
</div>It's an enormous amount of work to make it happen across all<br>
platforms. And it doesn't really solve an important problem.</blockquote><div><br>I partially agree.  It will be a lot of work.  I think the problem is valid, although not very important, I agree.<br> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
<div class="im"><br>
> Now just one final word why I think this matters.  The currently correct way<br>
> to remove a directory tree and only ignore the error "it does not exist" is:<br>
><br>
> try:<br>
>     shutil.rmtree("dirname")<br>
> except OSError, e:<br>
>     if errno.errorcode[e.errno] != 'ENOENT':<br>
>        raise<br>
><br>
> However, only very experienced programmers will know to write that correct<br>
> code (apparently I am not experienced enought!).<br>
<br>
</div>That doesn't strike me as correct at all, since it doesn't distinguish<br>
between ENOENT being raised for some file deep down in the tree vs.<br>
the root not existing. (This could happen if after you did<br>
os.listdir() some other process deleted some file.)</blockquote><div><br>OK.  Maybe in a generic case this could happen, although I'm sure this won't happen in my particular scenario.  This is about a build system, and I am assuming there are no two concurrent builds (or else a lot of other things would fail anyway).<br>
<br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
A better way might be<br>
<br>
try:<br>
  shutil.rmtree(<dir>)<br>
except OSError:<br>
  if os.path.exists(<dir>):<br>
   raise</blockquote><div><br>Sure, this works, but at the cost of an extra system call.  I think it's more elegant to check the errno (assuming the corner case you pointed out above is not an issue). <br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

<br>
Though I don't know what you wish to happen of <dir> were a dangling symlink.<br>
<div class="im"><br>
> What I am proposing is that the simpler correct code would be something<br>
> like:<br>
><br>
> try:<br>
>     shutil.rmtree("dirname")<br>
> except OSNoEntryError:<br>
>     pass<br>
><br>
> Much simpler, no?<br>
<br>
</div>And wrong.<br>
<div class="im"><br>
> Right now, developers are tempted to write code like:<br>
><br>
>     shutil.rmtree("dirname", ignore_errors=True)<br>
><br>
> Or:<br>
><br>
> try:<br>
>     shutil.rmtree("dirname")<br>
> except OSError:<br>
>     pass<br>
><br>
> Both of which follow the error hiding anti-pattern [1].<br>
><br>
> [1] <a href="http://en.wikipedia.org/wiki/Error_hiding" target="_blank">http://en.wikipedia.org/wiki/Error_hiding</a><br>
><br>
> Thanks for reading this far.<br>
<br>
</div>Thanks for not wasting any more of my time.</blockquote></div><br>OK, I won't waste more time.  If this were an obvious improvement beyond doubt to most people, I would pursue it, but since it's not, I can live with it.<br>
<br>Thanks anyway,<br clear="all"><br>-- <br>Gustavo J. A. M. Carneiro<br>INESC Porto, Telecommunications and Multimedia Unit<br>"The universe is always one step beyond logic." -- Frank Herbert<br>