python / python/typeshed

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

オープン
#15,526 コメント 6 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

主要言語
Python
スター
5.1k
フォーク
2.1k
平均マージ
1日 19時間
マージ済み PR(30日)
82

説明

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?

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

typeshed の汎用 slice スタブから始め、#13008 で議論されている new のアノテーションを #13007 の代替案と併せて確認します。issue の slice(42) の例を .start、.stop、.step の型と照合します。アノテーションが None を保持し、示されている type-checking の動作が正しければ完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
devtools
issue の種類
バグ
難易度
2/5
見積もり時間
1〜3時間
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
55/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。