Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check that two python pathlib.Path have the same parents?

With two Path objects that share the same parent paths, how do you compare them to assert that they do in fact share the same parents?

>>> list(Path(input).parents)
[PosixPath('/usr/src/app'), PosixPath('/usr/src'), PosixPath('/usr'), PosixPath('/')]
>>> list(Path(output).parents)
[PosixPath('/usr/src/app'), PosixPath('/usr/src'), PosixPath('/usr'), PosixPath('/')]
>>> Path(input).parents == Path(output).parents
False

# huh?

Although the following works, it seems awkward to cast it to a List:

>>> list(Path(input).parents) == list(Path(output).parents)
True
like image 719
Darren Weber Avatar asked Mar 21 '26 02:03

Darren Weber


1 Answers

Path.parents actually returns a helper object which enables indexed access and efficient iteration over the path elements (of type pathlib._PathParents). As a result your comparison is failing because it is trying to compare these two helper objects rather than their contents.

The docs are somewhat misleading in this sense:

Path.parents: An immutable sequence providing access to the logical ancestors of the path

...to actually answer the question, you have options:

As pointed out in comments you can simply compare the parents:

Path(input).parent == Path(output).parent

This works in many cases but will not match if the path isn't of the same form - i.e. when .. appears in the path, or symlinks are present.

The Path(...).samefile(...) method provides a good way to avoid these issues, but be warned that using Path(...).parent.samefile(...) can still be a problem due to to parent calculation ignoring ...

Using the form Path(...).resolve().parent.samefile(...) is the most comprehensive way I've found of avoiding all of these issues.

For this particular question it would look like:

Path(input).resolve().parent.samefile(Path(output).resolve().parent)
like image 134
Ant Avatar answered Mar 23 '26 17:03

Ant