summaryrefslogtreecommitdiff
path: root/plac/doc/plac.html
blob: 006ee7cb2fd0390997ac53da76d9d8d267878514 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parsing the Command Line the Easy Way: Introducing plac, the Easiest Argument Parser in the Python World</title>
<meta name="author" content="Michele Simionato" />
<style type="text/css">

.first {
  margin-top: 0 }

.last {
  margin-bottom: 0 }

a.toc-backref {
  text-decoration: none ;
  color: black }

dd {
  margin-bottom: 0.5em }

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em }

div.footer, div.header {
  font-size: smaller }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

hr {
  width: 75% }

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font-family: serif ;
  font-size: 100% }

pre.line-block {
  font-family: serif ;
  font-size: 100% }

pre.literal-block, pre.doctest-block {
  background-color: #eeeeee }

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option-argument {
  font-style: italic }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

table {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.citation {
  border-left: solid thin gray ;
  padding-left: 0.5ex }

table.docinfo {
  margin: 2em 4em }

table.footnote {
  border-left: solid thin black ;
  padding-left: 0.5ex }

td, th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

th.docinfo-name, th.field-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap }

h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
  font-size: 100% }

tt {
  background-color: #eeeeee }

ul.auto-toc {
  list-style-type: none }


/*
Additional styles for "modern"-style of DocFactory.

:Author: Gunnar Schwant
:Contact: g.schwant@gmx.de
*/

.first {
  font-size: 10pt }

.last {
  font-size: 10pt }

a {
  text-decoration: none }

a.reference {
  color: #00009F }

a:hover {
  background-color: #00009F ;
  color: white }

body {
  font-family: arial,helvetica,univers ;
  font-size: 10pt ;
  padding-top: 0.6cm ;
  margin-left:0.5cm ;
  margin-right:0.5cm ;
  margin-bottom:0.5cm }

dd {
  font-size: 10pt ;
  padding-top: 0.1cm
}

dt {
  font-size: 10pt ;
  font-weight: bold ;
  background-color: #6FC7FB ;
  padding-left: 0.1cm ;
  padding-top: 0.1cm ;
  padding-bottom: 0.1cm }

div.abstract {
  font-size: 10pt }

div.abstract p.topic-title {
  font-size: 10pt }

div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning {
  font-size: 10pt }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, div.hint p.admonition-title, 
div.important p.admonition-title, div.note p.admonition-title, 
div.tip p.admonition-title {
  margin-top: 0em ;
  font-size: 12pt ;
  font-family: arial,helvetica,univers }

div.dedication {
  font-size: 10pt }

div.dedication p.topic-title {
  font-size: 10pt }

div.figure {
  font-size: 10pt }

div.footer, div.header {
  font-size: 8pt }

div.system-messages {
  font-size: 10pt }

div.system-messages h1 {
  font-size: 12pt }

div.system-message {
  font-size: 10pt }

div.system-message p.system-message-title {
  font-size: 10pt }

div.topic {
  font-size: 10pt }

h1, h2, h3, h4, h5, h6 {
  padding-top: 0.5cm ;
  page-break-after: avoid ;
  font-family: arial,helvetica,univers }

h1 {
  font-size: 18pt }

h1.title {
  color: white ;
  background-color: #00009F ;
  padding-top: 0cm }

h2 {
  font-size: 16pt }

h2.subtitle {
  padding-top: 0cm }

h3 {
  font-size: 14pt }

h4 {
  font-size: 12pt }

h5, h6 {
  font-size: 10pt }

hr {
  width: 100%;
  page-break-after: always }

li {
  padding-top: 1mm ;
  padding-bottom: 1mm }

ol.simple, ul.simple {
  font-size: 10pt }

ol.arabic {
  font-size: 10pt }

ol.loweralpha {
  font-size: 10pt }

ol.upperalpha {
  font-size: 10pt }

ol.lowerroman {
  font-size: 10pt }

ol.upperroman {
  font-size: 10pt }

p.caption {
  font-size: 10pt }

p.credits {
  font-style: italic ;
  font-size: 8pt }

p.label {
  font-size: 10pt }

p.topic-title {
  font-size: 10pt }

pre.address {
  font-family: arial,helvetica,univers ;
  font-size: 10pt }

pre.line-block {
  font-size: 10pt }

pre.literal-block, pre.doctest-block {
  border-width: 1pt ;
  border-style: solid ;
  border-color: #999999 ;
  color: #0000C0 ;
  background-color: #ffffe0 ;
  font-size: 9pt }

span.classifier {
  font-size: 10pt ;
  font-family: arial,helvetica,univers }

span.classifier-delimiter {
  font-size: 10pt ;
  font-family: arial,helvetica,univers }

span.field-argument {
  font-size: 10pt }

span.interpreted {
  font-size: 10pt ;
  font-family: arial,helvetica,univers }

span.option-argument {
  font-size: 10pt }

span.problematic {
  font-size: 10pt }

table {
  font-size: 10pt ;
  border-collapse: collapse ;
  border-width: 1.5pt ;
  border-color: #003366 }

table.citation {
  font-size: 10pt }

table.docinfo {
  font-size: 10pt }

table.footnote {
  font-size: 8pt ;
  text-align: left }

table.table {
  width: 100% }

th {
  border-width: 1.5pt }

td {
  border-width: 1pt }

td, th {
  font-size: 10pt ;
  border-style: thin ;
  border-color: #003366 }

td.docinfo-name, th.field-name {
  font-size: 10pt }

h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
  font-size: 10pt }

</style>
</head>
<body>
<div class="document" id="parsing-the-command-line-the-easy-way-introducing-plac-the-easiest-argument-parser-in-the-python-world">
<h1 class="title">Parsing the Command Line the Easy Way: Introducing plac, the Easiest Argument Parser in the Python World</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Michele Simionato</td></tr>
<tr class="field"><th class="docinfo-name">E-mail:</th><td class="field-body"><a class="reference external" href="mailto:michele.simionato&#64;gmail.com">michele.simionato&#64;gmail.com</a></td>
</tr>
<tr class="field"><th class="docinfo-name">Requires:</th><td class="field-body">Python 2.3+</td>
</tr>
<tr class="field"><th class="docinfo-name">Download page:</th><td class="field-body"><a class="reference external" href="http://pypi.python.org/pypi/plac">http://pypi.python.org/pypi/plac</a></td>
</tr>
<tr class="field"><th class="docinfo-name">Project page:</th><td class="field-body"><a class="reference external" href="http://micheles.googlecode.com/hg/plac/doc/plac.html">http://micheles.googlecode.com/hg/plac/doc/plac.html</a></td>
</tr>
<tr class="field"><th class="docinfo-name">Installation:</th><td class="field-body"><tt class="docutils literal">easy_install plac</tt></td>
</tr>
<tr class="field"><th class="docinfo-name">License:</th><td class="field-body">BSD license</td>
</tr>
</tbody>
</table>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#the-importance-of-scaling-down" id="id1">The importance of scaling down</a></li>
<li><a class="reference internal" href="#scripts-with-required-arguments" id="id2">Scripts with required arguments</a></li>
<li><a class="reference internal" href="#scripts-with-default-arguments" id="id3">Scripts with default arguments</a></li>
<li><a class="reference internal" href="#scripts-with-options" id="id4">Scripts with options</a></li>
<li><a class="reference internal" href="#scripts-with-flags" id="id5">Scripts with flags</a></li>
<li><a class="reference internal" href="#plac-for-python-2-x-users" id="id6">plac for Python 2.X users</a></li>
<li><a class="reference internal" href="#more-features" id="id7">More features</a></li>
<li><a class="reference internal" href="#a-more-realistic-example" id="id8">A more realistic example</a></li>
<li><a class="reference internal" href="#advanced-usage" id="id9">Advanced usage</a></li>
<li><a class="reference internal" href="#custom-annotation-objects" id="id10">Custom annotation objects</a></li>
<li><a class="reference internal" href="#plac-vs-argparse" id="id11">plac vs argparse</a></li>
<li><a class="reference internal" href="#the-future" id="id12">The future</a></li>
<li><a class="reference internal" href="#trivia-the-story-behind-the-name" id="id13">Trivia: the story behind the name</a></li>
</ul>
</div>
<div class="section" id="the-importance-of-scaling-down">
<h1><a class="toc-backref" href="#id1">The importance of scaling down</a></h1>
<p>There is no want of command line arguments parsers in the Python
world. The standard library alone contains three different modules:
<a class="reference external" href="http://docs.python.org/library/getopt.html">getopt</a> (from the stone age),
<a class="reference external" href="http://docs.python.org/library/optparse.html">optparse</a> (from Python 2.3) and <a class="reference external" href="http://argparse.googlecode.com">argparse</a> (from Python 2.7).  All of
them are quite powerful and especially <a class="reference external" href="http://argparse.googlecode.com">argparse</a> is an industrial
strength solution; unfortunately, all of them feature a non-zero learning
curve and a certain verbosity. They do not scale down well enough, at
least in my opinion.</p>
<p>It should not be necessary to stress the importance <a class="reference external" href="http://www.welton.it/articles/scalable_systems">scaling down</a>;
nevertheless most people are obsessed with features and concerned with
the possibility of scaling up, whereas I think that we should be even
more concerned with the issue of scaling down. This is an old meme in
the computing world: programs should address the common cases simply,
simple things should be kept simple, while at the same keeping
difficult things possible. <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> adhere as much as possible to this
philosophy and it is designed to handle well the simple cases, while
retaining the ability to handle complex cases by relying on the
underlying power of <a class="reference external" href="http://argparse.googlecode.com">argparse</a>.</p>
<p>Technically <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> is just a simple wrapper over <a class="reference external" href="http://argparse.googlecode.com">argparse</a> which hides
most of its complexity by using a declarative interface: the argument
parser is inferred rather than written down by imperatively.  Still, <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> is
surprisingly scalable upwards, even without using the underlying
<a class="reference external" href="http://argparse.googlecode.com">argparse</a>. I have been using Python for 8 years and in my experience
it is extremely unlikely that you will ever need to go beyond the
features provided by the declarative interface of <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>: they should
be more than enough for 99.9% of the use cases.</p>
<p><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> is targetting especially unsophisticated users,
programmers, sys-admins, scientists and in general people writing
throw-away scripts for themselves, choosing the command line
interface because it is the quick and simple. Such users are not
interested in features, they are interested in a small learning curve:
they just want to be able to write a simple command line tool from a
simple specification, not to build a command line parser by
hand. Unfortunately, the modules in the standard library forces them
to go the hard way. They are designed to implement power user tools
and they have a non-trivial learning curve. On the contrary, <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>
is designed to be simple to use and extremely concise, as the examples
below will show.</p>
</div>
<div class="section" id="scripts-with-required-arguments">
<h1><a class="toc-backref" href="#id2">Scripts with required arguments</a></h1>
<p>Let me start with the simplest possible thing: a script that takes a
single argument and does something to it.  It cannot get simpler
than that, unless you consider a script without command line
arguments, where there is nothing to parse. Still, it is a use
case <em>extremely common</em>: I need to write scripts like that nearly
every day, I wrote hundreds of them in the last few years and I have
never been happy. Here is a typical example of code I have been
writing by hand for years:</p>
<pre class="literal-block">
# example1.py
def main(dsn):
    &quot;Do something with the database&quot;
    print(dsn)
    # ...

if __name__ == '__main__':
    import sys
    n = len(sys.argv[1:])
    if n == 0:
        sys.exit('usage: python %s dsn' % sys.argv[0])
    elif n == 1:
        main(sys.argv[1])
    else:
        sys.exit('Unrecognized arguments: %s' % ' '.join(sys.argv[2:]))

</pre>
<p>As you see the whole <tt class="docutils literal">if __name__ == '__main__'</tt> block (nine lines)
is essentially boilerplate that should not exists.  Actually I think
the language should recognize the main function and pass to it the
command line arguments automatically; unfortunaly this is unlikely to
happen. I have been writing boilerplate like this in hundreds of
scripts for years, and every time I <em>hate</em> it. The purpose of using a
scripting language is convenience and trivial things should be
trivial. Unfortunately the standard library does not help for this
incredibly common use case. Using <a class="reference external" href="http://docs.python.org/library/getopt.html">getopt</a> and <a class="reference external" href="http://docs.python.org/library/optparse.html">optparse</a> does not help,
since they are intended to manage options and not positional
arguments; the <a class="reference external" href="http://argparse.googlecode.com">argparse</a> module helps a bit and it is able to reduce
the boilerplate from nine lines to six lines:</p>
<pre class="literal-block">
# example2.py
def main(dsn):
    &quot;Do something on the database&quot;
    print(dsn)
    # ...

if __name__ == '__main__':
    import argparse
    p = argparse.ArgumentParser()
    p.add_argument('dsn')
    arg = p.parse_args()
    main(arg.dsn)

</pre>
<p>However saving three lines does not justify introducing the external
dependency: most people will not switch to Python 2.7, which at the time of
this writing is just about to be released, for many years.
Moreover, it just feels too complex to instantiate a class and to
define a parser by hand for such a trivial task.</p>
<p>The <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> module is designed to manage well such use cases, and it is able
to reduce the original nine lines of boiler plate to two lines. With the
<a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> module all you need to write is</p>
<pre class="literal-block">
# example3.py
def main(dsn):
    &quot;Do something with the database&quot;
    print(dsn)
    # ...
 
if __name__ == '__main__':
    import plac; plac.call(main)

</pre>
<p>The <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> module provides for free (actually the work is done by the
underlying <a class="reference external" href="http://argparse.googlecode.com">argparse</a> module) a nice usage message:</p>
<pre class="literal-block">
$ python example3.py -h
usage: example3.py [-h] dsn

positional arguments:
  dsn

optional arguments:
  -h, --help  show this help message and exit
</pre>
<p>This is only the tip of the iceberg: <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> is able to do much more than that.</p>
</div>
<div class="section" id="scripts-with-default-arguments">
<h1><a class="toc-backref" href="#id3">Scripts with default arguments</a></h1>
<p>The need to have suitable defaults for command line arguments is quite
common. For instance I have encountered this use case at work hundreds
of times:</p>
<pre class="literal-block">
# example4.py
from datetime import datetime

def main(dsn, table='product', today=datetime.today()):
    &quot;Do something on the database&quot;
    print(dsn, table, today)

if __name__ == '__main__':
    import sys
    args = sys.argv[1:]
    if not args:
        sys.exit('usage: python %s dsn' % sys.argv[0])
    elif len(args) &gt; 2:
        sys.exit('Unrecognized arguments: %s' % ' '.join(argv[2:]))
    main(*args)

</pre>
<p>Here I want to perform a query on a database table, by extracting the
today's data: it makes sense for <tt class="docutils literal">today</tt> to be a default argument.
If there is a most used table (in this example a table called <tt class="docutils literal">'product'</tt>)
it also makes sense to make it a default argument. Performing the parsing
of the command lines arguments by hand takes 8 ugly lines of boilerplate
(using <a class="reference external" href="http://argparse.googlecode.com">argparse</a> would require about the same number of lines).
With <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> the entire <tt class="docutils literal">__main__</tt> block reduces to the usual two lines:</p>
<pre class="literal-block">
if __name__ == '__main__':
    import plac; plac.call(main)
</pre>
<p>In other words, six lines of boilerplate have been removed, and we get
the usage message for free:</p>
<pre class="literal-block">
usage: example5.py [-h] dsn [table] [today]

positional arguments:
  dsn
  table
  today

optional arguments:
  -h, --help  show this help message and exit
</pre>
<p><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> manages transparently even the case when you want to pass a
variable number of arguments. Here is an example, a script running
on a database a series of SQL scripts:</p>
<pre class="literal-block">
# example6.py
from datetime import datetime

def main(dsn, *scripts):
    &quot;Run the given scripts on the database&quot;
    for script in scripts:
        print('executing %s' % script)
        # ...

if __name__ == '__main__':
    import sys
    if len(sys.argv) &lt; 2:
        sys.exit('usage: python %s dsn script.sql ...' % sys.argv[0])
    main(sys.argv[1:])

</pre>
<p>Using <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>, you can just replace the <tt class="docutils literal">__main__</tt> block with the
usual two lines (I have defined an Emacs keybinding for them)
and then you get the following nice usage message:</p>
<pre class="literal-block">
usage: example7.py [-h] dsn [scripts [scripts ...]]

positional arguments:
  dsn
  scripts

optional arguments:
  -h, --help  show this help message and exit
</pre>
<p>The examples here should have made clear that <em>plac is able to figure out
the command line arguments parser to use from the signature of the main
function</em>. This is the whole idea behind <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>: if the intent is clear,
let's the machine take care of the details.</p>
</div>
<div class="section" id="scripts-with-options">
<h1><a class="toc-backref" href="#id4">Scripts with options</a></h1>
<p>It is surprising how few command line scripts with options I have
written over the years (probably less than a hundred), compared to the
number of scripts with positional arguments I wrote (certainly more
than a thousand of them).  Still, this use case cannot be neglected.
The standard library modules (all of them) are quite verbose when it
comes to specifying the options and frankly I have never used them
directly. Instead, I have always relied on an old recipe of mine, the
<a class="reference external" href="http://code.activestate.com/recipes/278844-parsing-the-command-line/">optionparse</a> recipe, which provides a convenient wrapper over
<a class="reference external" href="http://code.activestate.com/recipes/278844-parsing-the-command-line/">optionparse</a>. Alternatively, in the simplest cases, I have just
performed the parsing by hand.</p>
<p><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> is inspired to the <a class="reference external" href="http://code.activestate.com/recipes/278844-parsing-the-command-line/">optionparse</a> recipe, in the sense that it
delivers the programmer from the burden of writing the parser, but is
less of a hack: instead of extracting the parser from the docstring of
the module, it extracts it from the signature of the <tt class="docutils literal">main</tt>
function.</p>
<p>The idea comes from the <cite>function annotations</cite> concept, a new
feature of Python 3. An example is worth a thousand words, so here
it is:</p>
<pre class="literal-block">
# example8.py
def main(command: (&quot;SQL query&quot;, 'option', 'c'), dsn):
    if command:
        print('executing %s on %s' % (command, dsn))
        # ...

if __name__ == '__main__':
    import plac; plac.call(main)

</pre>
<p>As you see, the argument <tt class="docutils literal">command</tt> has been annotated with the tuple
<tt class="docutils literal">(&quot;SQL query&quot;, 'option', 'c')</tt>: the first string is the help string
which will appear in the usage message, the second string tell <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>
that <tt class="docutils literal">command</tt> is an option and the third string that it can be
abbreviated with the letter <tt class="docutils literal">c</tt>. Of course, the long option format
(<tt class="docutils literal"><span class="pre">--command=</span></tt>) comes from the argument name.  The resulting usage
message is the following:</p>
<pre class="literal-block">
usage: example8.py [-h] [-c COMMAND] dsn

positional arguments:
  dsn

optional arguments:
  -h, --help            show this help message and exit
  -c COMMAND, --command COMMAND
                        SQL query
</pre>
<p>Here are two examples of usage:</p>
<pre class="literal-block">
$ python3 example8.py -c&quot;select * from table&quot; dsn
executing select * from table on dsn

$ python3 example8.py --command=&quot;select * from table&quot; dsn
executing select * from table on dsn
</pre>
<p>Notice that if the option is not passed, the variable <tt class="docutils literal">command</tt>
will get the value <tt class="docutils literal">None</tt>. It is possible to specify a non-trivial
default for an option. Here is an example:</p>
<pre class="literal-block">
# example8_.py
def main(dsn, command: (&quot;SQL query&quot;, 'option', 'c')='select * from table'):
    print('executing %r on %s' % (command, dsn))

if __name__ == '__main__':
    import plac; plac.call(main)

</pre>
<p>Now if you do not pass the <tt class="docutils literal">command option</tt>, the
default query will be executed:</p>
<pre class="literal-block">
$ python example8_.py dsn
executing 'select * from table' on dsn
</pre>
<p>Positional argument can be annotated too:</p>
<pre class="literal-block">
def main(command: (&quot;SQL query&quot;, 'option', 'c'),
         dsn: (&quot;Database dsn&quot;, 'positional', None)):
    ...
</pre>
<p>Of course explicit is better than implicit, an no special cases are
special enough, but sometimes practicality beats purity, so <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> is
able to use smart defaults; in particular you can omit the third argument
and write:</p>
<pre class="literal-block">
def main(command: (&quot;SQL query&quot;, 'option'),
         dsn: (&quot;Database dsn&quot;, 'positional')):
    ...
</pre>
<p>When omitted, the third argument is assumed to be the first letter of
the variable name for options and flags, and <tt class="docutils literal">None</tt> for positional
arguments. Moreover, smart enough to convert help messages into tuples;
in other words, you can just write <tt class="docutils literal">&quot;Database dsn&quot;</tt> instead of
<tt class="docutils literal">(&quot;Database dsn&quot;, 'positional')</tt>.</p>
<p>I should notice that varargs (starred-arguments) can be annotated too;
here is an example:</p>
<pre class="literal-block">
def main(dsn: &quot;Database dsn&quot;, *scripts: &quot;SQL scripts&quot;):
    ...
</pre>
<p>This is a valid signature for <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>, which will recognize the help strings
for both <tt class="docutils literal">dsn</tt> and <tt class="docutils literal">scripts</tt>:</p>
<pre class="literal-block">
positional arguments:
  dsn                          Database dsn
  scripts                      SQL scripts
</pre>
</div>
<div class="section" id="scripts-with-flags">
<h1><a class="toc-backref" href="#id5">Scripts with flags</a></h1>
<p><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> also recognizes flags, i.e. boolean options which are
<tt class="docutils literal">True</tt> if they are passed to the command line and <tt class="docutils literal">False</tt>
if they are absent. Here is an example:</p>
<pre class="literal-block">
# example9.py

def main(verbose: ('prints more info', 'flag', 'v'), dsn: 'connection string'):
    if verbose:
        print('connecting to %s' % dsn)
    # ...

if __name__ == '__main__':
    import plac; plac.call(main)

</pre>
<pre class="literal-block">
$ python3 example9.py -h
usage: example9.py [-h] [-v] dsn

positional arguments:
  dsn            connection string

optional arguments:
  -h, --help     show this help message and exit
  -v, --verbose  prints more info
</pre>
<pre class="literal-block">
$ python3 example9.py -v dsn
connecting to dsn
</pre>
<p>Notice that it is an error trying to specify a default for flags: the
default value for a flag is always <tt class="docutils literal">False</tt>. If you feel the need to
implement non-boolean flags, you should use an option with two
choices, as explained in the &quot;more features&quot; section.</p>
<p>For consistency with the way the usage message is printed, I suggest
you to follow the Flag-Option-Required-Default (FORD) convention: in
the <tt class="docutils literal">main</tt> function write first the flag arguments, then the option
arguments, then the required arguments and finally the default
arguments. This is just a convention and you are not forced to use it,
except for the default arguments (including the varargs) which must
stay at the end as it is required by the Python syntax.</p>
</div>
<div class="section" id="plac-for-python-2-x-users">
<h1><a class="toc-backref" href="#id6">plac for Python 2.X users</a></h1>
<p>I do not use Python 3. At work we are just starting to think about
migrating to Python 2.6. It will take years before we
think to migrate to Python 3. I am pretty much sure most Pythonistas
are in the same situation. Therefore <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> provides a way to work
with function annotations even in Python 2.X (including Python 2.3).
There is no magic involved; you just need to add the annotations
by hand. For instance the annotate function declaration</p>
<pre class="literal-block">
def main(dsn: &quot;Database dsn&quot;, *scripts: &quot;SQL scripts&quot;):
    ...
</pre>
<p>is equivalent to the following code:</p>
<pre class="literal-block">
def main(dsn, *scripts):
    ...
main.__annotations__ = dict(
    dsn=&quot;Database dsn&quot;,
    scripts=&quot;SQL scripts&quot;)
</pre>
<p>One should be careful to match the keys of the annotation dictionary
with the names of the arguments in the annotated function; for lazy
people with Python 2.4 available the simplest way is to use the
<tt class="docutils literal">plac.annotations</tt> decorator that performs the check for you:</p>
<pre class="literal-block">
&#64;plac.annotations(
    dsn=&quot;Database dsn&quot;,
    scripts=&quot;SQL scripts&quot;)
def main(dsn, *scripts):
    ...
</pre>
<p>In the rest of this article I will assume that you are using Python 2.X with
<tt class="docutils literal">X &gt;= 4</tt> and I will use the <tt class="docutils literal">plac.annotations</tt> decorator. Notice however
that the tests for <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> runs even on Python 2.3.</p>
</div>
<div class="section" id="more-features">
<h1><a class="toc-backref" href="#id7">More features</a></h1>
<p>Even if one of the goals of plac is to have a learning curve of
<em>minutes</em>, compared to the learning curve of <em>hours</em> of
<a class="reference external" href="http://argparse.googlecode.com">argparse</a>, it does not mean that I have removed all the features of
<a class="reference external" href="http://argparse.googlecode.com">argparse</a>. Actually a lot of <a class="reference external" href="http://argparse.googlecode.com">argparse</a> power persists in <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>.  Until
now, I have only showed simple annotations, but in general an
annotation is a 5-tuple of the form</p>
<blockquote>
<tt class="docutils literal">(help, kind, abbrev, type, choices, metavar)</tt></blockquote>
<p>where <tt class="docutils literal">help</tt> is the help message, <tt class="docutils literal">kind</tt> is a string in the set {
<tt class="docutils literal">&quot;flag&quot;</tt>, <tt class="docutils literal">&quot;option&quot;</tt>, <tt class="docutils literal">&quot;positional&quot;</tt>}, <tt class="docutils literal">abbrev</tt> is a
one-character string, <tt class="docutils literal">type</tt> is a callable taking a string in input,
<tt class="docutils literal">choices</tt> is a discrete sequence of values and <tt class="docutils literal">metavar</tt> is a string.</p>
<p><tt class="docutils literal">type</tt> is used to automagically convert the command line arguments
from the string type to any Python type; by default there is no
convertion and <tt class="docutils literal">type=None</tt>.</p>
<p><tt class="docutils literal">choices</tt> is used to restrict the number of the valid
options; by default there is no restriction i.e. <tt class="docutils literal">choices=None</tt>.</p>
<p><tt class="docutils literal">metavar</tt> is used to change the argument name in the usage message
(and only there); by default the metavar is <tt class="docutils literal">None</tt>: this means that
the name in the usage message is the same as the argument name,
unless the argument has a default and in such a case is
equal to the stringified form of the default.</p>
<p>Here is an example showing many of the features (taken from the
<a class="reference external" href="http://argparse.googlecode.com">argparse</a> documentation):</p>
<pre class="literal-block">
# example10.py
import plac

&#64;plac.annotations(
operator=(&quot;The name of an operator&quot;, 'positional', None, str, ['add', 'mul']),
numbers=(&quot;A number&quot;, 'positional', None, float, None, &quot;n&quot;))
def main(operator, *numbers):
    &quot;A script to add and multiply numbers&quot;
    op = getattr(float, '__%s__' % operator)
    result = dict(add=0.0, mul=1.0)[operator]
    for n in numbers:
        result = op(result, n)
    print(result)

if __name__ == '__main__':
    plac.call(main)

</pre>
<p>Here is the usage:</p>
<pre class="literal-block">
usage: example10.py [-h] {add,mul} [n [n ...]]

A script to add and multiply numbers

positional arguments:
  {add,mul}   The name of an operator
  n           A number

optional arguments:
  -h, --help  show this help message and exit
</pre>
<p>Notice that the docstring of the <tt class="docutils literal">main</tt> function has been automatically added
to the usage message. Here are a couple of examples of use:</p>
<pre class="literal-block">
$ python example10.py add 1 2 3 4
10.0
$ python example10.py mul 1 2 3 4
24.0
$ python example10.py ad 1 2 3 4 # a mispelling error
usage: example10.py [-h] {add,mul} [n [n ...]]
example10.py: error: argument operator: invalid choice: 'ad' (choose from 'add', 'mul')
</pre>
</div>
<div class="section" id="a-more-realistic-example">
<h1><a class="toc-backref" href="#id8">A more realistic example</a></h1>
<p>Here is a more realistic script using most of the features of <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> to
run SQL queries on a database by relying on <a class="reference external" href="http://www.sqlalchemy.org/">SQLAlchemy</a>. Notice the usage
of the <tt class="docutils literal">type</tt> feature to automagically convert a SQLAlchemy connection
string into a <a class="reference external" href="http://www.sqlalchemy.org/docs/reference/ext/sqlsoup.html">SqlSoup</a> object:</p>
<pre class="literal-block">
# dbcli.py
import plac
from sqlalchemy.ext.sqlsoup import SqlSoup

&#64;plac.annotations(
    db=(&quot;Connection string&quot;, 'positional', None, SqlSoup),
    header=(&quot;Header&quot;, 'flag', 'H'),
    sqlcmd=(&quot;SQL command&quot;, 'option', 'c', str, None, &quot;SQL&quot;),
    delimiter=(&quot;Column separator&quot;, 'option', 'd'),
    scripts=&quot;SQL scripts&quot;,
    )
