diff --git a/borg/archive.py b/borg/archive.py index e8fe2feda..f6acf8be4 100644 --- a/borg/archive.py +++ b/borg/archive.py @@ -18,7 +18,7 @@ from io import BytesIO from . import xattr from .helpers import parse_timestamp, Error, uid2user, user2uid, gid2group, group2gid, format_timedelta, \ Manifest, Statistics, decode_dict, make_path_safe, StableDict, int_to_bigint, bigint_to_int, \ - st_atime_ns, st_ctime_ns, st_mtime_ns, ProgressIndicatorPercent + ProgressIndicatorPercent from .platform import acl_get, acl_set from .chunker import Chunker from .hashindex import ChunkIndex @@ -39,7 +39,6 @@ ITEMS_CHUNKER_PARAMS = (12, 16, 14, HASH_WINDOW_SIZE) utime_supports_fd = os.utime in getattr(os, 'supports_fd', {}) utime_supports_follow_symlinks = os.utime in getattr(os, 'supports_follow_symlinks', {}) -has_mtime_ns = sys.version >= '3.3' has_lchmod = hasattr(os, 'lchmod') has_lchflags = hasattr(os, 'lchflags') @@ -435,9 +434,9 @@ Number of files: {0.stats.nfiles}'''.format(self) b'mode': st.st_mode, b'uid': st.st_uid, b'user': uid2user(st.st_uid), b'gid': st.st_gid, b'group': gid2group(st.st_gid), - b'atime': int_to_bigint(st_atime_ns(st)), - b'ctime': int_to_bigint(st_ctime_ns(st)), - b'mtime': int_to_bigint(st_mtime_ns(st)), + b'atime': int_to_bigint(st.st_atime_ns), + b'ctime': int_to_bigint(st.st_ctime_ns), + b'mtime': int_to_bigint(st.st_mtime_ns), } if self.numeric_owner: item[b'user'] = item[b'group'] = None diff --git a/borg/archiver.py b/borg/archiver.py index ffb0727c1..e595715ba 100644 --- a/borg/archiver.py +++ b/borg/archiver.py @@ -1,4 +1,4 @@ -from binascii import hexlify +from binascii import hexlify, unhexlify from datetime import datetime from hashlib import sha256 from operator import attrgetter @@ -16,7 +16,7 @@ import traceback from . import __version__ from .helpers import Error, location_validator, format_time, format_file_size, \ format_file_mode, parse_pattern, PathPrefixPattern, to_localtime, timestamp, \ - get_cache_dir, get_keys_dir, prune_within, prune_split, unhexlify, \ + get_cache_dir, get_keys_dir, prune_within, prune_split, \ Manifest, remove_surrogates, update_excludes, format_archive, check_extension_modules, Statistics, \ dir_is_tagged, bigint_to_int, ChunkerParams, CompressionSpec, is_slow_msgpack, yes, sysinfo, \ EXIT_SUCCESS, EXIT_WARNING, EXIT_ERROR, log_multi, PatternMatcher diff --git a/borg/cache.py b/borg/cache.py index cbefcd5ef..feffc1fd2 100644 --- a/borg/cache.py +++ b/borg/cache.py @@ -3,13 +3,13 @@ from .remote import cache_if_remote from collections import namedtuple import os import stat -from binascii import hexlify +from binascii import hexlify, unhexlify import shutil from .key import PlaintextKey from .logger import create_logger logger = create_logger() -from .helpers import Error, get_cache_dir, decode_dict, st_mtime_ns, unhexlify, int_to_bigint, \ +from .helpers import Error, get_cache_dir, decode_dict, int_to_bigint, \ bigint_to_int, format_file_size, yes from .locking import UpgradableLock from .hashindex import ChunkIndex @@ -401,7 +401,7 @@ Chunk index: {0.total_unique_chunks:20d} {0.total_chunks:20d}""" if not entry: return None entry = msgpack.unpackb(entry) - if entry[2] == st.st_size and bigint_to_int(entry[3]) == st_mtime_ns(st) and entry[1] == st.st_ino: + if entry[2] == st.st_size and bigint_to_int(entry[3]) == st.st_mtime_ns and entry[1] == st.st_ino: # reset entry age entry[0] = 0 self.files[path_hash] = msgpack.packb(entry) @@ -413,6 +413,6 @@ Chunk index: {0.total_unique_chunks:20d} {0.total_chunks:20d}""" if not (self.do_files and stat.S_ISREG(st.st_mode)): return # Entry: Age, inode, size, mtime, chunk ids - mtime_ns = st_mtime_ns(st) + mtime_ns = st.st_mtime_ns self.files[path_hash] = msgpack.packb((0, st.st_ino, st.st_size, int_to_bigint(mtime_ns), ids)) self._newest_mtime = max(self._newest_mtime, mtime_ns) diff --git a/borg/helpers.py b/borg/helpers.py index 8670419b9..89968c8ce 100644 --- a/borg/helpers.py +++ b/borg/helpers.py @@ -835,35 +835,6 @@ class StableDict(dict): return sorted(super().items()) -if sys.version < '3.3': - # st_xtime_ns attributes only available in 3.3+ - def st_atime_ns(st): - return int(st.st_atime * 1e9) - - def st_ctime_ns(st): - return int(st.st_ctime * 1e9) - - def st_mtime_ns(st): - return int(st.st_mtime * 1e9) - - # unhexlify in < 3.3 incorrectly only accepts bytes input - def unhexlify(data): - if isinstance(data, str): - data = data.encode('ascii') - return binascii.unhexlify(data) -else: - def st_atime_ns(st): - return st.st_atime_ns - - def st_ctime_ns(st): - return st.st_ctime_ns - - def st_mtime_ns(st): - return st.st_mtime_ns - - unhexlify = binascii.unhexlify - - def bigint_to_int(mtime): """Convert bytearray to int """ diff --git a/borg/repository.py b/borg/repository.py index 80bbe6690..0789a0213 100644 --- a/borg/repository.py +++ b/borg/repository.py @@ -1,5 +1,5 @@ from configparser import ConfigParser -from binascii import hexlify +from binascii import hexlify, unhexlify from itertools import islice import errno import logging @@ -11,7 +11,7 @@ import struct from zlib import crc32 import msgpack -from .helpers import Error, ErrorWithTraceback, IntegrityError, unhexlify, ProgressIndicatorPercent +from .helpers import Error, ErrorWithTraceback, IntegrityError, ProgressIndicatorPercent from .hashindex import NSIndex from .locking import UpgradableLock, LockError, LockErrorT from .lrucache import LRUCache diff --git a/borg/testsuite/__init__.py b/borg/testsuite/__init__.py index 3af1738ba..cb643153b 100644 --- a/borg/testsuite/__init__.py +++ b/borg/testsuite/__init__.py @@ -7,7 +7,6 @@ import sys import sysconfig import time import unittest -from ..helpers import st_mtime_ns from ..xattr import get_all try: @@ -31,7 +30,6 @@ else: if sys.platform.startswith('netbsd'): st_mtime_ns_round = -4 # only >1 microsecond resolution here? -has_mtime_ns = sys.version >= '3.3' utime_supports_fd = os.utime in getattr(os, 'supports_fd', {}) @@ -83,11 +81,11 @@ class BaseTestCase(unittest.TestCase): if not os.path.islink(path1) or utime_supports_fd: # Older versions of llfuse do not support ns precision properly if fuse and not have_fuse_mtime_ns: - d1.append(round(st_mtime_ns(s1), -4)) - d2.append(round(st_mtime_ns(s2), -4)) + d1.append(round(s1.st_mtime_ns, -4)) + d2.append(round(s2.st_mtime_ns, -4)) else: - d1.append(round(st_mtime_ns(s1), st_mtime_ns_round)) - d2.append(round(st_mtime_ns(s2), st_mtime_ns_round)) + d1.append(round(s1.st_mtime_ns, st_mtime_ns_round)) + d2.append(round(s2.st_mtime_ns, st_mtime_ns_round)) d1.append(get_all(path1, follow_symlinks=False)) d2.append(get_all(path2, follow_symlinks=False)) self.assert_equal(d1, d2) diff --git a/borg/testsuite/archiver.py b/borg/testsuite/archiver.py index 2b27a516c..3192d60d8 100644 --- a/borg/testsuite/archiver.py +++ b/borg/testsuite/archiver.py @@ -21,7 +21,7 @@ from ..archive import Archive, ChunkBuffer, CHUNK_MAX_EXP from ..archiver import Archiver from ..cache import Cache from ..crypto import bytes_to_long, num_aes_blocks -from ..helpers import Manifest, EXIT_SUCCESS, EXIT_WARNING, EXIT_ERROR, st_atime_ns, st_mtime_ns +from ..helpers import Manifest, EXIT_SUCCESS, EXIT_WARNING, EXIT_ERROR from ..remote import RemoteRepository, PathNotAllowed from ..repository import Repository from . import BaseTestCase, changedir, environment_variable @@ -358,12 +358,12 @@ class ArchiverTestCase(ArchiverTestCaseBase): self.cmd('extract', self.repository_location + '::test') sti = os.stat('input/file1') sto = os.stat('output/input/file1') - assert st_mtime_ns(sti) == st_mtime_ns(sto) == mtime * 1e9 + assert sti.st_mtime_ns == sto.st_mtime_ns == mtime * 1e9 if hasattr(os, 'O_NOATIME'): - assert st_atime_ns(sti) == st_atime_ns(sto) == atime * 1e9 + assert sti.st_atime_ns == sto.st_atime_ns == atime * 1e9 else: # it touched the input file's atime while backing it up - assert st_atime_ns(sto) == atime * 1e9 + assert sto.st_atime_ns == atime * 1e9 def _extract_repository_id(self, path): return Repository(self.repository_path).id diff --git a/borg/testsuite/key.py b/borg/testsuite/key.py index b2011d8f5..4c57d1f02 100644 --- a/borg/testsuite/key.py +++ b/borg/testsuite/key.py @@ -2,11 +2,11 @@ import os import re import shutil import tempfile -from binascii import hexlify +from binascii import hexlify, unhexlify from ..crypto import bytes_to_long, num_aes_blocks from ..key import PlaintextKey, PassphraseKey, KeyfileKey -from ..helpers import Location, unhexlify +from ..helpers import Location from . import BaseTestCase