diff -r 45eab45be175 Lib/mailbox.py --- a/Lib/mailbox.py Mon Nov 21 04:22:43 2016 +0000 +++ b/Lib/mailbox.py Mon Nov 21 16:09:32 2016 +0100 @@ -313,11 +313,12 @@ # final position in order to prevent race conditions with changes # from other programs try: - if hasattr(os, 'link'): + try: os.link(tmp_file.name, dest) + except (AttributeError, PermissionError): + os.rename(tmp_file.name, dest) + else: os.remove(tmp_file.name) - else: - os.rename(tmp_file.name, dest) except OSError as e: os.remove(tmp_file.name) if e.errno == errno.EEXIST: @@ -1200,13 +1201,14 @@ for key in self.iterkeys(): if key - 1 != prev: changes.append((key, prev + 1)) - if hasattr(os, 'link'): + try: os.link(os.path.join(self._path, str(key)), os.path.join(self._path, str(prev + 1))) - os.unlink(os.path.join(self._path, str(key))) - else: + except (AttributeError, PermissionError): os.rename(os.path.join(self._path, str(key)), os.path.join(self._path, str(prev + 1))) + else: + os.unlink(os.path.join(self._path, str(key))) prev += 1 self._next_key = prev + 1 if len(changes) == 0: @@ -2076,12 +2078,13 @@ else: raise try: - if hasattr(os, 'link'): + try: os.link(pre_lock.name, f.name + '.lock') - dotlock_done = True + except (AttributeError, PermissionError): + os.rename(pre_lock.name, f.name + '.lock') + else: os.unlink(pre_lock.name) - else: - os.rename(pre_lock.name, f.name + '.lock') + finally: dotlock_done = True except FileExistsError: os.remove(pre_lock.name) diff -r 45eab45be175 Lib/test/test_mailbox.py --- a/Lib/test/test_mailbox.py Mon Nov 21 04:22:43 2016 +0000 +++ b/Lib/test/test_mailbox.py Mon Nov 21 16:09:32 2016 +0100 @@ -2137,9 +2137,9 @@ if mbox: fp.write(FROM_) fp.write(DUMMY_MESSAGE) - if hasattr(os, "link"): + try: os.link(tmpname, newname) - else: + except (AttributeError, PermissionError): with open(newname, "w") as fp: fp.write(DUMMY_MESSAGE) self._msgfiles.append(newname)