def main(db, header, sqlcmd, delimiter=&quot;|&quot;, *scripts):
    &quot;A script to run queries and SQL scripts on a database&quot;
    print('Working on %s' % db.bind.url)
    if sqlcmd:
        result = db.bind.execute(sqlcmd)
        if header: # print the header
            print(delimiter.join(result.keys()))
        for row in result: # print the rows
            print(delimiter.join(map(str, row)))

    for script in scripts:
        db.bind.execute(file(script).read())

if __name__ == '__main__':
    plac.call(main)

</pre>
<p>Here is the usage message:</p>
<pre class="literal-block">
$ python dbcli.py -h
usage: dbcli.py [-h] [-H] [-c SQL] [-d |] db [scripts [scripts ...]]

A script to run queries and SQL scripts on a database

positional arguments:
  db                    Connection string
  scripts               SQL scripts

optional arguments:
  -h, --help            show this help message and exit
  -H, --header          Header
  -c SQL, --sqlcmd SQL  SQL command
  -d |, --delimiter |   Column separator
</pre>
</div>
<div class="section" id="advanced-usage">
<h1><a class="toc-backref" href="#id9">Advanced usage</a></h1>
<p><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> relies on a <a class="reference external" href="http://argparse.googlecode.com">argparse</a> for all of the heavy lifting work and it is
possible to leverage on <a class="reference external" href="http://argparse.googlecode.com">argparse</a> features directly or indirectly.</p>
<p>For instance, you can make invisible an argument in the usage message
simply by using <tt class="docutils literal"><span class="pre">'==SUPPRESS=='</span></tt> as help string (or
<tt class="docutils literal">argparse.SUPPRESS</tt>). Similarly, you can use <a class="reference external" href="http://argparse.googlecode.com/svn/tags/r11/doc/other-utilities.html?highlight=filetype#FileType">argparse.FileType</a>
directly.</p>
<p>It is also possible to pass options to the underlying
<tt class="docutils literal">argparse.ArgumentParser</tt> object (currently it accepts the default
arguments <tt class="docutils literal">description</tt>, <tt class="docutils literal">epilog</tt>, <tt class="docutils literal">prog</tt>, <tt class="docutils literal">usage</tt>,
<tt class="docutils literal">add_help</tt>, <tt class="docutils literal">argument_default</tt>, <tt class="docutils literal">parents</tt>, <tt class="docutils literal">prefix_chars</tt>,
<tt class="docutils literal">fromfile_prefix_chars</tt>, <tt class="docutils literal">conflict_handler</tt>, <tt class="docutils literal">formatter_class</tt>).
It is enough to set such attributes on the <tt class="docutils literal">main</tt> function.  For
instance</p>
<pre class="literal-block">
def main(...):
    pass

