Search code examples
pythonpathlib

How does pathlib.Path implement '/' when the left operand is a string?


I understand how __truediv__ works, per this answer.

But in this case:

>>> from pathlib import Path
>>> 'foo' / Path('bar')
PosixPath('foo/bar')

Surely __truediv__ is called on str, because 'foo' is the left operand to /, in that case how can it return a Path?


Solution

  • Here's a toy path – call it a ploth. It implements __rtruediv__ and __truediv__, so you can use it for division either way around. Since str does not implement either __rtruediv__ or __truediv__, Ploth gets to do that. (I'm only deriving from str to get a convenient constructor and __repr__().)

    class Ploth(str):
        def __rtruediv__(self, other):
            print(f"__rtruediv__({self!r}, {other!r})")
            return f"{other!r} / {self!r}"
    
        def __truediv__(self, other):
            print(f"__truediv__({self!r}, {other!r})")
            return f"{self!r} / {other!r}"
    
    
    print("plar" / Ploth("ploth"))
    print(Ploth("ploth") / "plar")
    

    This prints out:

    __rtruediv__('ploth', 'plar')
    'plar' / 'ploth'
    __truediv__('ploth', 'plar')
    'ploth' / 'plar'
    

    From Python's docs on __rtruediv__:

    These methods are called to implement the binary arithmetic operations (+, -, *, @, /, //, %, divmod(), pow(), **, <<, >>, &, ^, |) with reflected (swapped) operands. These functions are only called if the left operand does not support the corresponding operation and the operands are of different types.