Problems trying to override __str__ on path class

Peter Otten __peter__ at web.de
Mon Oct 23 04:35:04 EDT 2006


Mike Krell wrote:

> Peter Otten <__peter__ at web.de> wrote in
> news:ehggfk$60i$00$1 at news.t-online.com:
>  
>> I get
>> 
>> np: "overridden __str__: c:/mbk/test"
>> str(np): "overridden __str__: c:/mbk/test"
>> overridden __str__: overridden __str__: c:/mbk/test/appendtest
> 
> Hmmm.  I guess you're not running under windows, since normpath()
> converts / to \ on windows.  I wonder if that's part of the problem.
> 
>  
>> Are you using the latest version of the path module?
> 
> My path.py says it's 2.1, which is the latest according to the site.
> 
>  Older versions
>> implied a Path() call in the __div__() operator which would explain at
>> least the output you get for
>> 
>> print np / 'appendtest'
> 
> You've lost me here.  What do you mean about "implied a Path() call"?
> Here is the definition of __div__ from path.py:
> 
> '''
>     # The / operator joins paths.
>     def __div__(self, rel):
>         """ fp.__div__(rel) == fp / rel == fp.joinpath(rel)
> 
>         Join two path components, adding a separator character if
>         needed.
>         """
>         return self.__class__(os.path.join(self, rel))
> '''

>From http://www.jorendorff.com/articles/python/path/changes.html:

"""
This page describes recent changes to the Python path module.

2.1

[...]

Better support for subclassing path. All methods that returned path objects
now respect subclassing.

Before: type(PathSubclass(s).parent) is path

Now: type(PathSubclass(s).parent) is PathSubclass
"""

So my assumption was that you are using a pre-2.1 version of path.
I suggest that you double-check that by inserting a

print path.__version__

into the code showing the odd behaviour before you start looking for more
exotic causes.

> I still don't understand the TypeError in the delegation case.

For newstyle classes

a = A()
a / 42 # or any other operation implemented via __xxx__()

(unlike a.__div__) will only look into the class for a __div__() special
method and ignore methods defined in the instance or via the __getattr__()
mechanism.

For delegation to work you need (untested)

class NormPath(object):
   def __div__(self, other):
       return self.__class__(self._path / other)
   # ...

Peter



More information about the Python-list mailing list