I'm writing some unit tests (using the unittest module) for my application, and want to write something which can verify that a method I'm calling returns a "file-like" object. Since this isn't a simple isinstance call, I wonder what the best-practice would be for determining this?
So, in outline:
possible_file = self.dao.get_file("anotherfile.pdf")
self.assertTrue(possible_file is file-like)
Perhaps I have to care which specific interface this file object implements, or which methods that make it file-like I want to support?
Thanks,
R
There is no "official definition" of what objects are "sufficiently file-like", because the various uses of file-like objects have such different requirements -- e.g., some only require read
or write
methods, other require some subset of the various line-reading methods... all the ways to some requiring the fileno
method, which can't even be supplied by the "very file-like objects" offered by StringIO
and cStringIO
modules in the standard library. It's definitely a question of "shades of gray", not a black-and-white taxonomy!
So, you need to determine which methods you need. To check for them, I recommended defining your own FileLikeEnoughForMe
abstract base class with abstractmethod
decorators, and checking the object with an isinstance
for that class, if you're on Python 2.6 or better: this is the recommended idiom these days, rather than a bunch of hasattr
checks which would be less readable and more complex (when properly beefed up with checks that those attributes are actually methods, etc;-).
The classical Python mentality is that it's easier to ask forgiveness than permission. In other words, don't check, catch the exception caused by write
ing to it.
The new way is to use an IO abstract base class in an isinstance
check. This was introduced when people realised that duck typing is awesome, but sometimes you really do want an instance check.
In your case (unittesting), you probably want to try it and see:
thingy = ...
try:
thingy.write( ... )
thingy.writeline( ... )
...
thingy.read( )
except AttributeError:
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With