Path.parents does not play as good sequence

July Tikhonov avatarJuly Tikhonov created an issue

Recent commit 045d415 introduced parents attribute of paths, which is declared to behave like a sequence. A notable difference from most sequences is that its __getitem__() method returns a value for any positive index, instead of raising IndexError for those greater than len()-1.

One of the consequences is that its __iter__() method, derived from Sequence, never stops yielding values, since it expects a sequence to raise IndexError at its end, and does not pay any attention to the value of len() (which is well-defined in this case). Hence loop for p in path.parents: will never exhaust. Moreover, a condition if Path('/not/a/parent') in path.parents: will hang forever too (in false case), because __contains__() implementation of Sequence is bounded to iteration over the sequence.

I propose reimplementing _PathParents.__iter__() method, so it will yield only len() values.

Alternative can be changing the semantics of __getitem__() to make it raise IndexError for indices greater than len()-1 (this will more strictly conform to the language definition of __getitem__ special method, but make path.parents[1] == path.parent.parent not always true).

On the other hand, this can be considered a bug in Sequence.__iter__() implementation, which probably should pay attention to the value of len(), since the abstract class requires it to be defined anyway.

Comments (2)

  1. Log in to comment
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.