main.add_help = False
</pre>
<p>disable the recognition of the help flag <tt class="docutils literal"><span class="pre">-h,</span> <span class="pre">--help</span></tt>. This is not
particularly elegant, but I assume the typical user of <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> will be
happy with the defaults and would not want to change them; still it is
possible if she wants to. For instance, by setting the <tt class="docutils literal">description</tt>
attribute, it is possible to add a comment to the usage message (by
default the docstring of the <tt class="docutils literal">main</tt> function is used as
description). It is also possible to change the option prefix; for
instance if your script must run under Windows and you want to use &quot;/&quot;
as option prefix you can add the lines:</p>
<pre class="literal-block">
main.prefix_chars='-/'
main.short_prefix = '/'
</pre>
<p>The recognition of the <tt class="docutils literal">short_prefix</tt> attribute is a <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>
extension; there is also a companion <tt class="docutils literal">long_prefix</tt> attribute with
default value of <tt class="docutils literal"><span class="pre">&quot;--&quot;</span></tt>. <tt class="docutils literal">prefix_chars</tt> is an <a class="reference external" href="http://argparse.googlecode.com">argparse</a> feature.
Interested readers should read the documentation of <a class="reference external" href="http://argparse.googlecode.com">argparse</a> to
understand the meaning of the other options. If there is a set of
options that you use very often, you may consider writing a decorator
adding such options to the <tt class="docutils literal">main</tt> function for you. For simplicity,
<a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> does not perform any magic of that kind.</p>
<p>It is possible to access directly the underlying <a class="reference external" href="http://argparse.googlecode.com/svn/tags/r11/doc/ArgumentParser.html">ArgumentParser</a> object, by
invoking the <tt class="docutils literal">plac.parser_from</tt> utility function:</p>
<pre class="doctest-block">
&gt;&gt;&gt; import plac
&gt;&gt;&gt; def main(arg):
...     pass
...
&gt;&gt;&gt; print plac.parser_from(main)
ArgumentParser(prog='', usage=None, description=None, version=None,
formatter_class=&lt;class 'argparse.HelpFormatter'&gt;, conflict_handler='error',
add_help=True)
</pre>
<p>I use <tt class="docutils literal">plac.parser_from</tt> in the unit tests of the module, but regular
users should never need to use it.</p>
</div>
<div class="section" id="custom-annotation-objects">
<h1><a class="toc-backref" href="#id10">Custom annotation objects</a></h1>
<p>Internally <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> uses an <tt class="docutils literal">Annotation</tt> class to convert the tuples
in the function signature into annotation objects, i.e. objects with
six attributes <tt class="docutils literal">help, kind, short, type, choices, metavar</tt>.</p>
<p>Advanced users can implement their own annotation objects.
For instance, here is an example of how you could implement annotations for
positional arguments:</p>
<pre class="literal-block">
# annotations.py
class Positional(object):
    def __init__(self, help='', type=None, choices=None, metavar=None):
        self.help = help
        self.kind = 'positional'
        self.abbrev = None
        self.type = type
        self.choices = choices
        self.metavar = metavar

