path: Why is not `Path("test.txt").parent.parent` a valid path?

Hello.

I love the concept of path.py, but this is the first time I use it and I am a bit disappointed.

While working with relative paths, I was wondering why Path("test.txt").parent.parent and Path("test.txt").parent return both "" instead of "../somefolder/" and ".".

My use case is very simple. The user gives me some string path where I need to create a file. So, I first need to create the folder where the file will be located.

Path("test.txt").parent.makedirs_p()

This raises a FileNotFoundError because path Path('') does not exist.

By extension, I notice that parent.parent will unfortunately not return a relative path starting with ...

I have the feeling that we miss the opportunity for a very useful feature here.

Do you think this would make sense to implement this?

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 16 (8 by maintainers)

Commits related to this issue

Most upvoted comments

I don’t understand how is the meaning of “parent” related to something being a file or not. Whether something is a file or a directory, its parent can be defined as “the directory which contains something”. What is the ambiguity I’m missing?

As I read this now, almost a year later, I don’t know what I was thinking at the time, but I agree with you, there does not seem to be any ambiguity.

In #194, I’ve added the proposal, basically unchanged from how I drafted it at the time of this discussion. Given that I’ve not had a use-case for this myself and that even the OP is not confident this behavior is needed, I’m going to suggest users interested in this feature try out a copy of Concrete locally. If it serves a useful purpose, please feel free to revisit this issue and report its usefulness (and any issues you might have encountered)… and this project will happily host it if it serves a need.

After considering it more closely, perhaps it is a false good idea…

I looked a bit at what was being done in other implementations.

Python’s documentation explictly states that “this is a purely lexical operation”.

This is why the equivalent of Path("../..").parent returns Path("..") in the three listed languages.

Is it the desired behavior for path.py? Would Path("../../..") seem more logical?


At first I thought we could simply use an absolute path internally, but of course it is a bad idea (a relative path converted to absolute will be incorrect if initialized in a different folder).

I think my initial misunderstanding comes from the fact that some methods of a Path() object act on the real and “physical” path (the file on the hard drive), while others work only on the string of the path. Path “strings” and Path “files” are two different things, and we have to be careful about what the method or attribute we are using is doing.

The thing is that some properties like .ctime will translate a relative path automatically in order to retrieve the value, while .parent or .name will directly perform on the string. On the other hand, methods like .dirname() returns a result with respect to the string while most other methods are related to the pointed file.

While doing some research, I found two issues that were somehow related to what I am describing: https://github.com/jaraco/path.py/issues/26 and https://github.com/jaraco/path.py/issues/58.

My opinion on this: a property which works on the file itself will, at least implicitly, convert a relative path into an absolute path to retrieve the information it needs. This is an important context-dependent operation, and should therefore be a method rather than an attribute.

So, ctime would become ctime() and getctime() could be removed. Quite conveniently, we could then have Path("../..").dirname == Path("..") and Path("../..").parent() == Path("../../..").

Sorry to get away from the initial problem, just sharing some thoughts.