action-hero
action-hero copied to clipboard
test_on_multiple_mixed_existing_files fails on Windows Python 3.7+
Only Python 3.7+ are available in Windows Store atm, and 3.7, 3.8 and 3.10 all have same error.
I dont see any Windows specific notes in https://docs.python.org/3/library/tempfile.html#tempfile.mkstemp , however there is one in https://docs.python.org/3/library/os.html#os.remove .
_________ TestEnsureFileAction.test_on_multiple_mixed_existing_files __________
self = <tests.test_path.TestEnsureFileAction testMethod=test_on_multiple_mixed_existing_files>
def test_on_multiple_mixed_existing_files(self):
self.parser.add_argument("--path", nargs="+", action=EnsureFileAction)
with tempfile.TemporaryDirectory() as parent_directory:
# Specify few new temporary files
file1 = tempfile.mkstemp(dir=parent_directory)[1]
file2 = tempfile.mkstemp(dir=parent_directory)[1]
# files deleted immediately to confirm they do not exist
file3 = tempfile.mkstemp(dir=parent_directory)[1]
> os.remove(file3)
E PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\61412\\AppData\\Local\\Temp\\tmpfhz9tczn\\tmp2a11n1sq'
tests\test_path.py:186: PermissionError
During handling of the above exception, another exception occurred:
path = 'C:\\Users\\61412\\AppData\\Local\\Temp\\tmpfhz9tczn'
onerror = <function TemporaryDirectory._rmtree.<locals>.onerror at 0x000001FEB85130A0>
def _rmtree_unsafe(path, onerror):
try:
with os.scandir(path) as scandir_it:
entries = list(scandir_it)
except OSError:
onerror(os.scandir, path, sys.exc_info())
entries = []
for entry in entries:
fullname = entry.path
if _rmtree_isdir(entry):
try:
if entry.is_symlink():
# This can only happen if someone replaces
# a directory with a symlink after the call to
# os.scandir or entry.is_dir above.
raise OSError("Cannot call rmtree on a symbolic link")
except OSError:
onerror(os.path.islink, fullname, sys.exc_info())
continue
_rmtree_unsafe(fullname, onerror)
else:
try:
> os.unlink(fullname)
E PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\61412\\AppData\\Local\\Temp\\tmpfhz9tczn\\tmp2a11n1sq'
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\shutil.py:617: PermissionError
During handling of the above exception, another exception occurred:
func = <built-in function unlink>
path = 'C:\\Users\\61412\\AppData\\Local\\Temp\\tmpfhz9tczn\\tmp2a11n1sq'
exc_info = (<class 'PermissionError'>, PermissionError(13, 'The process cannot access the file because it is being used by another process'), <traceback object at 0x000001FEB8A34D00>)
def onerror(func, path, exc_info):
if issubclass(exc_info[0], PermissionError):
def resetperms(path):
try:
_os.chflags(path, 0)
except AttributeError:
pass
_os.chmod(path, 0o700)
try:
if path != name:
resetperms(_os.path.dirname(path))
resetperms(path)
try:
> _os.unlink(path)
E PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\61412\\AppData\\Local\\Temp\\tmpfhz9tczn\\tmp2a11n1sq'
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\tempfile.py:820: PermissionError
During handling of the above exception, another exception occurred:
self = <tests.test_path.TestEnsureFileAction testMethod=test_on_multiple_mixed_existing_files>
def test_on_multiple_mixed_existing_files(self):
self.parser.add_argument("--path", nargs="+", action=EnsureFileAction)
> with tempfile.TemporaryDirectory() as parent_directory:
tests\test_path.py:179:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\tempfile.py:846: in __exit__
self.cleanup()
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\tempfile.py:850: in cleanup
self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors)
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\tempfile.py:832: in _rmtree
_shutil.rmtree(name, onerror=onerror)
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\shutil.py:749: in rmtree
return _rmtree_unsafe(path, onerror)
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\shutil.py:619: in _rmtree_unsafe
onerror(os.unlink, fullname, sys.exc_info())
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\tempfile.py:823: in onerror
cls._rmtree(path, ignore_errors=ignore_errors)
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\tempfile.py:832: in _rmtree
_shutil.rmtree(name, onerror=onerror)
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\shutil.py:749: in rmtree
return _rmtree_unsafe(path, onerror)
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\shutil.py:600: in _rmtree_unsafe
onerror(os.scandir, path, sys.exc_info())
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
path = 'C:\\Users\\61412\\AppData\\Local\\Temp\\tmpfhz9tczn\\tmp2a11n1sq'
onerror = <function TemporaryDirectory._rmtree.<locals>.onerror at 0x000001FEB8511D80>
def _rmtree_unsafe(path, onerror):
try:
> with os.scandir(path) as scandir_it:
E NotADirectoryError: [WinError 267] The directory name is invalid: 'C:\\Users\\61412\\AppData\\Local\\Temp\\tmpfhz9tczn\\tmp2a11n1sq'
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\shutil.py:597: NotADirectoryError
The test itself passes if I apply the following patch
diff --git a/tests/test_path.py b/tests/test_path.py
index 7e70d80..903e6e4 100644
--- a/tests/test_path.py
+++ b/tests/test_path.py
@@ -181,11 +181,10 @@ class TestEnsureFileAction(ActionHeroTestCase):
file1 = tempfile.mkstemp(dir=parent_directory)[1]
file2 = tempfile.mkstemp(dir=parent_directory)[1]
- # files deleted immediately to confirm they do not exist
- file3 = tempfile.mkstemp(dir=parent_directory)[1]
- os.remove(file3)
- file4 = tempfile.mkstemp(dir=parent_directory)[1]
- os.remove(file4)
+ # Specify two temporary files that do not exist
+ file3 = tempfile.mktemp(dir=parent_directory)
+ file4 = tempfile.mktemp(dir=parent_directory)
+ self.assertNotEqual(file3, file4)
mixed_files = [file1, file2, file3, file4]
@@ -200,7 +199,8 @@ class TestEnsureFileAction(ActionHeroTestCase):
self.assertNotIn(False, [os.path.isfile(f) for f in mixed_files])
# Tear down temporary files
- [os.remove(f) for f in mixed_files]
+ if os.name != "nt":
+ [os.remove(f) for f in [file1, file2]]
class TestPathIsValidAction(ActionHeroTestCase):
But, then the tempfile cleanup fails
tests\test_path.py F [100%]
================================== FAILURES ===================================
_________ TestEnsureFileAction.test_on_multiple_mixed_existing_files __________
path = 'C:\\Users\\61412\\AppData\\Local\\Temp\\tmp6v8sp0pt'
onerror = <function TemporaryDirectory._rmtree.<locals>.onerror at 0x000001E378A9CE50>
def _rmtree_unsafe(path, onerror):
try:
with os.scandir(path) as scandir_it:
entries = list(scandir_it)
except OSError:
onerror(os.scandir, path, sys.exc_info())
entries = []
for entry in entries:
fullname = entry.path
if _rmtree_isdir(entry):
try:
if entry.is_symlink():
# This can only happen if someone replaces
# a directory with a symlink after the call to
# os.scandir or entry.is_dir above.
raise OSError("Cannot call rmtree on a symbolic link")
except OSError:
onerror(os.path.islink, fullname, sys.exc_info())
continue
_rmtree_unsafe(fullname, onerror)
else:
try:
> os.unlink(fullname)
E PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\61412\\AppData\\Local\\Temp\\tmp6v8sp0pt\\tmpd9uaoh03'
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\shutil.py:617: PermissionError
During handling of the above exception, another exception occurred:
func = <built-in function unlink>
path = 'C:\\Users\\61412\\AppData\\Local\\Temp\\tmp6v8sp0pt\\tmpd9uaoh03'
exc_info = (<class 'PermissionError'>, PermissionError(13, 'The process cannot access the file because it is being used by another process'), <traceback object at 0x000001E378AAA7C0>)
def onerror(func, path, exc_info):
if issubclass(exc_info[0], PermissionError):
def resetperms(path):
try:
_os.chflags(path, 0)
except AttributeError:
pass
_os.chmod(path, 0o700)
try:
if path != name:
resetperms(_os.path.dirname(path))
resetperms(path)
try:
> _os.unlink(path)
E PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\61412\\AppData\\Local\\Temp\\tmp6v8sp0pt\\tmpd9uaoh03'
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\tempfile.py:820: PermissionError
During handling of the above exception, another exception occurred:
self = <tests.test_path.TestEnsureFileAction testMethod=test_on_multiple_mixed_existing_files>
def test_on_multiple_mixed_existing_files(self):
self.parser.add_argument("--path", nargs="+", action=EnsureFileAction)
> with tempfile.TemporaryDirectory() as parent_directory:
tests\test_path.py:179:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\tempfile.py:846: in __exit__
self.cleanup()
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\tempfile.py:850: in cleanup
self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors)
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\tempfile.py:832: in _rmtree
_shutil.rmtree(name, onerror=onerror)
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\shutil.py:749: in rmtree
return _rmtree_unsafe(path, onerror)
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\shutil.py:619: in _rmtree_unsafe
onerror(os.unlink, fullname, sys.exc_info())
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\tempfile.py:823: in onerror
cls._rmtree(path, ignore_errors=ignore_errors)
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\tempfile.py:832: in _rmtree
_shutil.rmtree(name, onerror=onerror)
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\shutil.py:749: in rmtree
return _rmtree_unsafe(path, onerror)
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\shutil.py:600: in _rmtree_unsafe
onerror(os.scandir, path, sys.exc_info())
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
path = 'C:\\Users\\61412\\AppData\\Local\\Temp\\tmp6v8sp0pt\\tmpd9uaoh03'
onerror = <function TemporaryDirectory._rmtree.<locals>.onerror at 0x000001E378A9CEE0>
def _rmtree_unsafe(path, onerror):
try:
> with os.scandir(path) as scandir_it:
E NotADirectoryError: [WinError 267] The directory name is invalid: 'C:\\Users\\61412\\AppData\\Local\\Temp\\tmp6v8sp0pt\\tmpd9uaoh03'
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1520.0_x64__qbz5n2kfra8p0\lib\shutil.py:597: NotADirectoryError
=========================== short test summary info ===========================
FAILED tests/test_path.py::TestEnsureFileAction::test_on_multiple_mixed_existing_files
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!
====================== 1 failed, 363 deselected in 0.57s ======================
As a result, I think it is easier to skip this test on Windows.