-
Notifications
You must be signed in to change notification settings - Fork 53
Description
tl;dr: Each scenario adds a new recursion level in multiple places (usually the settings fetch), and ends up throwing RecursionError: maximum recursion depth exceeded. The error can be replicated with a vanilla Django project from Django 4.1 onward. I am unable to find a culprit and require help from someone to investigate further. The issue doesn't happen on vanilla LiveServerTestCase unit tests. The recursion error is not consistently in the same place.
Background
After bumping from Django 5.0.x to 5.1 in a project, our feature tests started to fail after ~50min with the error pasted in the collapsed menu below. Turns out once too many tests are ran, a recursion error happens.
Click to expand!
Scenario Outline: server-side validation with invalid data: Injection Post above maximum -- @1.14 # FeatureTests/features/update_gfr.feature:134
Given I am logged in as clinician1 # FeatureTests/steps/login.py:17
2025-06-17 09:54:00,092 - ERROR - django.request - Internal Server Error: /accounts/login/
Traceback (most recent call last):
return self._cursor()
File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 296, in _cursor
self.ensure_connection()
File "/usr/local/lib/python3.10/site-packages/django/test/testcases.py", line 311, in patched_ensure_connection
real_ensure_connection(self, *args, **kwargs)
File "/usr/local/lib/python3.10/site-packages/django/test/testcases.py", line 311, in patched_ensure_connection
real_ensure_connection(self, *args, **kwargs)
File "/usr/local/lib/python3.10/site-packages/django/test/testcases.py", line 311, in patched_ensure_connection
real_ensure_connection(self, *args, **kwargs)
[Previous line repeated 319 more times]
File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 279, in ensure_connection
self.connect()
File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 255, in connect
conn_params = self.get_connection_params()
File "/usr/local/lib/python3.10/site-packages/django/db/backends/postgresql/base.py", line 295, in get_connection_params
settings.USE_TZ, self.timezone
File "/usr/local/lib/python3.10/site-packages/django/conf/__init__.py", line 83, in __getattr__
val = getattr(_wrapped, name)
File "/usr/local/lib/python3.10/site-packages/django/conf/__init__.py", line 235, in __getattr__
return getattr(self.default_settings, name)
File "/usr/local/lib/python3.10/site-packages/django/conf/__init__.py", line 235, in __getattr__
return getattr(self.default_settings, name)
File "/usr/local/lib/python3.10/site-packages/django/conf/__init__.py", line 235, in __getattr__
return getattr(self.default_settings, name)
[Previous line repeated 292 more times]
RecursionError: maximum recursion depth exceeded
Reproduction
This super plain Django project reproduces the error. It has:
- Dependencies managed with Poetry
- The latest Django version
- Starts a PostgreSQL DB in docker-compose
- No models
- Just 1 "Scenario Outline" calling 1 step that does nothing 1000+ times
- The recursion limit set to
sys.setrecursionlimit(300)in the settings.py to fail a bit faster.
The project:
django_issue.zip
To use: unzip and:
- run
make allto run the 1000+ repeated feature tests - run
make run-unit-teststo compare with 1200 unit tests not failing - Change
pyproject.tomlline for django todjango = "4.1"to test with Django 4.1 (it will use behave-django 1.4.0) or<4.1to check with the version that doesn't fail.- Then
poetry updatethenmake allto replicate the issue
- Then
Here is the end of the output of make all. Note that the stack is different than the above error. The error is not really consistently in the same place, meaning there are recursion errors in several places.
Click to expand!
Scenario Outline: A plain scenario -- @1.131 # features/feature_one.feature:138
Given I run a step # features/steps/steps.py:3 0.000s
Scenario Outline: A plain scenario -- @1.132 # features/feature_one.feature:139
Given I run a step # features/steps/steps.py:3 0.000s
Scenario Outline: A plain scenario -- @1.133 # features/feature_one.feature:140
Given I run a step # features/steps/steps.py:3 0.000s
Exception RecursionError: maximum recursion depth exceeded
Traceback (most recent call last):
File "/home/paul/git/REDACTED/django_issue/manage.py", line 22, in <module>
main()
~~~~^^
File "/home/paul/git/REDACTED/django_issue/manage.py", line 18, in main
execute_from_command_line(sys.argv)
~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
utility.execute()
~~~~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/__init__.py", line 436, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/base.py", line 416, in run_from_argv
self.execute(*args, **cmd_options)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/base.py", line 460, in execute
output = self.handle(*args, **options)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave_django/management/commands/behave.py", line 197, in handle
exit_status = behave_main(args=behave_args)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/__main__.py", line 290, in main
return run_behave(config)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/__main__.py", line 112, in run_behave
failed = runner.run()
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/runner.py", line 936, in run
return self.run_with_paths()
~~~~~~~~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/runner.py", line 956, in run_with_paths
return self.run_model()
~~~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/runner.py", line 757, in run_model
failed = feature.run(self)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/model.py", line 418, in run
failed = run_item.run(runner)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/model.py", line 1668, in run
failed = scenario.run(runner)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/model.py", line 1231, in run
runner.run_hook("after_scenario", runner.context, self)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave_django/environment.py", line 147, in run_hook
django_test_runner.teardown_test(context)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave_django/environment.py", line 124, in teardown_test
context.test._post_teardown(run=True)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave_django/testcase.py", line 20, in _post_teardown
super()._post_teardown()
~~~~~~~~~~~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/test/testcases.py", line 1227, in _post_teardown
self._fixture_teardown()
~~~~~~~~~~~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/test/testcases.py", line 1262, in _fixture_teardown
call_command(
~~~~~~~~~~~~^
"flush",
^^^^^^^^
...<5 lines>...
inhibit_post_migrate=inhibit_post_migrate,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/__init__.py", line 194, in call_command
return command.execute(*args, **defaults)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/base.py", line 460, in execute
output = self.handle(*args, **options)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/commands/flush.py", line 52, in handle
sql_list = sql_flush(
self.style,
...<2 lines>...
allow_cascade=allow_cascade,
)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/sql.py", line 11, in sql_flush
tables = connection.introspection.django_table_names(
only_existing=True, include_views=False
)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/db/backends/base/introspection.py", line 110, in django_table_names
existing_tables = set(self.table_names(include_views=include_views))
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/db/backends/base/introspection.py", line 56, in table_names
with self.connection.cursor() as cursor:
~~~~~~~~~~~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/db/backends/base/base.py", line 320, in cursor
return self._cursor()
~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/db/backends/base/base.py", line 296, in _cursor
self.ensure_connection()
~~~~~~~~~~~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/test/testcases.py", line 311, in patched_ensure_connection
real_ensure_connection(self, *args, **kwargs)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/test/testcases.py", line 311, in patched_ensure_connection
real_ensure_connection(self, *args, **kwargs)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/test/testcases.py", line 311, in patched_ensure_connection
real_ensure_connection(self, *args, **kwargs)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
[Previous line repeated 130 more times]
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/db/backends/base/base.py", line 279, in ensure_connection
self.connect()
~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/db/backends/base/base.py", line 257, in connect
self.set_autocommit(self.settings_dict["AUTOCOMMIT"])
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/db/backends/base/base.py", line 473, in set_autocommit
self.ensure_connection()
~~~~~~~~~~~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/test/testcases.py", line 311, in patched_ensure_connection
real_ensure_connection(self, *args, **kwargs)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/test/testcases.py", line 311, in patched_ensure_connection
real_ensure_connection(self, *args, **kwargs)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/test/testcases.py", line 311, in patched_ensure_connection
real_ensure_connection(self, *args, **kwargs)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
[Previous line repeated 130 more times]
RecursionError: maximum recursion depth exceeded
make: *** [Makefile:31: run-feature-tests] Error 1
And here with Django 4.1:
Click to expand!
Scenario Outline: A plain scenario -- @1.267 # features/feature_one.feature:274
Given I run a step # features/steps/steps.py:3 0.000s
Scenario Outline: A plain scenario -- @1.268 # features/feature_one.feature:275
Given I run a step # features/steps/steps.py:3 0.000s
Scenario Outline: A plain scenario -- @1.269 # features/feature_one.feature:276
Given I run a step # features/steps/steps.py:3 0.000s
Exception RecursionError: maximum recursion depth exceeded
Traceback (most recent call last):
File "/home/paul/git/REDACTED/django_issue/manage.py", line 22, in <module>
main()
~~~~^^
File "/home/paul/git/REDACTED/django_issue/manage.py", line 18, in main
execute_from_command_line(sys.argv)
~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
utility.execute()
~~~~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/__init__.py", line 440, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/base.py", line 402, in run_from_argv
self.execute(*args, **cmd_options)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/base.py", line 448, in execute
output = self.handle(*args, **options)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave_django/management/commands/behave.py", line 150, in handle
exit_status = behave_main(args=behave_args)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/__main__.py", line 183, in main
return run_behave(config)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/__main__.py", line 127, in run_behave
failed = runner.run()
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/runner.py", line 804, in run
return self.run_with_paths()
~~~~~~~~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/runner.py", line 824, in run_with_paths
return self.run_model()
~~~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/runner.py", line 626, in run_model
failed = feature.run(self)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/model.py", line 321, in run
failed = scenario.run(runner)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/model.py", line 1114, in run
failed = scenario.run(runner)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave/model.py", line 758, in run
runner.run_hook("after_scenario", runner.context, self)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave_django/environment.py", line 126, in run_hook
django_test_runner.teardown_test(context)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave_django/environment.py", line 103, in teardown_test
context.test._post_teardown(run=True)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/behave_django/testcase.py", line 20, in _post_teardown
super(BehaviorDrivenTestMixin, self)._post_teardown()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/test/testcases.py", line 1270, in _post_teardown
self._fixture_teardown()
~~~~~~~~~~~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/test/testcases.py", line 1304, in _fixture_teardown
call_command(
~~~~~~~~~~~~^
"flush",
^^^^^^^^
...<5 lines>...
inhibit_post_migrate=inhibit_post_migrate,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/__init__.py", line 198, in call_command
return command.execute(*args, **defaults)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/base.py", line 448, in execute
output = self.handle(*args, **options)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/commands/flush.py", line 51, in handle
sql_list = sql_flush(
self.style,
...<2 lines>...
allow_cascade=allow_cascade,
)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/core/management/sql.py", line 11, in sql_flush
tables = connection.introspection.django_table_names(
only_existing=True, include_views=False
)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/db/backends/base/introspection.py", line 110, in django_table_names
existing_tables = set(self.table_names(include_views=include_views))
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/db/backends/base/introspection.py", line 56, in table_names
with self.connection.cursor() as cursor:
~~~~~~~~~~~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/db/backends/base/base.py", line 323, in cursor
return self._cursor()
~~~~~~~~~~~~^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/db/backends/base/base.py", line 301, in _cursor
return self._prepare_cursor(self.create_cursor(name))
~~~~~~~~~~~~~~~~~~^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/db/backends/postgresql/base.py", line 270, in create_cursor
cursor.tzinfo_factory = self.tzinfo_factory if settings.USE_TZ else None
^^^^^^^^^^^^^^^
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/conf/__init__.py", line 94, in __getattr__
val = getattr(_wrapped, name)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/conf/__init__.py", line 270, in __getattr__
return getattr(self.default_settings, name)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/conf/__init__.py", line 270, in __getattr__
return getattr(self.default_settings, name)
File "/home/paul/git/REDACTED/django_issue/.venv/lib/python3.13/site-packages/django/conf/__init__.py", line 270, in __getattr__
return getattr(self.default_settings, name)
[Previous line repeated 265 more times]
RecursionError: maximum recursion depth exceeded
make: *** [Makefile:31: run-feature-tests] Error 1
Debugging
I recommend adding a breakpoint in your venv's django.conf.UserSettingsHolder.__getattr__, make it conditional like name == "DEBUG" and observe the stack having 1 more __getattr__ call per test. These are the kind of stacks I saw:
Here in Django 5
__getattr__, __init__.py:236
__getattr__, __init__.py:241
__getattr__, __init__.py:241
__getattr__, __init__.py:83
get_connection_params, base.py:295
connect, base.py:255
inner, asyncio.py:26
ensure_connection, base.py:279
inner, asyncio.py:26
patched_ensure_connection, testcases.py:311
patched_ensure_connection, testcases.py:311
patched_ensure_connection, testcases.py:311
patched_ensure_connection, testcases.py:311
_cursor, base.py:296
cursor, base.py:320
inner, asyncio.py:26
execute_sql, compiler.py:1621
__iter__, query.py:91
_fetch_all, query.py:1949
__len__, query.py:366
get, query.py:629
manager_method, manager.py:87
get_by_natural_key, base_user.py:37
authenticate, backends.py:65
authenticate, __init__.py:114
sensitive_variables_wrapper, debug.py:75
clean, forms.py:366
sensitive_variables_wrapper, debug.py:75
_clean_form, forms.py:354
full_clean, forms.py:338
errors, forms.py:201
is_valid, forms.py:206
post, edit.py:150
dispatch, base.py:144
dispatch, views.py:89
_view_wrapper, cache.py:80
_wrapper, decorators.py:48
_view_wrapper, decorators.py:190
_wrapper, decorators.py:48
sensitive_post_parameters_wrapper, debug.py:143
_wrapper, decorators.py:48
_wrapper, decorators.py:48
view, base.py:105
_get_response, base.py:197
inner, exception.py:55
__call__, deprecation.py:120
inner, exception.py:55
__call__, deprecation.py:120
inner, exception.py:55
__call__, deprecation.py:120
inner, exception.py:55
__call__, deprecation.py:120
inner, exception.py:55
__call__, deprecation.py:120
inner, exception.py:55
__call__, deprecation.py:120
inner, exception.py:55
__call__, middleware.py:123
inner, exception.py:55
__call__, deprecation.py:120
inner, exception.py:55
__call__, deprecation.py:120
inner, exception.py:55
__call__, middleware.py:56
inner, exception.py:55
get_response, base.py:140
__call__, wsgi.py:124
__call__, testcases.py:1695
__call__, handlers.py:80
run, handlers.py:137
handle_one_request, basehttp.py:253
handle, basehttp.py:230
__init__, socketserver.py:766
finish_request, socketserver.py:362
process_request_thread, socketserver.py:697
process_request_thread, basehttp.py:103
run, threading.py:992
_bootstrap_inner, threading.py:1041
_bootstrap, threading.py:1012
Here in Django 4.1
__getattr__, __init__.py:270
__getattr__, __init__.py:270
__getattr__, __init__.py:270
__getattr__, __init__.py:270
__getattr__, __init__.py:94
__init__, middleware.py:15
load_middleware, base.py:61
__init__, wsgi.py:125
run, testcases.py:1747
_bootstrap_inner, threading.py:1016
_bootstrap, threading.py:973
Another one in 4.1
__getattr__, __init__.py:270
__getattr__, __init__.py:270
__getattr__, __init__.py:270
__getattr__, __init__.py:94
swapped, options.py:413
get_models, config.py:258
<listcomp>, utils.py:278
get_migratable_models, utils.py:278
<genexpr>, introspection.py:87
django_table_names, introspection.py:99
sql_flush, sql.py:11
handle, flush.py:51
execute, base.py:448
call_command, __init__.py:198
_fixture_teardown, testcases.py:1304
_post_teardown, testcases.py:1270
_post_teardown, testcase.py:20
teardown_test, environment.py:103
run_hook, environment.py:126
run, model.py:758
run, model.py:1114
run, model.py:321
run_model, runner.py:626
run_with_paths, runner.py:824
run, runner.py:804
run_behave, __main__.py:127
main, __main__.py:183
handle, behave.py:150
execute, base.py:448
run_from_argv, base.py:402
execute, __init__.py:440
run_as_django_behave, _jb_django_behave.py:38
<module>, behave_runner.py:331
And a normal one in 4.0
# Note: there is only ever 1 __getattr__ called after that
swapped, options.py:417
get_models, config.py:293
<listcomp>, utils.py:301
get_migratable_models, utils.py:301
<genexpr>, introspection.py:87
django_table_names, introspection.py:99
sql_flush, sql.py:11
handle, flush.py:51
execute, base.py:460
call_command, __init__.py:198
_fixture_teardown, testcases.py:1230
_post_teardown, testcases.py:1196
_post_teardown, testcase.py:20
teardown_test, environment.py:103
run_hook, environment.py:126
run, model.py:758
run, model.py:1114
run, model.py:321
run_model, runner.py:626
run_with_paths, runner.py:824
run, runner.py:804
run_behave, __main__.py:127
main, __main__.py:183
handle, behave.py:150
execute, base.py:460
run_from_argv, base.py:414
execute, __init__.py:440
run_as_django_behave, _jb_django_behave.py:38
<module>, behave_runner.py:331
