Fixed #31989 -- Fixed return value of django.core.files.locks.lock()/unlock() on POSIX systems.

This commit is contained in:
Hasan Ramezani 2020-09-11 11:48:40 +02:00 committed by Mariusz Felisiak
parent 580a4341cb
commit 7be6a6a4d6
3 changed files with 28 additions and 5 deletions

View File

@ -107,9 +107,12 @@ else:
return True return True
else: else:
def lock(f, flags): def lock(f, flags):
ret = fcntl.flock(_fd(f), flags) try:
return ret == 0 fcntl.flock(_fd(f), flags)
return True
except BlockingIOError:
return False
def unlock(f): def unlock(f):
ret = fcntl.flock(_fd(f), fcntl.LOCK_UN) fcntl.flock(_fd(f), fcntl.LOCK_UN)
return ret == 0 return True

View File

@ -504,6 +504,10 @@ Miscellaneous
distinguishes inherited field instances across models. Additionally, the distinguishes inherited field instances across models. Additionally, the
ordering of such fields is now defined. ordering of such fields is now defined.
* The undocumented ``django.core.files.locks.lock()`` function now returns
``False`` if the file cannot be locked, instead of raising
:exc:`BlockingIOError`.
.. _deprecated-features-3.2: .. _deprecated-features-3.2:
Features deprecated in 3.2 Features deprecated in 3.2

View File

@ -8,7 +8,7 @@ from io import BytesIO, StringIO, TextIOWrapper
from pathlib import Path from pathlib import Path
from unittest import mock from unittest import mock
from django.core.files import File from django.core.files import File, locks
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.files.move import file_move_safe from django.core.files.move import file_move_safe
from django.core.files.temp import NamedTemporaryFile from django.core.files.temp import NamedTemporaryFile
@ -169,6 +169,22 @@ class FileTests(unittest.TestCase):
test_file.seek(0) test_file.seek(0)
self.assertEqual(test_file.read(), (content * 2).encode()) self.assertEqual(test_file.read(), (content * 2).encode())
def test_exclusive_lock(self):
file_path = Path(__file__).parent / 'test.png'
with open(file_path) as f1, open(file_path) as f2:
self.assertIs(locks.lock(f1, locks.LOCK_EX), True)
self.assertIs(locks.lock(f2, locks.LOCK_EX | locks.LOCK_NB), False)
self.assertIs(locks.lock(f2, locks.LOCK_SH | locks.LOCK_NB), False)
self.assertIs(locks.unlock(f1), True)
def test_shared_lock(self):
file_path = Path(__file__).parent / 'test.png'
with open(file_path) as f1, open(file_path) as f2:
self.assertIs(locks.lock(f1, locks.LOCK_SH), True)
self.assertIs(locks.lock(f2, locks.LOCK_SH | locks.LOCK_NB), True)
self.assertIs(locks.unlock(f1), True)
self.assertIs(locks.unlock(f2), True)
class NoNameFileTestCase(unittest.TestCase): class NoNameFileTestCase(unittest.TestCase):
""" """