flaskのソースコードを読んでいく(２)

以下のソースコードを読んでいきます。

https://github.com/pallets/flask/blob/master/src/flask/sessions.py

```Python
class SessionMixin(collections_abc.MutableMapping):
    """Expands a basic dictionary with session attributes."""

    @property
    def permanent(self):
        """This reflects the ``'_permanent'`` key in the dict."""
        return self.get("_permanent", False)

    @permanent.setter
    def permanent(self, value):
        self["_permanent"] = bool(value)

    #: Some implementations can detect whether a session is newly
    #: created, but that is not guaranteed. Use with caution. The mixin
    # default is hard-coded ``False``.
    new = False

    #: Some implementations can detect changes to the session and set
    #: this when that happens. The mixin default is hard coded to
    #: ``True``.
    modified = True

    #: Some implementations can detect when session data is read or
    #: written and set this when that happens. The mixin default is hard
    #: coded to ``True``.
    accessed = True
```
collections_abc.MutableMappingを継承した、SessionMixinを定義しています。SessionMixinはセッション属性によって、基本的な辞書を拡張するクラスのようです。Mapと辞書が同じ意味でここでは使われていますね。

collections_abc.MutableMappingは以下のところで定義されています。cpythonですね。
https://github.com/python/cpython/blob/master/Lib/_collections_abc.py#L767
説明文を読むと以下のように書いてあります。

```Python

    """A MutableMapping is a generic container for associating
    key/value pairs.
    This class provides concrete generic implementations of all
    methods except for __getitem__, __setitem__, __delitem__,
    __iter__, and __len__.
    """
```
キー/値ペアを関連付けるジェネリックのコンテナのようです。完全にMapの機能ですね。以下のようなメソッドがあります。


def __setitem__(self, key, value): #要素を追加
def __delitem__(self, key):　　#要素を削除
def pop(self, key, default=__marker):　 #指定されたキーにあたる値をポップ
def popitem(self):  #最後の値とキーのペアのタプルをポップ
def clear(self):　　#全ての値を削除
def update(self, other=(), /, **kwds):　#otherからMapをコピー
def setdefault(self, key, default=None):　#指定されたキーにデフォルト値を設定

これらは全てキー/値ペアを持つMapを制御するメソッドです。
@property属性が使われているようですが、@propertyはゲッターメソッドの前に使われるデコレータです。つまるところ、以下のコードはゲッターということになります。

```Python
    @property
    def permanent(self):
        """This reflects the ``'_permanent'`` key in the dict."""
        return self.get("_permanent", False)
```
ゲッターということは、permanentというプロパティが存在することになります。辞書においての、'_permanent'キーを持つ値を反映していることになります。ゲッターであるので、クラス外部に値を出力する必要があります。self.get("_permanent", False)によって、'_permanent'キーを持つ値を探し、その値を返し、存在しない場合はFalseを返すようです。

以下のコードは@permanent.setterが使われているため、セッターです。値をクラス外部からもらってきて、内部に格納します。

```Python
    @permanent.setter
    def permanent(self, value):
        self["_permanent"] = bool(value)
```

new属性について調べていきます。

```Python
    #: Some implementations can detect whether a session is newly
    #: created, but that is not guaranteed. Use with caution. The mixin
    # default is hard-coded ``False``.
    new = False
```
幾らかの実装において、セッションが新たに作られたものであるかを検出します。しかしながら、mixinはデフォルトにおいては、Falseにハードコードされています。もちろん後に変更できます。

```Python
    #: Some implementations can detect changes to the session and set
    #: this when that happens. The mixin default is hard coded to
    #: ``True``.
    modified = True
```
いくらかの実装において、セッションの変更を検出します。デフォルトにおいては、Trueにハードコードされています。

```Python
    #: Some implementations can detect when session data is read or
    #: written and set this when that happens. The mixin default is hard
    #: coded to ``True``.
    accessed = True
```
いくらかの実装において、セッションが読まれるか書かれる時、セットされる。デフォルトは、Trueにハードコードされている。

以上で言われている「いくらかの実装において」とは、SessionMixinがインポートされる局面ということが推測できます。また、以下のSecureCookieSessionのように、これを継承するクラスもフレームワーク内に存在し、またフレームワークであるため、これを継承するクラスをユーザーが作成することも推測できます。（githubで検索してみると多数ヒットする）

https://github.com/pallets/flask/blob/200ce9bd39c70a7782ef8ace0338ad71dbdb175d/src/flask/sessions.py#L53