Skip to content

Commit d46eca8

Browse files
authored
Merge pull request #111 from cs50/fix/issue-92-handle-permission-errors
Add error handling for PermissionError in excepthook
2 parents 99d43d8 + 43143c2 commit d46eca8

File tree

3 files changed

+25
-2
lines changed

3 files changed

+25
-2
lines changed

compare50/__main__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ def excepthook(cls, exc, tb):
2727
termcolor.cprint(str(exc), "red", file=sys.stderr)
2828
elif cls is FileNotFoundError:
2929
termcolor.cprint("{} not found".format(exc.filename), "red", file=sys.stderr)
30+
elif cls is PermissionError:
31+
termcolor.cprint("Permission denied: {}".format(exc.filename), "red", file=sys.stderr)
3032
elif not issubclass(cls, Exception) and not isinstance(exc, KeyboardInterrupt):
3133
# Class is some other BaseException, better just let it go
3234
return

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@
2222
packages=find_packages(exclude=["tests"]),
2323
scripts=["bin/compare50"],
2424
url="https://github.com/cs50/compare50",
25-
version="1.2.11",
25+
version="1.2.12",
2626
include_package_data=True,
2727
)

tests/main_tests.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import unittest
22
import tempfile
3-
import zipfile
43
import os
4+
import io
5+
from unittest.mock import patch
56
import compare50.__main__ as main
67
import compare50._api as api
78

@@ -110,6 +111,26 @@ def test_ignore_non_utf8(self):
110111
subs = {sub for sub in subs if sub.files}
111112
self.assertEqual(subs, set())
112113

114+
def test_permission_error(self):
115+
os.mkdir("foo")
116+
file_path = "foo/bar.py"
117+
with open(file_path, "w") as f:
118+
f.write("test content")
119+
os.chmod(file_path, 0o000)
120+
with self.assertRaises(PermissionError):
121+
main.SubmissionFactory._is_valid_utf8(file_path)
122+
os.chmod(file_path, 0o644)
123+
124+
def test_excepthook_permission_error(self):
125+
error = PermissionError("Permission denied")
126+
error.filename = "/path/to/restricted/file.py"
127+
with patch('sys.stderr', new_callable=io.StringIO) as mock_stderr:
128+
with patch('sys.exit') as mock_exit:
129+
main.excepthook(PermissionError, error, None)
130+
error_output = mock_stderr.getvalue()
131+
self.assertIn("Permission denied: /path/to/restricted/file.py", error_output)
132+
mock_exit.assert_called_once_with(1)
133+
113134

114135
if __name__ == "__main__":
115136
unittest.main()

0 commit comments

Comments
 (0)