Title: pathlib.PurePath.parents rejects negative indexes
Type: enhancement Stage:
Components: Library (Lib) Versions: Python 3.8
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: akira, barry, pitrou, r.david.murray, thejcannon
Priority: normal Keywords: patch

Created on 2014-03-23 22:16 by akira, last changed 2018-12-17 15:06 by thejcannon.

File name Uploaded Description Edit
pathlib-parents-allow-negative-index.patch akira, 2014-03-23 22:16 the fix and tests review
Messages (10)
msg214642 - (view) Author: Akira Li (akira) * Date: 2014-03-23 22:16
`pathlib.PurePath.parents` is a sequence [1] but it rejects negative indexes:

  >>> from pathlib import PurePath
  >>> PurePath('a/b/c').parents[-2]
  Traceback (most recent call last):
  IndexError: -2

Sequences in Python interpret negative indexes as `len(seq) + i` [2]

I've included the patch that fixes the issue and adds corresponding tests. No documentation changes are needed.

msg214709 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-03-24 18:55
I think this is a doc bug.  That object shouldn't be called a sequence, since it isn't one.
msg214716 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2014-03-24 19:50
Well, it is a sequence, it's just that it doesn't respect the convention about negative indices :-)

As to why they are disallowed, I don't remember exactly (!) but I think it's because the exact semantics would be confusing otherwise.
msg214717 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-03-24 19:57
Which is exactly what I mean by saying it is not a sequence.  It is 'sequence-like'.  Kind of like email Messages are dict-like: they share many methods and behaviors, but the exact behaviors and semantics are different.
msg215746 - (view) Author: Akira Li (akira) * Date: 2014-04-08 09:05

> An iterable which supports efficient element access using integer indices via the __getitem__() special method and defines a __len__() method that returns the length of the sequence.

.parents *is* a sequence. And it *is* confusing that it doesn't accept negative indexes -- that is how I've encountered the bug.

Antoine, could you elaborate on what are the negative consequences of negative indexes to justify breaking the expectations?
msg223048 - (view) Author: Barry A. Warsaw (barry) * (Python committer) Date: 2014-07-14 18:55
Aren't negative indexes well defined in Python?  E.g.

>>> p = Path('/tmp/tmp123/foo/bar/baz.xz')
>>> p.parents[len(p.parents)-2]

p.parents[-2] should == p.parents[len(p.parents)-2]
msg223054 - (view) Author: Akira Li (akira) * Date: 2014-07-14 20:16
> Aren't negative indexes well defined in Python?  

yes. I've provided the link to Python docs [1] in msg214642 that 
explicitly defines the behavior:

> If i or j is negative, the index is relative to the end of the string: 
> len(s) + i or len(s) + j is substituted. But note that -0 is still 0.

msg223059 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2014-07-14 20:59
#7951 has an interesting debate on negative indexes that is possibly applicable here.
msg225503 - (view) Author: Akira Li (akira) * Date: 2014-08-18 19:17
> #7951 has an interesting debate on negative indexes that is possibly applicable here.

Mark could you point to a message that explains why p.parents[-2] is worse
than p.parents[len(p.parents)-2]?
msg332008 - (view) Author: Joshua Cannon (thejcannon) * Date: 2018-12-17 15:06
I created issue35498 about .parents rejecting slices as well. (It was pointed out this discussion would probably decide that issue's fate)
I think that .parents looking like a duck, but not quacking like one isn't very pythonic.

Besides, the fact that p.parents[len(p.parents)-2] is allowed but p.parents[-2] is not just seems like extra steps. There's also list(p.parents)[-2], which is still not ideal. In either case, I'd imagine authors to put a comment like "PathLib .parents doesn't support negative indexes", which goes to show clients are expecting negative indices to work.

I see that this issue is several years old. I'm happy to shepherd it if it needs further contributions.
Date User Action Args
2018-12-17 15:06:05thejcannonsetnosy: + thejcannon
messages: + msg332008
2018-12-16 16:35:30BreamoreBoysetnosy: - BreamoreBoy
2018-12-16 11:27:24serhiy.storchakasettype: behavior -> enhancement
versions: + Python 3.8, - Python 3.4, Python 3.5
2018-12-16 11:27:04serhiy.storchakalinkissue35498 dependencies
2014-08-18 19:17:12akirasetmessages: + msg225503
2014-07-14 20:59:14BreamoreBoysetnosy: + BreamoreBoy
messages: + msg223059
2014-07-14 20:16:46akirasetmessages: + msg223054
2014-07-14 18:55:58barrysetmessages: + msg223048
2014-07-14 18:53:23barrysetnosy: + barry
2014-04-08 09:05:31akirasetmessages: + msg215746
2014-03-24 19:57:38r.david.murraysetmessages: + msg214717
2014-03-24 19:50:16pitrousetmessages: + msg214716
2014-03-24 18:55:41r.david.murraysetmessages: + msg214709
2014-03-24 18:53:35r.david.murraysetnosy: + pitrou, r.david.murray
2014-03-24 18:50:12akirasettype: behavior
2014-03-23 22:16:51akiracreate