10

The following code is what I tried first, but some_path.with_suffix('.jpg') obviously returns a pathlib.PosixPath object (I'm on Linux) instead of my version of PosixPath, because I didn't redefine with_suffix. Do I have to copy everything from pathlib or is there a better way?

import os
import pathlib
from shutil import rmtree


class Path(pathlib.Path):

    def __new__(cls, *args, **kwargs):
        if cls is Path:
            cls = WindowsPath if os.name == 'nt' else PosixPath
        self = cls._from_parts(args, init=False)
        if not self._flavour.is_supported:
            raise NotImplementedError("cannot instantiate %r on your system"
                                      % (cls.__name__,))
        self._init()
        return self

    def with_stem(self, stem):
        """
        Return a new path with the stem changed.

        The stem is the final path component, minus its last suffix.
        """
        if not self.name:
            raise ValueError("%r has an empty name" % (self,))
        return self._from_parsed_parts(self._drv, self._root,
                                       self._parts[:-1] + [stem + self.suffix])

    def rmtree(self, ignore_errors=False, onerror=None):
        """
        Delete the entire directory even if it contains directories / files.
        """
        rmtree(str(self), ignore_errors, onerror)


class PosixPath(Path, pathlib.PurePosixPath):
    __slots__ = ()


class WindowsPath(Path, pathlib.PureWindowsPath):
    __slots__ = ()
twasbrillig
  • 17,084
  • 9
  • 43
  • 67
Joschua
  • 5,816
  • 5
  • 33
  • 44
  • Maybe have a function decorator that converts `pathlib.Path` results to your `Path` class, then use `__metaclass__` or class decorators to apply this decorator to all class methods. – kalhartt Nov 16 '14 at 00:14
  • 1
    I don't see why you should need to do that. `with_suffix()` calls `_from_parsed_parts()`, which calls `object.__new__(cls)`. `cls` is your custom class, not anything from `pathlib`, so I don't see how you could end up with a `pathlib` class here. Anyone have any ideas? Perhaps OP needs to override `__repr__()` to see the difference? – Kevin Nov 16 '14 at 01:25

1 Answers1

3

Is some_path an instance of your version of Path?

I tested with the following 2 lines appended to your codes:

p = Path('test.foo')
print(type(p.with_suffix('.bar')))

Result is correct: <class '__main__.PosixPath'>

Only when using p = pathlib.Path('test.foo'), result is <class 'pathlib.PosixPath'>

ZZY
  • 3,689
  • 19
  • 22
  • It should have been an instance of my `Path`, but I don't know for sure and the problem doesn't occur anymore (and after reading the source code, I don't see why it should). What is the standard procedure for situations like this? Should I simply delete the question? – Joschua Dec 24 '14 at 15:30