On Sat, Apr 25, 2009 at 11:13:20AM -0700, Christopher Lee wrote: -> On Apr 25, 2009, at 8:39 AM, C. Titus Brown wrote: -> > What does this do that 'fp.close()' wouldn't already do? It raises a -> > specialized exception; it calls 'close' on delete; and it supports -> > closeOptional. -> -> As I mentioned in my original posting, the problem is shelve: if you -> try to access a shelve after closing it, it generates an error message -> that is totally incomprehensible, something like "TypeError: int -> object has no index lookup method". The purpose of OpenFileDescriptor -> is to ensure that a consistent error and error message is raised by -> any attempt to access a closed object -- without having to insert code -> to check that the shelve is valid at each and every place that -> accesses it. I don't want to saddle users with shelve's -> incomprehensible error message, as I think this will come up -> frequently, and will reflect badly on Pygr (even if it's shelve's -> fault). But I agree with you that OpenFileDescriptor seems more -> complicated than it needs to be. -> -> A simpler solution: since we already provide our own shelve subclass -> (to replace its hideous, slow __iter__), we could directly solve the -> problem there, i.e. write a replacement close() method that will make -> the closed Shelve raise a good error message.
Ahh! Yes, OK. Sorry, I should have gone back and read the original justification ;) -> For completeness sake, I'll try to enumerate the possible solutions: -> - use a descriptor to guard access to file, shelve or other "open -> objects". This is what OpenFileDescriptor does. -> -> - make the close() method simply delete the shelve attribute -> altogether. Now the user will get an AttributeError telling him -> "there is no attribute seqLenDict" -- hardly a good way of reminding -> the user "you already closed this object!" -> -> - make the close() method replace the shelve attribute with a dummy -> object whose sole purpose is to raise an exception if anyone tries to -> use it, with a sensible error message like "you already closed this -> object..." This uses less "Python magic" than using a descriptor, and -> hopefully would be clearer to anyone looking at the code, i.e. a -> close() method would look like this: -> -> def close(self): -> self.myfile.close() -> self.myfile = ClosedFileGuard() # raises clear error message -> if the user later tries to access myfile... I like this last one. -> Since closed file objects already raise a good error message, our -> close() method wouldn't have to replace them with ClosedFileGuard. -> Currently ClosedFileGuard would only be for replacing closed Shelve -> objects, but if other Python classes turn out also to have rotten -> error messsages when already closed, we could apply it to those cases -> as well. Perhaps name it ClosedObjectGuard? Sure! -> > Why raise FileAlreadyClosedError when operating on an already closed -> > file? python already uses ValueError: -> > -> > We probably want the exception raised to be the same whether or not -> > you're using an OpenFileDescriptor, because if you inadvertently call -> > 'close' on the file descriptor itself, it will raise a ValueError on -> > other I/O operations; see 'test_ofd_close' in classutil_test.py. -> -> When an error represents a "category" that arises in several different -> places, I think it's useful to create an error specific for this -> category subclassed from the appropriate Python error. Then try... -> except clauses can test for this specific category rather than -> assuming that all instances of ValueError really mean -> FileAlreadyClosedError (i.e. that there is no other way a ValueError -> could be raised within the called code) which can itself lead to -> subtle bugs. I originally subclassed FileAlreadyClosedError from -> ValueError, but later its delattr() aspect led me to subclass it from -> AttributeError. Since Python raises ValueError for this case, we -> should subclass from ValueError as you said. OK -> > Closing an already-closed file descriptor doesn't do anything in -> > Python. -> -> OK, we can permit double close()... great! ;) cheers, --titus -- C. Titus Brown, c...@msu.edu --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "pygr-dev" group. To post to this group, send email to pygr-dev@googlegroups.com To unsubscribe from this group, send email to pygr-dev+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pygr-dev?hl=en -~----------~----~----~----~------~----~------~--~---