Pythonで有限体を実装しようと思い立ち、j2kun/finite-fields · GitHubを参考に体上の多項式環を実装しようとしていた。
多項式の和で組み込みのsum
を利用しようとしたらTypeError
が生じた。原因を調べたところ、sum
内で組み込み型int
と自作の体のクラスと__add__
をしようとしてはまっていることがわかった。自作の体のクラスにはきちんと__add__
を定義しているのに…と思ってsum
の実装を調べてみた。
組み込みのsum
のコードの本質的と思われる箇所の抜粋は以下の通りである。
static PyObject * builtin_sum_impl(PyModuleDef *module, PyObject *iterable, PyObject *start) { PyObject *result = start; PyObject *temp, *item, *iter; iter = PyObject_GetIter(iterable); if (iter == NULL) return NULL; if (result == NULL) { result = PyLong_FromLong(0); if (result == NULL) { Py_DECREF(iter); return NULL; } } else { /* reject string values for 'start' parameter */ if (PyUnicode_Check(result)) { PyErr_SetString(PyExc_TypeError, "sum() can't sum strings [use ''.join(seq) instead]"); Py_DECREF(iter); return NULL; } if (PyBytes_Check(result)) { PyErr_SetString(PyExc_TypeError, "sum() can't sum bytes [use b''.join(seq) instead]"); Py_DECREF(iter); return NULL; } if (PyByteArray_Check(result)) { PyErr_SetString(PyExc_TypeError, "sum() can't sum bytearray [use b''.join(seq) instead]"); Py_DECREF(iter); return NULL; } Py_INCREF(result); } for(;;) { item = PyIter_Next(iter); if (item == NULL) { /* error, or end-of-sequence */ if (PyErr_Occurred()) { Py_DECREF(result); result = NULL; } break; } temp = PyNumber_Add(result, item); Py_DECREF(result); Py_DECREF(item); result = temp; if (result == NULL) break; } Py_DECREF(iter); return result; }
わかったこととして、
if (result == NULL) { result = PyLong_FromLong(0); if (result == NULL) { Py_DECREF(iter); return NULL; }
の部分でsum(iterable, start)
のstart
に何も入れないとint
型の0
がstart
に入り、
自作の型と__add__
をしようとしてエラーになった、と。
そのため、start
に自作の有限体の零元を入れることで期待通りの動作をした。
また、sum
関数は文字列を拒絶する旨がヘルプに書いてあるが、引用したコードを見るとバイト列も拒絶していることがわかる。
普段はPythonの内部ソースなんて気にしていないが、こう読んでみると面白い。
なお、ソースコードにはArgument Clinic How-To — Python 3.4.3 ドキュメントにあるツールが使われた痕跡があった。 Argument Clinicは"Monty Python's Flying Circus"の第3シーズンエピソード3の最後のスケッチが由来だと思われる。 "I'd like to have an argument please." という不思議な台詞から始まる。 案内された部屋に入ると罵声を浴びせられたり、謎の水掛け論の応酬が始まったり、仕舞いには突然ハンマーで殴られて「ここは頭を殴られる教室だ」と続き、そして警察が…とチャップマンとクリーズのケンブリッジ組が書いたと思われる会話主体の面白いスケッチである。