Werkzeug: get_content_type()でのPython3互換性の問題

作成日 2014年12月04日  ·  10コメント  ·  ソース: pallets/werkzeug

私はジャンゴを使用してdjango_extensionsその用途は、使用している場合、デバッグのためにWERKZEUG runserver_plus 。 Werkzeugは、Python3を使用すると、次のトレースバックでget_content_type()で爆発するようです。

Traceback (most recent call last):
  File "/Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/serving.py", line 177, in run_wsgi
    execute(self.server.app)
  File "/Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/serving.py", line 165, in execute
    application_iter = app(environ, start_response)
  File "/Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/debug/__init__.py", line 173, in __call__
    response = self.get_resource(request, arg)
  File "/Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/debug/__init__.py", line 154, in get_resource
    return Response(f.read(), mimetype=mimetype)
  File "/Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/wrappers.py", line 749, in __init__
    mimetype = get_content_type(mimetype, self.charset)
  File "/Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/utils.py", line 224, in get_content_type
    if mimetype.startswith('text/') or \
TypeError: startswith first arg must be bytes or a tuple of bytes, not str
bug

最も参考になるコメント

こんにちは、これは上記のようにdjango-extensionsパッケージを使用するときによく発生します。 これは2年近く触れられていませんが、リンクされたMRのマージに問題はありますか?

全てのコメント10件

問題を修正するPRを提出

これがWerkzeugのせいなのか、Djangoが応答で間違った文字列型を使用しているのかはわかりません。

これがipdbの完全なトレースバックであり、Djangoがどこでも呼び出されているのを見ていません。 完全なstackstaceはwerkzeugだけにあるようです。

ipdb> w
  /Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/serving.py(692)inner()
    690         make_server(hostname, port, application, threaded,
    691                     processes, request_handler,
--> 692                     passthrough_errors, ssl_context).serve_forever()
    693 
    694     if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':

  /Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/serving.py(436)serve_forever()
    434         self.shutdown_signal = False
    435         try:
--> 436             HTTPServer.serve_forever(self)
    437         except KeyboardInterrupt:
    438             pass

  /usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/socketserver.py(238)serve_forever()
    236                                        poll_interval)
    237                 if self in r:
--> 238                     self._handle_request_noblock()
    239 
    240                 self.service_actions()

  /usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/socketserver.py(305)_handle_request_noblock()
    303         if self.verify_request(request, client_address):
    304             try:
