Werkzeug: Masalah kompatibilitas Python3 di get_content_type()

Dibuat pada 4 Des 2014  ·  10Komentar  ·  Sumber: pallets/werkzeug

Saya menggunakan Django dengan django_extensions yang menggunakan werkzeug untuk debugging saat menggunakan runserver_plus . Werkzeug tampaknya meledak di get_content_type() dengan traceback berikut saat menggunakan Python3:

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

Komentar yang paling membantu

Hai, ini sering terjadi saat menggunakan paket django-extensions seperti yang disebutkan di atas. Ini belum tersentuh dalam hampir 2 tahun, apakah ada masalah dengan menggabungkan MR yang ditautkan?

Semua 10 komentar

mengirimkan PR yang memperbaiki masalah

Saya tidak yakin apakah ini kesalahan Werkzeug atau Django menggunakan tipe string yang salah dalam tanggapannya.

Ini traceback penuh di ipdb dan saya tidak melihat Django dipanggil di mana pun. Stackstace lengkap tampaknya hanya ada di 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'>)

Masalahnya sepertinya ada di 2 frame di atas:

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'

Yang aneh adalah guess_type mengembalikan byte vs string. Saat mencoba menebak jenis file yang sama di Shell saya mendapatkan string:

>>> 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'>

Haruskah saya menyesuaikan PR untuk mengonversi mimetype di sini alih-alih di get_content_type() ?

Yang aneh adalah bahwa guess_type mengembalikan byte vs string

PR Anda memang menyelesaikan masalah, tetapi ini seharusnya tidak pernah terjadi, seperti yang Anda katakan.

Apa nama file dalam bingkai tempat panggilan guess_type terjadi?

talinya. Saya pikir itu mungkin guess_type mengembalikan tipe yang sama dengan nama file tetapi ternyata tidak demikian.

Hai, ini sering terjadi saat menggunakan paket django-extensions seperti yang disebutkan di atas. Ini belum tersentuh dalam hampir 2 tahun, apakah ada masalah dengan menggabungkan MR yang ditautkan?

Baru-baru ini saya mendapat masalah yang sama, bagi saya itu terjadi pada file javascript. Setelah debugging saya menemukan masalah saya adalah Django-pipeline: itu memodifikasi types_map dan mengatur ini https://github.com/jazzband/Django-pipeline/blob/master/pipeline/conf.py#L81 -L87 di sini https://github.com/jazzband/Django-pipeline/blob/master/pipeline/utils.py#L42 -L43 .. :S :S ... .

Mungkin Anda harus mempertimbangkan kembali untuk menggabungkan PR.

Semoga ini bisa membantu seseorang ... selamat men-debug!

Django-Pipelines harus diperbaiki sehingga tidak memasukkan byte ke dalam peta tipe mimetype. Django-Extensions tampaknya tidak melakukan apa pun, tetapi itu hanya berarti beberapa ketergantungan lain berperilaku tidak semestinya. Saya menutup ini karena saya pikir itu harus ditangani di perpustakaan menambahkan data yang buruk. Jika seseorang dapat memposting alasan bagus bahwa byte harus diharapkan dalam peta tipe mimetypes, saya akan mempertimbangkan kembali.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat