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
だったよ。と言ってくれています。
で、実装を確認したら、
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 サフィックス . . . . .:
と。ホスト名
が全角文字だったのが原因。
うーん(^^;)このパソコンを買ったときの自分を殴りたい。
解決手段
①ホスト名を直す。
こことかを参考に、PC名を直す。
そして、当然ですが、
PC名は、最大15文字の半角英数字(a~z、A~Z、0~9)を設定してください。
と書かれてるので、皆さんも気を付けましょう。。。
②socket.pyを直す。
OSSなので、コミットしてもいいかもですが、
すくなくとも、ホスト名を全角文字にするというアグレッシブなことがなければ、
この修正もいらないので、ローカルで直してみる。
これでもうまくいった。
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名に全角を使うんなかれ(^^;)