Python の time.sleep の上限
これは何?
Python で、雑に「一生寝てろ」という気持ちで
time.sleep(1<<62)
としたら OverflowError: timestamp too large to convert to C PyTime_t と言われ、え、上限あるの? となったのでそのことを調べた話。
ちなみに、(1<<62) と書いたのは、整数になっても無理なくという気持ち。
調査対象
手元の環境で uv が入れてくれる範囲内で試した。
具体的には
| 名前 | 下限 | 上限 |
|---|---|---|
| CPython | 3.8 | 3.14 |
| Pypy | 3.8 (PyPy 7.3.11) | 3.11 (PyPy 7.3.20) |
| Graal | 3.10 (Java 22) | 3.12 (Java 25) |
という感じ。ハードウェアは Apple Silicon の MacBook。
二分探索
結果は下表
| バージョン | 上限 |
|---|---|
| CPython-3.14 | 9223372036.854774 = 0x1.12e0be826d694p+33 |
| CPython-3.13 | 9223372036.854774 = 0x1.12e0be826d694p+33 |
| CPython-3.12 | 9223372036.854774 = 0x1.12e0be826d694p+33 |
| CPython-3.11 | 9223372036.854774 = 0x1.12e0be826d694p+33 |
| CPython-3.10 | 100000000.99999899 = 0x1.7d78403ffffbcp+26 |
| CPython-3.9 | 100000000.99999899 = 0x1.7d78403ffffbcp+26 |
| CPython-3.8 | 100000000.99999899 = 0x1.7d78403ffffbcp+26 |
| pypy-3.11 | 9223372036.854774 = 0x1.12e0be826d694p+33 |
| pypy-3.10 | 100000000.99999999 = 0x1.7d78403ffffffp+26 |
| pypy-3.9 | 100000000.99999999 = 0x1.7d78403ffffffp+26 |
| pypy-3.8 | 100000000.99999999 = 0x1.7d78403ffffffp+26 |
| graalpy-3.12 | 9223372036854776.0 = 0x1.0624dd2f1a9fcp+53 |
| graalpy-3.11 | 9223372036854776.0 = 0x1.0624dd2f1a9fcp+53 |
見どころ
CPython
3.10 までと 3.11 からで仕様が変わったのかな。
3.10 までは 約 1億秒。3年ちょい。
上限が「1億秒 + 1秒 の手前」なのはどうかと思う。
3.11 からの 約 92億秒 は、10進数でも2進数でも中途半端な値となっていてパット見よくわからないけど、どうも 2の63乗 nano秒 ということらしい。
PyPy
表を見ると CPython とおなじに見えるが、実はちょっと違う。
雑な動作
import time
t0=time.time()
time.sleep(2**60+1)
print(f"ok: dur={time.time()-t0:.2f}s")
を実行すると、CPython では
File "/略/longsleep.py", line 4, in <module>
time.sleep(2**60+1)
~~~~~~~~~~^^^^^^^^^
OverflowError: timestamp too large to convert to C PyTime_t
と、ちゃんと例外になるが、pypy 3.8〜3.11 では
ok: dur=1.01s
などとなる。エラー処理が不足している。
GraalPy
Graal の Python で現れる 約 9223兆秒 という値は、2**63/1000 に等しい。ミリ秒単位で 64bit 符号付き整数を入れてるんだと思う。
所感
このような処理で、CPython・PyPy・graalpy に差異があるのは意外だった。
Windows では試していないけど、なんか違う結果になるかもしれないね。
CPython 3.10 などの 上限「約 (1億+1)秒」はもっと意外だった。ちょっとみっともない印象。
いずれにせよ、ちゃんとしていれば 3年 sleep とかしたいことはないので困ることはないのだけれど。
あ、PyPy でエラー処理が不足しているのは稀に困るかもね。
Discussion