diff -r 63c5531cfdf7 Lib/test/support/__init__.py --- a/Lib/test/support/__init__.py Sat Jan 07 09:33:28 2017 +0300 +++ b/Lib/test/support/__init__.py Sat Jan 07 21:52:28 2017 +0100 @@ -107,7 +107,7 @@ "check_warnings", "check_no_resource_warning", "EnvironmentVarGuard", "run_with_locale", "swap_item", "swap_attr", "Matcher", "set_memlimit", "SuppressCrashReport", "sortdict", - "run_with_tz", "PGO", "missing_compiler_executable", + "run_with_tz", "PGO", "missing_compiler_executable", "os_link", ] class Error(Exception): @@ -2573,6 +2573,14 @@ return cmd[0] +def os_link(src, dst, **kwds): + """Create a hard link, raising SkipTest if PermissionError is raised.""" + try: + os.link(src, dst, **kwds) + except PermissionError: + raise unittest.SkipTest('cannot create a hard link') + + _is_android_emulator = None def setswitchinterval(interval): # Setting a very low gil interval on the Android emulator causes python diff -r 63c5531cfdf7 Lib/test/test_os.py --- a/Lib/test/test_os.py Sat Jan 07 09:33:28 2017 +0300 +++ b/Lib/test/test_os.py Sat Jan 07 21:52:28 2017 +0100 @@ -1695,7 +1695,7 @@ def _test_link(self, file1, file2): create_file(file1) - os.link(file1, file2) + support.os_link(file1, file2) with open(file1, "r") as f1, open(file2, "r") as f2: self.assertTrue(os.path.sameopenfile(f1.fileno(), f2.fileno())) @@ -2793,7 +2793,8 @@ """ try: size = subprocess.check_output(['stty', 'size']).decode().split() - except (FileNotFoundError, subprocess.CalledProcessError): + except (FileNotFoundError, subprocess.CalledProcessError, + PermissionError): self.skipTest("stty invocation failed") expected = (int(size[1]), int(size[0])) # reversed order @@ -3147,7 +3148,7 @@ os.mkdir(dirname) filename = self.create_file("file.txt") if link: - os.link(filename, os.path.join(self.path, "link_file.txt")) + support.os_link(filename, os.path.join(self.path, "link_file.txt")) if symlink: os.symlink(dirname, os.path.join(self.path, "symlink_dir"), target_is_directory=True)