def tox_addoption(parser):
def positive_integer(value):
ivalue = int(value)
if ivalue <= 0:
raise argparse.ArgumentTypeError(
"%s is an invalid positive int value" % value)
return ivalue
try:
num_proc = multiprocessing.cpu_count()
except Exception:
num_proc = 2
parser.add_argument(
"-n", "--num",
type=positive_integer,
action="store",
default=num_proc,
dest="numproc",
help="set the number of concurrent processes "
"(default %s)." % num_proc)
python类ArgumentTypeError()的实例源码
def int_greater_than_zero(time: int) -> int:
"""
>>> int_greater_than_zero(1)
1
>>> int_greater_than_zero(0)
Traceback (most recent call last):
argparse.ArgumentTypeError: Value should be greater than 0.
>>> int_greater_than_zero(-10)
Traceback (most recent call last):
argparse.ArgumentTypeError: Value should be greater than 0.
"""
time = int(time)
if time <= 0:
raise ArgumentTypeError('Value should be greater than 0.')
return time
def int_is_valid_port(port: int) -> int:
"""
>>> int_is_valid_port(4092)
4092
>>> int_is_valid_port(80)
Traceback (most recent call last):
argparse.ArgumentTypeError: Privileged port used.
>>> int_is_valid_port(9999999)
Traceback (most recent call last):
argparse.ArgumentTypeError: Port outside port range.
>>> int_is_valid_port(-4092)
Traceback (most recent call last):
argparse.ArgumentTypeError: Port outside port range.
"""
port = int(port)
if port in range(1, 1024):
raise ArgumentTypeError("Privileged port used.")
elif not port in range(1024, 2 ** 16):
raise ArgumentTypeError("Port outside port range.")
else:
return int_is_open_port(port)
def str_is_existing_path(path: str) -> str:
"""
>>> import tempfile
>>> with tempfile.TemporaryFile() as f:
... str_is_existing_file(f.name) == f.name
True
>>> with tempfile.TemporaryDirectory() as path:
... str_is_existing_path(path) == path
True
>>> str_is_existing_path('')
Traceback (most recent call last):
argparse.ArgumentTypeError: Given path is not an existing file or directory.
>>> str_is_existing_path('/non/existing/dir')
Traceback (most recent call last):
argparse.ArgumentTypeError: Given path is not an existing file or directory.
"""
if isfile(path) or isdir(path):
return path
else:
raise ArgumentTypeError("Given path is not an existing file or directory.")
def str_is_existing_file(path: str) -> str:
"""
>>> import tempfile
>>> with tempfile.TemporaryFile() as f:
... str_is_existing_file(f.name) == f.name
True
>>> str_is_existing_file('/home')
Traceback (most recent call last):
argparse.ArgumentTypeError: Given path is not an existing file.
>>> str_is_existing_file('')
Traceback (most recent call last):
argparse.ArgumentTypeError: Given path is not an existing file.
>>> str_is_existing_file('/non/existing/file')
Traceback (most recent call last):
argparse.ArgumentTypeError: Given path is not an existing file.
"""
if isfile(path):
return path
else:
raise ArgumentTypeError("Given path is not an existing file.")
def dirname_is_existing_dir(path: str) -> str:
"""
>>> import tempfile
>>> with tempfile.TemporaryDirectory() as dir:
... dirname_is_existing_dir(dir) == dir
True
>>> dirname_is_existing_dir('/non/existing/dir')
Traceback (most recent call last):
argparse.ArgumentTypeError: Dirname of path is not an existing directory.
"""
if isdir(dirname(abspath(path))):
return path
else:
raise ArgumentTypeError("Dirname of path is not an existing directory.")
def make_list_of_values(allowed):
"""
Take a list of allowed values for an option and return a function that can be
used to typecheck a string of given values and ensure they match the allowed
values. This is required to support options that take comma separated lists
such as --rights in 'tenant set --rights=create,delete,mount'
"""
def list_of_values(string):
given = string.split(',')
for g in given:
if g not in allowed:
msg = (
'invalid choices: {0} (choices must be a comma separated list of '
'only the following words \n {1}. '
'No spaces are allowed between choices.)').format(g, repr(allowed).replace(' ', ''))
raise argparse.ArgumentTypeError(msg)
return given
return list_of_values
def check_handler(value):
h = None
HANDLER_PREFIX = "handler_"
name = HANDLER_PREFIX + "base"
base_mod = load_mod(PKG_NAME, name)
if not base_mod:
print("load module %s failed" % (name), file=sys.stderr)
sys.exit(1)
try:
base_cls = getattr(base_mod, "HandlerBase")
except AttributeError as e:
print("err=%s, can't find HandlerBase class" % (e), file=sys.stderr)
sys.exit(1)
name = HANDLER_PREFIX + value
mod = load_mod(PKG_NAME, name)
if not mod:
print("load module %s failed" % (name), file=sys.stderr)
sys.exit(1)
for v in dir(mod):
cls = getattr(mod, v)
if inspect.isclass(cls) and issubclass(cls, base_cls):
return cls()
if h is None:
raise argparse.ArgumentTypeError("%s is an invalid handler" % value)
def valid_url(url):
"""validate url.
:rtype: str
:return: url
:param str url: package homepage url.
"""
regex = re.compile(
r'^(?:http)s?://'
r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+'
r'(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?))'
r'(?:/?|[/?]\S+)$', re.IGNORECASE)
if not regex.match(url):
raise argparse.ArgumentTypeError('"{0}" is invalid url.'.format(url))
return url
def __init__(self, arg_parser):
super(DisplayPlugin, self).__init__(arg_parser)
def filename(fn):
if not os.path.exists(fn):
raise ArgumentTypeError("The file %s does not exist!" % fn)
return fn
pattern_group = \
self.arg_group.add_mutually_exclusive_group(required=True)
pattern_group.add_argument("--pattern-help", action="store_true",
dest="pattern_help",
help=ARGS_HELP["--pattern-help"])
pattern_group.add_argument("-p", "--pattern", dest="pattern_string",
metavar="STRING",
help=ARGS_HELP["--pattern"])
pattern_group.add_argument("-f", "--pattern-file", dest="pattern_file",
metavar="FILE", type=filename,
help=ARGS_HELP["--pattern-file"])
self.arg_group.add_argument("--no-newline", action="store_true",
dest="no_newline",
help=ARGS_HELP["--no-newline"])
self.__pattern = None
self.__return_code = 0
def _check_toolplus(x):
"""Parse options for adding non-standard/commercial tools like GATK and MuTecT.
"""
import argparse
Tool = collections.namedtuple("Tool", ["name", "fname"])
std_choices = set(["data", "cadd", "dbnsfp"])
if x in std_choices:
return Tool(x, None)
elif "=" in x and len(x.split("=")) == 2:
name, fname = x.split("=")
fname = os.path.normpath(os.path.realpath(fname))
if not os.path.exists(fname):
raise argparse.ArgumentTypeError("Unexpected --toolplus argument for %s. File does not exist: %s"
% (name, fname))
return Tool(name, fname)
else:
raise argparse.ArgumentTypeError("Unexpected --toolplus argument. Expect toolname=filename.")
def read_file(filename, mode="rb"):
"""Returns the given file's contents.
:param str filename: path to file
:param str mode: open mode (see `open`)
:returns: absolute path of filename and its contents
:rtype: tuple
:raises argparse.ArgumentTypeError: File does not exist or is not readable.
"""
try:
filename = os.path.abspath(filename)
return filename, open(filename, mode).read()
except IOError as exc:
raise argparse.ArgumentTypeError(exc.strerror)
def nonnegative_int(value):
"""Converts value to an int and checks that it is not negative.
This function should used as the type parameter for argparse
arguments.
:param str value: value provided on the command line
:returns: integer representation of value
:rtype: int
:raises argparse.ArgumentTypeError: if value isn't a non-negative integer
"""
try:
int_value = int(value)
except ValueError:
raise argparse.ArgumentTypeError("value must be an integer")
if int_value < 0:
raise argparse.ArgumentTypeError("value must be non-negative")
return int_value
def __call__(self, parser, namespace, values, option_string=None):
# Make sure we have an empty dict rather than None
if getattr(namespace, self.dest, None) is None:
setattr(namespace, self.dest, {})
# Add value if an assignment else remove it
if '=' in values:
values_list = values.split('=', 1)
# NOTE(qtang): Prevent null key setting in property
if '' == values_list[0]:
msg = _("Property key must be specified: %s")
raise argparse.ArgumentTypeError(msg % str(values))
else:
getattr(namespace, self.dest, {}).update([values_list])
else:
msg = _("Expected 'key=value' type, but got: %s")
raise argparse.ArgumentTypeError(msg % str(values))
def test_mkvca_invalid_key(self):
try:
self.parser.parse_args([
'--test', 'req1=aaa,bbb=',
])
self.fail('ArgumentTypeError should be raised')
except argparse.ArgumentTypeError as e:
self.assertIn(
'Invalid keys bbb specified.\nValid keys are:',
str(e),
)
try:
self.parser.parse_args([
'--test', 'nnn=aaa',
])
self.fail('ArgumentTypeError should be raised')
except argparse.ArgumentTypeError as e:
self.assertIn(
'Invalid keys nnn specified.\nValid keys are:',
str(e),
)
def value_or_filename(string):
# argparse running on old version of python (<2.7) will pass an empty
# string to this function before it passes the actual value.
# If an empty string is passes in, just return an empty string
if string == "":
return ""
if string == '-':
try:
return sys.stdin.read()
except KeyboardInterrupt:
raise argparse.ArgumentTypeError("Unable to read value from stdin")
elif string[0] == "@":
filename = string[1:]
try:
with open(os.path.expanduser(filename)) as f:
output = f.read()
except IOError:
raise argparse.ArgumentTypeError("Unable to read file %s" %
filename)
else:
output = string
return output
def __call__(self, string):
"""Parse credentials from `string`.
("username" or "username:password").
"""
try:
return super(AuthCredentialsArgType, self).__call__(string)
except ArgumentTypeError:
# No password provided, will prompt for it later.
return self.key_value_class(
key=string,
value=None,
sep=SEP_CREDENTIALS,
orig=string
)
def required_length(minimum: int, maximum: int, optional: bool = False):
"""Returns a custom required length class"""
class RequiredLength(argparse.Action):
def __call__(self, parser, args, values, option_string=None):
is_allowed = (
(minimum <= len(values) <= maximum) or
(optional and not len(values))
)
if is_allowed:
setattr(args, self.dest, values)
return
raise argparse.ArgumentTypeError(
'Argument "{}" must have {}-{} arguments'.format(
self.dest,
minimum,
maximum
)
)
return RequiredLength
def __call__(self, parser, namespace, value, option_string=None):
pieces = value.split('-')
if not (0 < len(pieces) <= 3):
raise argparse.ArgumentError("wrong syntax in IntsRange with {}"
.format(value))
try:
if len(pieces) == 1:
self.result.append(int(pieces[0]))
elif len(pieces) == 2:
a, b = (int(x) for x in pieces)
self.result += list(range(a, b+1))
else:
a, b, c = (int(x) for x in pieces)
self.result += list(range(a, b+1, c))
self.result = sorted(set(self.result))
except ValueError as e:
raise argparse.ArgumentTypeError(value, "IntsRange requires integers")
setattr(namespace, self.dest, self.result)
#################### unit test
def sizetype(arg):
"""
Custom type for ArgumentParser
Converts size string in <num>[K|k|M|G] format into the integer value
"""
if arg.isdigit():
return int(arg) * 1024
if not arg[:-1].isdigit():
raise ArgumentTypeError("Invalid size: %r" % arg)
size = int(arg[:-1])
if arg.endswith("k") or arg.endswith("K"):
return size
if arg.endswith("M"):
return size * 1024
if arg.endswith("G"):
return size * 1024 * 1024
raise ArgumentTypeError("Invalid size: %r" % arg)
def systemidtype(arg):
"""
Custom type for ArgumentParser
Checks if the argument sutisfies system id requirements,
i.e. if it's one byte long integer > 0
"""
error = "Invalid system type: %s. must be hex "\
"between 0x1 and 0xFF" % arg
try:
result = int(arg, 16)
except ValueError:
raise ArgumentTypeError(error)
if result <= 0 or result > 0xff:
raise ArgumentTypeError(error)
return arg
def monkeytype_config(path: str) -> Config:
"""Imports the config instance specified by path.
Path should be in the form module:qualname. Optionally, path may end with (),
in which case we will call/instantiate the given class/function.
"""
should_call = False
if path.endswith('()'):
should_call = True
path = path[:-2]
module, qualname = module_path_with_qualname(path)
try:
config = get_name_in_module(module, qualname)
except MonkeyTypeError as mte:
raise argparse.ArgumentTypeError(f'cannot import {path}: {mte}')
if should_call:
config = config()
return config
def test_argument_type_error(self):
def spam(string):
raise argparse.ArgumentTypeError('spam!')
parser = ErrorRaisingArgumentParser(prog='PROG', add_help=False)
parser.add_argument('x', type=spam)
try:
parser.parse_args(['XXX'])
except ArgumentParserError:
expected = 'usage: PROG x\nPROG: error: argument x: spam!\n'
msg = sys.exc_info()[1].stderr
self.assertEqual(expected, msg)
else:
self.fail()
# ======================
# parse_known_args tests
# ======================
def learning_schedule() -> Callable:
"""
Returns a method that can be used in argument parsing to check that the argument is a valid learning rate schedule
string.
:return: A method that can be used as a type in argparse.
"""
def parse(schedule_str):
try:
schedule = LearningRateSchedulerFixedStep.parse_schedule_str(schedule_str)
except ValueError:
raise argparse.ArgumentTypeError(
"Learning rate schedule string should have form rate1:num_updates1[,rate2:num_updates2,...]")
return schedule
return parse
def int_range_type(from_, to):
def wrapped(user_input):
try:
int_user_input = int(user_input)
except ValueError:
msg = _("Not a valid integer value: %s") % user_input
raise argparse.ArgumentTypeError(msg)
if int_user_input > to:
tpl = _("Your input %s is great than max valid value %d")
msg = tpl % (user_input, to)
raise argparse.ArgumentTypeError(msg)
if int_user_input < from_:
tpl = _("Your input %s is less than min valid value %d")
msg = tpl % (user_input, from_)
raise argparse.ArgumentTypeError(msg)
return int_user_input
return wrapped
def volume_type(user_input=''):
try:
volume = user_input.split(':', 1)
if len(volume) != 2:
raise ValueError
_volume_type = string.upper(volume[0])
volume_size = int(volume[1])
if _volume_type != 'SSD' and _volume_type != 'SATA':
raise ValueError
return dict(type=_volume_type, size=volume_size)
except ValueError:
msg = _("%s is not a valid volume format") % user_input
raise argparse.ArgumentTypeError(msg)
# noinspection PyTypeChecker
def subnet_type(user_input=''):
try:
kv = {}
for kv_str in user_input.split(","):
split = kv_str.split("=", 1)
kv[split[0]] = split[1]
subnet = {}
if "subnet" in kv:
subnet["subnet_id"] = kv["subnet"]
else:
raise ValueError
if "ip" in kv:
subnet["ip_address"] = kv["ip"]
return subnet
except ValueError as e:
msg = _("%s is not a valid NIC") % user_input
raise argparse.ArgumentTypeError(msg)
def _comma_separated_numbers(string):
"""Parses an input consisting of comma-separated numbers."""
error_msg = 'Argument should be a comma-separated list of numbers: {}'
values = string.split(',')
if not values:
raise argparse.ArgumentTypeError(error_msg.format(string))
numbervalues = []
for value in values:
try:
numbervalues.append(int(value))
except ValueError:
try:
numbervalues.append(float(value))
except ValueError:
raise argparse.ArgumentTypeError(error_msg.format(string))
return numbervalues
def _decode_date(string):
"""Decodes a date from a command line argument, as msec since the epoch."""
try:
return int(string)
except ValueError:
date_formats = ['%Y-%m-%d',
'%Y-%m-%dT%H:%M:%S',
'%Y-%m-%dT%H:%M:%S.%f']
for date_format in date_formats:
try:
dt = datetime.datetime.strptime(string, date_format)
return _timestamp_ms_for_datetime(dt)
except ValueError:
continue
raise argparse.ArgumentTypeError(
'Invalid value for property of type "date": "%s".' % string)
def _decode_property(string):
"""Decodes a general key-value property from a command line argument."""
m = PROPERTY_RE.match(string)
if not m:
raise argparse.ArgumentTypeError(
'Invalid property: "%s". Must have the form "name=value" or '
'"(type)name=value".', string)
_, type_str, name, value_str = m.groups()
if type_str is None:
# Guess numeric types automatically.
try:
value = _decode_number(value_str)
except argparse.ArgumentTypeError:
value = value_str
elif type_str == TYPE_DATE:
value = _decode_date(value_str)
elif type_str == TYPE_NUMBER:
value = _decode_number(value_str)
elif type_str == TYPE_STRING:
value = value_str
else:
raise argparse.ArgumentTypeError(
'Unrecognized property type name: "%s". Expected one of "string", '
'"number", "date", or a prefix.' % type_str)
return (name, value)