equal
deleted
inserted
replaced
1096 ''' |
1096 ''' |
1097 assert not (copystat and checkambig) |
1097 assert not (copystat and checkambig) |
1098 oldstat = None |
1098 oldstat = None |
1099 if os.path.lexists(dest): |
1099 if os.path.lexists(dest): |
1100 if checkambig: |
1100 if checkambig: |
1101 oldstat = checkambig and filestat(dest) |
1101 oldstat = checkambig and filestat.frompath(dest) |
1102 unlink(dest) |
1102 unlink(dest) |
1103 if hardlink: |
1103 if hardlink: |
1104 # Hardlinks are problematic on CIFS (issue4546), do not allow hardlinks |
1104 # Hardlinks are problematic on CIFS (issue4546), do not allow hardlinks |
1105 # unless we are confident that dest is on a whitelisted filesystem. |
1105 # unless we are confident that dest is on a whitelisted filesystem. |
1106 try: |
1106 try: |
1126 # copystat also copies mode |
1126 # copystat also copies mode |
1127 shutil.copystat(src, dest) |
1127 shutil.copystat(src, dest) |
1128 else: |
1128 else: |
1129 shutil.copymode(src, dest) |
1129 shutil.copymode(src, dest) |
1130 if oldstat and oldstat.stat: |
1130 if oldstat and oldstat.stat: |
1131 newstat = filestat(dest) |
1131 newstat = filestat.frompath(dest) |
1132 if newstat.isambig(oldstat): |
1132 if newstat.isambig(oldstat): |
1133 # stat of copied file is ambiguous to original one |
1133 # stat of copied file is ambiguous to original one |
1134 advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff |
1134 advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff |
1135 os.utime(dest, (advanced, advanced)) |
1135 os.utime(dest, (advanced, advanced)) |
1136 except shutil.Error as inst: |
1136 except shutil.Error as inst: |
1504 |
1504 |
1505 'stat' attribute is result of 'os.stat()' if specified 'path' |
1505 'stat' attribute is result of 'os.stat()' if specified 'path' |
1506 exists. Otherwise, it is None. This can avoid preparative |
1506 exists. Otherwise, it is None. This can avoid preparative |
1507 'exists()' examination on client side of this class. |
1507 'exists()' examination on client side of this class. |
1508 """ |
1508 """ |
1509 def __init__(self, path): |
1509 def __init__(self, stat): |
|
1510 self.stat = stat |
|
1511 |
|
1512 @classmethod |
|
1513 def frompath(cls, path): |
1510 try: |
1514 try: |
1511 self.stat = os.stat(path) |
1515 stat = os.stat(path) |
1512 except OSError as err: |
1516 except OSError as err: |
1513 if err.errno != errno.ENOENT: |
1517 if err.errno != errno.ENOENT: |
1514 raise |
1518 raise |
1515 self.stat = None |
1519 stat = None |
|
1520 return cls(stat) |
1516 |
1521 |
1517 __hash__ = object.__hash__ |
1522 __hash__ = object.__hash__ |
1518 |
1523 |
1519 def __eq__(self, old): |
1524 def __eq__(self, old): |
1520 try: |
1525 try: |
1620 |
1625 |
1621 def close(self): |
1626 def close(self): |
1622 if not self._fp.closed: |
1627 if not self._fp.closed: |
1623 self._fp.close() |
1628 self._fp.close() |
1624 filename = localpath(self.__name) |
1629 filename = localpath(self.__name) |
1625 oldstat = self._checkambig and filestat(filename) |
1630 oldstat = self._checkambig and filestat.frompath(filename) |
1626 if oldstat and oldstat.stat: |
1631 if oldstat and oldstat.stat: |
1627 rename(self._tempname, filename) |
1632 rename(self._tempname, filename) |
1628 newstat = filestat(filename) |
1633 newstat = filestat.frompath(filename) |
1629 if newstat.isambig(oldstat): |
1634 if newstat.isambig(oldstat): |
1630 # stat of changed file is ambiguous to original one |
1635 # stat of changed file is ambiguous to original one |
1631 advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff |
1636 advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff |
1632 os.utime(filename, (advanced, advanced)) |
1637 os.utime(filename, (advanced, advanced)) |
1633 else: |
1638 else: |