On Mon, Feb 13, 2012 at 2:01 PM, Bruce Eckel <lists.ec...@gmail.com> wrote: > I'm creating a class to encapsulate OS paths, to reduce the visual > noise and typing from the os.path methods. I've got the class and nose > tests below, and everything works except the last test which I've > prefixed with XXX: > > def XXXtest_should_work(self): > """ > Produces: > open(self.p2, 'w').write('') > TypeError: coercing to Unicode: need string or buffer, Path > found > """ > open(self.p2, 'w').write('') > assert self.p2 > > Note that I *have* a __str__(self) method to perform automatic > conversion to string, and I've commented out the __unicode__(self) > method because it wasn't getting called. The problem appears to be > that open() does not seem to be calling __str__ on its first argument, > but instead it appears to want a basestring and this doesn't > automatically call __str__.
Right. Python is strongly-typed, so it requires a genuine str here (as opposed to just something that's stringifyable) and doesn't do an coercion call to str() for you. Just like how str.join() doesn't automatically call str() on the elements of the list you give it. This is to prevent silliness like trying to open() e.g. a dict. Your alternatives are: - Learn to live with having to write open(str(path_obj)) - Add a .open() method to Path, and use that instead of the open() built-in function - Have Path subclass `str` or `unicode` > I'm trying to write the Path class so I can just hand a Path object > to, for example, open() and have it produce the path string. Impossible, short of subclassing `str` or `unicode`. Cheers, Chris -- http://mail.python.org/mailman/listinfo/python-list