Python Bottle で UnicodeDecodeError が発生したときに確認した方がいいことと、回避方法

# PythonのBottleフレームワークでハマった。
WindowsPC を使って、PythonのBottleアプリを使って、
サービスを実行したときに、

```
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 0: invalid start byte
```
というエラーが出て、
実行が出来ない状態になってしまった。
その時に確認したことと、回避方法を説明する。

# 確認したこと
まず、エラーの内容を確認する。

```
> python .\service.py
Bottle v0.12.16 server starting up (using WSGIRefServer())...
Listening on http://0.0.0.0:5000/
Hit Ctrl-C to quit.

Traceback (most recent call last):
  File ".\service.py", line 41, in <module>
    run(host="0.0.0.0", port=5000)
  File "C:\Users\xxx\Programs\Python\Python37\lib\site-packages\bottle.py", line 3129, in run
    server.run(app)
  File "C:\Users\xxx\Programs\Python\Python37\lib\site-packages\bottle.py", line 2781, in run
    srv = make_server(self.host, self.port, app, server_cls, handler_cls)
  File "C:\Users\xxx\Programs\Python\Python37\lib\wsgiref\simple_server.py", line 153, in make_server
    server = server_class((host, port), handler_class)
  File "C:\Users\xxx\Programs\Python\Python37\lib\socketserver.py", line 452, in __init__
    self.server_bind()
  File "C:\Users\xxx\Programs\Python\Python37\lib\wsgiref\simple_server.py", line 50, in server_bind
    HTTPServer.server_bind(self)
  File "C:\Users\xxx\Programs\Python\Python37\lib\http\server.py", line 139, in server_bind
    self.server_name = socket.getfqdn(host)
  File "C:\Users\xxx\Programs\Python\Python37\lib\socket.py", line 676, in getfqdn
    hostname, aliases, ipaddrs = gethostbyaddr(name)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 0: invalid start byte
```

で、これは何を言っているのかというと、

```
  File "C:\Users\xxx\Programs\Python\Python37\lib\socket.py", line 676, in getfqdn
    hostname, aliases, ipaddrs = gethostbyaddr(name)
```
`socket.py`といファイルの、676行目にある、
`gethostbyaddr(name)`という処理で、

```
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 0: invalid start byte
```
だったよ。と言ってくれています。

で、実装を確認したら、

```python:socket.py抜粋
def getfqdn(name=''):
    """Get fully qualified domain name from name.

    An empty argument is interpreted as meaning the local host.

    First the hostname returned by gethostbyaddr() is checked, then
    possibly existing aliases. In case no FQDN is available, hostname
    from gethostname() is returned.
    """
    name = name.strip()
    if not name or name == '0.0.0.0':
        name = gethostname() ★ここからとられるnameが元凶
    try:
        print(name)
        hostname, aliases, ipaddrs = gethostbyaddr(name) ☆ここが問題箇所
    except error:
        pass
    else:
        aliases.insert(0, hostname)
        for name in aliases:
            if '.' in name:
                break
        else:
            name = hostname
    return name
```
↑の状況なので、
`cmd`を開き、`ipconfig /all`を確認したところ、

```
>ipconfig /all

Windows IP 構成

   ホスト名. . . . . . . . . . . . . . .: ほげほげ
   プライマリ DNS サフィックス . . . . .:
```
と。`ホスト名`が全角文字だったのが原因。
うーん(＾＾；)このパソコンを買ったときの自分を殴りたい。

# 解決手段
### ①ホスト名を直す。
[こことか](https://121ware.com/qasearch/1007/app/servlet/relatedqa?QID=017895)を参考に、PC名を直す。
そして、当然ですが、

> PC名は、最大15文字の半角英数字（a～z、A～Z、0～9）を設定してください。

と書かれてるので、皆さんも気を付けましょう。。。

### ②socket.pyを直す。
OSSなので、コミットしてもいいかもですが、
すくなくとも、ホスト名を全角文字にするというアグレッシブなことがなければ、
この修正もいらないので、ローカルで直してみる。
これでもうまくいった。

```python:socket.py抜粋
def getfqdn(name=''):
    """Get fully qualified domain name from name.

    An empty argument is interpreted as meaning the local host.

    First the hostname returned by gethostbyaddr() is checked, then
    possibly existing aliases. In case no FQDN is available, hostname
    from gethostname() is returned.
    """
    name = name.strip()
    if not name or name == '0.0.0.0':
        name = gethostname()
    try:
        print(name)
        hostname, aliases, ipaddrs = gethostbyaddr(name.encode("utf-8")) ★修正
    except error:
        pass
    else:
        aliases.insert(0, hostname)
        for name in aliases:
            if '.' in name:
                break
        else:
            name = hostname
    return name
```

# 結論
ホスト名、PC名に全角を使うんなかれ(＾＾；)