python / python/typeshed

Properties `.start`, `.stop`, `. step` of (generic) `slice[...]` should be optional (`| None`)

Open
#15,526 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
5.1k
Forks
2.1k
Avg merge
1d 19h
Merged PRs (30d)
82

Description

Situation

#13008 made slice.__new__ more precise. Generic slice[T] accepts T | None as arguments when creating a slice.
However, properties .start, .stop, . step of (generic) slice[...] are typed as there respective types, i.e. T in above example.

Consequence

This leads to typecheckers accepting:

def test(s: slice[int]) -> None:
    assert_type(s.start, int)
    if s.start is None:
        assert_never(s.start)

whereas below obviously breaks:

test(slice(42))

Solution

Therefore, I suggest properties .start, .stop, . step should have optional (| None) return types:

    @property
    def start(self) -> _StartT_co | None: ...
    @property
    def step(self) -> _StepT_co | None: ...
    @property
    def stop(self) -> _StopT_co | None: ...

Alternative

Currently, typeshed uses slice[...] as slice[T | None] explicitly as per #13007, e.g.

class str:
    def __getitem__(self, key: SupportsIndex | slice[SupportsIndex | None], /) -> str: ...

While that works/typechecks correctly:

def test(s: slice[int | None]) -> None:
    assert_type(s.start, int | None)
    if s.start is None or isinstance(s.start, int):
        pass
    else:
        assert_never(s.start)

test(slice(42))   # okay
test(slice('x'))  # error: Argument 1 to "slice" has incompatible type "str"; expected "int | None"  [arg-type]

I see as downsides:

  1. it's error-prone / less ergonomic
  2. it renders part of #13008 __new__ overloading complexity superfluous
  3. it made #13007 more complex

Question

@Sachaa-Thanasius: Was the proposed solution considered for #13007?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at typeshed’s generic slice stub and review the new annotations discussed in #13008 alongside the alternative in #13007. Check the issue’s slice(42) examples against the .start, .stop, and .step types; done when the annotations preserve None and the shown type-checking behavior is correct.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.