--> 305                 self.process_request(request, client_address)
    306             except:
    307                 self.handle_error(request, client_address)

  /usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/socketserver.py(331)process_request()
    329 
    330         """
--> 331         self.finish_request(request, client_address)
    332         self.shutdown_request(request)
    333 

  /usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/socketserver.py(344)finish_request()
    342     def finish_request(self, request, client_address):
    343         """Finish one request by instantiating RequestHandlerClass."""
--> 344         self.RequestHandlerClass(request, client_address, self)
    345 
    346     def shutdown_request(self, request):

  /usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/socketserver.py(669)__init__()
    667         self.setup()
    668         try:
--> 669             self.handle()
    670         finally:
    671             self.finish()

  /Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/serving.py(200)handle()
    198         rv = None
    199         try:
--> 200             rv = BaseHTTPRequestHandler.handle(self)
    201         except (socket.error, socket.timeout) as e:
    202             self.connection_dropped(e)

  /usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/http/server.py(398)handle()
    396         self.close_connection = 1
    397 
--> 398         self.handle_one_request()
    399         while not self.close_connection:
    400             self.handle_one_request()

  /Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/serving.py(235)handle_one_request()
    233             self.close_connection = 1
    234         elif self.parse_request():
--> 235             return self.run_wsgi()
    236 
    237     def send_response(self, code, message=None):

  /Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/serving.py(177)run_wsgi()
    175 
    176         try:
--> 177             execute(self.server.app)
    178         except (socket.error, socket.timeout) as e:
    179             self.connection_dropped(e, environ)

  /Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/serving.py(165)execute()
    163 
    164         def execute(app):
--> 165             application_iter = app(environ, start_response)
    166             try:
    167                 for data in application_iter:

  /Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/debug/__init__.py(173)__call__()
    171             frame = self.frames.get(request.args.get('frm', type=int))
    172             if cmd == 'resource' and arg:
--> 173                 response = self.get_resource(request, arg)
    174             elif cmd == 'paste' and traceback is not None and \
    175                  secret == self.secret:

  /Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/debug/__init__.py(154)get_resource()
    152             f = open(filename, 'rb')
    153             try:
--> 154                 return Response(f.read(), mimetype=mimetype)
    155             finally:
    156                 f.close()

  /Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/wrappers.py(749)__init__()
    747                 mimetype = self.default_mimetype
    748             if mimetype is not None:
--> 749                 mimetype = get_content_type(mimetype, self.charset)
    750             content_type = mimetype
    751         if content_type is not None:

> /Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/utils.py(224)get_content_type()
    222     #     charset = charset.decode('utf-8')
    223     import ipdb; ipdb.set_trace()
--> 224     if mimetype.startswith('text/') or \
    225        mimetype == 'application/xml' or \
    226        (mimetype.startswith('application/') and

ipdb> type(mimetype), type(charset)
(<class 'bytes'>, <class 'str'>)

問題は上記の2フレームにあるようです。

ipdb> up
> /Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/wrappers.py(749)__init__()
    748             if mimetype is not None:
--> 749                 mimetype = get_content_type(mimetype, self.charset)
    750             content_type = mimetype

ipdb> up
> /Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/debug/__init__.py(154)get_resource()
    153             try:
--> 154                 return Response(f.read(), mimetype=mimetype)
    155             finally:

ipdb> l
    149         if isfile(filename):
    150             mimetype = mimetypes.guess_type(filename)[0] \
    151                 or 'application/octet-stream'
    152             f = open(filename, 'rb')
    153             try:
--> 154                 return Response(f.read(), mimetype=mimetype)
    155             finally:
    156                 f.close()
    157         return Response('Not Found', status=404)
    158 
    159     def __call__(self, environ, start_response):

ipdb> mimetypes.guess_type(filename)[0]
b'text/javascript'

奇妙なことに、 guess_typeはバイトと文字列を返します。 シェル内の同じファイルのタイプを推測しようとすると、文字列が表示されます。

>>> mimetype = mimetypes.guess_type('/Volumes/Data/Users/miki725/.virtualenvs/test-py3/lib/python3.4/site-packages/werkzeug/debug/shared/jquery.js')[0]
>>> type(mimetype)
<class 'str'>

get_content_type()ではなくここでmimetypeを変換するようにPRを調整する必要がありますか?

奇妙なことに、guess_typeはバイトと文字列を返します

あなたのPRは問題を解決しますが、あなたが言ったように、これは決して起こらないはずです。

guess_type呼び出しが発生するフレームのファイル名は何ですか?

その文字列。 guess_typeはファイル名と同じタイプを返すかもしれませんが、明らかにそうではありません。

こんにちは、これは上記のようにdjango-extensionsパッケージを使用するときによく発生します。 これは2年近く触れられていませんが、リンクされたMRのマージに問題はありますか?

最近私は同じ問題を抱えています、私にとってそれはjavascriptファイルで起こります。 デバッグ後、問題がdjango-pipelineであることがわかりました。 types_mapを変更し、これを設定しますhttps://github.com/jazzband/django-pipeline/blob/master/pipeline/conf.py#L81 -L87ここhttps://github.com/jazzband/django-pipeline/blob/master/pipeline/utils.py#L42-L43 ..:S:S ...解決するには、パイプライン設定でMIMETYPEを正しく設定する必要がありました。 。

たぶん、PRのマージを再考する必要があります。

これが誰かに役立つことを願っています...幸せなデバッグ!

Django-パイプラインは、mimetypeタイプマップにバイトを入れないように修正する必要があります。 Django-Extensionsは何もしていないようですが、それは他の依存関係が誤動作していることを意味します。 悪いデータを追加するライブラリで対処する必要があると思うので、これを閉じます。 誰かがmimetypesタイプマップでバイトが期待されるべきであるという正当な理由を投稿できるなら、私は再考します。

このページは役に立ちましたか?
0 / 5 - 0 評価