</pre>
<p>You can use such annotations objects as follows:</p>
<pre class="literal-block">
# example11.py
import plac
from annotations import Positional

&#64;plac.annotations(
    i=Positional(&quot;This is an int&quot;, int),
    n=Positional(&quot;This is a float&quot;, float),
    rest=Positional(&quot;Other arguments&quot;))
def main(i, n, *rest):
    print(i, n, rest)

if __name__ == '__main__':
    import plac; plac.call(main)

</pre>
<p>Here is the usage message you get:</p>
<pre class="literal-block">
usage: example11.py [-h] i n [rest [rest ...]]

positional arguments:
  i           This is an int
  n           This is a float
  rest        Other arguments

optional arguments:
  -h, --help  show this help message and exit
</pre>
<p>You can go on and define <tt class="docutils literal">Option</tt> and <tt class="docutils literal">Flag</tt> classes, if you like.
Using custom annotation objects you could do advanced things like extracting the
annotations from a configuration file or from a database, but I expect such
use cases to be quite rare: the default mechanism should work
pretty well for most users.</p>
</div>
<div class="section" id="plac-vs-argparse">
<h1><a class="toc-backref" href="#id11">plac vs argparse</a></h1>
<p><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> is opinionated and by design it does not try to make available
all of the features of <a class="reference external" href="http://argparse.googlecode.com">argparse</a> in an easy way.  In particular you
should be aware of the following limitations/differences (the
following assumes knowledge of <a class="reference external" href="http://argparse.googlecode.com">argparse</a>):</p>
<ul class="simple">
<li><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> automatically defines both a long and short form for each options,
just like <a class="reference external" href="http://docs.python.org/library/optparse.html">optparse</a>. <a class="reference external" href="http://argparse.googlecode.com">argparse</a> allows you to define only a long form,
or only a short form, if you like. However, since I have always been
happy with the behavior of <a class="reference external" href="http://docs.python.org/library/optparse.html">optparse</a>, which I feel is pretty much
consistent, I have decided not to support this feature.</li>
<li>plac does not support the destination concept: the destination
coincides with the name of the argument, always. This restriction
has some drawbacks. For instance, suppose you want to define a long
option called <tt class="docutils literal"><span class="pre">--yield</span></tt>. In this case the destination would be <tt class="docutils literal">yield</tt>,
which is a Python keyword, and since you cannot introduce an
argument with that name in a function definition, it is impossible
to implement it. Your choices are to change the name of the long
option, or to use <a class="reference external" href="http://argparse.googlecode.com">argparse</a> with a suitable destination.</li>
<li><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> does not support &quot;required options&quot;. As the <a class="reference external" href="http://argparse.googlecode.com">argparse</a>
documentation puts it: <em>Required options are generally considered bad
form - normal users expect options to be optional. You should avoid
the use of required options whenever possible.</em></li>
<li><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> supports only regular boolean flags. <a class="reference external" href="http://argparse.googlecode.com">argparse</a> has the ability to
define generalized two-value flags with values different from <tt class="docutils literal">True</tt>
and <tt class="docutils literal">False</tt>. An earlier version of <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> had this feature too, but
since you can use options with two choices instead, and in any case
the conversion from <tt class="docutils literal">{True, False}</tt> to any couple of values
can be trivially implemented with a ternary operator
(<tt class="docutils literal">value1 if flag else value2</tt>), I have removed it (KISS rules!).</li>
<li><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> does not support <tt class="docutils literal">nargs</tt> options directly (it uses them internally,
though, to implement flag recognition). The reason it that all the use
cases of interest to me are covered by <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> and did not feel the need
to increase the learning curve by adding direct support for <tt class="docutils literal">nargs</tt>.</li>
<li><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> does not support subparsers directly. For the moment, this
looks like a feature too advanced for the goals of <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>.</li>
<li><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> does not support actions directly. This also
looks like a feature too advanced for the goals of <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>. Notice however
that the ability to define your own annotation objects may mitigate the
need for custom actions.</li>
</ul>
<p>I should stress again that if you want to access all of the <a class="reference external" href="http://argparse.googlecode.com">argparse</a> features
from <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> you can use <tt class="docutils literal">plac.parser_from</tt> and you will get
the underlying <a class="reference external" href="http://argparse.googlecode.com/svn/tags/r11/doc/ArgumentParser.html">ArgumentParser</a> object. The the full power of <a class="reference external" href="http://argparse.googlecode.com">argparse</a>
is then available to you: you can use <tt class="docutils literal">add_argument</tt>, <tt class="docutils literal">add_subparsers()</tt>,
etc. In other words, while some features are not supported directly,
<em>all</em> features are supported indirectly.</p>
</div>
<div class="section" id="the-future">
<h1><a class="toc-backref" href="#id12">The future</a></h1>
<p>Currently plac is below 100 lines of code, not counting blanks, comments
and docstrings. I do not plan to extend it much in the future. The idea is
to keep the module short: it is and it should remain a little wrapper over
<a class="reference external" href="http://argparse.googlecode.com">argparse</a>. Actually I have thought about contributing the code back to
<a class="reference external" href="http://argparse.googlecode.com">argparse</a> if <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> becomes successfull and gains a reasonable number of
users. For the moment it should be considered experimental: after all
I wrote it in three days, including the tests, the documentation and the
time to learn <a class="reference external" href="http://argparse.googlecode.com">argparse</a>.</p>
</div>
<div class="section" id="trivia-the-story-behind-the-name">
<h1><a class="toc-backref" href="#id13">Trivia: the story behind the name</a></h1>
<p>The <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> project started very humble: I just wanted to make
easy_installable my old <a class="reference external" href="http://code.activestate.com/recipes/278844-parsing-the-command-line/">optionparse</a> recipe, and to publish it on PyPI.
The original name of <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> was optionparser and the idea behind it was
to build an <a class="reference external" href="http://docs.python.org/library/optparse.html?highlight=optionparser#optparse.OptionParser">OptionParser</a> object from the docstring of the module.
However, before doing that, I decided to check out the <a class="reference external" href="http://argparse.googlecode.com">argparse</a> module,
since I knew it was going into Python 2.7 and Python 2.7 was coming out.
Soon enough I realized two things:</p>
<ol class="arabic simple">
<li>the single greatest idea of <a class="reference external" href="http://argparse.googlecode.com">argparse</a> was unifying the positional arguments
and the options in a single namespace object;</li>
<li>parsing the docstring was so old-fashioned, considering the existence
of functions annotations in Python 3.</li>
</ol>
<p>Putting together these two observations with the original idea of inferring the
parser I decided to build an <a class="reference external" href="http://argparse.googlecode.com/svn/tags/r11/doc/ArgumentParser.html">ArgumentParser</a> object from function
annotations. The <tt class="docutils literal">optionparser</tt> name was ruled out, since I was
now using <a class="reference external" href="http://argparse.googlecode.com">argparse</a>; a name like <tt class="docutils literal">argparse_plus</tt> was also ruled out,
since the typical usage was completely different from the <a class="reference external" href="http://argparse.googlecode.com">argparse</a> usage.</p>
<p>I made a research on PyPI and the name plac (Command Line Arguments Parser)
was not taken, so I renamed everything to plac. After two days
a <a class="reference external" href="http://pypi.python.org/pypi/Clap/0.7">Clap</a> module appeared on PyPI &lt;expletives deleted&gt;!</p>
<p>Having little imagination, I decided to rename everything again to plac,
an anagram of plac: since it is a non-existing English name, I hope nobody
will steal it from me!</p>
<p>That's all, I hope you will enjoy working with plac!</p>
</div>
</div>
</body>
</html>