diff --git a/src/borg/compress.pyx b/src/borg/compress.pyx index 98a546509..012d124de 100644 --- a/src/borg/compress.pyx +++ b/src/borg/compress.pyx @@ -15,6 +15,7 @@ which compressor has been used to compress the data and dispatch to the correct decompressor. """ +from argparse import ArgumentTypeError import random from struct import Struct import zlib @@ -551,7 +552,7 @@ class CompressionSpec: values = s.split(',') count = len(values) if count < 1: - raise ValueError + raise ArgumentTypeError("not enough arguments") # --compression algo[,level] self.name = values[0] if self.name in ('none', 'lz4', ): @@ -562,9 +563,9 @@ class CompressionSpec: elif count == 2: level = int(values[1]) if not 0 <= level <= 9: - raise ValueError + raise ArgumentTypeError("level must be >= 0 and <= 9") else: - raise ValueError + raise ArgumentTypeError("too many arguments") self.level = level elif self.name in ('zstd', ): if count < 2: @@ -572,28 +573,28 @@ class CompressionSpec: elif count == 2: level = int(values[1]) if not 1 <= level <= 22: - raise ValueError + raise ArgumentTypeError("level must be >= 1 and <= 22") else: - raise ValueError + raise ArgumentTypeError("too many arguments") self.level = level elif self.name == 'auto': if 2 <= count <= 3: compression = ','.join(values[1:]) else: - raise ValueError + raise ArgumentTypeError("bad arguments") self.inner = CompressionSpec(compression) elif self.name == 'obfuscate': if 3 <= count <= 5: level = int(values[1]) if not ((1 <= level <= 6) or (110 <= level <= 123)): - raise ValueError + raise ArgumentTypeError("level must be >= 1 and <= 6 or >= 110 and <= 123") self.level = level compression = ','.join(values[2:]) else: - raise ValueError + raise ArgumentTypeError("bad arguments") self.inner = CompressionSpec(compression) else: - raise ValueError + raise ArgumentTypeError("unsupported compression type") @property def compressor(self): diff --git a/src/borg/helpers/parseformat.py b/src/borg/helpers/parseformat.py index 087c718bb..9dfda8d24 100644 --- a/src/borg/helpers/parseformat.py +++ b/src/borg/helpers/parseformat.py @@ -98,7 +98,7 @@ def ChunkerParams(s): params = s.strip().split(',') count = len(params) if count == 0: - raise ValueError('no chunker params given') + raise argparse.ArgumentTypeError('no chunker params given') algo = params[0].lower() if algo == CH_FIXED and 2 <= count <= 3: # fixed, block_size[, header_size] block_size = int(params[1]) @@ -109,9 +109,11 @@ def ChunkerParams(s): # or in-memory chunk management. # choose the block (chunk) size wisely: if you have a lot of data and you cut # it into very small chunks, you are asking for trouble! - raise ValueError('block_size must not be less than 64 Bytes') + raise argparse.ArgumentTypeError('block_size must not be less than 64 Bytes') if block_size > MAX_DATA_SIZE or header_size > MAX_DATA_SIZE: - raise ValueError('block_size and header_size must not exceed MAX_DATA_SIZE [%d]' % MAX_DATA_SIZE) + raise argparse.ArgumentTypeError( + 'block_size and header_size must not exceed MAX_DATA_SIZE [%d]' % MAX_DATA_SIZE + ) return algo, block_size, header_size if algo == 'default' and count == 1: # default return CHUNKER_PARAMS @@ -119,14 +121,18 @@ def ChunkerParams(s): if algo == CH_BUZHASH and count == 5 or count == 4: # [buzhash, ]chunk_min, chunk_max, chunk_mask, window_size chunk_min, chunk_max, chunk_mask, window_size = (int(p) for p in params[count - 4:]) if not (chunk_min <= chunk_mask <= chunk_max): - raise ValueError('required: chunk_min <= chunk_mask <= chunk_max') + raise argparse.ArgumentTypeError('required: chunk_min <= chunk_mask <= chunk_max') if chunk_min < 6: # see comment in 'fixed' algo check - raise ValueError('min. chunk size exponent must not be less than 6 (2^6 = 64B min. chunk size)') + raise argparse.ArgumentTypeError( + 'min. chunk size exponent must not be less than 6 (2^6 = 64B min. chunk size)' + ) if chunk_max > 23: - raise ValueError('max. chunk size exponent must not be more than 23 (2^23 = 8MiB max. chunk size)') + raise argparse.ArgumentTypeError( + 'max. chunk size exponent must not be more than 23 (2^23 = 8MiB max. chunk size)' + ) return CH_BUZHASH, chunk_min, chunk_max, chunk_mask, window_size - raise ValueError('invalid chunker params') + raise argparse.ArgumentTypeError('invalid chunker params') def FilesCacheMode(s): @@ -134,11 +140,13 @@ def FilesCacheMode(s): VALID_MODES = ('cis', 'ims', 'cs', 'ms', 'cr', 'mr', 'd', 's') # letters in alpha order entries = set(s.strip().split(',')) if not entries <= set(ENTRIES_MAP): - raise ValueError('cache mode must be a comma-separated list of: %s' % ','.join(sorted(ENTRIES_MAP))) + raise argparse.ArgumentTypeError( + 'cache mode must be a comma-separated list of: %s' % ','.join(sorted(ENTRIES_MAP)) + ) short_entries = {ENTRIES_MAP[entry] for entry in entries} mode = ''.join(sorted(short_entries)) if mode not in VALID_MODES: - raise ValueError('cache mode short must be one of: %s' % ','.join(VALID_MODES)) + raise argparse.ArgumentTypeError('cache mode short must be one of: %s' % ','.join(VALID_MODES)) return mode @@ -219,7 +227,7 @@ def SortBySpec(text): from .manifest import AI_HUMAN_SORT_KEYS for token in text.split(','): if token not in AI_HUMAN_SORT_KEYS: - raise ValueError('Invalid sort key: %s' % token) + raise argparse.ArgumentTypeError('Invalid sort key: %s' % token) return text.replace('timestamp', 'ts') diff --git a/src/borg/testsuite/compress.py b/src/borg/testsuite/compress.py index b7818e997..7c5dbcbe4 100644 --- a/src/borg/testsuite/compress.py +++ b/src/borg/testsuite/compress.py @@ -1,3 +1,4 @@ +import argparse import os import zlib try: @@ -198,7 +199,7 @@ def test_obfuscate(): def test_compression_specs(): - with pytest.raises(ValueError): + with pytest.raises(argparse.ArgumentTypeError): CompressionSpec('') assert isinstance(CompressionSpec('none').compressor, CNONE) @@ -213,7 +214,7 @@ def test_compression_specs(): zlib = CompressionSpec('zlib,9').compressor assert isinstance(zlib, ZLIB) assert zlib.level == 9 - with pytest.raises(ValueError): + with pytest.raises(argparse.ArgumentTypeError): CompressionSpec('zlib,9,invalid') lzma = CompressionSpec('lzma').compressor @@ -236,7 +237,7 @@ def test_compression_specs(): assert isinstance(zstd, ZSTD) assert zstd.level == 22 - with pytest.raises(ValueError): + with pytest.raises(argparse.ArgumentTypeError): CompressionSpec('lzma,9,invalid') - with pytest.raises(ValueError): + with pytest.raises(argparse.ArgumentTypeError): CompressionSpec('invalid') diff --git a/src/borg/testsuite/helpers.py b/src/borg/testsuite/helpers.py index c97b806c3..0785a82c4 100644 --- a/src/borg/testsuite/helpers.py +++ b/src/borg/testsuite/helpers.py @@ -348,19 +348,19 @@ def test_chunkerparams(): assert ChunkerParams('fixed,4096') == ('fixed', 4096, 0) assert ChunkerParams('fixed,4096,200') == ('fixed', 4096, 200) # invalid values checking - with pytest.raises(ValueError): + with pytest.raises(ArgumentTypeError): ChunkerParams('crap,1,2,3,4') # invalid algo - with pytest.raises(ValueError): + with pytest.raises(ArgumentTypeError): ChunkerParams('buzhash,5,7,6,4095') # too small min. size - with pytest.raises(ValueError): + with pytest.raises(ArgumentTypeError): ChunkerParams('buzhash,19,24,21,4095') # too big max. size - with pytest.raises(ValueError): + with pytest.raises(ArgumentTypeError): ChunkerParams('buzhash,23,19,21,4095') # violates min <= mask <= max - with pytest.raises(ValueError): + with pytest.raises(ArgumentTypeError): ChunkerParams('fixed,63') # too small block size - with pytest.raises(ValueError): + with pytest.raises(ArgumentTypeError): ChunkerParams('fixed,%d,%d' % (MAX_DATA_SIZE + 1, 4096)) # too big block size - with pytest.raises(ValueError): + with pytest.raises(ArgumentTypeError): ChunkerParams('fixed,%d,%d' % (4096, MAX_DATA_SIZE + 1)) # too big header size