Opened 3 years ago

Last modified 3 years ago

#33653 closed Bug

no signature found for builtin raised for non-existant items — at Initial Version

Reported by: Daniel Owned by: nobody
Component: Template system Version: 3.2
Severity: Normal Keywords: template
Cc: Baptiste Mispelon Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Found during a 2.2 -> 3.2 upgrade:

Given a template:

{{ foo }}

where foo is non-existant, it returns nothing, empty. (That's good)

{{ foo.count }}

also empty (Also good)

{% include 'second_template.html' with bar=foo %}

and then in second_template.html having:

{{ foo.count }}

results in

  File "/Users/daniel/src/django-bug-test/.v/lib/python3.8/site-packages/django/template/base.py", line 861, in _resolve_lookup
    signature = inspect.signature(current)
  File "/Users/daniel/.pyenv/versions/3.8.3/lib/python3.8/inspect.py", line 3093, in signature
    return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
  File "/Users/daniel/.pyenv/versions/3.8.3/lib/python3.8/inspect.py", line 2842, in from_callable
    return _signature_from_callable(obj, sigcls=cls,
  File "/Users/daniel/.pyenv/versions/3.8.3/lib/python3.8/inspect.py", line 2296, in _signature_from_callable
    return _signature_from_builtin(sigcls, obj,
  File "/Users/daniel/.pyenv/versions/3.8.3/lib/python3.8/inspect.py", line 2107, in _signature_from_builtin
    raise ValueError("no signature found for builtin {!r}".format(func))

Exception Type: ValueError at /
Exception Value: no signature found for builtin <built-in method count of str object at 0x1100ff2f0>

On django 2.2, this would not crash, but resulted in empty (as I expected).

this seems to fix it for me:

diff --git a/django/template/base.py b/django/template/base.py
index a1ab437eca..f95aec5a90 100644
--- a/django/template/base.py
+++ b/django/template/base.py
@@ -913,15 +913,19 @@ def _resolve_lookup(self, context):
                         try:  # method call (assuming no args required)
                             current = current()
                         except TypeError:
-                            signature = inspect.signature(current)
                             try:
-                                signature.bind()
-                            except TypeError:  # arguments *were* required
-                                current = (
-                                    context.template.engine.string_if_invalid
-                                )  # invalid method call
+                                signature = inspect.signature(current)
+                            except ValueError: # python builtins might not have signature
+                                current = context.template.engine.string_if_invalid
                             else:
-                                raise
+                                try:
+                                    signature.bind()
+                                except TypeError:  # arguments *were* required
+                                    current = (
+                                        context.template.engine.string_if_invalid
+                                    )  # invalid method call
+                                else:
+                                    raise
         except Exception as e:
             template_name = getattr(context, "template_name", None) or "unknown"
             logger.debug(

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top