Prep for type annotations
- Remove unused pyver var - Fix ret_string type for ECStripingDriver - Clean up ECDriver signature - Fix AttributeError in ECDriver repr when no ec_type specified - Fix typo in verify_stripe_metadata docstring - Ensure positive_int_value works properly regardless of optimization level Change-Id: If20196d067ff42a1179923b422a6f0bed9917d45
This commit is contained in:
@@ -28,9 +28,6 @@ from .ec_iface import PyECLib_FRAGHDRCHKSUM_Types
|
|||||||
|
|
||||||
import math
|
import math
|
||||||
import pyeclib_c
|
import pyeclib_c
|
||||||
import sys
|
|
||||||
|
|
||||||
pyver = float('%s.%s' % sys.version_info[:2])
|
|
||||||
|
|
||||||
|
|
||||||
class ECPyECLibDriver(object):
|
class ECPyECLibDriver(object):
|
||||||
@@ -254,7 +251,7 @@ class ECStripingDriver(object):
|
|||||||
"Decode requires %d fragments, %d fragments were given" %
|
"Decode requires %d fragments, %d fragments were given" %
|
||||||
(len(fragment_payloads), self.k))
|
(len(fragment_payloads), self.k))
|
||||||
|
|
||||||
ret_string = ''
|
ret_string = b''
|
||||||
|
|
||||||
for fragment in fragment_payloads:
|
for fragment in fragment_payloads:
|
||||||
ret_string += fragment
|
ret_string += fragment
|
||||||
|
|||||||
@@ -93,7 +93,15 @@ class PyECLib_FRAGHDRCHKSUM_Types(Enum):
|
|||||||
class ECDriver(object):
|
class ECDriver(object):
|
||||||
'''A driver to encode, decode, and reconstruct erasure-coded data.'''
|
'''A driver to encode, decode, and reconstruct erasure-coded data.'''
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(
|
||||||
|
self, *,
|
||||||
|
ec_type=None,
|
||||||
|
library_import_str='pyeclib.core.ECPyECLibDriver',
|
||||||
|
k,
|
||||||
|
m,
|
||||||
|
chksum_type='none',
|
||||||
|
validate=False,
|
||||||
|
):
|
||||||
'''
|
'''
|
||||||
:param ec_type: the erasure coding type to use for this driver.
|
:param ec_type: the erasure coding type to use for this driver.
|
||||||
:param k: number of data fragments to use. Required.
|
:param k: number of data fragments to use. Required.
|
||||||
@@ -112,43 +120,39 @@ class ECDriver(object):
|
|||||||
self.hd = -1
|
self.hd = -1
|
||||||
self.ec_type = None
|
self.ec_type = None
|
||||||
self.chksum_type = None
|
self.chksum_type = None
|
||||||
self.validate = False
|
|
||||||
|
|
||||||
for required in ('k', 'm'):
|
if (
|
||||||
if required not in kwargs:
|
ec_type is None and
|
||||||
raise ECDriverError(
|
library_import_str == 'pyeclib.core.ECPyECLibDriver'
|
||||||
"Invalid Argument: %s is required" % required)
|
):
|
||||||
|
|
||||||
if 'ec_type' not in kwargs and 'library_import_str' not in kwargs:
|
|
||||||
raise ECDriverError(
|
raise ECDriverError(
|
||||||
"Invalid Argument: either ec_type or library_import_str "
|
"Invalid Argument: either ec_type or library_import_str "
|
||||||
"must be provided")
|
"must be provided")
|
||||||
|
|
||||||
for (key, value) in kwargs.items():
|
|
||||||
if key == "k":
|
|
||||||
try:
|
try:
|
||||||
self.k = positive_int_value(value)
|
self.k = positive_int_value(k)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ECDriverError(
|
raise ECDriverError(
|
||||||
"Invalid number of data fragments (k)")
|
"Invalid number of data fragments (k)")
|
||||||
elif key == "m":
|
|
||||||
try:
|
try:
|
||||||
self.m = positive_int_value(value)
|
self.m = positive_int_value(m)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ECDriverError(
|
raise ECDriverError(
|
||||||
"Invalid number of parity fragments (m)")
|
"Invalid number of parity fragments (m)")
|
||||||
elif key == "ec_type":
|
|
||||||
if value in ["flat_xor_hd", "flat_xor_hd_3", "flat_xor_hd_4"]:
|
if ec_type:
|
||||||
if value == "flat_xor_hd" or value == "flat_xor_hd_3":
|
if ec_type in ["flat_xor_hd", "flat_xor_hd_3", "flat_xor_hd_4"]:
|
||||||
|
if ec_type == "flat_xor_hd" or ec_type == "flat_xor_hd_3":
|
||||||
self.hd = 3
|
self.hd = 3
|
||||||
elif value == "flat_xor_hd_4":
|
elif ec_type == "flat_xor_hd_4":
|
||||||
self.hd = 4
|
self.hd = 4
|
||||||
value = "flat_xor_hd"
|
ec_type = "flat_xor_hd"
|
||||||
elif value == "libphazr":
|
elif ec_type == "libphazr":
|
||||||
self.hd = 1
|
self.hd = 1
|
||||||
|
|
||||||
if value in PyECLib_EC_Types.__members__:
|
if ec_type in PyECLib_EC_Types.__members__:
|
||||||
self.ec_type = PyECLib_EC_Types[value]
|
self.ec_type = PyECLib_EC_Types[ec_type]
|
||||||
if self.ec_type in (PyECLib_EC_Types.jerasure_rs_vand,
|
if self.ec_type in (PyECLib_EC_Types.jerasure_rs_vand,
|
||||||
PyECLib_EC_Types.jerasure_rs_cauchy):
|
PyECLib_EC_Types.jerasure_rs_cauchy):
|
||||||
warnings.warn('Jerasure support is deprecated and '
|
warnings.warn('Jerasure support is deprecated and '
|
||||||
@@ -157,23 +161,22 @@ class ECDriver(object):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
raise ECBackendNotSupported(
|
raise ECBackendNotSupported(
|
||||||
"%s is not a valid EC type for PyECLib!" % value)
|
"%s is not a valid EC type for PyECLib!" % ec_type)
|
||||||
elif key == "chksum_type":
|
|
||||||
if value in PyECLib_FRAGHDRCHKSUM_Types.__members__:
|
if chksum_type in PyECLib_FRAGHDRCHKSUM_Types.__members__:
|
||||||
self.chksum_type = \
|
self.chksum_type = \
|
||||||
PyECLib_FRAGHDRCHKSUM_Types[value]
|
PyECLib_FRAGHDRCHKSUM_Types[chksum_type]
|
||||||
else:
|
else:
|
||||||
raise ECDriverError(
|
raise ECDriverError(
|
||||||
"%s is not a valid checksum type for PyECLib!" % value)
|
"%s is not a valid checksum type for PyECLib!"
|
||||||
elif key == "validate":
|
% chksum_type)
|
||||||
# validate if the ec type is available (runtime check)
|
|
||||||
self.validate = value
|
self.validate = validate
|
||||||
|
|
||||||
if self.hd == -1:
|
if self.hd == -1:
|
||||||
self.hd = self.m
|
self.hd = self.m
|
||||||
|
|
||||||
self.library_import_str = kwargs.pop('library_import_str',
|
self.library_import_str = library_import_str
|
||||||
'pyeclib.core.ECPyECLibDriver')
|
|
||||||
#
|
#
|
||||||
# Instantiate EC backend driver
|
# Instantiate EC backend driver
|
||||||
#
|
#
|
||||||
@@ -211,12 +214,15 @@ class ECDriver(object):
|
|||||||
"in %s: %s" % (self.library_import_str, missing_methods))
|
"in %s: %s" % (self.library_import_str, missing_methods))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '%s(ec_type=%r, k=%r, m=%r)' % (
|
if self.ec_type is None:
|
||||||
type(self).__name__,
|
ec_type = 'None'
|
||||||
'flat_xor_hd_%s' % self.hd if self.ec_type.name == 'flat_xor_hd'
|
elif self.ec_type.name == 'flat_xor_hd':
|
||||||
else self.ec_type.name,
|
ec_type = f'flat_xor_hd_{self.hd}'
|
||||||
self.k,
|
else:
|
||||||
self.m)
|
ec_type = self.ec_type.name
|
||||||
|
|
||||||
|
return (f'{type(self).__name__}('
|
||||||
|
f'ec_type={ec_type!r}, k={self.k}, m={self.m})')
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self.ec_lib_reference.close()
|
self.ec_lib_reference.close()
|
||||||
@@ -313,7 +319,7 @@ class ECDriver(object):
|
|||||||
Verify a subset of fragments generated by encode()
|
Verify a subset of fragments generated by encode()
|
||||||
|
|
||||||
:param fragment_metadata_list: a list of buffers representing the
|
:param fragment_metadata_list: a list of buffers representing the
|
||||||
metadata from a subset of the framgments
|
metadata from a subset of the fragments
|
||||||
generated by encode().
|
generated by encode().
|
||||||
:returns: 'None' if the metadata is consistent.
|
:returns: 'None' if the metadata is consistent.
|
||||||
a list of fragment indexes corresponding to inconsistent
|
a list of fragment indexes corresponding to inconsistent
|
||||||
|
|||||||
@@ -30,10 +30,11 @@ def positive_int_value(param):
|
|||||||
# Returns value as a positive int or raises ValueError otherwise
|
# Returns value as a positive int or raises ValueError otherwise
|
||||||
try:
|
try:
|
||||||
value = int(param)
|
value = int(param)
|
||||||
assert value > 0
|
if value <= 0:
|
||||||
except (TypeError, ValueError, AssertionError):
|
raise ValueError
|
||||||
|
except (TypeError, ValueError):
|
||||||
# Handle: TypeError for 'None', ValueError for non-int strings
|
# Handle: TypeError for 'None', ValueError for non-int strings
|
||||||
# and AssertionError for values <= 0
|
# and values <= 0
|
||||||
raise ValueError('Must be an integer > 0, not "%s".' % param)
|
raise ValueError('Must be an integer > 0, not "%s".' % param)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|||||||
@@ -124,16 +124,16 @@ class TestPyECLibDriver(unittest.TestCase):
|
|||||||
|
|
||||||
for ec_type in VALID_EC_TYPES:
|
for ec_type in VALID_EC_TYPES:
|
||||||
# missing k
|
# missing k
|
||||||
with self.assertRaises(ECDriverError) as err_context:
|
with self.assertRaises(TypeError) as err_context:
|
||||||
ECDriver(ec_type=ec_type, m=1)
|
ECDriver(ec_type=ec_type, m=1)
|
||||||
self.assertEqual(str(err_context.exception),
|
self.assertIn("missing 1 required keyword-only argument: 'k'",
|
||||||
"Invalid Argument: k is required")
|
str(err_context.exception))
|
||||||
|
|
||||||
# missing m
|
# missing m
|
||||||
with self.assertRaises(ECDriverError) as err_context:
|
with self.assertRaises(TypeError) as err_context:
|
||||||
ECDriver(ec_type=ec_type, k=1)
|
ECDriver(ec_type=ec_type, k=1)
|
||||||
self.assertEqual(str(err_context.exception),
|
self.assertIn("missing 1 required keyword-only argument: 'm'",
|
||||||
"Invalid Argument: m is required")
|
str(err_context.exception))
|
||||||
|
|
||||||
def test_invalid_km_args(self):
|
def test_invalid_km_args(self):
|
||||||
for ec_type in VALID_EC_TYPES:
|
for ec_type in VALID_EC_TYPES:
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ from pyeclib.ec_iface import VALID_EC_TYPES
|
|||||||
class Timer:
|
class Timer:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.start_time = 0
|
self.start_time = 0.0
|
||||||
self.end_time = 0
|
self.end_time = 0.0
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.start_time = time.time()
|
self.start_time = time.time()
|
||||||
|
|||||||
Reference in New Issue
Block a user