Bobby Ocean
Bobby Ocean

Reputation: 3294

Custom pathlib.Path()

I attempted to customize pathlib.Path() with extra features. In particular, I really like to use a context manager as a method to move in and out of a directory. I use this all the time, but I seem to be getting errors on getting Path() to work with a custom context manager. Does anyone know why the code below causes an error and how do I fix it, without re-creating all Path() in a custom class?

# Python 3.7.3; Ubuntu 18.04.1
from pathlib import Path
import os
class mypath(Path):
    def __enter__(self):
        self.prdir = os.getcwd()
        os.chdir(str(self))
    def __exit__(self,**error_stuff):
        os.chdir(self.prdir)

p = mypath('~').expanduser()
...
AttributeError: type object 'mypath' has no attribute '_flavour'

Upvotes: 3

Views: 807

Answers (1)

progmatico
progmatico

Reputation: 4964

It works if you subclass from a derived concrete class instead of Path.

from pathlib import PosixPath
import os
class mypath(PosixPath):
    def __enter__(self):
        print('Entering...')
        self.prdir = os.getcwd()
        os.chdir(str(self))
    def __exit__(self, e_type, e_value, e_traceback):
        os.chdir(self.prdir)
        print('Exiting...')

p = mypath('~').home()
with p:
    # print(p.prdir)
    print(p)

Unfortunately I don't know why is that so. And you might want to be more generic. After some research I found that this question is much better than it looks. It seems this has to do with the way a Path is created (the way it chooses to be either a PosixPath or a WindowsPath), in that the behaviour cannot be replicated by subclasses of Path.

See Kevin's answer here

Please also take a look at the discussion and explanations here.

I cannot read it all right now. You can also try to take a look at pathlib source code.

Upvotes: 1

Related Questions