Python/C APIを読む その4(Noneオブジェクト)

#概要
Pythonの構造を理解する助けとして、C APIのドキュメントを読み砕いていく。

#内容
##環境
Python 3.7 (CPython)に話を固定したいが、必ずしもそうはならない。
[tree](https://github.com/python/cpython/tree/a144feeb7ec501aaf30072d50e70d54b200e5ef0)   ([コミット](https://github.com/python/cpython/commit/79373951b3eab585d42e0f0ab83718cbe1d0ee33); [ブランチ](https://github.com/python/cpython/tree/3.7))
(↑　githubのリンク)


##前置き
`None`に対する`PyTypeObject`は、Python/C APIでは直接公開されていないので注意。
`None`は単量子 (singleton) なので、オブジェクトの同一性テスト (C では`==`) を使うだけで十分であり、 `PyNone_Check()`関数はない。

##`PyObject* Py_None`
###＜概説＞
Pythonにおける`None`オブジェクトで、値がないことを表す。
参照カウントは他のオブジェクトと同様に扱う。メソッドはない。
###＜定義＞
```c:定義　(cpython/Include/object.h)
PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */
#define Py_None (&_Py_NoneStruct)
```
([定義出典](https://github.com/python/cpython/blob/f311290f091957653bba5ebfda28ad981bb78363/Include/object.h#L517))

###＜定義補足＞
```c:定義　(cpython/Include/object.h)
PyTypeObject _PyNone_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "NoneType",
    0,
    0,
    none_dealloc,       /*tp_dealloc*/ /*never called*/
    0,                  /*tp_vectorcall_offset*/
    0,                  /*tp_getattr*/
    0,                  /*tp_setattr*/
    0,                  /*tp_as_async*/
    none_repr,          /*tp_repr*/
    &none_as_number,    /*tp_as_number*/
    0,                  /*tp_as_sequence*/
    0,                  /*tp_as_mapping*/
    0,                  /*tp_hash */
    0,                  /*tp_call */
    0,                  /*tp_str */
    0,                  /*tp_getattro */
    0,                  /*tp_setattro */
    0,                  /*tp_as_buffer */
    Py_TPFLAGS_DEFAULT, /*tp_flags */
    0,                  /*tp_doc */
    0,                  /*tp_traverse */
    0,                  /*tp_clear */
    0,                  /*tp_richcompare */
    0,                  /*tp_weaklistoffset */
    0,                  /*tp_iter */
    0,                  /*tp_iternext */
    0,                  /*tp_methods */
    0,                  /*tp_members */
    0,                  /*tp_getset */
    0,                  /*tp_base */
    0,                  /*tp_dict */
    0,                  /*tp_descr_get */
    0,                  /*tp_descr_set */
    0,                  /*tp_dictoffset */
    0,                  /*tp_init */
    0,                  /*tp_alloc */
    none_new,           /*tp_new */
};

PyObject _Py_NoneStruct = {
  _PyObject_EXTRA_INIT
  1, &_PyNone_Type
};
```
([定義出典](https://github.com/python/cpython/blob/32bd68c839adb7b42af12366ab0892303115d1d1/Objects/object.c#L1617))
###＜使用例＞
```c:使用例　(cpython/Objects/stringlib/unicode_format.h)
        if (conversion == '\0') {
            conversion_str = Py_None;
```
([使用例出典](https://github.com/python/cpython/blob/32bd68c839adb7b42af12366ab0892303115d1d1/Objects/stringlib/unicode_format.h#L1043))


##`Py_RETURN_NONE`
###＜概説＞
C関数からの`Py_None`の返却を適切に扱う。
(`None`の参照カウントをインクリメントして返す。)
####＜定義＞
```c:定義　(cpython/Include/object.h)
#define Py_RETURN_NONE return Py_NewRef(Py_None)
```
([定義出典](https://github.com/python/cpython/blob/145bf269df3530176f6ebeab1324890ef7070bf8/Include/object.h#L571))

##＜使用例＞
```c:使用例　(cpython/Modules/readline.c)
    Py_RETURN_NONE;
}
```
([使用例出典](https://github.com/python/cpython/blob/755f3c1521b422bc2177013d289f5439975fdc4f/Modules/readline.c#L641))


#参考にさせていただいた本・ページ
- https://github.com/python/cpython/
- https://docs.python.org/ja/3/c-api/none.html

#感想
バージョンが混ざってしまっているかもしれないが、雰囲気を掴むことが目的なので、今のところそこを修正する予定はない。