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