Skip to content
Snippets Groups Projects
Commit bd5d0263 authored by Bienchen's avatar Bienchen
Browse files

Alignment option is now required

parent d8c9c441
No related branches found
No related tags found
No related merge requests found
......@@ -121,9 +121,13 @@ def _AssembleTrgTplAln(target, template):
new_aln.SetSequenceOffset(1, start)
return new_aln
class PM3StoreOnceAction(argparse.Action):
"""Action for argument parsing to prevent multiple calls to an option.
"""
#pylint: disable=too-few-public-methods
def __init__(self, *args, **kwargs):
super(PM3StoreOnceAction, self).__init__(*args, **kwargs)
def __call__(self, parser, namespace, values, option_string=None):
if getattr(namespace, self.dest, None) is not None:
raise argparse.ArgumentError(self, 'may only be used once.')
......@@ -281,7 +285,7 @@ class PM3ArgumentParser(argparse.ArgumentParser):
"""
Actually add alignment arguments/ options
"""
aln_grp = self.add_mutually_exclusive_group()
aln_grp = self.add_mutually_exclusive_group(required=True)
# FastA input: - always pairwise alignments
# - callable multiple times
# - goes by 'trg:<SEQNAME> <FILE>'
......@@ -301,7 +305,6 @@ class PM3ArgumentParser(argparse.ArgumentParser):
aln_grp.add_argument('-j', '--json', metavar='<OBJECT>|<FILE>',
help='Alignments provided as JSON file/ object.',
action=PM3StoreOnceAction)
# possibility to add JSON: mention limitation!
class PM3OptionsNamespace(object):
"""
......@@ -332,6 +335,9 @@ class PM3OptionsNamespace(object):
seqfile, new_aln = _FetchAlnFromFastaOpt(src)
self.alignments.append(new_aln)
self.aln_sources.append(seqfile)
return
# Now for JSON input. Since one of the options needs to be given and
# we already checked for FastA, no need to open a new branch, here.
# LocalWords: param attr prog argparse ArgumentParser bool sys os init str
# LocalWords: progattr descattr argpinit argv formatter meth args namespace
......
......@@ -38,6 +38,7 @@ class PM3ArgParseTests(unittest.TestCase):
with self.assertRaises(SystemExit) as ecd:
parser.Parse(['-x'])
self.assertEqual(ecd.exception.code, 2)
self.assertEqual(len(self.log.messages['ERROR']), 2)
self.assertEqual(self.log.messages['ERROR'],
['usage: test_pm3argparse.py [-h]',
'test_pm3argparse.py: error: unrecognized '+
......@@ -85,9 +86,10 @@ class PM3ArgParseTests(unittest.TestCase):
with self.assertRaises(SystemExit) as ecd:
parser.Parse(['--fasta', 'data/fasta/alignment.fas'])
self.assertEqual(ecd.exception.code, 2)
self.assertEqual(len(self.log.messages['ERROR']), 2)
self.assertEqual(self.log.messages['ERROR'],
['usage: test_pm3argparse.py [-h] [-f trg:<NAME> '+
'<FILE> | -j <OBJECT>|<FILE>]',
['usage: test_pm3argparse.py [-h] (-f trg:<NAME> '+
'<FILE> | -j <OBJECT>|<FILE>)',
'test_pm3argparse.py: error: argument -f/--fasta: '+
'expected 2 argument(s)'])
......@@ -99,9 +101,10 @@ class PM3ArgParseTests(unittest.TestCase):
with self.assertRaises(SystemExit) as ecd:
parser.Parse(['--fasta', 'trg:target'])
self.assertEqual(ecd.exception.code, 2)
self.assertEqual(len(self.log.messages['ERROR']), 2)
self.assertEqual(self.log.messages['ERROR'],
['usage: test_pm3argparse.py [-h] [-f trg:<NAME> '+
'<FILE> | -j <OBJECT>|<FILE>]',
['usage: test_pm3argparse.py [-h] (-f trg:<NAME> '+
'<FILE> | -j <OBJECT>|<FILE>)',
'test_pm3argparse.py: error: argument -f/--fasta: '+
'expected 2 argument(s)'])
......@@ -114,6 +117,7 @@ class PM3ArgParseTests(unittest.TestCase):
with self.assertRaises(SystemExit) as ecd:
parser.Parse(['--fasta', 'foo', 'bar'])
self.assertEqual(ecd.exception.code, 11)
self.assertEqual(len(self.log.messages['ERROR']), 1)
self.assertEqual(self.log.messages['ERROR'][0],
"'--fasta foo bar' requires one "+
"argument prefixed with 'trg:' marking the target "+
......@@ -128,6 +132,7 @@ class PM3ArgParseTests(unittest.TestCase):
with self.assertRaises(SystemExit) as ecd:
parser.Parse(['--fasta', 'trg:', 'bar'])
self.assertEqual(ecd.exception.code, 14)
self.assertEqual(len(self.log.messages['ERROR']), 1)
self.assertEqual(self.log.messages['ERROR'][0], "'--fasta trg: bar' "+
"requires argument 'trg:' defining the target "+
"sequence name, empty one found: 'trg: bar'")
......@@ -141,6 +146,7 @@ class PM3ArgParseTests(unittest.TestCase):
with self.assertRaises(SystemExit) as ecd:
parser.Parse(['--fasta', 'bar', 'trg:'])
self.assertEqual(ecd.exception.code, 14)
self.assertEqual(len(self.log.messages['ERROR']), 1)
self.assertEqual(self.log.messages['ERROR'][0], "'--fasta bar trg:' "+
"requires argument 'trg:' defining the target "+
"sequence name, empty one found: 'bar trg:'")
......@@ -153,6 +159,7 @@ class PM3ArgParseTests(unittest.TestCase):
with self.assertRaises(SystemExit) as ecd:
parser.Parse(['--fasta', 'trg:foo', 'notexistingfile.fas'])
self.assertEqual(ecd.exception.code, 12)
self.assertEqual(len(self.log.messages['ERROR']), 1)
self.assertEqual(self.log.messages['ERROR'][0],
"Alignment file does not exist: notexistingfile.fas")
......@@ -164,6 +171,7 @@ class PM3ArgParseTests(unittest.TestCase):
with self.assertRaises(SystemExit) as ecd:
parser.Parse(['--fasta', 'trg:foo', 'data/fasta/alignment.fas'])
self.assertEqual(ecd.exception.code, 15)
self.assertEqual(len(self.log.messages['ERROR']), 1)
self.assertEqual(self.log.messages['ERROR'][0],
"'--fasta trg:foo data/fasta/alignment.fas' refers "+
"to an empty file or its in the wrong format.")
......@@ -175,6 +183,7 @@ class PM3ArgParseTests(unittest.TestCase):
with self.assertRaises(SystemExit) as ecd:
parser.Parse(['--fasta', 'trg:target', 'data/fasta/1ake_3.fas'])
self.assertEqual(ecd.exception.code, 16)
self.assertEqual(len(self.log.messages['ERROR']), 1)
self.assertEqual(self.log.messages['ERROR'][0], "'--fasta trg:target "+
"data/fasta/1ake_3.fas' points to an alignment with "+
"more than 2 sequences.")
......@@ -186,6 +195,7 @@ class PM3ArgParseTests(unittest.TestCase):
with self.assertRaises(SystemExit) as ecd:
parser.Parse(['--fasta', 'trg:trg', 'data/fasta/1ake.fas'])
self.assertEqual(ecd.exception.code, 17)
self.assertEqual(len(self.log.messages['ERROR']), 1)
self.assertEqual(self.log.messages['ERROR'][0], "'--fasta trg:trg "+
"data/fasta/1ake.fas' does not define a target name "+
"found in the alignment.")
......@@ -197,6 +207,7 @@ class PM3ArgParseTests(unittest.TestCase):
with self.assertRaises(SystemExit) as ecd:
parser.Parse(['--fasta', 'trg:target', 'data/fasta/1ake_nel.fas'])
self.assertEqual(ecd.exception.code, 18)
self.assertEqual(len(self.log.messages['ERROR']), 1)
self.assertEqual(self.log.messages['ERROR'][0], "'--fasta trg:target "+
"data/fasta/1ake_nel.fas': sequences in the "+
"alignment have different length.")
......@@ -274,18 +285,35 @@ class PM3ArgParseTests(unittest.TestCase):
self.assertEqual(opts.alignments[0].GetSequence(1).name, '1AKE.B')
self.assertEqual(opts.aln_sources[0], 'data/fasta/1ake.fas')
def testAddAlignmentNoneGiven(self):
# if we have none of '--fasta', '--json', fail.
parser = pm3argparse.PM3ArgumentParser(__doc__, action=False)
parser.AddAlignment()
parser.AssembleParser()
with self.assertRaises(SystemExit) as ecd:
parser.Parse([])
self.assertEqual(ecd.exception.code, 2)
self.assertEqual(len(self.log.messages['ERROR']), 2)
self.assertEqual(len(self.log.messages['ERROR']), 2)
self.assertEqual(self.log.messages['ERROR'][0],
'usage: test_pm3argparse.py [-h] (-f trg:<NAME> '+
'<FILE> | -j <OBJECT>|<FILE>)',
'test_pm3argparse.py: error: one of the arguments '+
'-f/--fasta -j/--json is required')
def testAddAlignmentFastaAndJson(self):
# testing that --fasta and --json DO NOT work together
parser = pm3argparse.PM3ArgumentParser(__doc__, action=False)
parser.AddAlignment()
parser.AssembleParser()
with self.assertRaises(SystemExit) as ecd:
opts = parser.Parse(['--fasta', 'trg:target',
'data/fasta/1ake.fas', '--json', 'foo'])
parser.Parse(['--fasta', 'trg:target', 'data/fasta/1ake.fas',
'--json', 'foo'])
self.assertEqual(ecd.exception.code, 2)
self.assertEqual(len(self.log.messages['ERROR']), 2)
self.assertEqual(self.log.messages['ERROR'][0],
'usage: test_pm3argparse.py [-h] [-f trg:<NAME> '+
'<FILE> | -j <OBJECT>|<FILE>]',
'usage: test_pm3argparse.py [-h] (-f trg:<NAME> '+
'<FILE> | -j <OBJECT>|<FILE>)',
'test_pm3argparse.py: error: argument -j/--json: '+
'not allowed with argument -f/--fasta')
......@@ -296,16 +324,15 @@ class PM3ArgParseTests(unittest.TestCase):
parser.AddAlignment()
parser.AssembleParser()
with self.assertRaises(SystemExit) as ecd:
opts = parser.Parse(['--json', 'foo', '--json', 'bar'])
parser.Parse(['--json', 'foo', '--json', 'bar'])
self.assertEqual(ecd.exception.code, 2)
self.assertEqual(len(self.log.messages['ERROR']), 2)
self.assertEqual(self.log.messages['ERROR'][0],
'usage: test_pm3argparse.py [-h] [-f trg:<NAME> '+
'<FILE> | -j <OBJECT>|<FILE>]',
'usage: test_pm3argparse.py [-h] (-f trg:<NAME> '+
'<FILE> | -j <OBJECT>|<FILE>)',
'test_pm3argparse.py: error: argument -j/--json: '+
'may only be used once.')
# test no multiple --json
if __name__ == "__main__":
from ost import testutils
testutils.RunTests()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment