Skip to content

Commit 584f856

Browse files
committed
Allow the use of space instead of = to separate the flag from its arg
Allow '-l python' instead of '-l=python' in the argument file. We still are limited to have a single argument per line so '--skip foo bar' will not work (neither '--skip=foo bar').
1 parent eacb16a commit 584f856

5 files changed

Lines changed: 133 additions & 8 deletions

File tree

byexample/cmdline.py

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
from .log_level import str_to_level
66
from .prof import profile
7+
'''
8+
>>> from byexample.cmdline import ByexampleArgumentParser
9+
'''
710

811

912
class _CSV(argparse.Action):
@@ -181,6 +184,74 @@ def _expand_glob_patterns(gpatterns):
181184
return list(set(fnames))
182185

183186

187+
class ByexampleArgumentParser(argparse.ArgumentParser):
188+
def convert_arg_line_to_args(self, arg_line):
189+
''' Return a list with the arguments read from a line.
190+
191+
If in the line there is a flag/argument with one or more
192+
values the flag may be separated from its value(s) with
193+
a space and this method will replace it with an '='.
194+
195+
This is in order to produce a single argument for each
196+
line as it is expected by argparse.ArgumentParser.
197+
198+
>>> parser = ByexampleArgumentParser()
199+
>>> parser.convert_arg_line_to_args('--skip=foo')
200+
['--skip=foo']
201+
202+
>>> parser.convert_arg_line_to_args('--skip foo')
203+
['--skip=foo']
204+
205+
>>> parser.convert_arg_line_to_args('--skip=foo bar')
206+
['--skip=foo bar']
207+
208+
>>> parser.convert_arg_line_to_args('--skip foo bar')
209+
['--skip=foo bar']
210+
211+
>>> parser.convert_arg_line_to_args('--skip=')
212+
['--skip=']
213+
214+
>>> parser.convert_arg_line_to_args('--skip ')
215+
['--skip ']
216+
217+
>>> parser.convert_arg_line_to_args('--skip')
218+
['--skip']
219+
220+
>>> parser.convert_arg_line_to_args('foo')
221+
['foo']
222+
223+
>>> parser.convert_arg_line_to_args('foo bar')
224+
['foo bar']
225+
'''
226+
arg_line = arg_line.lstrip()
227+
if arg_line and arg_line[0] in self.prefix_chars:
228+
flag, _, value = arg_line.partition(' ')
229+
value = value.lstrip()
230+
if not value:
231+
# the flag is argumentless or it is using '='
232+
# to paste the flag with its argument,
233+
# return the whole line then
234+
#
235+
# Ex:
236+
# -foo
237+
# -bar=32
238+
# -zaz=
239+
return [arg_line]
240+
else:
241+
if '=' in flag:
242+
# the line already has the '=' to paste the
243+
# flag with the argument, leave them as they are
244+
#
245+
# Ex:
246+
# -bar=32 42
247+
return [arg_line]
248+
249+
# Paste the flag with its value (or values) with a '='
250+
return [flag + '=' + value]
251+
252+
return [arg_line]
253+
254+
184255
@profile
185256
def parse_args(args=None):
186257
'''Parse the arguments args and return the them.
@@ -192,7 +263,7 @@ def parse_args(args=None):
192263
)
193264

194265
python_version = sys.version.split(' ', 1)[0]
195-
parser = argparse.ArgumentParser(
266+
parser = ByexampleArgumentParser(
196267
fromfile_prefix_chars='@',
197268
add_help=False,
198269
formatter_class=HelpExtraFormatter,

docs/basic/options.md

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ Other languages and concerns may add their owns.
6464
If the amount of options is a little overwhelming for you, you can
6565
write them down to a file and let ``byexample`` load them for you.
6666

67-
The only convention that you need to follow is to write one option
68-
per line and use ``=`` for the arguments.
67+
The only convention that you need to follow is to write **one** option
68+
per line.
6969

7070
```shell
7171
$ cat test/ds/options_file
72-
-l=python
73-
--options="+norm-ws"
72+
-l python
73+
--options "+norm-ws"
7474
```
7575

7676
Then load it with ``@`` and the file; you can use multiple files
@@ -83,7 +83,24 @@ File test/ds/python-tutorial.v2.md, 4/4 test ran in <...> seconds
8383
[PASS] Pass: 4 Fail: 0 Skip: 0
8484
```
8585

86-
## Glob or file pattern expansions
86+
> **Note:** before `10.5.2` the options in the file required to be followed by an
87+
> `=` like `-l=python`; spaces were not allowed.
88+
89+
Currently if the option receives more than one argument, you will still
90+
have to list *all* the arguments one per line.
91+
92+
```shell
93+
$ cat test/ds/pkg/bopts2
94+
--skip
95+
test/ds/pkg/foo1.py
96+
test/ds/pkg/foo2.py
97+
--
98+
test/ds/pkg/foo1.py
99+
test/ds/pkg/foo2.py
100+
test/ds/pkg/bar1.py
101+
```
102+
103+
## File pattern expansions
87104

88105
Consider the following:
89106

@@ -119,3 +136,30 @@ $ byexample -l python @test/ds/pkg/bopts | grep pkg | sort # byexample: +time
119136
File test/ds/pkg/bar1.py, 1/1 test ran in <...> seconds
120137
```
121138

139+
<!--
140+
141+
Extra test checking that options in a file with multiple spaces are
142+
interpreted correctly now that we support separate the flag from its
143+
value with a space (before an '=' was always required)
144+
145+
So the following lines are equivalent
146+
-skip=foo bar
147+
-skip foo bar
148+
149+
$ cat test/ds/pkg/bopts2
150+
<...>skip
151+
test/ds/pkg/foo1.py
152+
test/ds/pkg/foo2.py
153+
<...>
154+
155+
$ byexample -l python @test/ds/pkg/bopts2 | grep pkg | sort # byexample: +timeout=8
156+
File test/ds/pkg/bar1.py, 1/1 test ran in <...> seconds
157+
158+
$ cat test/ds/pkg/bopts3
159+
<...>skip=test/ds/pkg/foo1.py test/ds/pkg/foo2.py
160+
<...>
161+
162+
$ byexample -l python @test/ds/pkg/bopts2 | grep pkg | sort # byexample: +timeout=8
163+
File test/ds/pkg/bar1.py, 1/1 test ran in <...> seconds
164+
165+
-->

test/ds/options_file

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
-l=python
2-
--options="+norm-ws"
1+
-l python
2+
--options "+norm-ws"

test/ds/pkg/bopts2

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
--skip
2+
test/ds/pkg/foo1.py
3+
test/ds/pkg/foo2.py
4+
--
5+
test/ds/pkg/foo1.py
6+
test/ds/pkg/foo2.py
7+
test/ds/pkg/bar1.py

test/ds/pkg/bopts3

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
--skip=test/ds/pkg/foo1.py test/ds/pkg/foo2.py
2+
--
3+
test/ds/pkg/*.py

0 commit comments

Comments
 (0)