Repository navigation
Potential regression in Python 3.11 (multiprocess shutdown?) #97641
Description
Running the Django test suite against the Python 3.11 pre-releases, we have hit
a potential regression.
Steps to reproduce
git clone https://github.com/django/django.git
python3.11 -m venv env
.\env\Scripts\Activate.ps1
python -m pip install -e django
cd django\tests
python runtests.py --parallel
Bug report
On Python 3.8, 3.9, and 3.10 this runs without problem.
On Python 3.11 the following error in seen after the test suite completes,
during shutdown:
Traceback (most recent call last):
File "C:\Users\carlt\src\django\tests\runtests.py", line 773, in <module>
failures = django_tests(
^^^^^^^^^^^^^
File "C:\Users\carlt\src\django\tests\runtests.py", line 432, in django_tests
failures = test_runner.run_tests(test_labels)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\carlt\src\django\django\test\runner.py", line 1057, in run_tests
self.teardown_databases(old_config)
File "C:\Users\carlt\src\django\django\test\runner.py", line 980, in teardown_databases
_teardown_databases(
File "C:\Users\carlt\src\django\django\test\utils.py", line 378, in teardown_databases
connection.creation.destroy_test_db(
File "C:\Users\carlt\src\django\django\db\backends\base\creation.py", line 307, in destroy_test_db
self._destroy_test_db(test_database_name, verbosity)
File "C:\Users\carlt\src\django\django\db\backends\sqlite3\creation.py", line 111, in _destroy_test_db
os.remove(test_database_name)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'other_1.sqlite3'
This looked similar to us to open issue #95027 but we were asked to report it
separately.
I've tested all the way back to a1 where (along with other issues now resolved)
this error still occurs:
(django-py311) PS C:\Users\carlt\src\django\tests> python --version
Python 3.11.0rc2
...
(django-py311) PS C:\Users\carlt\src\django\tests> python --version
Python 3.11.0a1
This is somewhat frustrating as we've tried to test on all platforms since the
first releases.
Our test suite would only run on Windows with Python 3.11 very recently as
there was a third-party dependency that was not compatible with Windows. We
will try to adjust to test without dependencies as well on Windows for future
versions. (Sorry about that.)
Please do let us know if we can provide further info. I imagine though the
easiest thing is for you to run this yourself.
Thanks.
//cc @felixxm
Your environment
- CPython versions tested on: 3.11 pre-releases from a1 to rc2.
- Operating system and architecture: Windows 11.
Activity
sobolevn commentedon Sep 29, 2022
Based on
C:\Users\carlt\src\django\django\db\backends\sqlite3\creation.pyI think it might be sqlite related 🤔corona10 commentedon Oct 2, 2022
cc @erlend-aasland
erlend-aasland commentedon Oct 3, 2022
I don't have access to a PC with Windows 11, so unfortunately I am unable debug this :( If someone with Windows 11 could do a bisect, that would be super helpful.
A lot of changes happened between 3.10 entered the beta phase and the first 3.11 alpha was released:
carltongibson commentedon Oct 4, 2022
Hi @erlend-aasland I've given this a try but I'm hitting various (A, for earlier commits) tool-chain and (B, for later commits) linker errors trying to build previous versions that (frankly) I'm not familiar enough with Windows, or building CPython for that matter, to be able to progress with in a reasonable timeframe.
I was able to reproduce the issue at 0474d06, but I'm getting build errors by a3c11ce. A Windows expert would likely have more success.
(Sorry to not be of more help. Hopefully I'm a few steps along the road for the future.)
carltongibson commentedon Oct 4, 2022
Hi @erlend-aasland I've given this a try but I'm hitting various (A, for earlier commits) tool-chain and (B, for later commits) linker errors trying to build previous versions that I'm not familiar enough with Windows, or building CPython for that matter, to be able to progress with in a reasonable timeframe.
I was able to reproduce the issue at 0474d06, but I'm getting build errors by a3c11ce. A Windows expert would likely have more success.
I'm happy to keep trying, but I've reached a bit of a roadblock with building Python failing
(Sorry to not be of more help. Hopefully I'm a few steps along the road for the future.)
felixxm commentedon Oct 5, 2022
Can someone add
OS-Windowslabel? 🪟felixxm commentedon Oct 5, 2022
I'm not sure if it's related 🤔 but after forcing
spawnon Linux, I'm getting:tkanhe commentedon Oct 5, 2022
Just checked on following PC specifications:
Edition: Windows 11 Home Single Language
Version: 21H2
OS build: 22000.1042
with Python 3.11.0rc2, Django-4.2.dev20221005120449
Output:
`PS C:\Users\TK\Desktop> cd django\testsPS C:\Users\TK\Desktop\django\tests> python runtests.py --parallel
Testing against Django installed in 'C:\Users\TK\Desktop\django\django' with up to 16 processes
Found 16023 test(s).
Creating test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Cloning test database for alias 'default'...
Creating test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
Cloning test database for alias 'other'...
System check identified no issues (17 silenced).
ssssssssssssssssssssssssssssssssssssssssssssss.................................................................ss.........s.....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................s..............................................s..................................................................................................................s.....................s.....sss..ss.....................................................................................................................................................................................................................................................................................................................................................................................................s.....................................................................................................................................................................................s.................................................................s................sss...s.ss.....s..ss.sss..s......ss.s.................s........s.....................ss.....................s..s....s...s.....................s..............s......s...s...ss............s.....................
Ran 16021 tests in 74.720s
OK (skipped=1828, expected failures=5)
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'default'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...
Destroying test database for alias 'other'...`
*truncked some of .......sss........ output.
Let me know any other info/tests needed; I will be happy to help in the future regarding testing on Windows 11.
stic commentedon Oct 5, 2022
Couldn't replicate on auto (16 cores laptop).
python runtests.py --parallelBumping it up to ~40 started hitting the sharing violation on the removal of the 'other_1.sqlite3' (weirdly only the 1st i.e. other_1).
python runtests.py --parallel 40So confirmed on latest 3.11.0rc2.
I've disabled Windows Defender on the folder under test (django) as well as %TEMP% to make sure Windows Defender it's not causing issues. That's due to fact that I've got quite a few issues with pickling (i.e. cleaning after that) e.g.
Not 100% sure if that's a good troubleshooting approach, but a few observations:
Pass that passes manages to call CloseFile from the first process, that is the process creating the other_1.sqlite3 and it's the same process that will try to delete the db file (clean-up). Crashing test run doesn't make such CloseFile call, last syscalls seen on system level are to unlock the file. In itself that shouldn't be a problem I guess (as it's the same PID trying to close / remove the file later on). However, there is quite a gap (up to 2sec on my box) between syscalls to unlock the file and close. Can't really figure it out yet (first time with Django test suit), but if you compare vs. a run on 3.10 there is a visible wait whilst: Creating test database for alias 'other'...
Working theory - we are coming back on the same PID (process) to clean-up a file, that we are still keeping open (for close operation) elsewhere?
erlend-aasland commentedon Oct 10, 2022
FTR, I'm in the process of installing a Windows 11 development environment now. Will hopefully be up and running by this evening, or at least tomorrow. I'll need to delve into how to debug CPython on Windows using Visual Studio, since I have little experience with both Windows and Visual Studio.
erlend-aasland commentedon Oct 10, 2022
cc. release-manager @pablogsal
17 remaining items
erlend-aasland commentedon Oct 28, 2022
True, it used that hack. Part of my motivation for getting rid of the (duplicate) LRU cache implementation in the _sqlite extension module was getting rid of this hack.
That would have been possible, but you'd keep the GC hack. I'm not sure that is a very good idea.
tests: garbage collect sqlite connections on Windows + Python 3.11
tests: garbage collect sqlite connections on Windows + Python 3.11
tests: garbage collect sqlite connections on Windows + Python 3.11
gc.collect() before unlinking the db in some tests
gc.collect() before unlinking the db in some tests (#14491)
gc.collect() before unlinking the db in some tests (more)
gc.collect() before unlinking the db in some tests (more) (#14702)
Add explicit connection cleanup
erlend-aasland commentedon Aug 17, 2023
Following gh-108015, sqlite3 will now emit a ResourceWarning if connection objects are closed implicitly. Explicit resource management is recommended. cc. @eryksun
erlend-aasland commentedon Aug 22, 2023
gh-108015 has now landed; Python 3.13 will emit a ResourceWarning if a connection object is closed implicitly. Explicit resource management is now recommended. @felixxm has reported that Django already started to clean up their test suite (django/django#17178).
It seems to me the problems mentioned in this issue can all be handled by improved resource management. Suggesting to close this.
erlend-aasland commentedon Jan 12, 2024
Closing as per #97641 (comment).