Werkzeug: مشكلة توافق Python3 في get_content_type ()

تم إنشاؤها على ٤ ديسمبر ٢٠١٤  ·  10تعليقات  ·  مصدر: pallets/werkzeug

أستخدم Django مع django_extensions والذي يستخدم werkzeug لتصحيح الأخطاء عند استخدام runserver_plus . يبدو أن Werkzeug ينفجر في get_content_type() مع التتبع التالي عند استخدام 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

التعليق الأكثر فائدة

مرحبًا ، يحدث هذا غالبًا عند استخدام حزمة django-extensions كما هو مذكور أعلاه. لم يتم التطرق إلى هذا منذ ما يقرب من عامين ، فهل هناك أي مشكلة في دمج MR المرتبط؟

ال 10 كومينتر

العلاقات العامة المقدمة والتي تعمل على حل المشكلة

لست متأكدًا مما إذا كان هذا خطأ Werkzeug أم أن Django يستخدم أنواع سلسلة خاطئة في ردوده.

هذا هو التتبع الكامل في ipdb ولا أرى استدعاء Django في أي مكان. يبدو أن مكدس تكديس كامل موجود فقط في 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'>)

يبدو أن المشكلة في إطارين أعلاه:

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 يعرض بايت مقابل السلسلة. عند محاولة تخمين نوع الملف نفسه في shell ، أحصل على سلسلة نصية:

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

هل يجب أن أقوم بضبط PR لتحويل mimetype هنا بدلاً من get_content_type() ؟

الغريب أن guess_type يقوم بإرجاع بايت مقابل سلسلة

العلاقات العامة الخاصة بك تعمل على حل المشكلة ، لكن هذا ما كان يجب أن يحدث أبدًا ، كما قلت.

ما اسم الملف في الإطار الذي تحدث فيه المكالمة guess_type ؟

خيطها. على الرغم من أن هذا ربما يعرض guess_type نفس النوع مثل اسم الملف ولكن يبدو أنه ليس كذلك.

مرحبًا ، يحدث هذا غالبًا عند استخدام حزمة django-extensions كما هو مذكور أعلاه. لم يتم التطرق إلى هذا منذ ما يقرب من عامين ، فهل هناك أي مشكلة في دمج MR المرتبط؟

حصلت مؤخرًا على نفس المشكلة ، بالنسبة لي يحدث ذلك في ملفات جافا سكريبت. بعد تصحيح الأخطاء ، وجدت أن مشكلتي كانت 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 ... لحل هذه المشكلة ، كان علي فقط تعيين MIMETYPES بشكل صحيح على إعدادات خطوط الأنابيب الخاصة بي .

ربما يجب عليك إعادة النظر في دمج العلاقات العامة.

آمل أن يساعد هذا شخصًا ما ... تصحيح أخطاء سعيد!

يجب إصلاح خطوط أنابيب Django بحيث لا تضع بايت في خريطة نوع mimetype. لا يبدو أن Django-Extensions تفعل أي شيء ، لكن هذا يعني فقط أن بعض التبعية الأخرى تسيء التصرف. أقوم بإغلاق هذا لأنني أعتقد أنه يجب معالجته في المكتبات التي تضيف البيانات السيئة. إذا تمكن شخص ما من نشر سبب وجيه وهو توقع البايت في خريطة نوع mimetypes ، فسأعيد النظر.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات