#35041: DATA_UPLOAD_MAX_MEMORY_SIZE causes a confusing error when not an integer
-------------------------------------+-------------------------------------
Reporter: dtasev | Owner: nobody
Type: Bug | Status: new
Component: File | Version: 4.2
uploads/storage |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by dtasev:
Old description:
> When trying to POST to a FileField or ImageField, an error will be shown
> when trying to save the object (even without specifying a file) if
> DATA_UPLOAD_MAX_MEMORY_SIZE is not an integer.
>
> To replicate:
>
> {{{
> # in settings.py
> DATA_UPLOAD_MAX_MEMORY_SIZE = 4e7
>
> # in models.py
> from django.db import models
> class FileHolder(models.Model):
> file = models.FileField(upload_to="files", blank=True, null=True)
>
> # in admin,py
> from django.contrib import admin
> admin.site.register(FileHolder, EfasNewsAdmin)
> }}}
>
> Make migrations & migrate, then go to the Admin view of the model, create
> a new instance and save. There is no need to specify any file for upload,
> the error will be shown, here is a stacktrace with Django 4.2.8 and
> Python 3.11.6
>
> {{{
> Traceback (most recent call last):
> File "/usr/local/lib/python3.11/site-
> packages/django/core/handlers/exception.py", line 55, in inner
> response = get_response(request)
> ^^^^^^^^^^^^^^^^^^^^^
> File "/usr/local/lib/python3.11/site-
> packages/django/core/handlers/base.py", line 197, in _get_response
> response = wrapped_callback(request, *callback_args,
> **callback_kwargs)
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> File "/usr/local/lib/python3.11/site-
> packages/django/contrib/admin/options.py", line 688, in wrapper
> return self.admin_site.admin_view(view)(*args, **kwargs)
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> File "/usr/local/lib/python3.11/site-
> packages/django/utils/decorators.py", line 130, in _wrapper_view
> result = middleware.process_view(request, view_func, args, kwargs)
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> File "/usr/local/lib/python3.11/site-
> packages/django/middleware/csrf.py", line 470, in process_view
> self._check_token(request)
> File "/usr/local/lib/python3.11/site-
> packages/django/middleware/csrf.py", line 373, in _check_token
> request_csrf_token = request.POST.get("csrfmiddlewaretoken", "")
> ^^^^^^^^^^^^
> File "/usr/local/lib/python3.11/site-
> packages/django/core/handlers/wsgi.py", line 93, in _get_post
> self._load_post_and_files()
> File "/usr/local/lib/python3.11/site-packages/django/http/request.py",
> line 373, in _load_post_and_files
> self._post, self._files = self.parse_file_upload(self.META, data)
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> File "/usr/local/lib/python3.11/site-packages/django/http/request.py",
> line 321, in parse_file_upload
> return parser.parse()
> ^^^^^^^^^^^^^^
> File "/usr/local/lib/python3.11/site-
> packages/django/http/multipartparser.py", line 123, in parse
> return self._parse()
> ^^^^^^^^^^^^^
> File "/usr/local/lib/python3.11/site-
> packages/django/http/multipartparser.py", line 235, in _parse
> data = field_stream.read(size=read_size)
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> File "/usr/local/lib/python3.11/site-
> packages/django/http/multipartparser.py", line 465, in read
> return b"".join(parts())
> ^^^^^^^^^^^^^^^^^
> File "/usr/local/lib/python3.11/site-
> packages/django/http/multipartparser.py", line 460, in parts
> emitting = chunk[:remaining]
> ~~~~~^^^^^^^^^^^^
> TypeError: slice indices must be integers or None or have an __index__
> method
> }}}
>
> Changing DATA_UPLOAD_MAX_MEMORY_SIZE = 4e7 to DATA_UPLOAD_MAX_MEMORY_SIZE
> = 40000000 and repeating the steps will remove the error.
>
> As far as I can tell Django doesn't do type checking of the value of the
> settings, at least I couldn't get other settings to fail due to invalid
> types. If a type check during the "system check" step is not possible
> then an additional type assertion would be good so that a better error
> message can be shown as only integer works.
>
> I have only tested this through Django Admin, but the error happens
> inside django.http so perhaps it can be replicated via other ways of
> POST-ing.
>
> Related links:
> - StackOverflow question where I found the solution first:
> https://stackoverflow.com/questions/48865441/django-admin-typeerror-on-
> any-post-request
New description:
When trying to POST to a FileField or ImageField, an error will be shown
when trying to save the object (even without specifying a file) if
DATA_UPLOAD_MAX_MEMORY_SIZE is not an integer.
To replicate:
{{{
# in settings.py
DATA_UPLOAD_MAX_MEMORY_SIZE = 4e7
# in models.py
from django.db import models
class FileHolder(models.Model):
file = models.FileField(upload_to="files", blank=True, null=True)
# in admin,py
from django.contrib import admin
admin.site.register(FileHolder, admin.ModelAdmin)
}}}
Make migrations & migrate, then go to the Admin view of the model, create
a new instance and save. There is no need to specify any file for upload,
the error will be shown, here is a stacktrace with Django 4.2.8 and Python
3.11.6
{{{
Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-
packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-
packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args,
**callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-
packages/django/contrib/admin/options.py", line 688, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-
packages/django/utils/decorators.py", line 130, in _wrapper_view
result = middleware.process_view(request, view_func, args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-
packages/django/middleware/csrf.py", line 470, in process_view
self._check_token(request)
File "/usr/local/lib/python3.11/site-
packages/django/middleware/csrf.py", line 373, in _check_token
request_csrf_token = request.POST.get("csrfmiddlewaretoken", "")
^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-
packages/django/core/handlers/wsgi.py", line 93, in _get_post
self._load_post_and_files()
File "/usr/local/lib/python3.11/site-packages/django/http/request.py",
line 373, in _load_post_and_files
self._post, self._files = self.parse_file_upload(self.META, data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/http/request.py",
line 321, in parse_file_upload
return parser.parse()
^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-
packages/django/http/multipartparser.py", line 123, in parse
return self._parse()
^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-
packages/django/http/multipartparser.py", line 235, in _parse
data = field_stream.read(size=read_size)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-
packages/django/http/multipartparser.py", line 465, in read
return b"".join(parts())
^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-
packages/django/http/multipartparser.py", line 460, in parts
emitting = chunk[:remaining]
~~~~~^^^^^^^^^^^^
TypeError: slice indices must be integers or None or have an __index__
method
}}}
Changing DATA_UPLOAD_MAX_MEMORY_SIZE = 4e7 to DATA_UPLOAD_MAX_MEMORY_SIZE
= 40000000 and repeating the steps will remove the error.
As far as I can tell Django doesn't do type checking of the value of the
settings, at least I couldn't get other settings to fail due to invalid
types. If a type check during the "system check" step is not possible then
an additional type assertion would be good so that a better error message
can be shown as only integer works.
I have only tested this through Django Admin, but the error happens inside
django.http so perhaps it can be replicated via other ways of POST-ing.
Related links:
- StackOverflow question where I found the solution first:
https://stackoverflow.com/questions/48865441/django-admin-typeerror-on-
any-post-request
--
--
Ticket URL: <https://code.djangoproject.com/ticket/35041#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/0107018c6e187d83-f4bb3849-6b68-4684-a28c-e1815a2a0830-000000%40eu-central-1.amazonses.com.