#34204: Django cannot load when Python is compiled with --without-doc-strings
enabled
-----------------------------------------+------------------------
Reporter: Jon Janzen | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 4.1
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+------------------------
I'm not sure that this is even a supported configuration for Django, but
CPython's `./configure` script offers an option called
[https://docs.python.org/3/using/configure.html#cmdoption-without-doc-
strings --without-doc-strings] which improves memory utilization slightly.
Quoting the relevant portion from CPython docs:
> --without-doc-strings
> Disable static documentation strings to reduce the memory footprint
(enabled by default). Documentation strings defined in Python are not
affected.
I have an use-case where I need to deploy a Django service on a device
with low available memory. I'd like to disable built-in doc strings as
part of an overall strategy to reduce memory but compiling CPython with
that option and running the django service crashes:
{{{
File ".../asgi.py", line 3, in <module>
from django.core.asgi import get_asgi_application
File ".../lib/python3.11/site-packages/django/core/asgi.py", line 2, in
<module>
from django.core.handlers.asgi import ASGIHandler
File ".../lib/python3.11/site-packages/django/core/handlers/asgi.py",
line 11, in <module>
from django.core.handlers import base
File ".../lib/python3.11/site-packages/django/core/handlers/base.py",
line 11, in <module>
from django.urls import get_resolver, set_urlconf
File ".../lib/python3.11/site-packages/django/urls/__init__.py", line 1,
in <module>
from .base import (
File ".../lib/python3.11/site-packages/django/urls/base.py", line 8, in
<module>
from .exceptions import NoReverseMatch, Resolver404
File ".../lib/python3.11/site-packages/django/urls/exceptions.py", line
1, in <module>
from django.http import Http404
File ".../lib/python3.11/site-packages/django/http/__init__.py", line 2,
in <module>
from django.http.request import (
File ".../lib/python3.11/site-packages/django/http/request.py", line 8,
in <module>
from django.core import signing
File ".../lib/python3.11/site-packages/django/core/signing.py", line 43,
in <module>
from django.utils.crypto import constant_time_compare, salted_hmac
File ".../lib/python3.11/site-packages/django/utils/crypto.py", line 85,
in <module>
if func_supports_parameter(hashlib.md5, 'usedforsecurity'):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/django/utils/inspect.py", line
74, in func_supports_parameter
return any(param.name == name for param in
_get_callable_parameters(func))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/django/utils/inspect.py", line
16, in _get_callable_parameters
return _get_func_parameters(func, remove_first=is_method)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/django/utils/inspect.py", line 7,
in _get_func_parameters
parameters = tuple(inspect.signature(func).parameters.values())
^^^^^^^^^^^^^^^^^^^^^^^
File ".../cpython/Lib/inspect.py", line 3270, in signature
return Signature.from_callable(obj, follow_wrapped=follow_wrapped,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../cpython/Lib/inspect.py", line 3018, in from_callable
return _signature_from_callable(obj, sigcls=cls,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../cpython/Lib/inspect.py", line 2510, in
_signature_from_callable
return _signature_from_builtin(sigcls, obj,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../cpython/Lib/inspect.py", line 2317, in _signature_from_builtin
raise ValueError("no signature found for builtin {!r}".format(func))
ValueError: no signature found for builtin <built-in function openssl_md5>
}}}
(irrelevant information lightly censored)
Looking through this stack trace the problem looks to be
[https://github.com/django/django/blob/d10c7bfe56f025ccc690721c9f13e7029b777b9c/django/utils/crypto.py#L80-L92
some code] that executes at module import to determine whether or not md5
supports the `usedforsecurity` parameter.
If this ticket is accepted I'm happy to put up a PR to fix this, I've
included my proposed solution on this ticket to save a roundtrip in
discussion:
{{{
diff --git a/django/utils/inspect.py b/django/utils/inspect.py
index 28418f7312..d8622a22df 100644
--- a/django/utils/inspect.py
+++ b/django/utils/inspect.py
@@ -70,4 +70,12 @@ def method_has_no_args(meth):
def func_supports_parameter(func, name):
- return any(param.name == name for param in
_get_callable_parameters(func))
+ try:
+ callable_parameters = _get_callable_parameters(func)
+ except ValueError:
+ # When Python is compiled with the --without-doc-strings
+ # argument to ./configure the signatures for built-in
+ # functions are not available. In such a case, be
+ # conservative and assume no:
+ return False
+ return any(param.name == name for param in callable_parameters)
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34204>
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/01070184f578bae9-bad3b9a5-a7cb-4a19-b6f7-543c2df42e89-000000%40eu-central-1.amazonses.com.