<br><br><div class="gmail_quote">2009/4/2 Guido van Rossum <span dir="ltr"><<a href="mailto:guido@python.org">guido@python.org</a>></span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
[Moving to python-ideas]<br>
<div class="im"><br>
On Thu, Apr 2, 2009 at 9:12 AM, Gustavo Carneiro <<a href="mailto:gjcarneiro@gmail.com">gjcarneiro@gmail.com</a>> wrote:<br>
><br>
><br>
> 2009/4/2 Guido van Rossum <<a href="mailto:guido@python.org">guido@python.org</a>><br>
>><br>
>> On 4/2/09, Gustavo Carneiro <<a href="mailto:gjcarneiro@gmail.com">gjcarneiro@gmail.com</a>> wrote:<br>
>> > Apologies if this has already been discussed.<br>
>> ><br>
>> > I was expecting that by now, python 3.0,<br>
<br>
</div>Note, these words are pretty offensive (or perhaps<br>
passive-aggressive). How would you respond if some Perl hacker said "I<br>
was expecting that by now, Python 3.0, Python would have dropped the<br>
whitespace bug."</blockquote><div><br>Sorry.  I suck at this.  I think I'm too impatient (read: time constrained) to be polite :P<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>
<div class="im"><br>
>> > the following code:<br>
>> ><br>
>> >             # clean the target dir<br>
>> >             import errno<br>
>> >             try:<br>
>> >                 shutil.rmtree(trace_output_path)<br>
>> >             except OSError, ex:<br>
>> >                 if ex.errno not in [errno.ENOENT]:<br>
>> >                     raise<br>
>> ><br>
>> > Would have become something simpler, like this:<br>
>> ><br>
>> >             # clean the target dir<br>
>> >             try:<br>
>> >                 shutil.rmtree(trace_output_path)<br>
>> >             except OSErrorNoEntry:       # or maybe os.ErrorNoEntry<br>
>> >                 pass<br>
>> ><br>
>> > Apparently no one has bothered yet<br>
<br>
</div>Again, offensive words -- makes you sound like you are so much smarter than us.<br>
<div class="im"><br>
>> > to turn OSError + errno into a hierarchy<br>
>> > of OSError subclasses, as it should.  What's the problem, no will to do<br>
>> > it or no manpower?<br>
<br>
</div>Again poor choice of words. Note the leading question: you don't even<br>
consider the possibility that it's a bad idea. Compare "When did you<br>
stop beating your wife?"</blockquote><div><br>Maybe I didn't express myself very well.  By "no will to do it" I meant "no interest to do it".  If you thought it was a bad idea you would have no interest in doing it.<br>
<br>To be frank, what I thought most likely was that, with all the refactoring going on in Python 3, this issue, which was an obvious cleanup to me (but now I realize it is not obvious at all to everyone else), was overlooked because there were bigger problems to solve.<br>
<br>So there are usually only three reasons why something is not done:<br><br>  1- It's a bad idea;<br>  2- No one thought of it;<br>  3- It's a good and known idea, but there was no manpower to do it.<br><br>I was betting more on 2 and 3, but not entirely ruling out 1. <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>
<div class="im"><br>
>> Sounds like a bad idea. There are hundreds of errno values. I don't<br>
>> want to have hundreds of new exceptions -- especially not since not<br>
>> all are defined on each platform.<br>
><br>
> We already have the hundreds of errno values defined in the errno module.<br>
> It is just a matter of turning the integers that we already have into<br>
> exception subclasses of OSError.  My idea would be to only create exceptions<br>
> for the errors listed in the module 'errno', and use a generic OSError for<br>
> the rest of them.<br>
<br>
</div>This would cause more platform problems than we already have. Consider<br>
an errno (EWIN, mapped to OSWinError in your proposal) that exists<br>
only on Windows, and another (ELIN, OSLinError) that exists only on<br>
Linux. Now suppose you have to catch both of them. If you write your<br>
code like this:<br>
<br>
 try:<br>
    ...<br>
  except OSWinError:<br>
    ...<br>
  except OSLinError:<br>
    ...<br>
<br>
then on Linux, if OSLinError is raised, the "except OSWinError:"<br>
clause will raise a NameError because that exception isn't defined,<br>
and you'll never reach the "except OSLinError:" clause. If you reverse<br>
the clauses you have the same problem on Windows.<br>
<br>
While you would have the same problem if you tried to do something<br>
like "if e.errno == errno.EWIN:" on Linux, it's easier to circumvent<br>
-- one of the many ways to do so is to write "if<br>
errno.errorcode[e.errno] == 'EWIN':" instead..<br>
<div class="im"></div></blockquote><div><br></div></div>I just committed some code like "if e.errno == errno.EWIN".  I  had not realized not all constants are defined on all systems, although it is documented so I have no excuse.<br>
<br>The problem you report:<br><blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"> try:<br>
    ...<br>
  except OSWinError:<br>
    ...<br>
  except OSLinError:<br>
    ...<br><br></blockquote><br>Would be solved if both OSWinError and OSLinError were always defined in both Linux and Windows Python.  Programs could be written to catch both OSWinError and OSLinError, except that on Linux OSWinError would never actually be raised, and on Windows OSLinError would never occur.  Problem solved.<br>
<br>The downsides of this?  I can only see memory, at the moment, but I might be missing something.<br><br>Now just one final word why I think this matters.  The currently correct way to remove a directory tree and only ignore the error "it does not exist" is:<br>
<br><div style="margin-left: 40px;"><span style="font-family: courier new,monospace;">try:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    shutil.rmtree("dirname")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">except OSError, e:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    if
errno.errorcode[e.errno] != 'ENOENT':</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">       raise</span><br style="font-family: courier new,monospace;"></div>
<br style="font-family: courier new,monospace;">However, only very experienced programmers will know to write that correct code (apparently I am not experienced enought!).<br><br>What I am proposing is that the simpler correct code would be something like:<br>
<span style="font-family: courier new,monospace;"><br></span><div style="margin-left: 40px;"><span style="font-family: courier new,monospace;">try:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    shutil.rmtree("dirname")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">except OSNoEntryError:</span><br><span style="font-family: courier new,monospace;">    pass</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"></span></div>


<br>Much simpler, no?<br><br>Right now, developers are tempted to write code like:<br><br><span style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;">    shutil.rmtree("dirname", ignore_errors=True)</span><br style="font-family: courier new,monospace;">
<br>Or:<br><br><div style="margin-left: 40px;"><span style="font-family: courier new,monospace;">try:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    shutil.rmtree("dirname")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">except OSError:</span><br><span style="font-family: courier new,monospace;">
    pass</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"></span></div>



<span style="font-family: courier new,monospace;">
</span><br>Both of which follow the error hiding anti-pattern [1].<br><br>[1] <a href="http://en.wikipedia.org/wiki/Error_hiding">http://en.wikipedia.org/wiki/Error_hiding</a><br><br>Thanks for reading this far.<br><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>