Re: Granularity of OSError
In mailman.122.1253409745.2807.python-l...@python.org MRAB pyt...@mrabarnett.plus.com writes: kj wrote: In mailman.107.1253369463.2807.python-l...@python.org MRAB pyt...@mrabarnett.plus.com writes: If, for example, you're going to copy a file, it's a good idea to check beforehand that there's enough space available for the copy. How do you do that? There's os.statvfs(...), although that's Unix only. Thanks! kynn -- http://mail.python.org/mailman/listinfo/python-list
Re: Granularity of OSError
On Sep 19, 9:22 pm, MRAB pyt...@mrabarnett.plus.com wrote: The point is that it's sometimes a good idea to do a cheap check first before attempting an operation that's 'expensive' even when it fails. Strongly agree. Furthermore, with LBYL it's often easier to give a user clearer error messages for common usage errors, rather than waiting for an exception in a much lower-level place where it's less clear to them what the cause is. -- http://mail.python.org/mailman/listinfo/python-list
Re: Granularity of OSError
In mailman.107.1253369463.2807.python-l...@python.org MRAB pyt...@mrabarnett.plus.com writes: If, for example, you're going to copy a file, it's a good idea to check beforehand that there's enough space available for the copy. How do you do that? TIA, kynn -- http://mail.python.org/mailman/listinfo/python-list
Re: Granularity of OSError
kj wrote: In mailman.107.1253369463.2807.python-l...@python.org MRAB pyt...@mrabarnett.plus.com writes: If, for example, you're going to copy a file, it's a good idea to check beforehand that there's enough space available for the copy. How do you do that? There's os.statvfs(...), although that's Unix only. The point is that it's sometimes a good idea to do a cheap check first before attempting an operation that's 'expensive' even when it fails. -- http://mail.python.org/mailman/listinfo/python-list
Re: Granularity of OSError
On 2009-09-20, MRAB pyt...@mrabarnett.plus.com wrote: kj wrote: In mailman.107.1253369463.2807.python-l...@python.org MRAB pyt...@mrabarnett.plus.com writes: If, for example, you're going to copy a file, it's a good idea to check beforehand that there's enough space available for the copy. How do you do that? There's os.statvfs(...), although that's Unix only. The point is that it's sometimes a good idea to do a cheap check first before attempting an operation that's 'expensive' even when it fails. It's also important to note than under some circumstances, the side-effects of that particular failure (filling up a disk partition) can be unpleasant -- particularly if you do it as root. Incoming Mail gets bounced/dropped, cron jobs fail, etc. -- Grant -- http://mail.python.org/mailman/listinfo/python-list
Re: Granularity of OSError
On Sep 18, 11:54 am, kj no.em...@please.post wrote: I've often come across the idea that good Python style deals with potential errors using an EAFP (easier to ask forgiveness than permission) strategy rather than a LBYL (look before you leap) strategy. For example, LBYL would look like this: if os.path.isfile(some_file): os.unlink(some_file) In contrast, EAFP would look like this: try: os.unlink(some_file) except OSError: pass But, as written, the EAFP code above is not satisfactory, because there can be OSError's triggered for reasons other than the non-existence of the regular file some_file. What one needs is a finer granularity of exception, mapping to exactly the error that one is guarding against. Is there a standard approach to refining the granularity of exceptions such as OSError? The only approach I can think of is to somehow parse the error string (assuming is available) to determine whether the exception is indeed of the specific kind we're trying to catch. But this strikes me as grossly inelegant. Is there a better way? (BTW, the problem is generic, because client code has no control over the specificity of the exceptions raised by a library module. If these exceptions turn out to be too broad, client code has to somehow deal with this reality, at least in the short term.) TIA! kynn You can access the exception object which gives you greater detail. try: os.unlink(some_file) except OSError, e: print e.errno print e.strerror if e.errno == 2: pass else: raise If it's the error you are looking for, handle it, or else raise. ~Sean -- http://mail.python.org/mailman/listinfo/python-list
Re: Granularity of OSError
On Sep 18, 3:05 pm, Sean DiZazzo half.ital...@gmail.com wrote: On Sep 18, 11:54 am, kj no.em...@please.post wrote: I've often come across the idea that good Python style deals with potential errors using an EAFP (easier to ask forgiveness than permission) strategy rather than a LBYL (look before you leap) strategy. For example, LBYL would look like this: if os.path.isfile(some_file): os.unlink(some_file) In contrast, EAFP would look like this: try: os.unlink(some_file) except OSError: pass But, as written, the EAFP code above is not satisfactory, because there can be OSError's triggered for reasons other than the non-existence of the regular file some_file. What one needs is a finer granularity of exception, mapping to exactly the error that one is guarding against. Is there a standard approach to refining the granularity of exceptions such as OSError? The only approach I can think of is to somehow parse the error string (assuming is available) to determine whether the exception is indeed of the specific kind we're trying to catch. But this strikes me as grossly inelegant. Is there a better way? (BTW, the problem is generic, because client code has no control over the specificity of the exceptions raised by a library module. If these exceptions turn out to be too broad, client code has to somehow deal with this reality, at least in the short term.) TIA! kynn You can access the exception object which gives you greater detail. try: os.unlink(some_file) except OSError, e: print e.errno print e.strerror if e.errno == 2: pass else: raise If it's the error you are looking for, handle it, or else raise. ~Sean I do this myself in a lot of places, almost exactly like this. It's slightly clearer to use 'if e.errno == errno.ENOENT' in my opinion, but, whatever. The only place I've run into issues with this is when dealing with socket programming across operating systems. Python on Windows exports all of the WSA errors when dealing with sockets, but 'WSAEHOSTUNREACH' is not the same as 'ENETUNREACH.' In cases like that, you've got to be careful to check for all possible variations of the same error if you care about supporting Windows. Thanks, Jeff mcjeff.blogspot.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Granularity of OSError
In 254eac4d-ce19-4af9-8c6a-5be8e7b0f...@u16g2000pru.googlegroups.com Sean DiZazzo half.ital...@gmail.com writes: On Sep 18, 11:54=A0am, kj no.em...@please.post wrote: I've often come across the idea that good Python style deals with potential errors using an EAFP (easier to ask forgiveness than permission) strategy rather than a LBYL (look before you leap) strategy. For example, LBYL would look like this: if os.path.isfile(some_file): =A0 =A0 os.unlink(some_file) In contrast, EAFP would look like this: try: =A0 =A0 os.unlink(some_file) except OSError: =A0 =A0 pass But, as written, the EAFP code above is not satisfactory, because there can be OSError's triggered for reasons other than the non-existence of the regular file some_file. What one needs is a finer granularity of exception, mapping to exactly the error that one is guarding against. Is there a standard approach to refining the granularity of exceptions such as OSError? =A0The only approach I can think of is to somehow parse the error string (assuming is available) to determine whether the exception is indeed of the specific kind we're trying to catch. But this strikes me as grossly inelegant. =A0Is there a better way? (BTW, the problem is generic, because client code has no control over the specificity of the exceptions raised by a library module. If these exceptions turn out to be too broad, client code has to somehow deal with this reality, at least in the short term.) TIA! kynn You can access the exception object which gives you greater detail. try: os.unlink(some_file) except OSError, e: print e.errno print e.strerror if e.errno =3D=3D 2: pass else: raise If it's the error you are looking for, handle it, or else raise. Thanks, that's very handy. kynn -- http://mail.python.org/mailman/listinfo/python-list
Re: Granularity of OSError
You can access the exception object which gives you greater detail. try: os.unlink(some_file) except OSError, e: print e.errno print e.strerror if e.errno == 2: pass else: raise I do this myself in a lot of places, almost exactly like this. It's slightly clearer to use 'if e.errno == errno.ENOENT' in my opinion, but, whatever. In some cases it's also more correct. While ENOENT is always 2, some error codes differ between windows and posix. In general it's better to use the constants from the errno module. Ryan -- Ryan Kelly http://www.rfk.id.au | This message is digitally signed. Please visit r...@rfk.id.au| http://www.rfk.id.au/ramblings/gpg/ for details signature.asc Description: This is a digitally signed message part -- http://mail.python.org/mailman/listinfo/python-list
Re: Granularity of OSError
kj wrote: For example, LBYL would look like this: if os.path.isfile(some_file): os.unlink(some_file) In contrast, EAFP would look like this: try: os.unlink(some_file) except OSError: pass The two version aren't equal. The first one suffers from a race condition which may lead to a severe security issue. The file may be gone or replaced by a different file in the time span between the check and the call to unlink(). Christian -- http://mail.python.org/mailman/listinfo/python-list
Re: Granularity of OSError
On Sep 18, 5:23 pm, Christian Heimes li...@cheimes.de wrote: kj wrote: For example, LBYL would look like this: if os.path.isfile(some_file): os.unlink(some_file) In contrast, EAFP would look like this: try: os.unlink(some_file) except OSError: pass The two version aren't equal. The first one suffers from a race condition which may lead to a severe security issue. The file may be gone or replaced by a different file in the time span between the check and the call to unlink(). Christian Thanks for pointing that out. I never thought of it before. ~Sean -- http://mail.python.org/mailman/listinfo/python-list
Re: Granularity of OSError
On 2009-09-19, Christian Heimes li...@cheimes.de wrote: kj wrote: For example, LBYL would look like this: if os.path.isfile(some_file): os.unlink(some_file) In contrast, EAFP would look like this: try: os.unlink(some_file) except OSError: pass The two version aren't equal. The first one suffers from a race condition which may lead to a severe security issue. The file may be gone or replaced by a different file in the time span between the check and the call to unlink(). IOW, just be cause you look before you leap, it doesn't mean you're not going to land on anybody and have to ask for forgiveness afterwards. Since you always have to handle the error case, there's not much point in checking first unless the error case has bad side-effects that you're trying to avoid. In this case, attempting to unlink a non-existent file has no bad side-effects, so there's no point in checking before the unlink. -- Grant -- http://mail.python.org/mailman/listinfo/python-list