From 0e53765cf6fbac7a0cd3ecebb85168d4b374d508 Mon Sep 17 00:00:00 2001 From: Michele Simionato Date: Sun, 28 Nov 2010 09:47:48 +0100 Subject: Added df.css to plac --- plac/df.css | 400 +++++ plac/doc/plac.pdf | 4281 ++++++++++++++++++++++++++--------------------------- plac/doc/plac.txt | 2 + 3 files changed, 2498 insertions(+), 2185 deletions(-) create mode 100644 plac/df.css create mode 100644 plac/doc/plac.txt diff --git a/plac/df.css b/plac/df.css new file mode 100644 index 0000000..afa58bb --- /dev/null +++ b/plac/df.css @@ -0,0 +1,400 @@ +.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 } diff --git a/plac/doc/plac.pdf b/plac/doc/plac.pdf index 612eb98..55b19c0 100644 --- a/plac/doc/plac.pdf +++ b/plac/doc/plac.pdf @@ -1,4 +1,4 @@ -%PDF-1.3 +%PDF-1.4 %“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com % 'BasicFonts': class PDFDictionary 1 0 obj @@ -35,9 +35,9 @@ endobj 0 0 ] /Rect [ 153.7323 - 708.5936 + 705.7736 526.5827 - 720.5936 ] + 717.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -50,9 +50,9 @@ endobj 0 0 ] /Rect [ 153.7323 - 678.5936 + 675.7736 526.5827 - 690.5936 ] + 687.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -65,9 +65,9 @@ endobj 0 0 ] /Rect [ 153.7323 - 651.5936 + 648.7736 526.5827 - 663.5936 ] + 660.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -114,9 +114,9 @@ endobj 765.0236 0 ] /Rect [ 62.69291 - 726.5936 + 723.7736 286.0929 - 738.5936 ] + 735.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -132,9 +132,9 @@ endobj 765.0236 0 ] /Rect [ 527.0227 - 726.5936 + 723.7736 532.5827 - 738.5936 ] + 735.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -150,9 +150,9 @@ endobj 765.0236 0 ] /Rect [ 82.69291 - 708.5936 + 705.7736 223.8629 - 720.5936 ] + 717.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -168,9 +168,9 @@ endobj 765.0236 0 ] /Rect [ 527.0227 - 708.5936 + 705.7736 532.5827 - 720.5936 ] + 717.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -186,9 +186,9 @@ endobj 411.0236 0 ] /Rect [ 82.69291 - 690.5936 + 687.7736 223.2929 - 702.5936 ] + 699.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -204,9 +204,9 @@ endobj 411.0236 0 ] /Rect [ 527.0227 - 690.5936 + 687.7736 532.5827 - 702.5936 ] + 699.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -222,9 +222,9 @@ endobj 765.0236 0 ] /Rect [ 82.69291 - 672.5936 + 669.7736 216.6329 - 684.5936 ] + 681.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -240,9 +240,9 @@ endobj 765.0236 0 ] /Rect [ 527.0227 - 672.5936 + 669.7736 532.5827 - 684.5936 ] + 681.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -258,9 +258,9 @@ endobj 741.0236 0 ] /Rect [ 82.69291 - 654.5936 + 651.7736 257.7529 - 666.5936 ] + 663.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -276,9 +276,9 @@ endobj 741.0236 0 ] /Rect [ 527.0227 - 654.5936 + 651.7736 532.5827 - 666.5936 ] + 663.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -294,9 +294,9 @@ endobj 765.0236 0 ] /Rect [ 82.69291 - 636.5936 + 633.7736 157.7129 - 648.5936 ] + 645.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -312,9 +312,9 @@ endobj 765.0236 0 ] /Rect [ 527.0227 - 636.5936 + 633.7736 532.5827 - 648.5936 ] + 645.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -330,9 +330,9 @@ endobj 265.7299 0 ] /Rect [ 82.69291 - 618.5936 + 615.7736 194.4129 - 630.5936 ] + 627.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -348,9 +348,9 @@ endobj 265.7299 0 ] /Rect [ 527.0227 - 618.5936 + 615.7736 532.5827 - 630.5936 ] + 627.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -366,9 +366,9 @@ endobj 522.6236 0 ] /Rect [ 82.69291 - 600.5936 + 597.7736 144.3829 - 612.5936 ] + 609.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -384,9 +384,9 @@ endobj 522.6236 0 ] /Rect [ 521.4627 - 600.5936 + 597.7736 532.5827 - 612.5936 ] + 609.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -402,9 +402,9 @@ endobj 552.6236 0 ] /Rect [ 82.69291 - 582.5936 + 579.7736 166.6029 - 594.5936 ] + 591.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -420,9 +420,9 @@ endobj 552.6236 0 ] /Rect [ 521.4627 - 582.5936 + 579.7736 532.5827 - 594.5936 ] + 591.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -438,9 +438,9 @@ endobj 513.8236 0 ] /Rect [ 82.69291 - 564.5936 + 561.7736 171.6129 - 576.5936 ] + 573.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -456,9 +456,9 @@ endobj 513.8236 0 ] /Rect [ 521.4627 - 564.5936 + 561.7736 532.5827 - 576.5936 ] + 573.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -474,9 +474,9 @@ endobj 493.4236 0 ] /Rect [ 82.69291 - 546.5936 + 543.7736 228.8629 - 558.5936 ] + 555.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -492,9 +492,9 @@ endobj 493.4236 0 ] /Rect [ 521.4627 - 546.5936 + 543.7736 532.5827 - 558.5936 ] + 555.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -504,15 +504,15 @@ endobj 0 0 ] /Contents () - /Dest [ 158 0 R + /Dest [ 160 0 R /XYZ 62.69291 422.6236 0 ] /Rect [ 82.69291 - 528.5936 + 525.7736 156.0529 - 540.5936 ] + 537.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -522,15 +522,15 @@ endobj 0 0 ] /Contents () - /Dest [ 158 0 R + /Dest [ 160 0 R /XYZ 62.69291 422.6236 0 ] /Rect [ 521.4627 - 528.5936 + 525.7736 532.5827 - 540.5936 ] + 537.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -540,15 +540,15 @@ endobj 0 0 ] /Contents () - /Dest [ 207 0 R + /Dest [ 208 0 R /XYZ 62.69291 - 741.0236 + 765.0236 0 ] /Rect [ 82.69291 - 510.5936 + 507.7736 204.4129 - 522.5936 ] + 519.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -558,15 +558,15 @@ endobj 0 0 ] /Contents () - /Dest [ 207 0 R + /Dest [ 208 0 R /XYZ 62.69291 - 741.0236 + 765.0236 0 ] /Rect [ 521.4627 - 510.5936 + 507.7736 532.5827 - 522.5936 ] + 519.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -576,15 +576,15 @@ endobj 0 0 ] /Contents () - /Dest [ 207 0 R + /Dest [ 208 0 R /XYZ 62.69291 - 513.0236 + 543.0236 0 ] /Rect [ 82.69291 - 492.5936 + 489.7736 128.2729 - 504.5936 ] + 501.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -594,15 +594,15 @@ endobj 0 0 ] /Contents () - /Dest [ 207 0 R + /Dest [ 208 0 R /XYZ 62.69291 - 513.0236 + 543.0236 0 ] /Rect [ 521.4627 - 492.5936 + 489.7736 532.5827 - 504.5936 ] + 501.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -612,15 +612,15 @@ endobj 0 0 ] /Contents () - /Dest [ 207 0 R + /Dest [ 208 0 R /XYZ 62.69291 - 309.0236 + 339.0236 0 ] /Rect [ 82.69291 - 474.5936 + 471.7736 228.3129 - 486.5936 ] + 483.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -630,15 +630,15 @@ endobj 0 0 ] /Contents () - /Dest [ 207 0 R + /Dest [ 208 0 R /XYZ 62.69291 - 309.0236 + 339.0236 0 ] /Rect [ 521.4627 - 474.5936 + 471.7736 532.5827 - 486.5936 ] + 483.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -651,12 +651,12 @@ endobj /Dest [ 221 0 R /XYZ 62.69291 - 681.0236 + 711.0236 0 ] /Rect [ 62.69291 - 456.5936 + 453.7736 182.7329 - 468.5936 ] + 465.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -669,12 +669,12 @@ endobj /Dest [ 221 0 R /XYZ 62.69291 - 681.0236 + 711.0236 0 ] /Rect [ 521.4627 - 456.5936 + 453.7736 532.5827 - 468.5936 ] + 465.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -687,12 +687,12 @@ endobj /Dest [ 221 0 R /XYZ 62.69291 - 648.0236 + 678.0236 0 ] /Rect [ 82.69291 - 438.5936 + 435.7736 134.9429 - 450.5936 ] + 447.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -705,12 +705,12 @@ endobj /Dest [ 221 0 R /XYZ 62.69291 - 648.0236 + 678.0236 0 ] /Rect [ 521.4627 - 438.5936 + 435.7736 532.5827 - 450.5936 ] + 447.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -723,12 +723,12 @@ endobj /Dest [ 221 0 R /XYZ 62.69291 - 426.0236 + 456.0236 0 ] /Rect [ 82.69291 - 420.5936 + 417.7736 252.7429 - 432.5936 ] + 429.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -741,12 +741,12 @@ endobj /Dest [ 221 0 R /XYZ 62.69291 - 426.0236 + 456.0236 0 ] /Rect [ 521.4627 - 420.5936 + 417.7736 532.5827 - 432.5936 ] + 429.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -759,12 +759,12 @@ endobj /Dest [ 224 0 R /XYZ 62.69291 - 629.8236 + 663.0236 0 ] /Rect [ 82.69291 - 402.5936 + 399.7736 195.5229 - 414.5936 ] + 411.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -777,12 +777,12 @@ endobj /Dest [ 224 0 R /XYZ 62.69291 - 629.8236 + 663.0236 0 ] /Rect [ 521.4627 - 402.5936 + 399.7736 532.5827 - 414.5936 ] + 411.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -792,15 +792,15 @@ endobj 0 0 ] /Contents () - /Dest [ 227 0 R + /Dest [ 233 0 R /XYZ 62.69291 - 609.0236 + 645.0236 0 ] /Rect [ 82.69291 - 384.5936 + 381.7736 149.9429 - 396.5936 ] + 393.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -810,15 +810,15 @@ endobj 0 0 ] /Contents () - /Dest [ 227 0 R + /Dest [ 233 0 R /XYZ 62.69291 - 609.0236 + 645.0236 0 ] /Rect [ 521.4627 - 384.5936 + 381.7736 532.5827 - 396.5936 ] + 393.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -831,12 +831,12 @@ endobj /Dest [ 238 0 R /XYZ 62.69291 - 299.8485 + 347.8485 0 ] /Rect [ 82.69291 - 366.5936 + 363.7736 161.0529 - 378.5936 ] + 375.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -849,12 +849,12 @@ endobj /Dest [ 238 0 R /XYZ 62.69291 - 299.8485 + 347.8485 0 ] /Rect [ 521.4627 - 366.5936 + 363.7736 532.5827 - 378.5936 ] + 375.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -867,12 +867,12 @@ endobj /Dest [ 243 0 R /XYZ 62.69291 - 378.6236 + 426.6236 0 ] /Rect [ 82.69291 - 348.5936 + 345.7736 210.5129 - 360.5936 ] + 357.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -885,12 +885,12 @@ endobj /Dest [ 243 0 R /XYZ 62.69291 - 378.6236 + 426.6236 0 ] /Rect [ 521.4627 - 348.5936 + 345.7736 532.5827 - 360.5936 ] + 357.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -903,12 +903,12 @@ endobj /Dest [ 248 0 R /XYZ 62.69291 - 330.0679 + 367.2133 0 ] /Rect [ 82.69291 - 330.5936 + 327.7736 167.7229 - 342.5936 ] + 339.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -921,12 +921,12 @@ endobj /Dest [ 248 0 R /XYZ 62.69291 - 330.0679 + 367.2133 0 ] /Rect [ 521.4627 - 330.5936 + 327.7736 532.5827 - 342.5936 ] + 339.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -936,15 +936,15 @@ endobj 0 0 ] /Contents () - /Dest [ 254 0 R + /Dest [ 256 0 R /XYZ 62.69291 - 717.0236 + 765.0236 0 ] /Rect [ 82.69291 - 312.5936 + 309.7736 158.2829 - 324.5936 ] + 321.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -954,15 +954,15 @@ endobj 0 0 ] /Contents () - /Dest [ 254 0 R + /Dest [ 256 0 R /XYZ 62.69291 - 717.0236 + 765.0236 0 ] /Rect [ 521.4627 - 312.5936 + 309.7736 532.5827 - 324.5936 ] + 321.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -975,12 +975,12 @@ endobj /Dest [ 267 0 R /XYZ 62.69291 - 204.6236 + 258.6236 0 ] /Rect [ 82.69291 - 294.5936 + 291.7736 152.7229 - 306.5936 ] + 303.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -993,12 +993,12 @@ endobj /Dest [ 267 0 R /XYZ 62.69291 - 204.6236 + 258.6236 0 ] /Rect [ 521.4627 - 294.5936 + 291.7736 532.5827 - 306.5936 ] + 303.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1011,12 +1011,12 @@ endobj /Dest [ 271 0 R /XYZ 62.69291 - 371.4236 + 401.4236 0 ] /Rect [ 82.69291 - 276.5936 + 273.7736 205.5229 - 288.5936 ] + 285.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1029,12 +1029,12 @@ endobj /Dest [ 271 0 R /XYZ 62.69291 - 371.4236 + 401.4236 0 ] /Rect [ 521.4627 - 276.5936 + 273.7736 532.5827 - 288.5936 ] + 285.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1047,12 +1047,12 @@ endobj /Dest [ 274 0 R /XYZ 62.69291 - 384.6236 + 408.6236 0 ] /Rect [ 82.69291 - 258.5936 + 255.7736 209.9529 - 270.5936 ] + 267.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1065,12 +1065,12 @@ endobj /Dest [ 274 0 R /XYZ 62.69291 - 384.6236 + 408.6236 0 ] /Rect [ 521.4627 - 258.5936 + 255.7736 532.5827 - 270.5936 ] + 267.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1083,12 +1083,12 @@ endobj /Dest [ 278 0 R /XYZ 62.69291 - 211.4236 + 244.6236 0 ] /Rect [ 82.69291 - 240.5936 + 237.7736 192.7429 - 252.5936 ] + 249.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1101,12 +1101,12 @@ endobj /Dest [ 278 0 R /XYZ 62.69291 - 211.4236 + 244.6236 0 ] /Rect [ 521.4627 - 240.5936 + 237.7736 532.5827 - 252.5936 ] + 249.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1119,12 +1119,12 @@ endobj /Dest [ 281 0 R /XYZ 62.69291 - 318.6236 + 354.6236 0 ] /Rect [ 82.69291 - 222.5936 + 219.7736 177.1729 - 234.5936 ] + 231.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1137,12 +1137,12 @@ endobj /Dest [ 281 0 R /XYZ 62.69291 - 318.6236 + 354.6236 0 ] /Rect [ 521.4627 - 222.5936 + 219.7736 532.5827 - 234.5936 ] + 231.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1155,12 +1155,12 @@ endobj /Dest [ 285 0 R /XYZ 62.69291 - 475.8236 + 511.8236 0 ] /Rect [ 82.69291 - 204.5936 + 201.7736 271.6529 - 216.5936 ] + 213.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1173,12 +1173,12 @@ endobj /Dest [ 285 0 R /XYZ 62.69291 - 475.8236 + 511.8236 0 ] /Rect [ 521.4627 - 204.5936 + 201.7736 532.5827 - 216.5936 ] + 213.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1191,12 +1191,12 @@ endobj /Dest [ 287 0 R /XYZ 62.69291 - 675.0236 + 711.0236 0 ] /Rect [ 82.69291 - 186.5936 + 183.7736 286.6829 - 198.5936 ] + 195.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1209,12 +1209,12 @@ endobj /Dest [ 287 0 R /XYZ 62.69291 - 675.0236 + 711.0236 0 ] /Rect [ 521.4627 - 186.5936 + 183.7736 532.5827 - 198.5936 ] + 195.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1230,9 +1230,9 @@ endobj 765.0236 0 ] /Rect [ 82.69291 - 168.5936 + 165.7736 206.6229 - 180.5936 ] + 177.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1248,9 +1248,9 @@ endobj 765.0236 0 ] /Rect [ 521.4627 - 168.5936 + 165.7736 532.5827 - 180.5936 ] + 177.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1266,9 +1266,9 @@ endobj 630.4159 0 ] /Rect [ 82.69291 - 150.5936 + 147.7736 151.6029 - 162.5936 ] + 159.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1284,9 +1284,9 @@ endobj 630.4159 0 ] /Rect [ 521.4627 - 150.5936 + 147.7736 532.5827 - 162.5936 ] + 159.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1302,9 +1302,9 @@ endobj 160.0159 0 ] /Rect [ 82.69291 - 132.5936 + 129.7736 125.4729 - 144.5936 ] + 141.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1320,9 +1320,9 @@ endobj 160.0159 0 ] /Rect [ 521.4627 - 132.5936 + 129.7736 532.5827 - 144.5936 ] + 141.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1335,12 +1335,12 @@ endobj /Dest [ 296 0 R /XYZ 62.69291 - 508.6772 + 520.6772 0 ] /Rect [ 82.69291 - 114.5936 + 111.7736 246.1129 - 126.5936 ] + 123.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1353,12 +1353,12 @@ endobj /Dest [ 296 0 R /XYZ 62.69291 - 508.6772 + 520.6772 0 ] /Rect [ 521.4627 - 114.5936 + 111.7736 532.5827 - 126.5936 ] + 123.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1460,9 +1460,9 @@ endobj 0 0 ] /Rect [ 214.8914 - 720.5936 + 717.7736 246.5585 - 732.5936 ] + 729.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1475,9 +1475,9 @@ endobj 0 0 ] /Rect [ 346.507 - 720.5936 + 717.7736 389.2842 - 732.5936 ] + 729.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1490,9 +1490,9 @@ endobj 0 0 ] /Rect [ 493.1227 - 720.5936 + 717.7736 531.4956 - 732.5936 ] + 729.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1505,9 +1505,9 @@ endobj 0 0 ] /Rect [ 346.384 - 708.5936 + 705.7736 388.8477 - 720.5936 ] + 717.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1520,9 +1520,9 @@ endobj 0 0 ] /Rect [ 311.5097 - 666.5936 + 663.7736 371.5115 - 678.5936 ] + 675.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1535,9 +1535,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 618.5936 + 615.7736 84.90623 - 630.5936 ] + 627.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1550,9 +1550,9 @@ endobj 0 0 ] /Rect [ 453.4229 - 606.5936 + 603.7736 492.8829 - 618.5936 ] + 615.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1565,9 +1565,9 @@ endobj 0 0 ] /Rect [ 116.9711 - 588.5936 + 585.7736 139.5794 - 600.5936 ] + 597.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1580,9 +1580,9 @@ endobj 0 0 ] /Rect [ 277.9887 - 588.5936 + 585.7736 321.7169 - 600.5936 ] + 597.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1595,9 +1595,9 @@ endobj 0 0 ] /Rect [ 504.0394 - 576.5936 + 573.7736 525.3627 - 588.5936 ] + 585.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1610,9 +1610,9 @@ endobj 0 0 ] /Rect [ 351.0408 - 564.5936 + 561.7736 390.5008 - 576.5936 ] + 573.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1625,9 +1625,9 @@ endobj 0 0 ] /Rect [ 247.8817 - 540.5936 + 537.7736 266.2217 - 552.5936 ] + 549.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1640,9 +1640,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 510.5936 + 507.7736 85.3538 - 522.5936 ] + 519.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1655,9 +1655,9 @@ endobj 0 0 ] /Rect [ 124.2211 - 438.5936 + 435.7736 146.9252 - 450.5936 ] + 447.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1712,9 +1712,9 @@ endobj 0 0 ] /Rect [ 325.341 - 720.5936 + 717.7736 356.6198 - 732.5936 ] + 729.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1727,9 +1727,9 @@ endobj 0 0 ] /Rect [ 376.7786 - 720.5936 + 717.7736 419.1674 - 732.5936 ] + 729.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1742,9 +1742,9 @@ endobj 0 0 ] /Rect [ 365.694 - 708.5936 + 705.7736 408.8281 - 720.5936 ] + 717.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -1757,9 +1757,9 @@ endobj 0 0 ] /Rect [ 83.82606 - 457.3936 + 454.5736 106.0692 - 469.3936 ] + 466.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -1772,9 +1772,9 @@ endobj 0 0 ] /Rect [ 243.8829 - 445.3936 + 442.5736 265.0029 - 457.3936 ] + 454.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -1787,9 +1787,9 @@ endobj 0 0 ] /Rect [ 83.6329 - 308.1936 + 305.3736 105.6829 - 320.1936 ] + 317.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -1802,9 +1802,9 @@ endobj 0 0 ] /Rect [ 421.9727 - 308.1936 + 305.3736 465.1427 - 320.1936 ] + 317.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -1817,9 +1817,9 @@ endobj 0 0 ] /Rect [ 107.8707 - 113.7936 + 110.9736 129.1584 - 125.7936 ] + 122.9736 ] /Subtype /Link /Type /Annot >> endobj @@ -1832,9 +1832,9 @@ endobj 0 0 ] /Rect [ 117.7229 - 101.7936 + 98.97362 138.8429 - 113.7936 ] + 110.9736 ] /Subtype /Link /Type /Annot >> endobj @@ -1875,9 +1875,9 @@ endobj 0 0 ] /Rect [ 321.4303 - 463.3936 + 460.5736 363.754 - 475.3936 ] + 472.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -1890,9 +1890,9 @@ endobj 0 0 ] /Rect [ 126.0429 - 451.3936 + 448.5736 147.1629 - 463.3936 ] + 460.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -1905,9 +1905,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 212.9936 + 210.1736 84.20915 - 224.9936 ] + 222.1736 ] /Subtype /Link /Type /Annot >> endobj @@ -1942,9 +1942,9 @@ endobj 0 0 ] /Rect [ 446.1627 - 514.1936 + 511.3736 464.5027 - 526.1936 ] + 523.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -1957,9 +1957,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 484.1936 + 481.3736 86.84915 - 496.1936 ] + 493.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -1972,9 +1972,9 @@ endobj 0 0 ] /Rect [ 315.119 - 484.1936 + 481.3736 367.369 - 496.1936 ] + 493.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2009,9 +2009,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 756.5936 + 753.7736 83.81291 - 768.5936 ] + 765.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -2024,9 +2024,9 @@ endobj 0 0 ] /Rect [ 240.1228 - 660.5936 + 657.7736 297.7099 - 672.5936 ] + 669.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -2039,9 +2039,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 648.5936 + 645.7736 114.9429 - 660.5936 ] + 657.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -2054,9 +2054,9 @@ endobj 0 0 ] /Rect [ 496.4721 - 648.5936 + 645.7736 518.6827 - 660.5936 ] + 657.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -2069,9 +2069,9 @@ endobj 0 0 ] /Rect [ 494.1558 - 487.3936 + 484.5736 515.9027 - 499.3936 ] + 496.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -2127,9 +2127,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 732.5936 + 729.7736 84.62846 - 744.5936 ] + 741.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -2142,9 +2142,9 @@ endobj 0 0 ] /Rect [ 110.2829 - 209.2999 + 206.4799 132.8629 - 221.2999 ] + 218.4799 ] /Subtype /Link /Type /Annot >> endobj @@ -2178,9 +2178,9 @@ endobj 0 0 ] /Rect [ 392.5829 - 538.1936 + 535.3736 413.7029 - 550.1936 ] + 547.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2193,9 +2193,9 @@ endobj 0 0 ] /Rect [ 157.3904 - 490.1936 + 487.3736 179.9938 - 502.1936 ] + 499.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2208,9 +2208,9 @@ endobj 0 0 ] /Rect [ 184.0634 - 478.1936 + 475.3736 223.5234 - 490.1936 ] + 487.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2223,9 +2223,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 466.1936 + 463.3736 102.1529 - 478.1936 ] + 475.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2238,9 +2238,9 @@ endobj 0 0 ] /Rect [ 192.7997 - 466.1936 + 463.3736 237.9391 - 478.1936 ] + 475.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2253,9 +2253,9 @@ endobj 0 0 ] /Rect [ 324.4372 - 466.1936 + 463.3736 342.7772 - 478.1936 ] + 475.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2268,9 +2268,9 @@ endobj 0 0 ] /Rect [ 360.0429 - 238.1936 + 235.3736 402.2829 - 250.1936 ] + 247.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2328,9 +2328,9 @@ endobj 0 0 ] /Rect [ 338.1568 - 520.1936 + 517.3736 360.5113 - 532.1936 ] + 529.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2343,9 +2343,9 @@ endobj 0 0 ] /Rect [ 110.6843 - 508.1936 + 505.3736 169.0343 - 520.1936 ] + 517.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2358,9 +2358,9 @@ endobj 0 0 ] /Rect [ 168.3029 - 496.1936 + 493.3736 208.8829 - 508.1936 ] + 505.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2395,9 +2395,9 @@ endobj 0 0 ] /Rect [ 185.0709 - 481.3936 + 478.5736 208.0228 - 493.3936 ] + 490.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -2410,9 +2410,9 @@ endobj 0 0 ] /Rect [ 220.5998 - 469.3936 + 466.5736 243.819 - 481.3936 ] + 478.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -2446,9 +2446,9 @@ endobj 0 0 ] /Rect [ 374.4929 - 436.9936 + 434.1736 395.6129 - 448.9936 ] + 446.1736 ] /Subtype /Link /Type /Annot >> endobj @@ -2481,9 +2481,9 @@ endobj 0 0 ] /Rect [ 304.0655 - 378.3936 + 375.5736 348.3808 - 390.3936 ] + 387.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -2496,9 +2496,9 @@ endobj 0 0 ] /Rect [ 293.7749 - 204.3936 + 201.5736 316.2402 - 216.3936 ] + 213.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -2532,9 +2532,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 390.1936 + 387.3736 84.8789 - 402.1936 ] + 399.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2547,9 +2547,9 @@ endobj 0 0 ] /Rect [ 466.5307 - 390.1936 + 387.3736 509.8367 - 402.1936 ] + 399.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2562,9 +2562,9 @@ endobj 0 0 ] /Rect [ 124.3929 - 366.1936 + 363.3736 163.8529 - 378.1936 ] + 375.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2577,9 +2577,9 @@ endobj 0 0 ] /Rect [ 85.69291 - 285.1936 + 282.3736 127.9329 - 297.1936 ] + 294.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2592,9 +2592,9 @@ endobj 0 0 ] /Rect [ 85.69291 - 267.1936 + 264.3736 107.9337 - 279.1936 ] + 276.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2607,9 +2607,9 @@ endobj 0 0 ] /Rect [ 308.5389 - 267.1936 + 264.3736 351.8997 - 279.1936 ] + 276.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2622,9 +2622,9 @@ endobj 0 0 ] /Rect [ 380.6856 - 243.1936 + 240.3736 423.7999 - 255.1936 ] + 252.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2637,9 +2637,9 @@ endobj 0 0 ] /Rect [ 494.4684 - 243.1936 + 240.3736 516.4627 - 255.1936 ] + 252.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2652,9 +2652,9 @@ endobj 0 0 ] /Rect [ 85.69291 - 213.1936 + 210.3736 108.3529 - 225.1936 ] + 222.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2667,9 +2667,9 @@ endobj 0 0 ] /Rect [ 277.2428 - 213.1936 + 210.3736 321.0228 - 225.1936 ] + 222.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2682,9 +2682,9 @@ endobj 0 0 ] /Rect [ 404.5839 - 201.1936 + 198.3736 426.0657 - 213.1936 ] + 210.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2697,9 +2697,9 @@ endobj 0 0 ] /Rect [ 85.69291 - 147.1936 + 144.3736 108.61 - 159.1936 ] + 156.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2712,14 +2712,44 @@ endobj 0 0 ] /Rect [ 459.2622 - 135.1936 + 132.3736 481.289 - 147.1936 ] + 144.3736 ] /Subtype /Link /Type /Annot >> endobj -% 'Page16': class PDFPage +% 'Annot.NUMBER138': class PDFDictionary 158 0 obj +<< /A << /S /URI + /Type /Action + /URI (http://pypi.python.org/pypi/plac) >> + /Border [ 0 + 0 + 0 ] + /Rect [ 85.69291 + 102.3736 + 108.9242 + 114.3736 ] + /Subtype /Link + /Type /Annot >> +endobj +% 'Annot.NUMBER139': class PDFDictionary +159 0 obj +<< /A << /S /URI + /Type /Action + /URI (file:///home/micheles/Dropbox/md/gcodedev/plac/doc/in-writing) >> + /Border [ 0 + 0 + 0 ] + /Rect [ 340.9248 + 102.3736 + 470.1087 + 114.3736 ] + /Subtype /Link + /Type /Annot >> +endobj +% 'Page16': class PDFPage +160 0 obj % Page dictionary << /Annots [ 145 0 R 146 0 R @@ -2733,7 +2763,9 @@ endobj 154 0 R 155 0 R 156 0 R - 157 0 R ] + 157 0 R + 158 0 R + 159 0 R ] /Contents 352 0 R /MediaBox [ 0 0 @@ -2750,36 +2782,6 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER138': class PDFDictionary -159 0 obj -<< /A << /S /URI - /Type /Action - /URI (http://pypi.python.org/pypi/plac) >> - /Border [ 0 - 0 - 0 ] - /Rect [ 85.69291 - 753.5936 - 108.9242 - 765.5936 ] - /Subtype /Link - /Type /Annot >> -endobj -% 'Annot.NUMBER139': class PDFDictionary -160 0 obj -<< /A << /S /URI - /Type /Action - /URI (file:///home/micheles/Dropbox/md/gcodedev/plac/doc/in-writing) >> - /Border [ 0 - 0 - 0 ] - /Rect [ 340.9248 - 753.5936 - 470.1087 - 765.5936 ] - /Subtype /Link - /Type /Annot >> -endobj % 'Annot.NUMBER140': class PDFDictionary 161 0 obj << /A << /S /URI @@ -2789,9 +2791,9 @@ endobj 0 0 ] /Rect [ 85.69291 - 723.5936 + 750.7736 107.9247 - 735.5936 ] + 762.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -2804,9 +2806,9 @@ endobj 0 0 ] /Rect [ 85.69291 - 711.5936 + 738.7736 104.0329 - 723.5936 ] + 750.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -2819,9 +2821,9 @@ endobj 0 0 ] /Rect [ 489.2227 - 711.5936 + 738.7736 532.176 - 723.5936 ] + 750.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -2834,9 +2836,9 @@ endobj 0 0 ] /Rect [ 85.69291 - 699.5936 + 726.7736 159.6229 - 711.5936 ] + 738.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -2849,9 +2851,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 678.5936 + 711.7736 83.81291 - 690.5936 ] + 723.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -2864,9 +2866,9 @@ endobj 0 0 ] /Rect [ 219.4229 - 678.5936 + 711.7736 261.6629 - 690.5936 ] + 723.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -2879,9 +2881,9 @@ endobj 0 0 ] /Rect [ 455.2227 - 648.5936 + 681.7736 534.3667 - 660.5936 ] + 693.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -2894,9 +2896,9 @@ endobj 0 0 ] /Rect [ 325.7268 - 481.3936 + 514.5736 347.4138 - 493.3936 ] + 526.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -2909,9 +2911,9 @@ endobj 0 0 ] /Rect [ 327.2261 - 314.1936 + 347.3736 410.5152 - 326.1936 ] + 359.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -2924,9 +2926,9 @@ endobj 0 0 ] /Rect [ 275.5829 - 134.9936 + 168.1736 317.8229 - 146.9936 ] + 180.1736 ] /Subtype /Link /Type /Annot >> endobj @@ -2939,9 +2941,9 @@ endobj 0 0 ] /Rect [ 307.9178 - 116.9936 + 150.1736 351.5999 - 128.9936 ] + 162.1736 ] /Subtype /Link /Type /Annot >> endobj @@ -2954,18 +2956,16 @@ endobj 0 0 ] /Rect [ 329.8034 - 92.99362 + 126.1736 352.1804 - 104.9936 ] + 138.1736 ] /Subtype /Link /Type /Annot >> endobj % 'Page17': class PDFPage 173 0 obj % Page dictionary -<< /Annots [ 159 0 R - 160 0 R - 161 0 R +<< /Annots [ 161 0 R 162 0 R 163 0 R 164 0 R @@ -3002,9 +3002,9 @@ endobj 0 0 ] /Rect [ 109.0098 - 708.5936 + 729.7736 131.9967 - 720.5936 ] + 741.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3017,9 +3017,9 @@ endobj 0 0 ] /Rect [ 397.2929 - 684.5936 + 705.7736 415.6329 - 696.5936 ] + 717.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3032,9 +3032,9 @@ endobj 0 0 ] /Rect [ 85.69291 - 663.5936 + 684.7736 128.4929 - 675.5936 ] + 696.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3047,9 +3047,9 @@ endobj 0 0 ] /Rect [ 85.69291 - 645.5936 + 666.7736 124.5929 - 657.5936 ] + 678.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3062,9 +3062,9 @@ endobj 0 0 ] /Rect [ 464.3898 - 624.5936 + 651.7736 503.8498 - 636.5936 ] + 663.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3077,9 +3077,9 @@ endobj 0 0 ] /Rect [ 305.0429 - 612.5936 + 639.7736 323.3829 - 624.5936 ] + 651.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3092,9 +3092,9 @@ endobj 0 0 ] /Rect [ 455.0104 - 594.5936 + 621.7736 479.9015 - 606.5936 ] + 633.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3107,9 +3107,9 @@ endobj 0 0 ] /Rect [ 303.707 - 582.5936 + 609.7736 322.047 - 594.5936 ] + 621.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3122,9 +3122,9 @@ endobj 0 0 ] /Rect [ 328.8186 - 582.5936 + 609.7736 353.3701 - 594.5936 ] + 621.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3137,9 +3137,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 570.5936 + 597.7736 81.03291 - 582.5936 ] + 609.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3152,9 +3152,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 552.5936 + 579.7736 84.4354 - 564.5936 ] + 591.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3167,9 +3167,9 @@ endobj 0 0 ] /Rect [ 275.6978 - 552.5936 + 579.7736 297.9903 - 564.5936 ] + 591.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3182,9 +3182,9 @@ endobj 0 0 ] /Rect [ 203.5285 - 540.5936 + 567.7736 231.1357 - 552.5936 ] + 579.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3197,9 +3197,9 @@ endobj 0 0 ] /Rect [ 164.4129 - 528.5936 + 555.7736 191.6429 - 540.5936 ] + 567.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3212,9 +3212,9 @@ endobj 0 0 ] /Rect [ 302.7929 - 528.5936 + 555.7736 321.1329 - 540.5936 ] + 567.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3227,9 +3227,9 @@ endobj 0 0 ] /Rect [ 156.6051 - 480.5936 + 507.7736 177.8606 - 492.5936 ] + 519.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3242,9 +3242,9 @@ endobj 0 0 ] /Rect [ 186.6535 - 456.5936 + 483.7736 226.1135 - 468.5936 ] + 495.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3257,9 +3257,9 @@ endobj 0 0 ] /Rect [ 493.1227 - 456.5936 + 483.7736 532.4646 - 468.5936 ] + 495.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3272,9 +3272,9 @@ endobj 0 0 ] /Rect [ 72.7804 - 444.5936 + 471.7736 96.20788 - 456.5936 ] + 483.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3287,9 +3287,9 @@ endobj 0 0 ] /Rect [ 149.2229 - 414.5936 + 441.7736 171.2704 - 426.5936 ] + 453.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3302,9 +3302,9 @@ endobj 0 0 ] /Rect [ 128.0309 - 372.5936 + 399.7736 149.4369 - 384.5936 ] + 411.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3317,9 +3317,9 @@ endobj 0 0 ] /Rect [ 502.8367 - 372.5936 + 399.7736 524.2427 - 384.5936 ] + 411.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3332,9 +3332,9 @@ endobj 0 0 ] /Rect [ 187.4797 - 348.5936 + 375.7736 209.0991 - 360.5936 ] + 387.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3347,9 +3347,9 @@ endobj 0 0 ] /Rect [ 301.6965 - 348.5936 + 375.7736 426.0446 - 360.5936 ] + 387.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3362,9 +3362,9 @@ endobj 0 0 ] /Rect [ 83.6829 - 276.5936 + 303.7736 105.7829 - 288.5936 ] + 315.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3377,9 +3377,9 @@ endobj 0 0 ] /Rect [ 446.5627 - 276.5936 + 303.7736 502.5727 - 288.5936 ] + 315.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3392,9 +3392,9 @@ endobj 0 0 ] /Rect [ 275.6828 - 264.5936 + 291.7736 297.3688 - 276.5936 ] + 303.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3407,9 +3407,9 @@ endobj 0 0 ] /Rect [ 77.19665 - 252.5936 + 279.7736 139.4904 - 264.5936 ] + 291.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3422,9 +3422,9 @@ endobj 0 0 ] /Rect [ 96.54131 - 240.5936 + 267.7736 139.0255 - 252.5936 ] + 279.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3437,9 +3437,9 @@ endobj 0 0 ] /Rect [ 203.5016 - 207.5936 + 234.7736 245.8453 - 219.5936 ] + 246.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3452,9 +3452,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 132.5936 + 165.7736 138.7898 - 144.5936 ] + 177.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3467,9 +3467,9 @@ endobj 0 0 ] /Rect [ 114.6649 - 120.5936 + 153.7736 154.1249 - 132.5936 ] + 165.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3482,14 +3482,29 @@ endobj 0 0 ] /Rect [ 191.6329 - 108.5936 + 141.7736 233.8729 - 120.5936 ] + 153.7736 ] /Subtype /Link /Type /Annot >> endobj -% 'Page18': class PDFPage +% 'Annot.NUMBER185': class PDFDictionary 207 0 obj +<< /A << /S /URI + /Type /Action + /URI (http://pypi.python.org/pypi/Clap/0.7) >> + /Border [ 0 + 0 + 0 ] + /Rect [ 263.3429 + 111.7736 + 286.6829 + 123.7736 ] + /Subtype /Link + /Type /Annot >> +endobj +% 'Page18': class PDFPage +208 0 obj % Page dictionary << /Annots [ 174 0 R 175 0 R @@ -3523,7 +3538,8 @@ endobj 203 0 R 204 0 R 205 0 R - 206 0 R ] + 206 0 R + 207 0 R ] /Contents 354 0 R /MediaBox [ 0 0 @@ -3540,21 +3556,6 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER185': class PDFDictionary -208 0 obj -<< /A << /S /URI - /Type /Action - /URI (http://pypi.python.org/pypi/Clap/0.7) >> - /Border [ 0 - 0 - 0 ] - /Rect [ 263.3429 - 744.5936 - 286.6829 - 756.5936 ] - /Subtype /Link - /Type /Annot >> -endobj % 'Annot.NUMBER186': class PDFDictionary 209 0 obj << /A << /S /URI @@ -3564,9 +3565,9 @@ endobj 0 0 ] /Rect [ 258.5629 - 696.5936 + 723.7736 276.9029 - 708.5936 ] + 735.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3579,9 +3580,9 @@ endobj 0 0 ] /Rect [ 185.4471 - 615.5936 + 642.7736 207.1062 - 627.5936 ] + 654.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3594,9 +3595,9 @@ endobj 0 0 ] /Rect [ 177.6784 - 603.5936 + 630.7736 199.6123 - 615.5936 ] + 642.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3609,9 +3610,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 549.5936 + 576.7736 83.81291 - 561.5936 ] + 588.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3624,9 +3625,9 @@ endobj 0 0 ] /Rect [ 278.4678 - 531.5936 + 558.7736 300.0328 - 543.5936 ] + 570.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3639,9 +3640,9 @@ endobj 0 0 ] /Rect [ 117.3573 - 519.5936 + 546.7736 138.5845 - 531.5936 ] + 558.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3654,9 +3655,9 @@ endobj 0 0 ] /Rect [ 82.74466 - 477.5936 + 504.7736 104.4564 - 489.5936 ] + 516.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3669,9 +3670,9 @@ endobj 0 0 ] /Rect [ 127.2882 - 477.5936 + 504.7736 145.6282 - 489.5936 ] + 516.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3684,9 +3685,9 @@ endobj 0 0 ] /Rect [ 410.1674 - 477.5936 + 504.7736 433.5592 - 489.5936 ] + 516.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3699,9 +3700,9 @@ endobj 0 0 ] /Rect [ 265.9578 - 453.5936 + 480.7736 284.2978 - 465.5936 ] + 492.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3714,9 +3715,9 @@ endobj 0 0 ] /Rect [ 487.7492 - 453.5936 + 480.7736 506.0892 - 465.5936 ] + 492.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3729,17 +3730,16 @@ endobj 0 0 ] /Rect [ 62.69291 - 297.5936 + 324.7736 157.1829 - 309.5936 ] + 336.7736 ] /Subtype /Link /Type /Annot >> endobj % 'Page19': class PDFPage 221 0 obj % Page dictionary -<< /Annots [ 208 0 R - 209 0 R +<< /Annots [ 209 0 R 210 0 R 211 0 R 212 0 R @@ -3795,9 +3795,9 @@ endobj 0 0 ] /Rect [ 383.9329 - 675.3936 + 705.7736 405.0529 - 687.3936 ] + 717.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3830,9 +3830,9 @@ endobj 0 0 ] /Rect [ 370.6785 - 313.3936 + 346.5736 392.4956 - 325.3936 ] + 358.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -3845,35 +3845,14 @@ endobj 0 0 ] /Rect [ 455.8742 - 313.3936 + 346.5736 477.6913 - 325.3936 ] + 358.5736 ] /Subtype /Link /Type /Annot >> endobj -% 'Page22': class PDFPage -227 0 obj -% Page dictionary -<< /Annots [ 225 0 R - 226 0 R ] - /Contents 358 0 R - /MediaBox [ 0 - 0 - 595.2756 - 841.8898 ] - /Parent 336 0 R - /Resources << /Font 1 0 R - /ProcSet [ /PDF - /Text - /ImageB - /ImageC - /ImageI ] >> - /Rotate 0 - /Trans << >> - /Type /Page >> -endobj % 'Annot.NUMBER201': class PDFDictionary -228 0 obj +227 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3881,14 +3860,14 @@ endobj 0 0 ] /Rect [ 185.9351 - 756.5936 + 131.7893 207.4695 - 768.5936 ] + 143.7893 ] /Subtype /Link /Type /Annot >> endobj % 'Annot.NUMBER202': class PDFDictionary -229 0 obj +228 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/shlex.html) >> @@ -3896,14 +3875,14 @@ endobj 0 0 ] /Rect [ 369.8905 - 756.5936 + 131.7893 396.425 - 768.5936 ] + 143.7893 ] /Subtype /Link /Type /Annot >> endobj % 'Annot.NUMBER203': class PDFDictionary -230 0 obj +229 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3911,14 +3890,14 @@ endobj 0 0 ] /Rect [ 408.8916 - 744.5936 + 119.7893 427.2316 - 756.5936 ] + 131.7893 ] /Subtype /Link /Type /Annot >> endobj % 'Annot.NUMBER204': class PDFDictionary -231 0 obj +230 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/shlex.html) >> @@ -3926,14 +3905,14 @@ endobj 0 0 ] /Rect [ 62.69291 - 732.5936 + 107.7893 86.03291 - 744.5936 ] + 119.7893 ] /Subtype /Link /Type /Annot >> endobj % 'Annot.NUMBER205': class PDFDictionary -232 0 obj +231 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3941,14 +3920,14 @@ endobj 0 0 ] /Rect [ 92.4689 - 732.5936 + 107.7893 114.4649 - 744.5936 ] + 119.7893 ] /Subtype /Link /Type /Annot >> endobj % 'Annot.NUMBER206': class PDFDictionary -233 0 obj +232 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/shlex.html) >> @@ -3956,12 +3935,39 @@ endobj 0 0 ] /Rect [ 149.3204 - 720.5936 + 95.78932 176.9472 - 732.5936 ] + 107.7893 ] /Subtype /Link /Type /Annot >> endobj +% 'Page22': class PDFPage +233 0 obj +% Page dictionary +<< /Annots [ 225 0 R + 226 0 R + 227 0 R + 228 0 R + 229 0 R + 230 0 R + 231 0 R + 232 0 R ] + /Contents 358 0 R + /MediaBox [ 0 + 0 + 595.2756 + 841.8898 ] + /Parent 336 0 R + /Resources << /Font 1 0 R + /ProcSet [ /PDF + /Text + /ImageB + /ImageC + /ImageI ] >> + /Rotate 0 + /Trans << >> + /Type /Page >> +endobj % 'Annot.NUMBER207': class PDFDictionary 234 0 obj << /A << /S /URI @@ -3971,9 +3977,9 @@ endobj 0 0 ] /Rect [ 129.6923 - 624.5936 + 669.7736 151.4655 - 636.5936 ] + 681.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -3986,9 +3992,9 @@ endobj 0 0 ] /Rect [ 173.8529 - 612.5936 + 657.7736 194.9729 - 624.5936 ] + 669.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -4001,9 +4007,9 @@ endobj 0 0 ] /Rect [ 460.388 - 255.4185 + 300.5985 482.0127 - 267.4185 ] + 312.5985 ] /Subtype /Link /Type /Annot >> endobj @@ -4016,22 +4022,16 @@ endobj 0 0 ] /Rect [ 95.32996 - 189.4185 + 234.5985 116.857 - 201.4185 ] + 246.5985 ] /Subtype /Link /Type /Annot >> endobj % 'Page23': class PDFPage 238 0 obj % Page dictionary -<< /Annots [ 228 0 R - 229 0 R - 230 0 R - 231 0 R - 232 0 R - 233 0 R - 234 0 R +<< /Annots [ 234 0 R 235 0 R 236 0 R 237 0 R ] @@ -4060,9 +4060,9 @@ endobj 0 0 ] /Rect [ 316.3528 - 346.1936 + 391.3736 409.2453 - 358.1936 ] + 403.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -4075,9 +4075,9 @@ endobj 0 0 ] /Rect [ 419.1694 - 334.1936 + 379.3736 440.4061 - 346.1936 ] + 391.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -4090,9 +4090,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 304.1936 + 349.3736 84.70395 - 316.1936 ] + 361.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -4105,9 +4105,9 @@ endobj 0 0 ] /Rect [ 293.2359 - 226.1936 + 271.3736 316.4697 - 238.1936 ] + 283.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -4143,9 +4143,9 @@ endobj 0 0 ] /Rect [ 431.7904 - 231.3936 + 276.5736 453.7245 - 243.3936 ] + 288.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -4158,9 +4158,9 @@ endobj 0 0 ] /Rect [ 255.5885 - 201.3936 + 246.5736 278.2757 - 213.3936 ] + 258.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -4173,9 +4173,9 @@ endobj 0 0 ] /Rect [ 513.6927 - 177.3936 + 222.5736 532.1846 - 189.3936 ] + 234.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -4248,9 +4248,9 @@ endobj 0 0 ] /Rect [ 179.0529 - 684.5936 + 729.7736 201.1953 - 696.5936 ] + 741.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -4263,9 +4263,9 @@ endobj 0 0 ] /Rect [ 377.8504 - 104.6007 + 149.7807 409.861 - 116.6007 ] + 161.7807 ] /Subtype /Link /Type /Annot >> endobj @@ -4278,9 +4278,9 @@ endobj 0 0 ] /Rect [ 242.4466 - 92.60071 + 137.7807 263.7922 - 104.6007 ] + 149.7807 ] /Subtype /Link /Type /Annot >> endobj @@ -4293,37 +4293,14 @@ endobj 0 0 ] /Rect [ 456.2271 - 92.60071 + 137.7807 505.3627 - 104.6007 ] + 149.7807 ] /Subtype /Link /Type /Annot >> endobj -% 'Page28': class PDFPage -254 0 obj -% Page dictionary -<< /Annots [ 250 0 R - 251 0 R - 252 0 R - 253 0 R ] - /Contents 364 0 R - /MediaBox [ 0 - 0 - 595.2756 - 841.8898 ] - /Parent 336 0 R - /Resources << /Font 1 0 R - /ProcSet [ /PDF - /Text - /ImageB - /ImageC - /ImageI ] >> - /Rotate 0 - /Trans << >> - /Type /Page >> -endobj % 'Annot.NUMBER222': class PDFDictionary -255 0 obj +254 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4331,14 +4308,14 @@ endobj 0 0 ] /Rect [ 363.1739 - 744.5936 + 113.7807 386.5004 - 756.5936 ] + 125.7807 ] /Subtype /Link /Type /Annot >> endobj % 'Annot.NUMBER223': class PDFDictionary -256 0 obj +255 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4346,12 +4323,37 @@ endobj 0 0 ] /Rect [ 479.7508 - 732.5936 + 101.7807 501.4627 - 744.5936 ] + 113.7807 ] /Subtype /Link /Type /Annot >> endobj +% 'Page28': class PDFPage +256 0 obj +% Page dictionary +<< /Annots [ 250 0 R + 251 0 R + 252 0 R + 253 0 R + 254 0 R + 255 0 R ] + /Contents 364 0 R + /MediaBox [ 0 + 0 + 595.2756 + 841.8898 ] + /Parent 336 0 R + /Resources << /Font 1 0 R + /ProcSet [ /PDF + /Text + /ImageB + /ImageC + /ImageI ] >> + /Rotate 0 + /Trans << >> + /Type /Page >> +endobj % 'Annot.NUMBER224': class PDFDictionary 257 0 obj << /A << /S /URI @@ -4361,9 +4363,9 @@ endobj 0 0 ] /Rect [ 366.9454 - 702.5936 + 753.7736 388.8033 - 714.5936 ] + 765.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -4376,9 +4378,9 @@ endobj 0 0 ] /Rect [ 170.8855 - 690.5936 + 741.7736 189.7755 - 702.5936 ] + 753.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -4391,9 +4393,9 @@ endobj 0 0 ] /Rect [ 390.8027 - 349.3936 + 400.5736 435.0027 - 361.3936 ] + 412.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -4406,9 +4408,9 @@ endobj 0 0 ] /Rect [ 213.451 - 337.3936 + 388.5736 237.5255 - 349.3936 ] + 400.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -4421,9 +4423,9 @@ endobj 0 0 ] /Rect [ 114.9429 - 313.3936 + 364.5736 157.1829 - 325.3936 ] + 376.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -4436,9 +4438,9 @@ endobj 0 0 ] /Rect [ 385.0429 - 313.3936 + 364.5736 403.3829 - 325.3936 ] + 376.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -4451,9 +4453,9 @@ endobj 0 0 ] /Rect [ 350.6129 - 283.3936 + 334.5736 371.7329 - 295.3936 ] + 346.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -4466,9 +4468,9 @@ endobj 0 0 ] /Rect [ 256.6729 - 265.3936 + 316.5736 277.7929 - 277.3936 ] + 328.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -4481,9 +4483,9 @@ endobj 0 0 ] /Rect [ 149.5469 - 172.1936 + 223.3736 172.1982 - 184.1936 ] + 235.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -4496,18 +4498,16 @@ endobj 0 0 ] /Rect [ 224.3178 - 160.1936 + 211.3736 260.8853 - 172.1936 ] + 223.3736 ] /Subtype /Link /Type /Annot >> endobj % 'Page29': class PDFPage 267 0 obj % Page dictionary -<< /Annots [ 255 0 R - 256 0 R - 257 0 R +<< /Annots [ 257 0 R 258 0 R 259 0 R 260 0 R @@ -4533,10 +4533,26 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Page30': class PDFPage +% 'Annot.NUMBER234': class PDFDictionary 268 0 obj +<< /A << /S /URI + /Type /Action + /URI (http://argparse.googlecode.com) >> + /Border [ 0 + 0 + 0 ] + /Rect [ 381.1529 + 103.0005 + 423.3929 + 115.0005 ] + /Subtype /Link + /Type /Annot >> +endobj +% 'Page30': class PDFPage +269 0 obj % Page dictionary -<< /Contents 366 0 R +<< /Annots [ 268 0 R ] + /Contents 366 0 R /MediaBox [ 0 0 595.2756 @@ -4552,21 +4568,6 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER234': class PDFDictionary -269 0 obj -<< /A << /S /URI - /Type /Action - /URI (http://argparse.googlecode.com) >> - /Border [ 0 - 0 - 0 ] - /Rect [ 381.1529 - 744.5936 - 423.3929 - 756.5936 ] - /Subtype /Link - /Type /Annot >> -endobj % 'Annot.NUMBER235': class PDFDictionary 270 0 obj << /A << /S /URI @@ -4576,17 +4577,16 @@ endobj 0 0 ] /Rect [ 62.69291 - 338.9936 + 366.1736 84.72012 - 350.9936 ] + 378.1736 ] /Subtype /Link /Type /Annot >> endobj % 'Page31': class PDFPage 271 0 obj % Page dictionary -<< /Annots [ 269 0 R - 270 0 R ] +<< /Annots [ 270 0 R ] /Contents 367 0 R /MediaBox [ 0 0 @@ -4631,9 +4631,9 @@ endobj 0 0 ] /Rect [ 182.479 - 352.1936 + 373.3736 203.7662 - 364.1936 ] + 385.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -4666,9 +4666,9 @@ endobj 0 0 ] /Rect [ 255.1228 - 382.1936 + 412.5736 276.5028 - 394.1936 ] + 424.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -4681,9 +4681,9 @@ endobj 0 0 ] /Rect [ 295.0229 - 226.9936 + 257.3736 367.2629 - 238.9936 ] + 269.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -4696,9 +4696,9 @@ endobj 0 0 ] /Rect [ 179.1295 - 178.9936 + 209.3736 201.6839 - 190.9936 ] + 221.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -4733,9 +4733,9 @@ endobj 0 0 ] /Rect [ 414.8874 - 346.1936 + 379.3736 436.9487 - 358.1936 ] + 391.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -4748,9 +4748,9 @@ endobj 0 0 ] /Rect [ 122.7054 - 202.1936 + 235.3736 145.2085 - 214.1936 ] + 247.3736 ] /Subtype /Link /Type /Annot >> endobj @@ -4803,9 +4803,9 @@ endobj 0 0 ] /Rect [ 183.3657 - 431.3936 + 464.5736 207.8364 - 443.3936 ] + 476.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -4818,9 +4818,9 @@ endobj 0 0 ] /Rect [ 254.9929 - 407.3936 + 440.5736 327.2329 - 419.3936 ] + 452.5736 ] /Subtype /Link /Type /Annot >> endobj @@ -4854,9 +4854,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 642.5936 + 675.7736 85.70846 - 654.5936 ] + 687.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -4889,9 +4889,9 @@ endobj 0 0 ] /Rect [ 62.69291 - 732.5936 + 729.7736 84.98766 - 744.5936 ] + 741.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -4943,9 +4943,9 @@ endobj 0 0 ] /Rect [ 473.5049 - 726.5936 + 723.7736 494.7927 - 738.5936 ] + 735.7736 ] /Subtype /Link /Type /Annot >> endobj @@ -4958,9 +4958,9 @@ endobj 0 0 ] /Rect [ 172.4311 - 513.9859 + 511.1659 194.7087 - 525.9859 ] + 523.1659 ] /Subtype /Link /Type /Annot >> endobj @@ -4973,9 +4973,9 @@ endobj 0 0 ] /Rect [ 91.57623 - 127.5859 + 124.7659 114.8995 - 139.5859 ] + 136.7659 ] /Subtype /Link /Type /Annot >> endobj @@ -5010,9 +5010,9 @@ endobj 0 0 ] /Rect [ 106.6216 - 476.2472 + 485.4272 128.3202 - 488.2472 ] + 497.4272 ] /Subtype /Link /Type /Annot >> endobj @@ -5067,9 +5067,10 @@ endobj % 'R299': class PDFInfo 299 0 obj << /Author () - /CreationDate (D:20100904090628-01'00') + /CreationDate (D:20101128093806-01'00') + /Creator (\(unspecified\)) /Keywords () - /Producer (ReportLab http://www.reportlab.com) + /Producer (ReportLab PDF Library - www.reportlab.com) /Subject (\(unspecified\)) /Title () >> endobj @@ -5215,7 +5216,7 @@ endobj endobj % 'Outline.36.10': class OutlineEntryObject 312 0 obj -<< /Dest [ 158 0 R +<< /Dest [ 160 0 R /XYZ 62.69291 422.6236 @@ -5227,10 +5228,10 @@ endobj endobj % 'Outline.36.11': class OutlineEntryObject 313 0 obj -<< /Dest [ 207 0 R +<< /Dest [ 208 0 R /XYZ 62.69291 - 741.0236 + 765.0236 0 ] /Next 314 0 R /Parent 301 0 R @@ -5239,10 +5240,10 @@ endobj endobj % 'Outline.36.12': class OutlineEntryObject 314 0 obj -<< /Dest [ 207 0 R +<< /Dest [ 208 0 R /XYZ 62.69291 - 513.0236 + 543.0236 0 ] /Next 315 0 R /Parent 301 0 R @@ -5251,10 +5252,10 @@ endobj endobj % 'Outline.36.13': class OutlineEntryObject 315 0 obj -<< /Dest [ 207 0 R +<< /Dest [ 208 0 R /XYZ 62.69291 - 309.0236 + 339.0236 0 ] /Parent 301 0 R /Prev 314 0 R @@ -5266,7 +5267,7 @@ endobj /Dest [ 221 0 R /XYZ 62.69291 - 681.0236 + 711.0236 0 ] /First 317 0 R /Last 335 0 R @@ -5279,7 +5280,7 @@ endobj << /Dest [ 221 0 R /XYZ 62.69291 - 648.0236 + 678.0236 0 ] /Next 318 0 R /Parent 316 0 R @@ -5290,7 +5291,7 @@ endobj << /Dest [ 221 0 R /XYZ 62.69291 - 426.0236 + 456.0236 0 ] /Next 319 0 R /Parent 316 0 R @@ -5302,7 +5303,7 @@ endobj << /Dest [ 224 0 R /XYZ 62.69291 - 629.8236 + 663.0236 0 ] /Next 320 0 R /Parent 316 0 R @@ -5311,10 +5312,10 @@ endobj endobj % 'Outline.37.3': class OutlineEntryObject 320 0 obj -<< /Dest [ 227 0 R +<< /Dest [ 233 0 R /XYZ 62.69291 - 609.0236 + 645.0236 0 ] /Next 321 0 R /Parent 316 0 R @@ -5326,7 +5327,7 @@ endobj << /Dest [ 238 0 R /XYZ 62.69291 - 299.8485 + 347.8485 0 ] /Next 322 0 R /Parent 316 0 R @@ -5338,7 +5339,7 @@ endobj << /Dest [ 243 0 R /XYZ 62.69291 - 378.6236 + 426.6236 0 ] /Next 323 0 R /Parent 316 0 R @@ -5350,7 +5351,7 @@ endobj << /Dest [ 248 0 R /XYZ 62.69291 - 330.0679 + 367.2133 0 ] /Next 324 0 R /Parent 316 0 R @@ -5359,10 +5360,10 @@ endobj endobj % 'Outline.37.7': class OutlineEntryObject 324 0 obj -<< /Dest [ 254 0 R +<< /Dest [ 256 0 R /XYZ 62.69291 - 717.0236 + 765.0236 0 ] /Next 325 0 R /Parent 316 0 R @@ -5374,7 +5375,7 @@ endobj << /Dest [ 267 0 R /XYZ 62.69291 - 204.6236 + 258.6236 0 ] /Next 326 0 R /Parent 316 0 R @@ -5386,7 +5387,7 @@ endobj << /Dest [ 271 0 R /XYZ 62.69291 - 371.4236 + 401.4236 0 ] /Next 327 0 R /Parent 316 0 R @@ -5398,7 +5399,7 @@ endobj << /Dest [ 274 0 R /XYZ 62.69291 - 384.6236 + 408.6236 0 ] /Next 328 0 R /Parent 316 0 R @@ -5410,7 +5411,7 @@ endobj << /Dest [ 278 0 R /XYZ 62.69291 - 211.4236 + 244.6236 0 ] /Next 329 0 R /Parent 316 0 R @@ -5422,7 +5423,7 @@ endobj << /Dest [ 281 0 R /XYZ 62.69291 - 318.6236 + 354.6236 0 ] /Next 330 0 R /Parent 316 0 R @@ -5434,7 +5435,7 @@ endobj << /Dest [ 285 0 R /XYZ 62.69291 - 475.8236 + 511.8236 0 ] /Next 331 0 R /Parent 316 0 R @@ -5446,7 +5447,7 @@ endobj << /Dest [ 287 0 R /XYZ 62.69291 - 675.0236 + 711.0236 0 ] /Next 332 0 R /Parent 316 0 R @@ -5494,7 +5495,7 @@ endobj << /Dest [ 296 0 R /XYZ 62.69291 - 508.6772 + 520.6772 0 ] /Parent 316 0 R /Prev 334 0 R @@ -5519,21 +5520,21 @@ endobj 139 0 R 141 0 R 144 0 R - 158 0 R + 160 0 R 173 0 R - 207 0 R + 208 0 R 221 0 R 222 0 R 224 0 R - 227 0 R + 233 0 R 238 0 R 243 0 R 247 0 R 248 0 R 249 0 R - 254 0 R + 256 0 R 267 0 R - 268 0 R + 269 0 R 271 0 R 272 0 R 274 0 R @@ -5552,13 +5553,13 @@ endobj % 'R337': class PDFStream 337 0 obj % page stream -<< /Length 2996 >> +<< /Length 2944 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 744.0236 cm q -BT 1 0 0 1 0 8.435 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Plac: Parsing the Command Line the Easy Way) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Plac: Parsing the Command Line the Easy Way) Tj T* ET Q Q q @@ -5572,14 +5573,14 @@ q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F2 10 Tf 12 TL 36.93937 0 Td (Author:) Tj T* -36.93937 0 Td ET +BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 36.93937 0 Td (Author:) Tj T* -36.93937 0 Td ET Q Q q 1 0 0 1 91.03937 3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Michele Simionato) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Michele Simionato) Tj T* ET Q Q q @@ -5593,7 +5594,7 @@ q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F2 10 Tf 12 TL 39.69937 0 Td (E-mail:) Tj T* -39.69937 0 Td ET +BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 39.69937 0 Td (E-mail:) Tj T* -39.69937 0 Td ET Q Q q @@ -5601,7 +5602,7 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (michele.simionato@gmail.com) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (michele.simionato@gmail.com) Tj T* ET Q Q q @@ -5615,14 +5616,14 @@ q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F2 10 Tf 12 TL 48.03937 0 Td (Date:) Tj T* -48.03937 0 Td ET +BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 48.03937 0 Td (Date:) Tj T* -48.03937 0 Td ET Q Q q 1 0 0 1 91.03937 3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (August 2010) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (August 2010) Tj T* ET Q Q q @@ -5636,7 +5637,7 @@ q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F2 10 Tf 12 TL 25.25937 0 Td (Download) Tj T* 21.11 0 Td (page:) Tj T* -46.36937 0 Td ET +BT 1 0 0 1 0 14 Tm /F2 10 Tf 12 TL 25.25937 0 Td (Download) Tj T* 21.11 0 Td (page:) Tj T* -46.36937 0 Td ET Q Q q @@ -5644,7 +5645,7 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (http://pypi.python.org/pypi/plac) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (http://pypi.python.org/pypi/plac) Tj T* ET Q Q q @@ -5658,7 +5659,7 @@ q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F2 10 Tf 12 TL 9.68937 0 Td (Project page:) Tj T* -9.68937 0 Td ET +BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 9.68937 0 Td (Project page:) Tj T* -9.68937 0 Td ET Q Q q @@ -5666,7 +5667,7 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (http://micheles.googlecode.com/hg/plac/doc/plac.html) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (http://micheles.googlecode.com/hg/plac/doc/plac.html) Tj T* ET Q Q q @@ -5680,14 +5681,14 @@ q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F2 10 Tf 12 TL 26.91937 0 Td (Requires:) Tj T* -26.91937 0 Td ET +BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 26.91937 0 Td (Requires:) Tj T* -26.91937 0 Td ET Q Q q 1 0 0 1 91.03937 3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Python 2.3+) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python 2.3+) Tj T* ET Q Q q @@ -5701,14 +5702,14 @@ q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F2 10 Tf 12 TL 16.91937 0 Td (Installation:) Tj T* -16.91937 0 Td ET +BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 16.91937 0 Td (Installation:) Tj T* -16.91937 0 Td ET Q Q q 1 0 0 1 91.03937 3 cm q 0 0 0 rg -BT 1 0 0 1 0 5.71 Tm /F3 10 Tf 12 TL (easy_install -U plac) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (easy_install -U plac) Tj T* ET Q Q q @@ -5722,14 +5723,14 @@ q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F2 10 Tf 12 TL 32.46937 0 Td (License:) Tj T* -32.46937 0 Td ET +BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 32.46937 0 Td (License:) Tj T* -32.46937 0 Td ET Q Q q 1 0 0 1 91.03937 3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (BSD license) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (BSD license) Tj T* ET Q Q q @@ -5739,23 +5740,22 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 238.1649 0 Td (1) Tj T* -238.1649 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 238.1649 0 Td (1) Tj T* -238.1649 0 Td ET Q Q endstream - endobj % 'R338': class PDFStream 338 0 obj % page stream -<< /Length 9594 >> +<< /Length 9380 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 744.0236 cm q -BT 1 0 0 1 0 8.435 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Contents) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Contents) Tj T* ET Q Q q @@ -5765,7 +5765,7 @@ BT /F1 10 Tf 12 TL ET q 1 0 0 1 0 615 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Plac: Parsing the Command Line the Easy Way) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Plac: Parsing the Command Line the Easy Way) Tj T* ET Q Q q @@ -5773,13 +5773,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F2 10 Tf 12 TL 66.44 0 Td (1) Tj T* -66.44 0 Td ET +BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (1) Tj T* -66.44 0 Td ET Q Q q 1 0 0 1 0 597 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (The importance of scaling down) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (The importance of scaling down) Tj T* ET Q Q q @@ -5787,13 +5787,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 66.44 0 Td (3) Tj T* -66.44 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 66.44 0 Td (3) Tj T* -66.44 0 Td ET Q Q q 1 0 0 1 0 579 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Scripts with required arguments) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Scripts with required arguments) Tj T* ET Q Q q @@ -5801,13 +5801,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 66.44 0 Td (3) Tj T* -66.44 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 66.44 0 Td (3) Tj T* -66.44 0 Td ET Q Q q 1 0 0 1 0 561 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Scripts with default arguments) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Scripts with default arguments) Tj T* ET Q Q q @@ -5815,13 +5815,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 66.44 0 Td (5) Tj T* -66.44 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 66.44 0 Td (5) Tj T* -66.44 0 Td ET Q Q q 1 0 0 1 0 543 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Scripts with options \(and smart options\)) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Scripts with options \(and smart options\)) Tj T* ET Q Q q @@ -5829,13 +5829,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 66.44 0 Td (7) Tj T* -66.44 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 66.44 0 Td (7) Tj T* -66.44 0 Td ET Q Q q 1 0 0 1 0 525 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Scripts with flags) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Scripts with flags) Tj T* ET Q Q q @@ -5843,13 +5843,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 66.44 0 Td (9) Tj T* -66.44 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 66.44 0 Td (9) Tj T* -66.44 0 Td ET Q Q q 1 0 0 1 0 507 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac for Python 2.X users) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac for Python 2.X users) Tj T* ET Q Q q @@ -5857,13 +5857,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 66.44 0 Td (9) Tj T* -66.44 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 66.44 0 Td (9) Tj T* -66.44 0 Td ET Q Q q 1 0 0 1 0 489 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (More features) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (More features) Tj T* ET Q Q q @@ -5871,13 +5871,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (10) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (10) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 471 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (A realistic example) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (A realistic example) Tj T* ET Q Q q @@ -5885,13 +5885,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (12) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (12) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 453 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Keyword arguments) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Keyword arguments) Tj T* ET Q Q q @@ -5899,13 +5899,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (13) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (13) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 435 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Final example: a shelve interface) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Final example: a shelve interface) Tj T* ET Q Q q @@ -5913,13 +5913,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (14) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (14) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 417 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac vs argparse) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac vs argparse) Tj T* ET Q Q q @@ -5927,13 +5927,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (16) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (16) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 399 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac vs the rest of the world) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac vs the rest of the world) Tj T* ET Q Q q @@ -5941,13 +5941,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (18) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (18) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 381 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (The future) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (The future) Tj T* ET Q Q q @@ -5955,13 +5955,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (18) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (18) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 363 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Trivia: the story behind the name) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Trivia: the story behind the name) Tj T* ET Q Q q @@ -5969,13 +5969,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (18) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (18) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 345 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Advanced usages of plac) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Advanced usages of plac) Tj T* ET Q Q q @@ -5983,13 +5983,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F2 10 Tf 12 TL 60.88 0 Td (19) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 60.88 0 Td (19) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 327 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Introduction) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Introduction) Tj T* ET Q Q q @@ -5997,13 +5997,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (19) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (19) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 309 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (From scripts to interactive applications) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (From scripts to interactive applications) Tj T* ET Q Q q @@ -6011,13 +6011,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (19) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (19) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 291 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Testing a plac application) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Testing a plac application) Tj T* ET Q Q q @@ -6025,13 +6025,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (21) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (21) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 273 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Plac easy tests) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Plac easy tests) Tj T* ET Q Q q @@ -6039,13 +6039,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (22) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (22) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 255 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Plac batch scripts) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Plac batch scripts) Tj T* ET Q Q q @@ -6053,13 +6053,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (23) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (23) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 237 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Implementing subcommands) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Implementing subcommands) Tj T* ET Q Q q @@ -6067,13 +6067,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (24) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (24) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 219 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac.Interpreter.call) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac.Interpreter.call) Tj T* ET Q Q q @@ -6081,13 +6081,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (26) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (26) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 201 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Readline support) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Readline support) Tj T* ET Q Q q @@ -6095,13 +6095,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (28) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (28) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 183 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (The plac runner) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (The plac runner) Tj T* ET Q Q q @@ -6109,13 +6109,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (29) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (29) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 165 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (A non class-based example) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (A non class-based example) Tj T* ET Q Q q @@ -6123,13 +6123,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (31) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (31) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 147 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Writing your own plac runner) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Writing your own plac runner) Tj T* ET Q Q q @@ -6137,13 +6137,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (33) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (33) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 129 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Long running commands) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Long running commands) Tj T* ET Q Q q @@ -6151,13 +6151,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (34) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (34) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 111 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Threaded commands) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Threaded commands) Tj T* ET Q Q q @@ -6165,13 +6165,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (35) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (35) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 93 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Running commands as external processes) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Running commands as external processes) Tj T* ET Q Q q @@ -6179,13 +6179,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (37) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (37) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 75 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Managing the output of concurrent commands) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Managing the output of concurrent commands) Tj T* ET Q Q q @@ -6193,13 +6193,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (38) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (38) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 57 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Parallel computing with plac) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Parallel computing with plac) Tj T* ET Q Q q @@ -6207,13 +6207,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (39) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (39) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 39 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (The plac server) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (The plac server) Tj T* ET Q Q q @@ -6221,13 +6221,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (41) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (41) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 21 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Summary) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Summary) Tj T* ET Q Q q @@ -6235,13 +6235,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (41) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (41) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 3 cm q -BT 1 0 0 1 20 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Appendix: custom annotation objects) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Appendix: custom annotation objects) Tj T* ET Q Q q @@ -6249,7 +6249,7 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 60.88 0 Td (42) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (42) Tj T* -60.88 0 Td ET Q Q q @@ -6259,59 +6259,58 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 238.1649 0 Td (2) Tj T* -238.1649 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 238.1649 0 Td (2) Tj T* -238.1649 0 Td ET Q Q endstream - endobj % 'R339': class PDFStream 339 0 obj % page stream -<< /Length 5985 >> +<< /Length 5956 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 747.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (The importance of scaling down) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (The importance of scaling down) Tj T* ET Q Q q 1 0 0 1 62.69291 681.0236 cm q -BT 1 0 0 1 0 52.82 Tm 1.50936 Tw 12 TL /F1 10 Tf 0 0 0 rg (There is no want of command line arguments parsers in the Python world. The standard library alone) Tj T* 0 Tw 1.087126 Tw (contains three different modules: ) Tj 0 0 .501961 rg (getopt ) Tj 0 0 0 rg (\(from the stone age\), ) Tj 0 0 .501961 rg (optparse ) Tj 0 0 0 rg (\(from Python 2.3\) and ) Tj 0 0 .501961 rg (argparse) Tj T* 0 Tw .223735 Tw 0 0 0 rg (\(from Python 2.7\). All of them are quite powerful and especially ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (is an industrial strength solution;) Tj T* 0 Tw 1.40311 Tw (unfortunately, all of them feature a non-zero learning curve and a certain verbosity. They do not scale) Tj T* 0 Tw (down well, at least in my opinion.) Tj T* ET +BT 1 0 0 1 0 50 Tm 1.50936 Tw 12 TL /F1 10 Tf 0 0 0 rg (There is no want of command line arguments parsers in the Python world. The standard library alone) Tj T* 0 Tw 1.087126 Tw (contains three different modules: ) Tj 0 0 .501961 rg (getopt ) Tj 0 0 0 rg (\(from the stone age\), ) Tj 0 0 .501961 rg (optparse ) Tj 0 0 0 rg (\(from Python 2.3\) and ) Tj 0 0 .501961 rg (argparse) Tj T* 0 Tw .223735 Tw 0 0 0 rg (\(from Python 2.7\). All of them are quite powerful and especially ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (is an industrial strength solution;) Tj T* 0 Tw 1.40311 Tw (unfortunately, all of them feature a non-zero learning curve and a certain verbosity. They do not scale) Tj T* 0 Tw (down well, at least in my opinion.) Tj T* ET Q Q q 1 0 0 1 62.69291 603.0236 cm q -BT 1 0 0 1 0 64.82 Tm 2.20186 Tw 12 TL /F1 10 Tf 0 0 0 rg (It should not be necessary to stress the importance ) Tj 0 0 .501961 rg (scaling down) Tj 0 0 0 rg (; nevertheless, a lot of people are) Tj T* 0 Tw .968555 Tw (obsessed with features and concerned with the possibility of scaling up, forgetting the equally important) Tj T* 0 Tw .048221 Tw (issue of scaling down. This is an old meme in the computing world: programs should address the common) Tj T* 0 Tw .36311 Tw (cases simply and simple things should be kept simple, while at the same keeping difficult things possible.) Tj T* 0 Tw 1.09332 Tw 0 0 .501961 rg (plac ) Tj 0 0 0 rg (adhere as much as possible to this philosophy and it is designed to handle well the simple cases,) Tj T* 0 Tw (while retaining the ability to handle complex cases by relying on the underlying power of ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (.) Tj T* ET +BT 1 0 0 1 0 62 Tm 2.20186 Tw 12 TL /F1 10 Tf 0 0 0 rg (It should not be necessary to stress the importance ) Tj 0 0 .501961 rg (scaling down) Tj 0 0 0 rg (; nevertheless, a lot of people are) Tj T* 0 Tw .968555 Tw (obsessed with features and concerned with the possibility of scaling up, forgetting the equally important) Tj T* 0 Tw .048221 Tw (issue of scaling down. This is an old meme in the computing world: programs should address the common) Tj T* 0 Tw .36311 Tw (cases simply and simple things should be kept simple, while at the same keeping difficult things possible.) Tj T* 0 Tw 1.09332 Tw 0 0 .501961 rg (plac ) Tj 0 0 0 rg (adhere as much as possible to this philosophy and it is designed to handle well the simple cases,) Tj T* 0 Tw (while retaining the ability to handle complex cases by relying on the underlying power of ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (.) Tj T* ET Q Q q 1 0 0 1 62.69291 525.0236 cm q -BT 1 0 0 1 0 64.82 Tm 1.488221 Tw 12 TL /F1 10 Tf 0 0 0 rg (Technically ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is just a simple wrapper over ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (which hides most of its complexity by using a) Tj T* 0 Tw .203318 Tw (declarative interface: the argument parser is inferred rather than written down by imperatively. Still, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is) Tj T* 0 Tw .125984 Tw (surprisingly scalable upwards, even without using the underlying ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (. I have been using Python for 8) Tj T* 0 Tw 1.618876 Tw (years and in my experience it is extremely unlikely that you will ever need to go beyond the features) Tj T* 0 Tw 1.776457 Tw (provided by the declarative interface of ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (: they should be more than enough for 99.9% of the use) Tj T* 0 Tw (cases.) Tj T* ET +BT 1 0 0 1 0 62 Tm 1.488221 Tw 12 TL /F1 10 Tf 0 0 0 rg (Technically ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is just a simple wrapper over ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (which hides most of its complexity by using a) Tj T* 0 Tw .203318 Tw (declarative interface: the argument parser is inferred rather than written down by imperatively. Still, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is) Tj T* 0 Tw .125984 Tw (surprisingly scalable upwards, even without using the underlying ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (. I have been using Python for 8) Tj T* 0 Tw 1.618876 Tw (years and in my experience it is extremely unlikely that you will ever need to go beyond the features) Tj T* 0 Tw 1.776457 Tw (provided by the declarative interface of ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (: they should be more than enough for 99.9% of the use) Tj T* 0 Tw (cases.) Tj T* ET Q Q q 1 0 0 1 62.69291 423.0236 cm q -BT 1 0 0 1 0 88.82 Tm 1.540888 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is targetting especially unsophisticated users, programmers, sys-admins, scientists and in general) Tj T* 0 Tw .81284 Tw (people writing throw-away scripts for themselves, choosing the command line interface because it is the) Tj T* 0 Tw .471751 Tw (quick and simple. Such users are not interested in features, they are interested in a small learning curve:) Tj T* 0 Tw .984988 Tw (they just want to be able to write a simple command line tool from a simple specification, not to build a) Tj T* 0 Tw 1.127318 Tw (command-line parser by hand. Unfortunately, the modules in the standard library forces them to go the) Tj T* 0 Tw .014104 Tw (hard way. They are designed to implement power user tools and they have a non-trivial learning curve. On) Tj T* 0 Tw 1.584104 Tw (the contrary, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is designed to be simple to use and extremely concise, as the examples below will) Tj T* 0 Tw (show.) Tj T* ET +BT 1 0 0 1 0 86 Tm 1.540888 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is targetting especially unsophisticated users, programmers, sys-admins, scientists and in general) Tj T* 0 Tw .81284 Tw (people writing throw-away scripts for themselves, choosing the command line interface because it is the) Tj T* 0 Tw .471751 Tw (quick and simple. Such users are not interested in features, they are interested in a small learning curve:) Tj T* 0 Tw .984988 Tw (they just want to be able to write a simple command line tool from a simple specification, not to build a) Tj T* 0 Tw 1.127318 Tw (command-line parser by hand. Unfortunately, the modules in the standard library forces them to go the) Tj T* 0 Tw .014104 Tw (hard way. They are designed to implement power user tools and they have a non-trivial learning curve. On) Tj T* 0 Tw 1.584104 Tw (the contrary, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is designed to be simple to use and extremely concise, as the examples below will) Tj T* 0 Tw (show.) Tj T* ET Q Q q 1 0 0 1 62.69291 393.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Scripts with required arguments) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Scripts with required arguments) Tj T* ET Q Q q 1 0 0 1 62.69291 327.0236 cm q -BT 1 0 0 1 0 52.82 Tm .352209 Tw 12 TL /F1 10 Tf 0 0 0 rg (Let me start with the simplest possible thing: a script that takes a single argument and does something to) Tj T* 0 Tw 1.053984 Tw (it. It cannot get simpler than that, unless you consider a script without command-line arguments, where) Tj T* 0 Tw .735488 Tw (there is nothing to parse. Still, it is a use case ) Tj /F4 10 Tf (extremely common) Tj /F1 10 Tf (: I need to write scripts like that nearly) Tj T* 0 Tw .486655 Tw (every day, I wrote hundreds of them in the last few years and I have never been happy. Here is a typical) Tj T* 0 Tw (example of code I have been writing by hand for years:) Tj T* ET +BT 1 0 0 1 0 50 Tm .352209 Tw 12 TL /F1 10 Tf 0 0 0 rg (Let me start with the simplest possible thing: a script that takes a single argument and does something to) Tj T* 0 Tw 1.053984 Tw (it. It cannot get simpler than that, unless you consider a script without command-line arguments, where) Tj T* 0 Tw .735488 Tw (there is nothing to parse. Still, it is a use case ) Tj /F4 10 Tf (extremely common) Tj /F1 10 Tf (: I need to write scripts like that nearly) Tj T* 0 Tw .486655 Tw (every day, I wrote hundreds of them in the last few years and I have never been happy. Here is a typical) Tj T* 0 Tw (example of code I have been writing by hand for years:) Tj T* ET Q Q q @@ -6329,7 +6328,7 @@ n -6 -6 468.6898 192 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 173.71 Tm /F3 10 Tf 12 TL (# example1.py) Tj T* (def main\(dsn\):) Tj T* ( "Do something with the database") Tj T* ( print\(dsn\)) Tj T* ( # ...) Tj T* T* (if __name__ == '__main__':) Tj T* ( import sys) Tj T* ( n = len\(sys.argv[1:]\)) Tj T* ( if n == 0:) Tj T* ( sys.exit\('usage: python %s dsn' % sys.argv[0]\)) Tj T* ( elif n == 1:) Tj T* ( main\(sys.argv[1]\)) Tj T* ( else:) Tj T* ( sys.exit\('Unrecognized arguments: %s' % ' '.join\(sys.argv[2:]\)\)) Tj T* ET +BT 1 0 0 1 0 170 Tm /F3 10 Tf 12 TL (# example1.py) Tj T* (def main\(dsn\):) Tj T* ( "Do something with the database") Tj T* ( print\(dsn\)) Tj T* ( # ...) Tj T* T* (if __name__ == '__main__':) Tj T* ( import sys) Tj T* ( n = len\(sys.argv[1:]\)) Tj T* ( if n == 0:) Tj T* ( sys.exit\('usage: python %s dsn' % sys.argv[0]\)) Tj T* ( elif n == 1:) Tj T* ( main\(sys.argv[1]\)) Tj T* ( else:) Tj T* ( sys.exit\('Unrecognized arguments: %s' % ' '.join\(sys.argv[2:]\)\)) Tj T* ET Q Q Q @@ -6338,30 +6337,29 @@ Q q 1 0 0 1 62.69291 93.82362 cm q -BT 1 0 0 1 0 16.82 Tm .880651 Tw 12 TL /F1 10 Tf 0 0 0 rg (As you see the whole ) Tj /F3 10 Tf (if __name__ == '__main__' ) Tj /F1 10 Tf (block \(nine lines\) is essentially boilerplate that ) Tj T* 0 Tw 1.972927 Tw (should not exist. Actually I think the language should recognize the main function and pass to it the) Tj T* 0 Tw ET +BT 1 0 0 1 0 14 Tm .880651 Tw 12 TL /F1 10 Tf 0 0 0 rg (As you see the whole ) Tj /F3 10 Tf (if __name__ == '__main__' ) Tj /F1 10 Tf (block \(nine lines\) is essentially boilerplate that ) Tj T* 0 Tw 1.972927 Tw (should not exist. Actually I think the language should recognize the main function and pass to it the) Tj T* 0 Tw ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 238.1649 0 Td (3) Tj T* -238.1649 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 238.1649 0 Td (3) Tj T* -238.1649 0 Td ET Q Q endstream - endobj % 'R340': class PDFStream 340 0 obj % page stream -<< /Length 4448 >> +<< /Length 4418 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 693.0236 cm q -BT 1 0 0 1 0 64.82 Tm 3.309147 Tw 12 TL /F1 10 Tf 0 0 0 rg (command-line arguments automatically; unfortunaly this is unlikely to happen. I have been writing) Tj T* 0 Tw 1.767356 Tw (boilerplate like this in hundreds of scripts for years, and every time I ) Tj /F4 10 Tf (hate ) Tj /F1 10 Tf (it. The purpose of using a) Tj T* 0 Tw 1.47229 Tw (scripting language is convenience and trivial things should be trivial. Unfortunately the standard library) Tj T* 0 Tw .69881 Tw (does not help for this incredibly common use case. Using ) Tj 0 0 .501961 rg (getopt ) Tj 0 0 0 rg (and ) Tj 0 0 .501961 rg (optparse ) Tj 0 0 0 rg (does not help, since they) Tj T* 0 Tw .894104 Tw (are intended to manage options and not positional arguments; the ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (module helps a bit and it is) Tj T* 0 Tw (able to reduce the boilerplate from nine lines to six lines:) Tj T* ET +BT 1 0 0 1 0 62 Tm 3.309147 Tw 12 TL /F1 10 Tf 0 0 0 rg (command-line arguments automatically; unfortunaly this is unlikely to happen. I have been writing) Tj T* 0 Tw 1.767356 Tw (boilerplate like this in hundreds of scripts for years, and every time I ) Tj /F4 10 Tf (hate ) Tj /F1 10 Tf (it. The purpose of using a) Tj T* 0 Tw 1.47229 Tw (scripting language is convenience and trivial things should be trivial. Unfortunately the standard library) Tj T* 0 Tw .69881 Tw (does not help for this incredibly common use case. Using ) Tj 0 0 .501961 rg (getopt ) Tj 0 0 0 rg (and ) Tj 0 0 .501961 rg (optparse ) Tj 0 0 0 rg (does not help, since they) Tj T* 0 Tw .894104 Tw (are intended to manage options and not positional arguments; the ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (module helps a bit and it is) Tj T* 0 Tw (able to reduce the boilerplate from nine lines to six lines:) Tj T* ET Q Q q @@ -6379,7 +6377,7 @@ n -6 -6 468.6898 156 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 137.71 Tm /F3 10 Tf 12 TL (# example2.py) Tj T* (def main\(dsn\):) Tj T* ( "Do something on the database") Tj T* ( print\(dsn\)) Tj T* ( # ...) Tj T* T* (if __name__ == '__main__':) Tj T* ( import argparse) Tj T* ( p = argparse.ArgumentParser\(\)) Tj T* ( p.add_argument\('dsn'\)) Tj T* ( arg = p.parse_args\(\)) Tj T* ( main\(arg.dsn\)) Tj T* ET +BT 1 0 0 1 0 134 Tm /F3 10 Tf 12 TL (# example2.py) Tj T* (def main\(dsn\):) Tj T* ( "Do something on the database") Tj T* ( print\(dsn\)) Tj T* ( # ...) Tj T* T* (if __name__ == '__main__':) Tj T* ( import argparse) Tj T* ( p = argparse.ArgumentParser\(\)) Tj T* ( p.add_argument\('dsn'\)) Tj T* ( arg = p.parse_args\(\)) Tj T* ( main\(arg.dsn\)) Tj T* ET Q Q Q @@ -6389,13 +6387,13 @@ q 1 0 0 1 62.69291 471.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 40.82 Tm /F1 10 Tf 12 TL 1.644269 Tw (However saving three lines does not justify introducing the external dependency: most people will not) Tj T* 0 Tw 2.206303 Tw (switch to Python 2.7, which at the time of this writing is just about to be released, for many years.) Tj T* 0 Tw .678488 Tw (Moreover, it just feels too complex to instantiate a class and to define a parser by hand for such a trivial) Tj T* 0 Tw (task.) Tj T* ET +BT 1 0 0 1 0 38 Tm /F1 10 Tf 12 TL 1.644269 Tw (However saving three lines does not justify introducing the external dependency: most people will not) Tj T* 0 Tw 2.206303 Tw (switch to Python 2.7, which at the time of this writing is just about to be released, for many years.) Tj T* 0 Tw .678488 Tw (Moreover, it just feels too complex to instantiate a class and to define a parser by hand for such a trivial) Tj T* 0 Tw (task.) Tj T* ET Q Q q 1 0 0 1 62.69291 441.8236 cm q -BT 1 0 0 1 0 16.82 Tm 1.123145 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (module is designed to manage well such use cases, and it is able to reduce the original nine) Tj T* 0 Tw (lines of boiler plate to two lines. With the ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (module all you need to write is) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.123145 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (module is designed to manage well such use cases, and it is able to reduce the original nine) Tj T* 0 Tw (lines of boiler plate to two lines. With the ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (module all you need to write is) Tj T* ET Q Q q @@ -6413,7 +6411,7 @@ n -6 -6 468.6898 108 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 89.71 Tm /F3 10 Tf 12 TL (# example3.py) Tj T* (def main\(dsn\):) Tj T* ( "Do something with the database") Tj T* ( print\(dsn\)) Tj T* ( # ...) Tj T* ( ) Tj T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET +BT 1 0 0 1 0 86 Tm /F3 10 Tf 12 TL (# example3.py) Tj T* (def main\(dsn\):) Tj T* ( "Do something with the database") Tj T* ( print\(dsn\)) Tj T* ( # ...) Tj T* ( ) Tj T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET Q Q Q @@ -6422,7 +6420,7 @@ Q q 1 0 0 1 62.69291 292.6236 cm q -BT 1 0 0 1 0 16.82 Tm .929986 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (module provides for free \(actually the work is done by the underlying ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (module\) a nice) Tj T* 0 Tw (usage message:) Tj T* ET +BT 1 0 0 1 0 14 Tm .929986 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (module provides for free \(actually the work is done by the underlying ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (module\) a nice) Tj T* 0 Tw (usage message:) Tj T* ET Q Q q @@ -6440,7 +6438,7 @@ n -6 -6 468.6898 24 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 5.71 Tm /F3 10 Tf 12 TL ($ python example3.py -h) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL ($ python example3.py -h) Tj T* ET Q Q Q @@ -6461,7 +6459,7 @@ n -6 -6 468.6898 120 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 101.71 Tm /F3 10 Tf 12 TL (usage: example3.py [-h] dsn) Tj T* T* (Do something with the database) Tj T* T* (positional arguments:) Tj T* ( dsn) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ET +BT 1 0 0 1 0 98 Tm /F3 10 Tf 12 TL (usage: example3.py [-h] dsn) Tj T* T* (Do something with the database) Tj T* T* (positional arguments:) Tj T* ( dsn) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ET Q Q Q @@ -6470,37 +6468,36 @@ Q q 1 0 0 1 62.69291 98.22362 cm q -BT 1 0 0 1 0 16.82 Tm .167765 Tw 12 TL /F1 10 Tf 0 0 0 rg (Moreover ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (manages the case of missing arguments and of too many arguments. This is only the tip of) Tj T* 0 Tw (the iceberg: ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is able to do much more than that.) Tj T* ET +BT 1 0 0 1 0 14 Tm .167765 Tw 12 TL /F1 10 Tf 0 0 0 rg (Moreover ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (manages the case of missing arguments and of too many arguments. This is only the tip of) Tj T* 0 Tw (the iceberg: ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is able to do much more than that.) Tj T* ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 238.1649 0 Td (4) Tj T* -238.1649 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 238.1649 0 Td (4) Tj T* -238.1649 0 Td ET Q Q endstream - endobj % 'R341': class PDFStream 341 0 obj % page stream -<< /Length 4050 >> +<< /Length 4021 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 747.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Scripts with default arguments) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Scripts with default arguments) Tj T* ET Q Q q 1 0 0 1 62.69291 717.0236 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL 2.609984 Tw (The need to have suitable defaults for command-line scripts is quite common. For instance I have) Tj T* 0 Tw (encountered this use case at work hundreds of times:) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 2.609984 Tw (The need to have suitable defaults for command-line scripts is quite common. For instance I have) Tj T* 0 Tw (encountered this use case at work hundreds of times:) Tj T* ET Q Q q @@ -6517,7 +6514,7 @@ q n -6 -6 468.6898 192 re B* Q q -BT 1 0 0 1 0 173.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (# example4.py) Tj T* (from datetime import datetime) Tj T* T* (def main\(dsn, table='product', today=datetime.today\(\)\):) Tj T* ( "Do something on the database") Tj T* ( print\(dsn, table, today\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( import sys) Tj T* ( args = sys.argv[1:]) Tj T* ( if not args:) Tj T* ( sys.exit\('usage: python %s dsn' % sys.argv[0]\)) Tj T* ( elif len\(args\) ) Tj (>) Tj ( 2:) Tj T* ( sys.exit\('Unrecognized arguments: %s' % ' '.join\(argv[2:]\)\)) Tj T* ( main\(*args\)) Tj T* ET +BT 1 0 0 1 0 170 Tm 12 TL /F3 10 Tf 0 0 0 rg (# example4.py) Tj T* (from datetime import datetime) Tj T* T* (def main\(dsn, table='product', today=datetime.today\(\)\):) Tj T* ( "Do something on the database") Tj T* ( print\(dsn, table, today\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( import sys) Tj T* ( args = sys.argv[1:]) Tj T* ( if not args:) Tj T* ( sys.exit\('usage: python %s dsn' % sys.argv[0]\)) Tj T* ( elif len\(args\) ) Tj (>) Tj ( 2:) Tj T* ( sys.exit\('Unrecognized arguments: %s' % ' '.join\(argv[2:]\)\)) Tj T* ( main\(*args\)) Tj T* ET Q Q Q @@ -6526,7 +6523,7 @@ Q q 1 0 0 1 62.69291 447.8236 cm q -BT 1 0 0 1 0 52.82 Tm .038488 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here I want to perform a query on a database table, by extracting the most recent data: it makes sense for) Tj T* 0 Tw .299988 Tw /F3 10 Tf (today ) Tj /F1 10 Tf (to be a default argument. If there is a most used table \(in this example a table called ) Tj /F3 10 Tf ('product') Tj /F1 10 Tf (\)) Tj T* 0 Tw 3.313984 Tw (it also makes sense to make it a default argument. Performing the parsing of the command-line) Tj T* 0 Tw .083735 Tw (arguments by hand takes 8 ugly lines of boilerplate \(using ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (would require about the same number) Tj T* 0 Tw (of lines\). With ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (the entire ) Tj /F3 10 Tf (__main__ ) Tj /F1 10 Tf (block reduces to the usual two lines:) Tj T* ET +BT 1 0 0 1 0 50 Tm .038488 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here I want to perform a query on a database table, by extracting the most recent data: it makes sense for) Tj T* 0 Tw .299988 Tw /F3 10 Tf (today ) Tj /F1 10 Tf (to be a default argument. If there is a most used table \(in this example a table called ) Tj /F3 10 Tf ('product') Tj /F1 10 Tf (\)) Tj T* 0 Tw 3.313984 Tw (it also makes sense to make it a default argument. Performing the parsing of the command-line) Tj T* 0 Tw .083735 Tw (arguments by hand takes 8 ugly lines of boilerplate \(using ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (would require about the same number) Tj T* 0 Tw (of lines\). With ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (the entire ) Tj /F3 10 Tf (__main__ ) Tj /F1 10 Tf (block reduces to the usual two lines:) Tj T* ET Q Q q @@ -6544,7 +6541,7 @@ n -6 -6 468.6898 36 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 17.71 Tm /F3 10 Tf 12 TL (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET Q Q Q @@ -6554,7 +6551,7 @@ q 1 0 0 1 62.69291 382.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (In other words, six lines of boilerplate have been removed, and we get the usage message for free:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (In other words, six lines of boilerplate have been removed, and we get the usage message for free:) Tj T* ET Q Q q @@ -6572,7 +6569,7 @@ n -6 -6 468.6898 144 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 125.71 Tm /F3 10 Tf 12 TL (usage: example5.py [-h] dsn [table] [today]) Tj T* T* (Do something on the database) Tj T* T* (positional arguments:) Tj T* ( dsn) Tj T* ( table) Tj T* ( today) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ET +BT 1 0 0 1 0 122 Tm /F3 10 Tf 12 TL (usage: example5.py [-h] dsn [table] [today]) Tj T* T* (Do something on the database) Tj T* T* (positional arguments:) Tj T* ( dsn) Tj T* ( table) Tj T* ( today) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ET Q Q Q @@ -6581,7 +6578,7 @@ Q q 1 0 0 1 62.69291 197.4236 cm q -BT 1 0 0 1 0 16.82 Tm .396235 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (manages transparently even the case when you want to pass a variable number of arguments. Here) Tj T* 0 Tw (is an example, a script running on a database a series of SQL scripts:) Tj T* ET +BT 1 0 0 1 0 14 Tm .396235 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (manages transparently even the case when you want to pass a variable number of arguments. Here) Tj T* 0 Tw (is an example, a script running on a database a series of SQL scripts:) Tj T* ET Q Q q @@ -6599,7 +6596,7 @@ n -6 -6 468.6898 96 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 77.71 Tm /F3 10 Tf 12 TL (# example7.py) Tj T* (from datetime import datetime) Tj T* T* (def main\(dsn, *scripts\):) Tj T* ( "Run the given scripts on the database") Tj T* ( for script in scripts:) Tj T* ( print\('executing %s' % script\)) Tj T* ET +BT 1 0 0 1 0 74 Tm /F3 10 Tf 12 TL (# example7.py) Tj T* (from datetime import datetime) Tj T* T* (def main\(dsn, *scripts\):) Tj T* ( "Run the given scripts on the database") Tj T* ( for script in scripts:) Tj T* ( print\('executing %s' % script\)) Tj T* ET Q Q Q @@ -6609,19 +6606,18 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 238.1649 0 Td (5) Tj T* -238.1649 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 238.1649 0 Td (5) Tj T* -238.1649 0 Td ET Q Q endstream - endobj % 'R342': class PDFStream 342 0 obj % page stream -<< /Length 3901 >> +<< /Length 3872 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 703.8236 cm q @@ -6637,7 +6633,7 @@ n -6 -6 468.6898 60 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 41.71 Tm /F3 10 Tf 12 TL ( # ...) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET +BT 1 0 0 1 0 38 Tm /F3 10 Tf 12 TL ( # ...) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET Q Q Q @@ -6647,7 +6643,7 @@ q 1 0 0 1 62.69291 683.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Here is the usage message:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is the usage message:) Tj T* ET Q Q q @@ -6665,7 +6661,7 @@ n -6 -6 468.6898 132 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 113.71 Tm /F3 10 Tf 12 TL (usage: example7.py [-h] dsn [scripts [scripts ...]]) Tj T* T* (Run the given scripts on the database) Tj T* T* (positional arguments:) Tj T* ( dsn) Tj T* ( scripts) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ET +BT 1 0 0 1 0 110 Tm /F3 10 Tf 12 TL (usage: example7.py [-h] dsn [scripts [scripts ...]]) Tj T* T* (Run the given scripts on the database) Tj T* T* (positional arguments:) Tj T* ( dsn) Tj T* ( scripts) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ET Q Q Q @@ -6674,19 +6670,19 @@ Q q 1 0 0 1 62.69291 498.6236 cm q -BT 1 0 0 1 0 28.82 Tm .952485 Tw 12 TL /F1 10 Tf 0 0 0 rg (The examples here should have made clear that ) Tj /F4 10 Tf (plac is able to figure out the command-line arguments) Tj T* 0 Tw .899988 Tw (parser to use from the signature of the main function) Tj /F1 10 Tf (. This is the whole idea behind ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (: if the intent is) Tj T* 0 Tw (clear, let's the machine take care of the details.) Tj T* ET +BT 1 0 0 1 0 26 Tm .952485 Tw 12 TL /F1 10 Tf 0 0 0 rg (The examples here should have made clear that ) Tj /F4 10 Tf (plac is able to figure out the command-line arguments) Tj T* 0 Tw .899988 Tw (parser to use from the signature of the main function) Tj /F1 10 Tf (. This is the whole idea behind ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (: if the intent is) Tj T* 0 Tw (clear, let's the machine take care of the details.) Tj T* ET Q Q q 1 0 0 1 62.69291 456.6236 cm q -BT 1 0 0 1 0 28.82 Tm 3.036235 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is inspired to an old Python Cookbook recipe \() Tj 0 0 .501961 rg (optionparse) Tj 0 0 0 rg (\), in the sense that it delivers the) Tj T* 0 Tw .847209 Tw (programmer from the burden of writing the parser, but is less of a hack: instead of extracting the parser) Tj T* 0 Tw (from the docstring of the module, it extracts it from the signature of the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (function.) Tj T* ET +BT 1 0 0 1 0 26 Tm 3.036235 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is inspired to an old Python Cookbook recipe \() Tj 0 0 .501961 rg (optionparse) Tj 0 0 0 rg (\), in the sense that it delivers the) Tj T* 0 Tw .847209 Tw (programmer from the burden of writing the parser, but is less of a hack: instead of extracting the parser) Tj T* 0 Tw (from the docstring of the module, it extracts it from the signature of the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (function.) Tj T* ET Q Q q 1 0 0 1 62.69291 426.6236 cm q -BT 1 0 0 1 0 16.82 Tm .319987 Tw 12 TL /F1 10 Tf 0 0 0 rg (The idea comes from the ) Tj /F4 10 Tf (function annotations ) Tj /F1 10 Tf (concept, a new feature of Python 3. An example is worth a) Tj T* 0 Tw (thousand words, so here it is:) Tj T* ET +BT 1 0 0 1 0 14 Tm .319987 Tw 12 TL /F1 10 Tf 0 0 0 rg (The idea comes from the ) Tj /F4 10 Tf (function annotations ) Tj /F1 10 Tf (concept, a new feature of Python 3. An example is worth a) Tj T* 0 Tw (thousand words, so here it is:) Tj T* ET Q Q q @@ -6704,7 +6700,7 @@ n -6 -6 468.6898 144 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 125.71 Tm /F3 10 Tf 12 TL (# example7_.py) Tj T* (from datetime import datetime) Tj T* T* (def main\(dsn: "Database dsn", *scripts: "SQL scripts"\):) Tj T* ( "Run the given scripts on the database") Tj T* ( for script in scripts:) Tj T* ( print\('executing %s' % script\)) Tj T* ( # ...) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET +BT 1 0 0 1 0 122 Tm /F3 10 Tf 12 TL (# example7_.py) Tj T* (from datetime import datetime) Tj T* T* (def main\(dsn: "Database dsn", *scripts: "SQL scripts"\):) Tj T* ( "Run the given scripts on the database") Tj T* ( for script in scripts:) Tj T* ( print\('executing %s' % script\)) Tj T* ( # ...) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET Q Q Q @@ -6713,7 +6709,7 @@ Q q 1 0 0 1 62.69291 241.4236 cm q -BT 1 0 0 1 0 16.82 Tm .17528 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here the arguments of the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (function have been annotated with strings which are intented to be used) Tj T* 0 Tw (in the help message:) Tj T* ET +BT 1 0 0 1 0 14 Tm .17528 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here the arguments of the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (function have been annotated with strings which are intented to be used) Tj T* 0 Tw (in the help message:) Tj T* ET Q Q q @@ -6731,7 +6727,7 @@ n -6 -6 468.6898 132 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 113.71 Tm /F3 10 Tf 12 TL (usage: example7_.py [-h] dsn [scripts [scripts ...]]) Tj T* T* (Run the given scripts on the database) Tj T* T* (positional arguments:) Tj T* ( dsn Database dsn) Tj T* ( scripts SQL scripts) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ET +BT 1 0 0 1 0 110 Tm /F3 10 Tf 12 TL (usage: example7_.py [-h] dsn [scripts [scripts ...]]) Tj T* T* (Run the given scripts on the database) Tj T* T* (positional arguments:) Tj T* ( dsn Database dsn) Tj T* ( scripts SQL scripts) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ET Q Q Q @@ -6741,35 +6737,34 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 238.1649 0 Td (6) Tj T* -238.1649 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 238.1649 0 Td (6) Tj T* -238.1649 0 Td ET Q Q endstream - endobj % 'R343': class PDFStream 343 0 obj % page stream -<< /Length 5019 >> +<< /Length 4986 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 753.0236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is able to recognize much more complex annotations, as I will show in the next paragraphs.) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is able to recognize much more complex annotations, as I will show in the next paragraphs.) Tj T* ET Q Q q 1 0 0 1 62.69291 723.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Scripts with options \(and smart options\)) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Scripts with options \(and smart options\)) Tj T* ET Q Q q 1 0 0 1 62.69291 633.0236 cm q -BT 1 0 0 1 0 76.82 Tm .016457 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is surprising how few command-line scripts with options I have written over the years \(probably less than) Tj T* 0 Tw 1.02311 Tw (a hundred\), compared to the number of scripts with positional arguments I wrote \(certainly more than a) Tj T* 0 Tw .177045 Tw (thousand of them\). Still, this use case cannot be neglected. The standard library modules \(all of them\) are) Tj T* 0 Tw 2.30686 Tw (quite verbose when it comes to specifying the options and frankly I have never used them directly.) Tj T* 0 Tw 2.557126 Tw (Instead, I have always relied on the ) Tj 0 0 .501961 rg (optionparse ) Tj 0 0 0 rg (recipe, which provides a convenient wrapper over) Tj T* 0 Tw 1.09061 Tw 0 0 .501961 rg (optionparse) Tj 0 0 0 rg (. Alternatively, in the simplest cases, I have just performed the parsing by hand. In ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (the) Tj T* 0 Tw (parser is inferred by the function annotations. Here is an example:) Tj T* ET +BT 1 0 0 1 0 74 Tm .016457 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is surprising how few command-line scripts with options I have written over the years \(probably less than) Tj T* 0 Tw 1.02311 Tw (a hundred\), compared to the number of scripts with positional arguments I wrote \(certainly more than a) Tj T* 0 Tw .177045 Tw (thousand of them\). Still, this use case cannot be neglected. The standard library modules \(all of them\) are) Tj T* 0 Tw 2.30686 Tw (quite verbose when it comes to specifying the options and frankly I have never used them directly.) Tj T* 0 Tw 2.557126 Tw (Instead, I have always relied on the ) Tj 0 0 .501961 rg (optionparse ) Tj 0 0 0 rg (recipe, which provides a convenient wrapper over) Tj T* 0 Tw 1.09061 Tw 0 0 .501961 rg (optionparse) Tj 0 0 0 rg (. Alternatively, in the simplest cases, I have just performed the parsing by hand. In ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (the) Tj T* 0 Tw (parser is inferred by the function annotations. Here is an example:) Tj T* ET Q Q q @@ -6787,7 +6782,7 @@ n -6 -6 468.6898 108 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 89.71 Tm /F3 10 Tf 12 TL (# example8.py) Tj T* (def main\(command: \("SQL query", 'option', 'c'\), dsn\):) Tj T* ( if command:) Tj T* ( print\('executing %s on %s' % \(command, dsn\)\)) Tj T* ( # ...) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET +BT 1 0 0 1 0 86 Tm /F3 10 Tf 12 TL (# example8.py) Tj T* (def main\(command: \("SQL query", 'option', 'c'\), dsn\):) Tj T* ( if command:) Tj T* ( print\('executing %s on %s' % \(command, dsn\)\)) Tj T* ( # ...) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET Q Q Q @@ -6796,7 +6791,7 @@ Q q 1 0 0 1 62.69291 459.8236 cm q -BT 1 0 0 1 0 40.82 Tm .929213 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here the argument ) Tj /F3 10 Tf (command ) Tj /F1 10 Tf (has been annotated with the tuple ) Tj /F3 10 Tf (\("SQL query", 'option', 'c'\)) Tj /F1 10 Tf (:) Tj T* 0 Tw .62683 Tw (the first string is the help string which will appear in the usage message, the second string tells ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (that) Tj T* 0 Tw .931894 Tw /F3 10 Tf (command ) Tj /F1 10 Tf (is an option and the third string that there is also a short form of the option ) Tj /F3 10 Tf (-c) Tj /F1 10 Tf (, the long form) Tj T* 0 Tw (being ) Tj /F3 10 Tf (--command) Tj /F1 10 Tf (. The usage message is the following:) Tj T* ET +BT 1 0 0 1 0 38 Tm .929213 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here the argument ) Tj /F3 10 Tf (command ) Tj /F1 10 Tf (has been annotated with the tuple ) Tj /F3 10 Tf (\("SQL query", 'option', 'c'\)) Tj /F1 10 Tf (:) Tj T* 0 Tw .62683 Tw (the first string is the help string which will appear in the usage message, the second string tells ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (that) Tj T* 0 Tw .931894 Tw /F3 10 Tf (command ) Tj /F1 10 Tf (is an option and the third string that there is also a short form of the option ) Tj /F3 10 Tf (-c) Tj /F1 10 Tf (, the long form) Tj T* 0 Tw (being ) Tj /F3 10 Tf (--command) Tj /F1 10 Tf (. The usage message is the following:) Tj T* ET Q Q q @@ -6814,7 +6809,7 @@ n -6 -6 468.6898 120 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 101.71 Tm /F3 10 Tf 12 TL (usage: example8.py [-h] [-c COMMAND] dsn) Tj T* T* (positional arguments:) Tj T* ( dsn) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -c COMMAND, --command COMMAND) Tj T* ( SQL query) Tj T* ET +BT 1 0 0 1 0 98 Tm /F3 10 Tf 12 TL (usage: example8.py [-h] [-c COMMAND] dsn) Tj T* T* (positional arguments:) Tj T* ( dsn) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -c COMMAND, --command COMMAND) Tj T* ( SQL query) Tj T* ET Q Q Q @@ -6824,7 +6819,7 @@ q 1 0 0 1 62.69291 310.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Here are two examples of usage:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here are two examples of usage:) Tj T* ET Q Q q @@ -6842,7 +6837,7 @@ n -6 -6 468.6898 72 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 53.71 Tm /F3 10 Tf 12 TL ($ python3 example8.py -c"select * from table" dsn) Tj T* (executing select * from table on dsn) Tj T* T* ($ python3 example8.py --command="select * from table" dsn) Tj T* (executing select * from table on dsn) Tj T* ET +BT 1 0 0 1 0 50 Tm /F3 10 Tf 12 TL ($ python3 example8.py -c"select * from table" dsn) Tj T* (executing select * from table on dsn) Tj T* T* ($ python3 example8.py --command="select * from table" dsn) Tj T* (executing select * from table on dsn) Tj T* ET Q Q Q @@ -6851,7 +6846,7 @@ Q q 1 0 0 1 62.69291 173.4236 cm q -BT 1 0 0 1 0 40.82 Tm .268935 Tw 12 TL /F1 10 Tf 0 0 0 rg (The third argument in the function annotation can be omitted: in such case it will be assumed to be ) Tj /F3 10 Tf (None) Tj /F1 10 Tf (.) Tj T* 0 Tw 2.839213 Tw (The consequence is that the usual dichotomy between long and short options \(GNU-style options\)) Tj T* 0 Tw .396235 Tw (disappears: we get ) Tj /F4 10 Tf (smart options) Tj /F1 10 Tf (, which have the single character prefix of short options and behave like) Tj T* 0 Tw (both long and short options, since they can be abbreviated. Here is an example featuring smart options:) Tj T* ET +BT 1 0 0 1 0 38 Tm .268935 Tw 12 TL /F1 10 Tf 0 0 0 rg (The third argument in the function annotation can be omitted: in such case it will be assumed to be ) Tj /F3 10 Tf (None) Tj /F1 10 Tf (.) Tj T* 0 Tw 2.839213 Tw (The consequence is that the usual dichotomy between long and short options \(GNU-style options\)) Tj T* 0 Tw .396235 Tw (disappears: we get ) Tj /F4 10 Tf (smart options) Tj /F1 10 Tf (, which have the single character prefix of short options and behave like) Tj T* 0 Tw (both long and short options, since they can be abbreviated. Here is an example featuring smart options:) Tj T* ET Q Q q @@ -6869,7 +6864,7 @@ n -6 -6 468.6898 72 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 53.71 Tm /F3 10 Tf 12 TL (# example6.py) Tj T* (def main\(dsn, command: \("SQL query", 'option'\)\):) Tj T* ( print\('executing %r on %s' % \(command, dsn\)\)) Tj T* T* (if __name__ == '__main__':) Tj T* ET +BT 1 0 0 1 0 50 Tm /F3 10 Tf 12 TL (# example6.py) Tj T* (def main\(dsn, command: \("SQL query", 'option'\)\):) Tj T* ( print\('executing %r on %s' % \(command, dsn\)\)) Tj T* T* (if __name__ == '__main__':) Tj T* ET Q Q Q @@ -6879,19 +6874,18 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 238.1649 0 Td (7) Tj T* -238.1649 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 238.1649 0 Td (7) Tj T* -238.1649 0 Td ET Q Q endstream - endobj % 'R344': class PDFStream 344 0 obj % page stream -<< /Length 4318 >> +<< /Length 4279 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 739.8236 cm q @@ -6907,7 +6901,7 @@ n -6 -6 468.6898 24 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 5.71 Tm /F3 10 Tf 12 TL ( import plac; plac.call\(main\)) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL ( import plac; plac.call\(main\)) Tj T* ET Q Q Q @@ -6928,7 +6922,7 @@ n -6 -6 468.6898 108 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 89.71 Tm /F3 10 Tf 12 TL (usage: example6.py [-h] [-command COMMAND] dsn) Tj T* T* (positional arguments:) Tj T* ( dsn) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -command COMMAND SQL query) Tj T* ET +BT 1 0 0 1 0 86 Tm /F3 10 Tf 12 TL (usage: example6.py [-h] [-command COMMAND] dsn) Tj T* T* (positional arguments:) Tj T* ( dsn) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -command COMMAND SQL query) Tj T* ET Q Q Q @@ -6938,7 +6932,7 @@ q 1 0 0 1 62.69291 602.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (The following are all valid invocations ot the script:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The following are all valid invocations ot the script:) Tj T* ET Q Q q @@ -6956,7 +6950,7 @@ n -6 -6 468.6898 84 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 65.71 Tm /F3 10 Tf 12 TL ($ python3 example6.py -c "select" dsn) Tj T* (executing 'select' on dsn) Tj T* ($ python3 example6.py -com "select" dsn) Tj T* (executing 'select' on dsn) Tj T* ($ python3 example6.py -command="select" dsn) Tj T* (executing 'select' on dsn) Tj T* ET +BT 1 0 0 1 0 62 Tm /F3 10 Tf 12 TL ($ python3 example6.py -c "select" dsn) Tj T* (executing 'select' on dsn) Tj T* ($ python3 example6.py -com "select" dsn) Tj T* (executing 'select' on dsn) Tj T* ($ python3 example6.py -command="select" dsn) Tj T* (executing 'select' on dsn) Tj T* ET Q Q Q @@ -6965,7 +6959,7 @@ Q q 1 0 0 1 62.69291 489.4236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (Notice that the form ) Tj /F3 10 Tf (-command=SQL ) Tj /F1 10 Tf (is recognized only for the full option, not for its abbreviations:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Notice that the form ) Tj /F3 10 Tf (-command=SQL ) Tj /F1 10 Tf (is recognized only for the full option, not for its abbreviations:) Tj T* ET Q Q q @@ -6983,7 +6977,7 @@ n -6 -6 468.6898 48 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 29.71 Tm /F3 10 Tf 12 TL ($ python3 example6.py -com="select" dsn) Tj T* (usage: example6.py [-h] [-command COMMAND] dsn) Tj T* (example6.py: error: unrecognized arguments: -com=select) Tj T* ET +BT 1 0 0 1 0 26 Tm /F3 10 Tf 12 TL ($ python3 example6.py -com="select" dsn) Tj T* (usage: example6.py [-h] [-command COMMAND] dsn) Tj T* (example6.py: error: unrecognized arguments: -com=select) Tj T* ET Q Q Q @@ -6992,7 +6986,7 @@ Q q 1 0 0 1 62.69291 400.2236 cm q -BT 1 0 0 1 0 16.82 Tm 1.724987 Tw 12 TL /F1 10 Tf 0 0 0 rg (If the option is not passed, the variable ) Tj /F3 10 Tf (command ) Tj /F1 10 Tf (will get the value ) Tj /F3 10 Tf (None) Tj /F1 10 Tf (. However, it is possible to) Tj T* 0 Tw (specify a non-trivial default. Here is an example:) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.724987 Tw 12 TL /F1 10 Tf 0 0 0 rg (If the option is not passed, the variable ) Tj /F3 10 Tf (command ) Tj /F1 10 Tf (will get the value ) Tj /F3 10 Tf (None) Tj /F1 10 Tf (. However, it is possible to) Tj T* 0 Tw (specify a non-trivial default. Here is an example:) Tj T* ET Q Q q @@ -7010,7 +7004,7 @@ n -6 -6 468.6898 84 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 65.71 Tm /F3 10 Tf 12 TL (# example8_.py) Tj T* (def main\(dsn, command: \("SQL query", 'option'\)='select * from table'\):) Tj T* ( print\('executing %r on %s' % \(command, dsn\)\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET +BT 1 0 0 1 0 62 Tm /F3 10 Tf 12 TL (# example8_.py) Tj T* (def main\(dsn, command: \("SQL query", 'option'\)='select * from table'\):) Tj T* ( print\('executing %r on %s' % \(command, dsn\)\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET Q Q Q @@ -7020,7 +7014,7 @@ q 1 0 0 1 62.69291 287.0236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Notice that the default value appears in the help message:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Notice that the default value appears in the help message:) Tj T* ET Q Q q @@ -7038,7 +7032,7 @@ n -6 -6 468.6898 120 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 101.71 Tm /F3 10 Tf 12 TL (usage: example8_.py [-h] [-command select * from table] dsn) Tj T* T* (positional arguments:) Tj T* ( dsn) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -command select * from table) Tj T* ( SQL query) Tj T* ET +BT 1 0 0 1 0 98 Tm /F3 10 Tf 12 TL (usage: example8_.py [-h] [-command select * from table] dsn) Tj T* T* (positional arguments:) Tj T* ( dsn) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -command select * from table) Tj T* ( SQL query) Tj T* ET Q Q Q @@ -7047,7 +7041,7 @@ Q q 1 0 0 1 62.69291 137.8236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (When you run the script and you do not pass the ) Tj /F3 10 Tf (-command ) Tj /F1 10 Tf (option, the default query will be executed:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (When you run the script and you do not pass the ) Tj /F3 10 Tf (-command ) Tj /F1 10 Tf (option, the default query will be executed:) Tj T* ET Q Q q @@ -7065,7 +7059,7 @@ n -6 -6 468.6898 36 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 17.71 Tm /F3 10 Tf 12 TL ($ python3 example8_.py dsn) Tj T* (executing 'select * from table' on dsn) Tj T* ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL ($ python3 example8_.py dsn) Tj T* (executing 'select * from table' on dsn) Tj T* ET Q Q Q @@ -7075,29 +7069,28 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 238.1649 0 Td (8) Tj T* -238.1649 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 238.1649 0 Td (8) Tj T* -238.1649 0 Td ET Q Q endstream - endobj % 'R345': class PDFStream 345 0 obj % page stream -<< /Length 4916 >> +<< /Length 4877 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 747.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Scripts with flags) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Scripts with flags) Tj T* ET Q Q q 1 0 0 1 62.69291 717.0236 cm q -BT 1 0 0 1 0 16.82 Tm .815542 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is able to recognize flags, i.e. boolean options which are ) Tj /F3 10 Tf (True ) Tj /F1 10 Tf (if they are passed to the command) Tj T* 0 Tw (line and ) Tj /F3 10 Tf (False ) Tj /F1 10 Tf (if they are absent. Here is an example:) Tj T* ET +BT 1 0 0 1 0 14 Tm .815542 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is able to recognize flags, i.e. boolean options which are ) Tj /F3 10 Tf (True ) Tj /F1 10 Tf (if they are passed to the command) Tj T* 0 Tw (line and ) Tj /F3 10 Tf (False ) Tj /F1 10 Tf (if they are absent. Here is an example:) Tj T* ET Q Q q @@ -7115,7 +7108,7 @@ n -6 -6 486 120 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 101.71 Tm /F3 10 Tf 12 TL (# example9.py) Tj T* T* (def main\(verbose: \('prints more info', 'flag', 'v'\), dsn: 'connection string'\):) Tj T* ( if verbose:) Tj T* ( print\('connecting to %s' % dsn\)) Tj T* ( # ...) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET +BT 1 0 0 1 0 98 Tm /F3 10 Tf 12 TL (# example9.py) Tj T* T* (def main\(verbose: \('prints more info', 'flag', 'v'\), dsn: 'connection string'\):) Tj T* ( if verbose:) Tj T* ( print\('connecting to %s' % dsn\)) Tj T* ( # ...) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET Q Q Q @@ -7136,7 +7129,7 @@ n -6 -6 468.6898 108 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 89.71 Tm /F3 10 Tf 12 TL (usage: example9.py [-h] [-v] dsn) Tj T* T* (positional arguments:) Tj T* ( dsn connection string) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -v, --verbose prints more info) Tj T* ET +BT 1 0 0 1 0 86 Tm /F3 10 Tf 12 TL (usage: example9.py [-h] [-v] dsn) Tj T* T* (positional arguments:) Tj T* ( dsn connection string) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -v, --verbose prints more info) Tj T* ET Q Q Q @@ -7157,7 +7150,7 @@ n -6 -6 468.6898 36 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 17.71 Tm /F3 10 Tf 12 TL ($ python3 example9.py -v dsn) Tj T* (connecting to dsn) Tj T* ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL ($ python3 example9.py -v dsn) Tj T* (connecting to dsn) Tj T* ET Q Q Q @@ -7166,31 +7159,31 @@ Q q 1 0 0 1 62.69291 385.7299 cm q -BT 1 0 0 1 0 28.82 Tm .31408 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that it is an error trying to specify a default for flags: the default value for a flag is always ) Tj /F3 10 Tf (False) Tj /F1 10 Tf (. If) Tj T* 0 Tw 2.652485 Tw (you feel the need to implement non-boolean flags, you should use an option with two choices, as) Tj T* 0 Tw (explained in the "more features" section.) Tj T* ET +BT 1 0 0 1 0 26 Tm .31408 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that it is an error trying to specify a default for flags: the default value for a flag is always ) Tj /F3 10 Tf (False) Tj /F1 10 Tf (. If) Tj T* 0 Tw 2.652485 Tw (you feel the need to implement non-boolean flags, you should use an option with two choices, as) Tj T* 0 Tw (explained in the "more features" section.) Tj T* ET Q Q q 1 0 0 1 62.69291 319.7299 cm q -BT 1 0 0 1 0 52.82 Tm 5.832651 Tw 12 TL /F1 10 Tf 0 0 0 rg (For consistency with the way the usage message is printed, I suggest you to follow the) Tj T* 0 Tw 1.895433 Tw (Flag-Option-Required-Default \(FORD\) convention: in the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (function write first the flag arguments,) Tj T* 0 Tw .881235 Tw (then the option arguments, then the required arguments and finally the default arguments. This is just a) Tj T* 0 Tw .110574 Tw (convention and you are not forced to use it, except for the default arguments \(including the varargs\) which) Tj T* 0 Tw (must stay at the end as it is required by the Python syntax.) Tj T* ET +BT 1 0 0 1 0 50 Tm 5.832651 Tw 12 TL /F1 10 Tf 0 0 0 rg (For consistency with the way the usage message is printed, I suggest you to follow the) Tj T* 0 Tw 1.895433 Tw (Flag-Option-Required-Default \(FORD\) convention: in the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (function write first the flag arguments,) Tj T* 0 Tw .881235 Tw (then the option arguments, then the required arguments and finally the default arguments. This is just a) Tj T* 0 Tw .110574 Tw (convention and you are not forced to use it, except for the default arguments \(including the varargs\) which) Tj T* 0 Tw (must stay at the end as it is required by the Python syntax.) Tj T* ET Q Q q 1 0 0 1 62.69291 277.7299 cm q -BT 1 0 0 1 0 28.82 Tm .897045 Tw 12 TL /F1 10 Tf 0 0 0 rg (I also suggests to specify a one-character abbreviation for flags: in this way you can use the GNU-style) Tj T* 0 Tw 2.034431 Tw (composition of flags \(i.e. ) Tj /F3 10 Tf (-zxvf ) Tj /F1 10 Tf (is an abbreviation of ) Tj /F3 10 Tf (-z -x -v -f) Tj /F1 10 Tf (\). I usually do not provide the) Tj T* 0 Tw (one-character abbreviation for options, since it does not make sense to compose them.) Tj T* ET +BT 1 0 0 1 0 26 Tm .897045 Tw 12 TL /F1 10 Tf 0 0 0 rg (I also suggests to specify a one-character abbreviation for flags: in this way you can use the GNU-style) Tj T* 0 Tw 2.034431 Tw (composition of flags \(i.e. ) Tj /F3 10 Tf (-zxvf ) Tj /F1 10 Tf (is an abbreviation of ) Tj /F3 10 Tf (-z -x -v -f) Tj /F1 10 Tf (\). I usually do not provide the) Tj T* 0 Tw (one-character abbreviation for options, since it does not make sense to compose them.) Tj T* ET Q Q q 1 0 0 1 62.69291 247.7299 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (plac for Python 2.X users) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (plac for Python 2.X users) Tj T* ET Q Q q 1 0 0 1 62.69291 181.7299 cm q -BT 1 0 0 1 0 52.82 Tm .211807 Tw 12 TL /F1 10 Tf 0 0 0 rg (I do not use Python 3. At work we are just starting to think about migrating to Python 2.6. It will take years) Tj T* 0 Tw .304724 Tw (before we think to migrate to Python 3. I am pretty much sure most Pythonistas are in the same situation.) Tj T* 0 Tw 1.459984 Tw (Therefore ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (provides a way to work with function annotations even in Python 2.X \(including Python) Tj T* 0 Tw 2.692339 Tw (2.3\). There is no magic involved; you just need to add the annotations by hand. For instance the) Tj T* 0 Tw (annotated function declaration) Tj T* ET +BT 1 0 0 1 0 50 Tm .211807 Tw 12 TL /F1 10 Tf 0 0 0 rg (I do not use Python 3. At work we are just starting to think about migrating to Python 2.6. It will take years) Tj T* 0 Tw .304724 Tw (before we think to migrate to Python 3. I am pretty much sure most Pythonistas are in the same situation.) Tj T* 0 Tw 1.459984 Tw (Therefore ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (provides a way to work with function annotations even in Python 2.X \(including Python) Tj T* 0 Tw 2.692339 Tw (2.3\). There is no magic involved; you just need to add the annotations by hand. For instance the) Tj T* 0 Tw (annotated function declaration) Tj T* ET Q Q q @@ -7208,7 +7201,7 @@ n -6 -6 468.6898 36 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 17.71 Tm /F3 10 Tf 12 TL (def main\(dsn: "Database dsn", *scripts: "SQL scripts"\):) Tj T* ( ...) Tj T* ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL (def main\(dsn: "Database dsn", *scripts: "SQL scripts"\):) Tj T* ( ...) Tj T* ET Q Q Q @@ -7218,26 +7211,25 @@ q 1 0 0 1 62.69291 116.5299 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (is equivalent to the following code:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (is equivalent to the following code:) Tj T* ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 238.1649 0 Td (9) Tj T* -238.1649 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 238.1649 0 Td (9) Tj T* -238.1649 0 Td ET Q Q endstream - endobj % 'R346': class PDFStream 346 0 obj % page stream -<< /Length 6172 >> +<< /Length 6131 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 691.8236 cm q @@ -7253,7 +7245,7 @@ n -6 -6 468.6898 72 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 53.71 Tm /F3 10 Tf 12 TL (def main\(dsn, *scripts\):) Tj T* ( ...) Tj T* (main.__annotations__ = dict\() Tj T* ( dsn="Database dsn",) Tj T* ( scripts="SQL scripts"\)) Tj T* ET +BT 1 0 0 1 0 50 Tm /F3 10 Tf 12 TL (def main\(dsn, *scripts\):) Tj T* ( ...) Tj T* (main.__annotations__ = dict\() Tj T* ( dsn="Database dsn",) Tj T* ( scripts="SQL scripts"\)) Tj T* ET Q Q Q @@ -7262,7 +7254,7 @@ Q q 1 0 0 1 62.69291 647.8236 cm q -BT 1 0 0 1 0 28.82 Tm .536098 Tw 12 TL /F1 10 Tf 0 0 0 rg (One should be careful to match the keys of the annotation dictionary with the names of the arguments in) Tj T* 0 Tw 3.347485 Tw (the annotated function; for lazy people with Python 2.4 available the simplest way is to use the) Tj T* 0 Tw /F3 10 Tf (plac.annotations ) Tj /F1 10 Tf (decorator that performs the check for you:) Tj T* ET +BT 1 0 0 1 0 26 Tm .536098 Tw 12 TL /F1 10 Tf 0 0 0 rg (One should be careful to match the keys of the annotation dictionary with the names of the arguments in) Tj T* 0 Tw 3.347485 Tw (the annotated function; for lazy people with Python 2.4 available the simplest way is to use the) Tj T* 0 Tw /F3 10 Tf (plac.annotations ) Tj /F1 10 Tf (decorator that performs the check for you:) Tj T* ET Q Q q @@ -7280,7 +7272,7 @@ n -6 -6 468.6898 72 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 53.71 Tm /F3 10 Tf 12 TL (@plac.annotations\() Tj T* ( dsn="Database dsn",) Tj T* ( scripts="SQL scripts"\)) Tj T* (def main\(dsn, *scripts\):) Tj T* ( ...) Tj T* ET +BT 1 0 0 1 0 50 Tm /F3 10 Tf 12 TL (@plac.annotations\() Tj T* ( dsn="Database dsn",) Tj T* ( scripts="SQL scripts"\)) Tj T* (def main\(dsn, *scripts\):) Tj T* ( ...) Tj T* ET Q Q Q @@ -7289,19 +7281,19 @@ Q q 1 0 0 1 62.69291 534.6236 cm q -BT 1 0 0 1 0 16.82 Tm 1.846077 Tw 12 TL /F1 10 Tf 0 0 0 rg (In the rest of this article I will assume that you are using Python 2.X with X >) Tj (= 4 and I will use the) Tj T* 0 Tw /F3 10 Tf (plac.annotations ) Tj /F1 10 Tf (decorator. Notice however that the core features of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (run even on Python 2.3.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.846077 Tw 12 TL /F1 10 Tf 0 0 0 rg (In the rest of this article I will assume that you are using Python 2.X with X >) Tj (= 4 and I will use the) Tj T* 0 Tw /F3 10 Tf (plac.annotations ) Tj /F1 10 Tf (decorator. Notice however that the core features of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (run even on Python 2.3.) Tj T* ET Q Q q 1 0 0 1 62.69291 504.6236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (More features) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (More features) Tj T* ET Q Q q 1 0 0 1 62.69291 450.6236 cm q -BT 1 0 0 1 0 40.82 Tm 1.483488 Tw 12 TL /F1 10 Tf 0 0 0 rg (One of the goals of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is to have a learning curve of ) Tj /F4 10 Tf (minutes ) Tj /F1 10 Tf (for its core features, compared to the) Tj T* 0 Tw 1.152093 Tw (learning curve of ) Tj /F4 10 Tf (hours ) Tj /F1 10 Tf (of ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (. In order to reach this goal, I have ) Tj /F4 10 Tf (not ) Tj /F1 10 Tf (sacrificed all the features of) Tj T* 0 Tw 2.89936 Tw 0 0 .501961 rg (argparse) Tj 0 0 0 rg (. Actually a lot of ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (power persists in ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (. Until now, I have only showed simple) Tj T* 0 Tw (annotations, but in general an annotation is a 6-tuple of the form) Tj T* ET +BT 1 0 0 1 0 38 Tm 1.483488 Tw 12 TL /F1 10 Tf 0 0 0 rg (One of the goals of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is to have a learning curve of ) Tj /F4 10 Tf (minutes ) Tj /F1 10 Tf (for its core features, compared to the) Tj T* 0 Tw 1.152093 Tw (learning curve of ) Tj /F4 10 Tf (hours ) Tj /F1 10 Tf (of ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (. In order to reach this goal, I have ) Tj /F4 10 Tf (not ) Tj /F1 10 Tf (sacrificed all the features of) Tj T* 0 Tw 2.89936 Tw 0 0 .501961 rg (argparse) Tj 0 0 0 rg (. Actually a lot of ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (power persists in ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (. Until now, I have only showed simple) Tj T* 0 Tw (annotations, but in general an annotation is a 6-tuple of the form) Tj T* ET Q Q q @@ -7316,7 +7308,7 @@ q 1 0 0 1 20 0 cm q 0 0 0 rg -BT 1 0 0 1 0 5.71 Tm /F3 10 Tf 12 TL (\(help, kind, abbrev, type, choices, metavar\)) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (\(help, kind, abbrev, type, choices, metavar\)) Tj T* ET Q Q q @@ -7328,31 +7320,31 @@ Q q 1 0 0 1 62.69291 390.6236 cm q -BT 1 0 0 1 0 28.82 Tm 1.068735 Tw 12 TL /F1 10 Tf 0 0 0 rg (where ) Tj /F3 10 Tf (help ) Tj /F1 10 Tf (is the help message, ) Tj /F3 10 Tf (kind ) Tj /F1 10 Tf (is a string in the set { ) Tj /F3 10 Tf ("flag") Tj /F1 10 Tf (, ) Tj /F3 10 Tf ("option") Tj /F1 10 Tf (, ) Tj /F3 10 Tf ("positional") Tj /F1 10 Tf (},) Tj T* 0 Tw 1.579431 Tw /F3 10 Tf (abbrev ) Tj /F1 10 Tf (is a one-character string or ) Tj /F3 10 Tf (None) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (type ) Tj /F1 10 Tf (is a callable taking a string in input, ) Tj /F3 10 Tf (choices ) Tj /F1 10 Tf (is a) Tj T* 0 Tw (discrete sequence of values and ) Tj /F3 10 Tf (metavar ) Tj /F1 10 Tf (is a string.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.068735 Tw 12 TL /F1 10 Tf 0 0 0 rg (where ) Tj /F3 10 Tf (help ) Tj /F1 10 Tf (is the help message, ) Tj /F3 10 Tf (kind ) Tj /F1 10 Tf (is a string in the set { ) Tj /F3 10 Tf ("flag") Tj /F1 10 Tf (, ) Tj /F3 10 Tf ("option") Tj /F1 10 Tf (, ) Tj /F3 10 Tf ("positional") Tj /F1 10 Tf (},) Tj T* 0 Tw 1.579431 Tw /F3 10 Tf (abbrev ) Tj /F1 10 Tf (is a one-character string or ) Tj /F3 10 Tf (None) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (type ) Tj /F1 10 Tf (is a callable taking a string in input, ) Tj /F3 10 Tf (choices ) Tj /F1 10 Tf (is a) Tj T* 0 Tw (discrete sequence of values and ) Tj /F3 10 Tf (metavar ) Tj /F1 10 Tf (is a string.) Tj T* ET Q Q q 1 0 0 1 62.69291 360.6236 cm q -BT 1 0 0 1 0 16.82 Tm 1.05061 Tw 12 TL /F3 10 Tf 0 0 0 rg (type ) Tj /F1 10 Tf (is used to automagically convert the command line arguments from the string type to any Python) Tj T* 0 Tw (type; by default there is no conversion and ) Tj /F3 10 Tf (type=None) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.05061 Tw 12 TL /F3 10 Tf 0 0 0 rg (type ) Tj /F1 10 Tf (is used to automagically convert the command line arguments from the string type to any Python) Tj T* 0 Tw (type; by default there is no conversion and ) Tj /F3 10 Tf (type=None) Tj /F1 10 Tf (.) Tj T* ET Q Q q 1 0 0 1 62.69291 330.6236 cm q -BT 1 0 0 1 0 16.82 Tm 2.904692 Tw 12 TL /F3 10 Tf 0 0 0 rg (choices ) Tj /F1 10 Tf (is used to restrict the number of the valid options; by default there is no restriction i.e.) Tj T* 0 Tw /F3 10 Tf (choices=None) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.904692 Tw 12 TL /F3 10 Tf 0 0 0 rg (choices ) Tj /F1 10 Tf (is used to restrict the number of the valid options; by default there is no restriction i.e.) Tj T* 0 Tw /F3 10 Tf (choices=None) Tj /F1 10 Tf (.) Tj T* ET Q Q q 1 0 0 1 62.69291 252.6236 cm q -BT 1 0 0 1 0 64.82 Tm 1.171163 Tw 12 TL /F3 10 Tf 0 0 0 rg (metavar ) Tj /F1 10 Tf (has two meanings. For a positional argument it is used to change the argument name in the) Tj T* 0 Tw .352209 Tw (usage message \(and only there\). By default the metavar is ) Tj /F3 10 Tf (None ) Tj /F1 10 Tf (and the name in the usage message is) Tj T* 0 Tw .752339 Tw (the same as the argument name. For an option the ) Tj /F3 10 Tf (metavar ) Tj /F1 10 Tf (is used differently in the usage message,) Tj T* 0 Tw .802927 Tw (which has now the form ) Tj /F3 10 Tf ([--option-name METAVAR]) Tj /F1 10 Tf (. If the ) Tj /F3 10 Tf (metavar ) Tj /F1 10 Tf (is ) Tj /F3 10 Tf (None) Tj /F1 10 Tf (, then it is equal to the) Tj T* 0 Tw .50683 Tw (uppercased name of the argument, unless the argument has a default and in such a case is equal to the) Tj T* 0 Tw (stringified form of the default.) Tj T* ET +BT 1 0 0 1 0 62 Tm 1.171163 Tw 12 TL /F3 10 Tf 0 0 0 rg (metavar ) Tj /F1 10 Tf (has two meanings. For a positional argument it is used to change the argument name in the) Tj T* 0 Tw .352209 Tw (usage message \(and only there\). By default the metavar is ) Tj /F3 10 Tf (None ) Tj /F1 10 Tf (and the name in the usage message is) Tj T* 0 Tw .752339 Tw (the same as the argument name. For an option the ) Tj /F3 10 Tf (metavar ) Tj /F1 10 Tf (is used differently in the usage message,) Tj T* 0 Tw .802927 Tw (which has now the form ) Tj /F3 10 Tf ([--option-name METAVAR]) Tj /F1 10 Tf (. If the ) Tj /F3 10 Tf (metavar ) Tj /F1 10 Tf (is ) Tj /F3 10 Tf (None) Tj /F1 10 Tf (, then it is equal to the) Tj T* 0 Tw .50683 Tw (uppercased name of the argument, unless the argument has a default and in such a case is equal to the) Tj T* 0 Tw (stringified form of the default.) Tj T* ET Q Q q 1 0 0 1 62.69291 234.6236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (Here is an example showing many of the features \(copied from the ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (documentation\):) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Here is an example showing many of the features \(copied from the ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (documentation\):) Tj T* ET Q Q q @@ -7370,7 +7362,7 @@ n -6 -6 480 132 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 113.71 Tm /F3 10 Tf 12 TL (# example10.py) Tj T* (import plac) Tj T* T* (@plac.annotations\() Tj T* (operator=\("The name of an operator", 'positional', None, str, ['add', 'mul']\),) Tj T* (numbers=\("A number", 'positional', None, float, None, "n"\)\)) Tj T* (def main\(operator, *numbers\):) Tj T* ( "A script to add and multiply numbers") Tj T* ( if operator == 'mul':) Tj T* ( op = float.__mul__) Tj T* ET +BT 1 0 0 1 0 110 Tm /F3 10 Tf 12 TL (# example10.py) Tj T* (import plac) Tj T* T* (@plac.annotations\() Tj T* (operator=\("The name of an operator", 'positional', None, str, ['add', 'mul']\),) Tj T* (numbers=\("A number", 'positional', None, float, None, "n"\)\)) Tj T* (def main\(operator, *numbers\):) Tj T* ( "A script to add and multiply numbers") Tj T* ( if operator == 'mul':) Tj T* ( op = float.__mul__) Tj T* ET Q Q Q @@ -7380,19 +7372,18 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (10) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (10) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R347': class PDFStream 347 0 obj % page stream -<< /Length 4255 >> +<< /Length 4220 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 631.8236 cm q @@ -7408,7 +7399,7 @@ n -6 -6 468.6898 132 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 113.71 Tm /F3 10 Tf 12 TL ( result = 1.0) Tj T* ( else: # operator == 'add') Tj T* ( op = float.__add__) Tj T* ( result = 0.0) Tj T* ( for n in numbers:) Tj T* ( result = op\(result, n\)) Tj T* ( return result) Tj T* T* (if __name__ == '__main__':) Tj T* ( print\(plac.call\(main\)\)) Tj T* ET +BT 1 0 0 1 0 110 Tm /F3 10 Tf 12 TL ( result = 1.0) Tj T* ( else: # operator == 'add') Tj T* ( op = float.__add__) Tj T* ( result = 0.0) Tj T* ( for n in numbers:) Tj T* ( result = op\(result, n\)) Tj T* ( return result) Tj T* T* (if __name__ == '__main__':) Tj T* ( print\(plac.call\(main\)\)) Tj T* ET Q Q Q @@ -7418,7 +7409,7 @@ q 1 0 0 1 62.69291 611.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Here is the usage:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is the usage:) Tj T* ET Q Q q @@ -7436,7 +7427,7 @@ n -6 -6 468.6898 132 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 113.71 Tm /F3 10 Tf 12 TL (usage: example10.py [-h] {add,mul} [n [n ...]]) Tj T* T* (A script to add and multiply numbers) Tj T* T* (positional arguments:) Tj T* ( {add,mul} The name of an operator) Tj T* ( n A number) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ET +BT 1 0 0 1 0 110 Tm /F3 10 Tf 12 TL (usage: example10.py [-h] {add,mul} [n [n ...]]) Tj T* T* (A script to add and multiply numbers) Tj T* T* (positional arguments:) Tj T* ( {add,mul} The name of an operator) Tj T* ( n A number) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ET Q Q Q @@ -7445,7 +7436,7 @@ Q q 1 0 0 1 62.69291 438.6236 cm q -BT 1 0 0 1 0 16.82 Tm .15186 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that the docstring of the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (function has been automatically added to the usage message. Here) Tj T* 0 Tw (are a couple of examples of use:) Tj T* ET +BT 1 0 0 1 0 14 Tm .15186 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that the docstring of the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (function has been automatically added to the usage message. Here) Tj T* 0 Tw (are a couple of examples of use:) Tj T* ET Q Q q @@ -7463,7 +7454,7 @@ n -6 -6 534 96 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 77.71 Tm /F3 10 Tf 12 TL ($ python example10.py add 1 2 3 4) Tj T* (10.0) Tj T* ($ python example10.py mul 1 2 3 4) Tj T* (24.0) Tj T* ($ python example10.py ad 1 2 3 4 # a mispelling error) Tj T* (usage: example10.py [-h] {add,mul} [n [n ...]]) Tj T* (example10.py: error: argument operator: invalid choice: 'ad' \(choose from 'add', 'mul'\)) Tj T* ET +BT 1 0 0 1 0 74 Tm /F3 10 Tf 12 TL ($ python example10.py add 1 2 3 4) Tj T* (10.0) Tj T* ($ python example10.py mul 1 2 3 4) Tj T* (24.0) Tj T* ($ python example10.py ad 1 2 3 4 # a mispelling error) Tj T* (usage: example10.py [-h] {add,mul} [n [n ...]]) Tj T* (example10.py: error: argument operator: invalid choice: 'ad' \(choose from 'add', 'mul'\)) Tj T* ET Q Q Q @@ -7472,7 +7463,7 @@ Q q 1 0 0 1 62.69291 325.2849 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F3 10 Tf 0 0 0 rg (plac.call ) Tj /F1 10 Tf (can also be used in doctests like this:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (plac.call ) Tj /F1 10 Tf (can also be used in doctests like this:) Tj T* ET Q Q q @@ -7489,7 +7480,7 @@ q n -6 -6 468.6898 48 re B* Q q -BT 1 0 0 1 0 29.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( import plac, example10) Tj T* (>) Tj (>) Tj (>) Tj ( plac.call\(example10.main, ['add', '1', '2']\)) Tj T* (3.0) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( import plac, example10) Tj T* (>) Tj (>) Tj (>) Tj ( plac.call\(example10.main, ['add', '1', '2']\)) Tj T* (3.0) Tj T* ET Q Q Q @@ -7498,7 +7489,7 @@ Q q 1 0 0 1 62.69291 248.0849 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F3 10 Tf 0 0 0 rg (plac.call ) Tj /F1 10 Tf (works for generators too:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (plac.call ) Tj /F1 10 Tf (works for generators too:) Tj T* ET Q Q q @@ -7515,7 +7506,7 @@ q n -6 -6 468.6898 72 re B* Q q -BT 1 0 0 1 0 53.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( def main\(n\):) Tj T* (... for i in range\(int\(n\)\):) Tj T* (... yield i) Tj T* (>) Tj (>) Tj (>) Tj ( plac.call\(main, ['3']\)) Tj T* ([0, 1, 2]) Tj T* ET +BT 1 0 0 1 0 50 Tm 12 TL /F3 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( def main\(n\):) Tj T* (... for i in range\(int\(n\)\):) Tj T* (... yield i) Tj T* (>) Tj (>) Tj (>) Tj ( plac.call\(main, ['3']\)) Tj T* ([0, 1, 2]) Tj T* ET Q Q Q @@ -7524,32 +7515,31 @@ Q q 1 0 0 1 62.69291 122.8849 cm q -BT 1 0 0 1 0 28.82 Tm .158409 Tw 12 TL /F1 10 Tf 0 0 0 rg (Internally ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (tries to convert the output of the main function into a list, if possible. If the output is) Tj T* 0 Tw .725703 Tw (not iterable or it is a string, it is left unchanged, but if it is iterable it is converted. In particular, generator) Tj T* 0 Tw (objects are exhausted by ) Tj /F3 10 Tf (plac.call) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 26 Tm .158409 Tw 12 TL /F1 10 Tf 0 0 0 rg (Internally ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (tries to convert the output of the main function into a list, if possible. If the output is) Tj T* 0 Tw .725703 Tw (not iterable or it is a string, it is left unchanged, but if it is iterable it is converted. In particular, generator) Tj T* 0 Tw (objects are exhausted by ) Tj /F3 10 Tf (plac.call) Tj /F1 10 Tf (.) Tj T* ET Q Q q 1 0 0 1 62.69291 92.8849 cm q -BT 1 0 0 1 0 16.82 Tm 1.450751 Tw 12 TL /F1 10 Tf 0 0 0 rg (This behavior avoids mistakes like forgetting of applying ) Tj /F3 10 Tf (list\(result\) ) Tj /F1 10 Tf (to the result of ) Tj /F3 10 Tf (plac.call) Tj /F1 10 Tf (;) Tj T* 0 Tw (moreover it makes errors visible early, and avoids mistakes in code like the following:) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.450751 Tw 12 TL /F1 10 Tf 0 0 0 rg (This behavior avoids mistakes like forgetting of applying ) Tj /F3 10 Tf (list\(result\) ) Tj /F1 10 Tf (to the result of ) Tj /F3 10 Tf (plac.call) Tj /F1 10 Tf (;) Tj T* 0 Tw (moreover it makes errors visible early, and avoids mistakes in code like the following:) Tj T* ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (11) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (11) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R348': class PDFStream 348 0 obj % page stream -<< /Length 4298 >> +<< /Length 4269 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 703.8236 cm q @@ -7565,7 +7555,7 @@ n -6 -6 468.6898 60 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 41.71 Tm /F3 10 Tf 12 TL (try:) Tj T* ( result = plac.call\(main, args\)) Tj T* (except:) Tj T* ( # do something) Tj T* ET +BT 1 0 0 1 0 38 Tm /F3 10 Tf 12 TL (try:) Tj T* ( result = plac.call\(main, args\)) Tj T* (except:) Tj T* ( # do something) Tj T* ET Q Q Q @@ -7575,13 +7565,13 @@ q 1 0 0 1 62.69291 671.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL 3.122126 Tw (Without the "listify" functionality, a main function returning a generator object would not raise any) Tj T* 0 Tw (exception until the generator is iterated over.) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 3.122126 Tw (Without the "listify" functionality, a main function returning a generator object would not raise any) Tj T* 0 Tw (exception until the generator is iterated over.) Tj T* ET Q Q q 1 0 0 1 62.69291 641.8236 cm q -BT 1 0 0 1 0 16.82 Tm .647262 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you are a fan of lazyness, you can still have it by setting the ) Tj /F3 10 Tf (eager ) Tj /F1 10 Tf (flag to ) Tj /F3 10 Tf (False) Tj /F1 10 Tf (, as in the following) Tj T* 0 Tw (example:) Tj T* ET +BT 1 0 0 1 0 14 Tm .647262 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you are a fan of lazyness, you can still have it by setting the ) Tj /F3 10 Tf (eager ) Tj /F1 10 Tf (flag to ) Tj /F3 10 Tf (False) Tj /F1 10 Tf (, as in the following) Tj T* 0 Tw (example:) Tj T* ET Q Q q @@ -7599,7 +7589,7 @@ n -6 -6 468.6898 36 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 17.71 Tm /F3 10 Tf 12 TL (for line in plac.call\(main, args, eager=False\):) Tj T* ( print\(line\)) Tj T* ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL (for line in plac.call\(main, args, eager=False\):) Tj T* ( print\(line\)) Tj T* ET Q Q Q @@ -7608,19 +7598,19 @@ Q q 1 0 0 1 62.69291 564.6236 cm q -BT 1 0 0 1 0 16.82 Tm 1.35528 Tw 12 TL /F1 10 Tf 0 0 0 rg (If ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (returns a generator object this example will print each line as soon as available, whereas the) Tj T* 0 Tw (default behaviour is to print all the lines together and the end of the computation.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.35528 Tw 12 TL /F1 10 Tf 0 0 0 rg (If ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (returns a generator object this example will print each line as soon as available, whereas the) Tj T* 0 Tw (default behaviour is to print all the lines together and the end of the computation.) Tj T* ET Q Q q 1 0 0 1 62.69291 534.6236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (A realistic example) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (A realistic example) Tj T* ET Q Q q 1 0 0 1 62.69291 492.6236 cm q -BT 1 0 0 1 0 28.82 Tm 1.234488 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here is a more realistic script using most of the features of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (to run SQL queries on a database by) Tj T* 0 Tw .930697 Tw (relying on ) Tj 0 0 .501961 rg (SQLAlchemy) Tj 0 0 0 rg (. Notice the usage of the ) Tj /F3 10 Tf (type ) Tj /F1 10 Tf (feature to automagically convert a SQLAlchemy) Tj T* 0 Tw (connection string into a ) Tj 0 0 .501961 rg (SqlSoup ) Tj 0 0 0 rg (object:) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.234488 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here is a more realistic script using most of the features of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (to run SQL queries on a database by) Tj T* 0 Tw .930697 Tw (relying on ) Tj 0 0 .501961 rg (SQLAlchemy) Tj 0 0 0 rg (. Notice the usage of the ) Tj /F3 10 Tf (type ) Tj /F1 10 Tf (feature to automagically convert a SQLAlchemy) Tj T* 0 Tw (connection string into a ) Tj 0 0 .501961 rg (SqlSoup ) Tj 0 0 0 rg (object:) Tj T* ET Q Q q @@ -7638,7 +7628,7 @@ n -6 -6 468.6898 360 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 341.71 Tm /F3 10 Tf 12 TL (# dbcli.py) Tj T* (import plac) Tj T* (from sqlalchemy.ext.sqlsoup import SqlSoup) Tj T* T* (@plac.annotations\() Tj T* ( db=\("Connection string", 'positional', None, SqlSoup\),) Tj T* ( header=\("Header", 'flag', 'H'\),) Tj T* ( sqlcmd=\("SQL command", 'option', 'c', str, None, "SQL"\),) Tj T* ( delimiter=\("Column separator", 'option', 'd'\),) Tj T* ( scripts="SQL scripts",) Tj T* ( \)) Tj T* (def main\(db, header, sqlcmd, delimiter="|", *scripts\):) Tj T* ( "A script to run queries and SQL scripts on a database") Tj T* ( yield 'Working on %s' % db.bind.url) Tj T* T* ( if sqlcmd:) Tj T* ( result = db.bind.execute\(sqlcmd\)) Tj T* ( if header: # print the header) Tj T* ( yield delimiter.join\(result.keys\(\)\)) Tj T* ( for row in result: # print the rows) Tj T* ( yield delimiter.join\(map\(str, row\)\)) Tj T* T* ( for script in scripts:) Tj T* ( db.bind.execute\(file\(script\).read\(\)\)) Tj T* ( yield 'executed %s' % script) Tj T* T* (if __name__ == '__main__':) Tj T* ( for output in plac.call\(main\):) Tj T* ( print\(output\)) Tj T* ET +BT 1 0 0 1 0 338 Tm /F3 10 Tf 12 TL (# dbcli.py) Tj T* (import plac) Tj T* (from sqlalchemy.ext.sqlsoup import SqlSoup) Tj T* T* (@plac.annotations\() Tj T* ( db=\("Connection string", 'positional', None, SqlSoup\),) Tj T* ( header=\("Header", 'flag', 'H'\),) Tj T* ( sqlcmd=\("SQL command", 'option', 'c', str, None, "SQL"\),) Tj T* ( delimiter=\("Column separator", 'option', 'd'\),) Tj T* ( scripts="SQL scripts",) Tj T* ( \)) Tj T* (def main\(db, header, sqlcmd, delimiter="|", *scripts\):) Tj T* ( "A script to run queries and SQL scripts on a database") Tj T* ( yield 'Working on %s' % db.bind.url) Tj T* T* ( if sqlcmd:) Tj T* ( result = db.bind.execute\(sqlcmd\)) Tj T* ( if header: # print the header) Tj T* ( yield delimiter.join\(result.keys\(\)\)) Tj T* ( for row in result: # print the rows) Tj T* ( yield delimiter.join\(map\(str, row\)\)) Tj T* T* ( for script in scripts:) Tj T* ( db.bind.execute\(file\(script\).read\(\)\)) Tj T* ( yield 'executed %s' % script) Tj T* T* (if __name__ == '__main__':) Tj T* ( for output in plac.call\(main\):) Tj T* ( print\(output\)) Tj T* ET Q Q Q @@ -7647,37 +7637,36 @@ Q q 1 0 0 1 62.69291 91.42362 cm q -BT 1 0 0 1 0 16.82 Tm .049987 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can see the ) Tj /F4 10 Tf (yield-is-print ) Tj /F1 10 Tf (pattern here: instead of using ) Tj /F3 10 Tf (print ) Tj /F1 10 Tf (in the main function, I use ) Tj /F3 10 Tf (yield) Tj /F1 10 Tf (, and ) Tj T* 0 Tw 3.55061 Tw (I perform the print in the ) Tj /F3 10 Tf (__main__ ) Tj /F1 10 Tf (block. The advantage of the pattern is that tests invoking) Tj T* 0 Tw ET +BT 1 0 0 1 0 14 Tm .049987 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can see the ) Tj /F4 10 Tf (yield-is-print ) Tj /F1 10 Tf (pattern here: instead of using ) Tj /F3 10 Tf (print ) Tj /F1 10 Tf (in the main function, I use ) Tj /F3 10 Tf (yield) Tj /F1 10 Tf (, and ) Tj T* 0 Tw 3.55061 Tw (I perform the print in the ) Tj /F3 10 Tf (__main__ ) Tj /F1 10 Tf (block. The advantage of the pattern is that tests invoking) Tj T* 0 Tw ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (12) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (12) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R349': class PDFStream 349 0 obj % page stream -<< /Length 3562 >> +<< /Length 3533 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 741.0236 cm q -BT 1 0 0 1 0 16.82 Tm .52936 Tw 12 TL /F3 10 Tf 0 0 0 rg (plac.call ) Tj /F1 10 Tf (and checking the result become trivial: had I performed the printing in the main function, the) Tj T* 0 Tw (test would have involved an ugly hack like redirecting ) Tj /F3 10 Tf (sys.stdout ) Tj /F1 10 Tf (to a ) Tj /F3 10 Tf (StringIO ) Tj /F1 10 Tf (object.) Tj T* ET +BT 1 0 0 1 0 14 Tm .52936 Tw 12 TL /F3 10 Tf 0 0 0 rg (plac.call ) Tj /F1 10 Tf (and checking the result become trivial: had I performed the printing in the main function, the) Tj T* 0 Tw (test would have involved an ugly hack like redirecting ) Tj /F3 10 Tf (sys.stdout ) Tj /F1 10 Tf (to a ) Tj /F3 10 Tf (StringIO ) Tj /F1 10 Tf (object.) Tj T* ET Q Q q 1 0 0 1 62.69291 723.0236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Here is the usage message:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is the usage message:) Tj T* ET Q Q q @@ -7695,7 +7684,7 @@ n -6 -6 468.6898 168 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 149.71 Tm /F3 10 Tf 12 TL (usage: dbcli.py [-h] [-H] [-c SQL] [-d |] db [scripts [scripts ...]]) Tj T* T* (A script to run queries and SQL scripts on a database) Tj T* T* (positional arguments:) Tj T* ( db Connection string) Tj T* ( scripts SQL scripts) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -H, --header Header) Tj T* ( -c SQL, --sqlcmd SQL SQL command) Tj T* ( -d |, --delimiter | Column separator) Tj T* ET +BT 1 0 0 1 0 146 Tm /F3 10 Tf 12 TL (usage: dbcli.py [-h] [-H] [-c SQL] [-d |] db [scripts [scripts ...]]) Tj T* T* (A script to run queries and SQL scripts on a database) Tj T* T* (positional arguments:) Tj T* ( db Connection string) Tj T* ( scripts SQL scripts) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -H, --header Header) Tj T* ( -c SQL, --sqlcmd SQL SQL command) Tj T* ( -d |, --delimiter | Column separator) Tj T* ET Q Q Q @@ -7705,19 +7694,19 @@ q 1 0 0 1 62.69291 525.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (You can check for yourself that the script works.) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (You can check for yourself that the script works.) Tj T* ET Q Q q 1 0 0 1 62.69291 495.8236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Keyword arguments) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Keyword arguments) Tj T* ET Q Q q 1 0 0 1 62.69291 453.8236 cm q -BT 1 0 0 1 0 28.82 Tm 1.831984 Tw 12 TL /F1 10 Tf 0 0 0 rg (Starting from release 0.4, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (supports keyword arguments. In practice that means that if your main) Tj T* 0 Tw 2.099213 Tw (function has keyword arguments, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (treats specially arguments of the form ) Tj /F3 10 Tf ("name=value" ) Tj /F1 10 Tf (in the) Tj T* 0 Tw (command line. Here is an example:) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.831984 Tw 12 TL /F1 10 Tf 0 0 0 rg (Starting from release 0.4, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (supports keyword arguments. In practice that means that if your main) Tj T* 0 Tw 2.099213 Tw (function has keyword arguments, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (treats specially arguments of the form ) Tj /F3 10 Tf ("name=value" ) Tj /F1 10 Tf (in the) Tj T* 0 Tw (command line. Here is an example:) Tj T* ET Q Q q @@ -7735,7 +7724,7 @@ n -6 -6 468.6898 228 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 209.71 Tm /F3 10 Tf 12 TL (# example12.py) Tj T* (import plac) Tj T* T* (@plac.annotations\() Tj T* ( opt=\('some option', 'option'\),) Tj T* ( args='default arguments',) Tj T* ( kw='keyword arguments'\)) Tj T* (def main\(opt, *args, **kw\):) Tj T* ( if opt:) Tj T* ( yield 'opt=%s' % opt) Tj T* ( if args:) Tj T* ( yield 'args=%s' % str\(args\)) Tj T* ( if kw:) Tj T* ( yield 'kw=%s' % kw) Tj T* T* (if __name__ == '__main__':) Tj T* ( for output in plac.call\(main\):) Tj T* ( print\(output\)) Tj T* ET +BT 1 0 0 1 0 206 Tm /F3 10 Tf 12 TL (# example12.py) Tj T* (import plac) Tj T* T* (@plac.annotations\() Tj T* ( opt=\('some option', 'option'\),) Tj T* ( args='default arguments',) Tj T* ( kw='keyword arguments'\)) Tj T* (def main\(opt, *args, **kw\):) Tj T* ( if opt:) Tj T* ( yield 'opt=%s' % opt) Tj T* ( if args:) Tj T* ( yield 'args=%s' % str\(args\)) Tj T* ( if kw:) Tj T* ( yield 'kw=%s' % kw) Tj T* T* (if __name__ == '__main__':) Tj T* ( for output in plac.call\(main\):) Tj T* ( print\(output\)) Tj T* ET Q Q Q @@ -7745,7 +7734,7 @@ q 1 0 0 1 62.69291 196.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Here is the generated usage message:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is the generated usage message:) Tj T* ET Q Q q @@ -7763,7 +7752,7 @@ n -6 -6 468.6898 96 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 77.71 Tm /F3 10 Tf 12 TL (usage: example12.py [-h] [-opt OPT] [args [args ...]] [kw [kw ...]]) Tj T* T* (positional arguments:) Tj T* ( args default arguments) Tj T* ( kw keyword arguments) Tj T* T* (optional arguments:) Tj T* ET +BT 1 0 0 1 0 74 Tm /F3 10 Tf 12 TL (usage: example12.py [-h] [-opt OPT] [args [args ...]] [kw [kw ...]]) Tj T* T* (positional arguments:) Tj T* ( args default arguments) Tj T* ( kw keyword arguments) Tj T* T* (optional arguments:) Tj T* ET Q Q Q @@ -7773,19 +7762,18 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (13) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (13) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R350': class PDFStream 350 0 obj % page stream -<< /Length 4297 >> +<< /Length 4268 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 727.8236 cm q @@ -7801,7 +7789,7 @@ n -6 -6 468.6898 36 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 17.71 Tm /F3 10 Tf 12 TL ( -h, --help show this help message and exit) Tj T* ( -opt OPT some option) Tj T* ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL ( -h, --help show this help message and exit) Tj T* ( -opt OPT some option) Tj T* ET Q Q Q @@ -7811,7 +7799,7 @@ q 1 0 0 1 62.69291 707.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Here is how you call the script:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is how you call the script:) Tj T* ET Q Q q @@ -7829,7 +7817,7 @@ n -6 -6 468.6898 60 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 41.71 Tm /F3 10 Tf 12 TL ($ python example12.py -o X a1 a2 name=value) Tj T* (opt=X) Tj T* (args=\('a1', 'a2'\)) Tj T* (kw={'name': 'value'}) Tj T* ET +BT 1 0 0 1 0 38 Tm /F3 10 Tf 12 TL ($ python example12.py -o X a1 a2 name=value) Tj T* (opt=X) Tj T* (args=\('a1', 'a2'\)) Tj T* (kw={'name': 'value'}) Tj T* ET Q Q Q @@ -7838,7 +7826,7 @@ Q q 1 0 0 1 62.69291 606.6236 cm q -BT 1 0 0 1 0 16.82 Tm 2.133735 Tw 12 TL /F1 10 Tf 0 0 0 rg (When using keyword arguments, one must be careful to use names which are not alreay taken; for) Tj T* 0 Tw (instance in this examples the name ) Tj /F3 10 Tf (opt ) Tj /F1 10 Tf (is taken:) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.133735 Tw 12 TL /F1 10 Tf 0 0 0 rg (When using keyword arguments, one must be careful to use names which are not alreay taken; for) Tj T* 0 Tw (instance in this examples the name ) Tj /F3 10 Tf (opt ) Tj /F1 10 Tf (is taken:) Tj T* ET Q Q q @@ -7856,7 +7844,7 @@ n -6 -6 468.6898 48 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 29.71 Tm /F3 10 Tf 12 TL ($ python example12.py 1 2 kw1=1 kw2=2 opt=0) Tj T* (usage: example12.py [-h] [-o OPT] [args [args ...]] [kw [kw ...]]) Tj T* (example12.py: error: colliding keyword arguments: opt) Tj T* ET +BT 1 0 0 1 0 26 Tm /F3 10 Tf 12 TL ($ python example12.py 1 2 kw1=1 kw2=2 opt=0) Tj T* (usage: example12.py [-h] [-o OPT] [args [args ...]] [kw [kw ...]]) Tj T* (example12.py: error: colliding keyword arguments: opt) Tj T* ET Q Q Q @@ -7866,19 +7854,19 @@ q 1 0 0 1 62.69291 505.4236 cm q 0 0 0 rg -BT 1 0 0 1 0 28.82 Tm /F1 10 Tf 12 TL 1.024104 Tw (The names taken are the names of the flags, of the options, and of the positional arguments, excepted) Tj T* 0 Tw .60561 Tw (varargs and keywords. This limitation is a consequence of the way the argument names are managed in) Tj T* 0 Tw (function calls by the Python language.) Tj T* ET +BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL 1.024104 Tw (The names taken are the names of the flags, of the options, and of the positional arguments, excepted) Tj T* 0 Tw .60561 Tw (varargs and keywords. This limitation is a consequence of the way the argument names are managed in) Tj T* 0 Tw (function calls by the Python language.) Tj T* ET Q Q q 1 0 0 1 62.69291 475.4236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Final example: a shelve interface) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Final example: a shelve interface) Tj T* ET Q Q q 1 0 0 1 62.69291 433.4236 cm q -BT 1 0 0 1 0 28.82 Tm .603516 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here is a less trivial example for the keyword arguments feature. The use case is the following: suppose) Tj T* 0 Tw .82881 Tw (we have stored the configuration parameters of a given application into a Python shelve and we need a) Tj T* 0 Tw (command-line tool to edit the shelve. A possible implementation using ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (could be the following:) Tj T* ET +BT 1 0 0 1 0 26 Tm .603516 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here is a less trivial example for the keyword arguments feature. The use case is the following: suppose) Tj T* 0 Tw .82881 Tw (we have stored the configuration parameters of a given application into a Python shelve and we need a) Tj T* 0 Tw (command-line tool to edit the shelve. A possible implementation using ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (could be the following:) Tj T* ET Q Q q @@ -7895,7 +7883,7 @@ q n -6 -6 492 324 re B* Q q -BT 1 0 0 1 0 305.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (# ishelve.py) Tj T* (import os, shelve, plac) Tj T* T* (DEFAULT_SHELVE = os.path.expanduser\('~/conf.shelve'\)) Tj T* T* (@plac.annotations\() Tj T* ( help=\('show help', 'flag'\),) Tj T* ( showall=\('show all parameters in the shelve', 'flag'\),) Tj T* ( clear=\('clear the shelve', 'flag'\),) Tj T* ( delete=\('delete an element', 'option'\),) Tj T* ( filename=\('filename of the shelve', 'option'\),) Tj T* ( params='names of the parameters in the shelve',) Tj T* ( setters='setters param=value'\)) Tj T* (def main\(help, showall, clear, delete, filename=DEFAULT_SHELVE,) Tj T* ( *params, **setters\):) Tj T* ( "A simple interface to a shelve. Use .help to see the available commands.") Tj T* ( sh = shelve.open\(filename\)) Tj T* ( try:) Tj T* ( if not any\([help, showall, clear, delete, params, setters]\):) Tj T* ( yield 'no arguments passed, use .help to see the available commands') Tj T* ( elif help: # custom help) Tj T* ( yield 'Commands: .help, .showall, .clear, .delete') Tj T* ( yield ') Tj (<) Tj (param) Tj (>) Tj ( ...') Tj T* ( yield ') Tj (<) Tj (param=value) Tj (>) Tj ( ...') Tj T* ( elif showall:) Tj T* ( for param, name in sh.items\(\):) Tj T* ET +BT 1 0 0 1 0 302 Tm 12 TL /F3 10 Tf 0 0 0 rg (# ishelve.py) Tj T* (import os, shelve, plac) Tj T* T* (DEFAULT_SHELVE = os.path.expanduser\('~/conf.shelve'\)) Tj T* T* (@plac.annotations\() Tj T* ( help=\('show help', 'flag'\),) Tj T* ( showall=\('show all parameters in the shelve', 'flag'\),) Tj T* ( clear=\('clear the shelve', 'flag'\),) Tj T* ( delete=\('delete an element', 'option'\),) Tj T* ( filename=\('filename of the shelve', 'option'\),) Tj T* ( params='names of the parameters in the shelve',) Tj T* ( setters='setters param=value'\)) Tj T* (def main\(help, showall, clear, delete, filename=DEFAULT_SHELVE,) Tj T* ( *params, **setters\):) Tj T* ( "A simple interface to a shelve. Use .help to see the available commands.") Tj T* ( sh = shelve.open\(filename\)) Tj T* ( try:) Tj T* ( if not any\([help, showall, clear, delete, params, setters]\):) Tj T* ( yield 'no arguments passed, use .help to see the available commands') Tj T* ( elif help: # custom help) Tj T* ( yield 'Commands: .help, .showall, .clear, .delete') Tj T* ( yield ') Tj (<) Tj (param) Tj (>) Tj ( ...') Tj T* ( yield ') Tj (<) Tj (param=value) Tj (>) Tj ( ...') Tj T* ( elif showall:) Tj T* ( for param, name in sh.items\(\):) Tj T* ET Q Q Q @@ -7905,19 +7893,18 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (14) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (14) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R351': class PDFStream 351 0 obj % page stream -<< /Length 6595 >> +<< /Length 6251 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 415.8236 cm q @@ -7932,7 +7919,7 @@ q n -6 -6 468.6898 348 re B* Q q -BT 1 0 0 1 0 329.71 Tm 12 TL /F3 10 Tf 0 0 0 rg ( yield '%s=%s' % \(param, name\)) Tj T* ( elif clear:) Tj T* ( sh.clear\(\)) Tj T* ( yield 'cleared the shelve') Tj T* ( elif delete:) Tj T* ( try:) Tj T* ( del sh[delete]) Tj T* ( except KeyError:) Tj T* ( yield '%s: not found' % delete) Tj T* ( else:) Tj T* ( yield 'deleted %s' % delete) Tj T* ( for param in params:) Tj T* ( try:) Tj T* ( yield sh[param]) Tj T* ( except KeyError:) Tj T* ( yield '%s: not found' % param ) Tj T* ( for param, value in setters.items\(\):) Tj T* ( sh[param] = value) Tj T* ( yield 'setting %s=%s' % \(param, value\)) Tj T* ( finally:) Tj T* ( sh.close\(\)) Tj T* T* (main.add_help = False # there is a custom help, remove the default one) Tj T* (main.prefix_chars = '.' # use dot-prefixed commands) Tj T* T* (if __name__ == '__main__':) Tj T* ( for output in plac.call\(main\):) Tj T* ( print\(output\)) Tj T* ET +BT 1 0 0 1 0 326 Tm 12 TL /F3 10 Tf 0 0 0 rg ( yield '%s=%s' % \(param, name\)) Tj T* ( elif clear:) Tj T* ( sh.clear\(\)) Tj T* ( yield 'cleared the shelve') Tj T* ( elif delete:) Tj T* ( try:) Tj T* ( del sh[delete]) Tj T* ( except KeyError:) Tj T* ( yield '%s: not found' % delete) Tj T* ( else:) Tj T* ( yield 'deleted %s' % delete) Tj T* ( for param in params:) Tj T* ( try:) Tj T* ( yield sh[param]) Tj T* ( except KeyError:) Tj T* ( yield '%s: not found' % param ) Tj T* ( for param, value in setters.items\(\):) Tj T* ( sh[param] = value) Tj T* ( yield 'setting %s=%s' % \(param, value\)) Tj T* ( finally:) Tj T* ( sh.close\(\)) Tj T* T* (main.add_help = False # there is a custom help, remove the default one) Tj T* (main.prefix_chars = '.' # use dot-prefixed commands) Tj T* T* (if __name__ == '__main__':) Tj T* ( for output in plac.call\(main\):) Tj T* ( print\(output\)) Tj T* ET Q Q Q @@ -7942,7 +7929,7 @@ q 1 0 0 1 62.69291 395.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (A few notes are in order:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (A few notes are in order:) Tj T* ET Q Q q @@ -7952,20 +7939,20 @@ q 1 0 0 1 62.69291 389.8236 cm Q q -1 0 0 1 62.69291 359.8236 cm +1 0 0 1 62.69291 365.8236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 15 cm +1 0 0 1 6 9 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 16.82 Tm 2.075318 Tw 12 TL /F1 10 Tf 0 0 0 rg (I have disabled the ordinary help provided by ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (and I have implemented a custom help) Tj T* 0 Tw (command.) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.075318 Tw 12 TL /F1 10 Tf 0 0 0 rg (I have disabled the ordinary help provided by ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (and I have implemented a custom help) Tj T* 0 Tw (command.) Tj T* ET Q Q q @@ -7975,24 +7962,21 @@ q 1 0 0 1 62.69291 359.8236 cm Q q -1 0 0 1 62.69291 359.8236 cm -Q -q -1 0 0 1 62.69291 341.8236 cm +1 0 0 1 62.69291 347.8236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 3 cm +1 0 0 1 6 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (I have changed the prefix character used to recognize the options to a dot.) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (I have changed the prefix character used to recognize the options to a dot.) Tj T* ET Q Q q @@ -8002,23 +7986,20 @@ q 1 0 0 1 62.69291 341.8236 cm Q q -1 0 0 1 62.69291 341.8236 cm -Q -q -1 0 0 1 62.69291 311.8236 cm +1 0 0 1 62.69291 317.8236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 15 cm +1 0 0 1 6 9 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 16.82 Tm .864985 Tw 12 TL /F1 10 Tf 0 0 0 rg (Keyword arguments recognition \(in the ) Tj /F3 10 Tf (**setters) Tj /F1 10 Tf (\) is used to make it possible to store a value in) Tj T* 0 Tw (the shelve with the syntax ) Tj /F3 10 Tf (param_name=param_value) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 14 Tm .864985 Tw 12 TL /F1 10 Tf 0 0 0 rg (Keyword arguments recognition \(in the ) Tj /F3 10 Tf (**setters) Tj /F1 10 Tf (\) is used to make it possible to store a value in) Tj T* 0 Tw (the shelve with the syntax ) Tj /F3 10 Tf (param_name=param_value) Tj /F1 10 Tf (.) Tj T* ET Q Q q @@ -8028,23 +8009,20 @@ q 1 0 0 1 62.69291 311.8236 cm Q q -1 0 0 1 62.69291 311.8236 cm -Q -q -1 0 0 1 62.69291 281.8236 cm +1 0 0 1 62.69291 287.8236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 15 cm +1 0 0 1 6 9 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (4.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (4.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 16.82 Tm .649318 Tw 12 TL /F3 10 Tf 0 0 0 rg (*params ) Tj /F1 10 Tf (are used to retrieve parameters from the shelve and some error checking is performed in) Tj T* 0 Tw (the case of missing parameters) Tj T* ET +BT 1 0 0 1 0 14 Tm .649318 Tw 12 TL /F3 10 Tf 0 0 0 rg (*params ) Tj /F1 10 Tf (are used to retrieve parameters from the shelve and some error checking is performed in) Tj T* 0 Tw (the case of missing parameters) Tj T* ET Q Q q @@ -8054,23 +8032,20 @@ q 1 0 0 1 62.69291 281.8236 cm Q q -1 0 0 1 62.69291 281.8236 cm -Q -q -1 0 0 1 62.69291 263.8236 cm +1 0 0 1 62.69291 269.8236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 3 cm +1 0 0 1 6 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (5.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (5.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (A command to clear the shelve is implemented as a flag \() Tj /F3 10 Tf (.clear) Tj /F1 10 Tf (\).) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (A command to clear the shelve is implemented as a flag \() Tj /F3 10 Tf (.clear) Tj /F1 10 Tf (\).) Tj T* ET Q Q q @@ -8080,23 +8055,20 @@ q 1 0 0 1 62.69291 263.8236 cm Q q -1 0 0 1 62.69291 263.8236 cm -Q -q -1 0 0 1 62.69291 245.8236 cm +1 0 0 1 62.69291 251.8236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 3 cm +1 0 0 1 6 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (6.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (6.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (A command to delete a given parameter is implemented as an option \() Tj /F3 10 Tf (.delete) Tj /F1 10 Tf (\).) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (A command to delete a given parameter is implemented as an option \() Tj /F3 10 Tf (.delete) Tj /F1 10 Tf (\).) Tj T* ET Q Q q @@ -8106,23 +8078,20 @@ q 1 0 0 1 62.69291 245.8236 cm Q q -1 0 0 1 62.69291 245.8236 cm -Q -q -1 0 0 1 62.69291 227.8236 cm +1 0 0 1 62.69291 233.8236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 3 cm +1 0 0 1 6 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (7.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (7.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (There is an option with default \() Tj /F3 10 Tf (.filename=conf.shelve) Tj /F1 10 Tf (\) to store the filename of the shelve.) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (There is an option with default \() Tj /F3 10 Tf (.filename=conf.shelve) Tj /F1 10 Tf (\) to store the filename of the shelve.) Tj T* ET Q Q q @@ -8132,42 +8101,36 @@ q 1 0 0 1 62.69291 227.8236 cm Q q -1 0 0 1 62.69291 227.8236 cm -Q -q -1 0 0 1 62.69291 185.8236 cm +1 0 0 1 62.69291 191.8236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 27 cm +1 0 0 1 6 21 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (8.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (8.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 28.82 Tm 1.001984 Tw 12 TL /F1 10 Tf 0 0 0 rg (All things considered, the code looks like a poor man object oriented interface implemented with a) Tj T* 0 Tw 1.345251 Tw (chain of elifs instead of methods. Of course, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (can do better than that, but let me start from a) Tj T* 0 Tw (low-level approach first.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.001984 Tw 12 TL /F1 10 Tf 0 0 0 rg (All things considered, the code looks like a poor man object oriented interface implemented with a) Tj T* 0 Tw 1.345251 Tw (chain of elifs instead of methods. Of course, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (can do better than that, but let me start from a) Tj T* 0 Tw (low-level approach first.) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 185.8236 cm -Q -q -1 0 0 1 62.69291 185.8236 cm +1 0 0 1 62.69291 191.8236 cm Q q -1 0 0 1 62.69291 167.8236 cm +1 0 0 1 62.69291 173.8236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (If you run ) Tj /F3 10 Tf (ishelve.py ) Tj /F1 10 Tf (without arguments you get the following message:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If you run ) Tj /F3 10 Tf (ishelve.py ) Tj /F1 10 Tf (without arguments you get the following message:) Tj T* ET Q Q q -1 0 0 1 62.69291 122.6236 cm +1 0 0 1 62.69291 128.6236 cm q q 1 0 0 1 0 0 cm @@ -8181,35 +8144,34 @@ n -6 -6 468.6898 36 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 17.71 Tm /F3 10 Tf 12 TL ($ python ishelve.py) Tj T* (no arguments passed, use .help to see the available commands) Tj T* ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL ($ python ishelve.py) Tj T* (no arguments passed, use .help to see the available commands) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 102.6236 cm +1 0 0 1 62.69291 108.6236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (If you run ) Tj /F3 10 Tf (ishelve.py ) Tj /F1 10 Tf (with the option ) Tj /F3 10 Tf (.h ) Tj /F1 10 Tf (\(or any abbreviation of ) Tj /F3 10 Tf (.help) Tj /F1 10 Tf (\) you get:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If you run ) Tj /F3 10 Tf (ishelve.py ) Tj /F1 10 Tf (with the option ) Tj /F3 10 Tf (.h ) Tj /F1 10 Tf (\(or any abbreviation of ) Tj /F3 10 Tf (.help) Tj /F1 10 Tf (\) you get:) Tj T* ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (15) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (15) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R352': class PDFStream 352 0 obj % page stream -<< /Length 6264 >> +<< /Length 6569 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 703.8236 cm q @@ -8224,7 +8186,7 @@ q n -6 -6 468.6898 60 re B* Q q -BT 1 0 0 1 0 41.71 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ python ishelve.py .h) Tj T* (Commands: .help, .showall, .clear, .delete) Tj T* (<) Tj (param) Tj (>) Tj ( ...) Tj T* (<) Tj (param=value) Tj (>) Tj ( ...) Tj T* ET +BT 1 0 0 1 0 38 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ python ishelve.py .h) Tj T* (Commands: .help, .showall, .clear, .delete) Tj T* (<) Tj (param) Tj (>) Tj ( ...) Tj T* (<) Tj (param=value) Tj (>) Tj ( ...) Tj T* ET Q Q Q @@ -8234,7 +8196,7 @@ q 1 0 0 1 62.69291 683.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (You can check by hand that the tool work:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (You can check by hand that the tool work:) Tj T* ET Q Q q @@ -8252,7 +8214,7 @@ n -6 -6 468.6898 240 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 221.71 Tm /F3 10 Tf 12 TL ($ python ishelve.py .clear # start from an empty shelve) Tj T* (cleared the shelve) Tj T* ($ python ishelve.py a=1 b=2) Tj T* (setting a=1) Tj T* (setting b=2) Tj T* ($ python ishelve.py .showall) Tj T* (b=2) Tj T* (a=1) Tj T* ($ python ishelve.py .del b # abbreviation for .delete) Tj T* (deleted b) Tj T* ($ python ishelve.py a) Tj T* (1) Tj T* ($ python ishelve.py b) Tj T* (b: not found) Tj T* ($ python ishelve.py .cler # mispelled command) Tj T* (usage: ishelve.py [.help] [.showall] [.clear] [.delete DELETE]) Tj T* ( [.filename /home/micheles/conf.shelve]) Tj T* ( [params [params ...]] [setters [setters ...]]) Tj T* (ishelve.py: error: unrecognized arguments: .cler) Tj T* ET +BT 1 0 0 1 0 218 Tm /F3 10 Tf 12 TL ($ python ishelve.py .clear # start from an empty shelve) Tj T* (cleared the shelve) Tj T* ($ python ishelve.py a=1 b=2) Tj T* (setting a=1) Tj T* (setting b=2) Tj T* ($ python ishelve.py .showall) Tj T* (b=2) Tj T* (a=1) Tj T* ($ python ishelve.py .del b # abbreviation for .delete) Tj T* (deleted b) Tj T* ($ python ishelve.py a) Tj T* (1) Tj T* ($ python ishelve.py b) Tj T* (b: not found) Tj T* ($ python ishelve.py .cler # mispelled command) Tj T* (usage: ishelve.py [.help] [.showall] [.clear] [.delete DELETE]) Tj T* ( [.filename /home/micheles/conf.shelve]) Tj T* ( [params [params ...]] [setters [setters ...]]) Tj T* (ishelve.py: error: unrecognized arguments: .cler) Tj T* ET Q Q Q @@ -8261,13 +8223,13 @@ Q q 1 0 0 1 62.69291 404.6236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (plac vs argparse) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (plac vs argparse) Tj T* ET Q Q q 1 0 0 1 62.69291 362.6236 cm q -BT 1 0 0 1 0 28.82 Tm 1.065988 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is opinionated and by design it does not try to make available all of the features of ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (in an) Tj T* 0 Tw .177126 Tw (easy way. In particular you should be aware of the following limitations/differences \(the following assumes) Tj T* 0 Tw (knowledge of ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (\):) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.065988 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is opinionated and by design it does not try to make available all of the features of ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (in an) Tj T* 0 Tw .177126 Tw (easy way. In particular you should be aware of the following limitations/differences \(the following assumes) Tj T* 0 Tw (knowledge of ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (\):) Tj T* ET Q Q q @@ -8277,20 +8239,20 @@ q 1 0 0 1 62.69291 356.6236 cm Q q -1 0 0 1 62.69291 278.6236 cm +1 0 0 1 62.69291 284.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 63 cm +1 0 0 1 6 57 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 64.82 Tm 2.69784 Tw 12 TL /F1 10 Tf 0 0 0 rg (plac does not support the destination concept: the destination coincides with the name of the) Tj T* 0 Tw .359983 Tw (argument, always. This restriction has some drawbacks. For instance, suppose you want to define a) Tj T* 0 Tw 2.758651 Tw (long option called ) Tj /F3 10 Tf (--yield) Tj /F1 10 Tf (. In this case the destination would be ) Tj /F3 10 Tf (yield) Tj /F1 10 Tf (, which is a Python) Tj T* 0 Tw 1.181235 Tw (keyword, and since you cannot introduce an argument with that name in a function definition, it is) Tj T* 0 Tw 2.12528 Tw (impossible to implement it. Your choices are to change the name of the long option, or to use) Tj T* 0 Tw 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (with a suitable destination.) Tj T* ET +BT 1 0 0 1 0 62 Tm 2.69784 Tw 12 TL /F1 10 Tf 0 0 0 rg (plac does not support the destination concept: the destination coincides with the name of the) Tj T* 0 Tw .359983 Tw (argument, always. This restriction has some drawbacks. For instance, suppose you want to define a) Tj T* 0 Tw 2.758651 Tw (long option called ) Tj /F3 10 Tf (--yield) Tj /F1 10 Tf (. In this case the destination would be ) Tj /F3 10 Tf (yield) Tj /F1 10 Tf (, which is a Python) Tj T* 0 Tw 1.181235 Tw (keyword, and since you cannot introduce an argument with that name in a function definition, it is) Tj T* 0 Tw 2.12528 Tw (impossible to implement it. Your choices are to change the name of the long option, or to use) Tj T* 0 Tw 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (with a suitable destination.) Tj T* ET Q Q q @@ -8300,23 +8262,20 @@ q 1 0 0 1 62.69291 278.6236 cm Q q -1 0 0 1 62.69291 278.6236 cm -Q -q -1 0 0 1 62.69291 224.6236 cm +1 0 0 1 62.69291 230.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 39 cm +1 0 0 1 6 33 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 40.82 Tm 1.120751 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (does not support "required options". As the ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (documentation puts it: ) Tj /F4 10 Tf (Required options) Tj T* 0 Tw 1.075318 Tw (are generally considered bad form - normal users expect options to be optional. You should avoid) Tj T* 0 Tw .874269 Tw (the use of required options whenever possible. ) Tj /F1 10 Tf (Notice that since ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (supports them, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (can) Tj T* 0 Tw (manage them too, but not directly.) Tj T* ET +BT 1 0 0 1 0 38 Tm 1.120751 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (does not support "required options". As the ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (documentation puts it: ) Tj /F4 10 Tf (Required options) Tj T* 0 Tw 1.075318 Tw (are generally considered bad form - normal users expect options to be optional. You should avoid) Tj T* 0 Tw .874269 Tw (the use of required options whenever possible. ) Tj /F1 10 Tf (Notice that since ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (supports them, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (can) Tj T* 0 Tw (manage them too, but not directly.) Tj T* ET Q Q q @@ -8326,23 +8285,20 @@ q 1 0 0 1 62.69291 224.6236 cm Q q -1 0 0 1 62.69291 224.6236 cm -Q -q -1 0 0 1 62.69291 158.6236 cm +1 0 0 1 62.69291 164.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 51 cm +1 0 0 1 6 45 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 52.82 Tm 1.539982 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (supports only regular boolean flags. ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (has the ability to define generalized two-value) Tj T* 0 Tw .361751 Tw (flags with values different from ) Tj /F3 10 Tf (True ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (False) Tj /F1 10 Tf (. An earlier version of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (had this feature too, but) Tj T* 0 Tw .814985 Tw (since you can use options with two choices instead, and in any case the conversion from ) Tj /F3 10 Tf ({True,) Tj T* 0 Tw .901984 Tw (False} ) Tj /F1 10 Tf (to any couple of values can be trivially implemented with a ternary operator \() Tj /F3 10 Tf (value1 if) Tj T* 0 Tw (flag else value2) Tj /F1 10 Tf (\), I have removed it \(KISS rules!\).) Tj T* ET +BT 1 0 0 1 0 50 Tm 1.539982 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (supports only regular boolean flags. ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (has the ability to define generalized two-value) Tj T* 0 Tw .361751 Tw (flags with values different from ) Tj /F3 10 Tf (True ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (False) Tj /F1 10 Tf (. An earlier version of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (had this feature too, but) Tj T* 0 Tw .814985 Tw (since you can use options with two choices instead, and in any case the conversion from ) Tj /F3 10 Tf ({True,) Tj T* 0 Tw .901984 Tw (False} ) Tj /F1 10 Tf (to any couple of values can be trivially implemented with a ternary operator \() Tj /F3 10 Tf (value1 if) Tj T* 0 Tw (flag else value2) Tj /F1 10 Tf (\), I have removed it \(KISS rules!\).) Tj T* ET Q Q q @@ -8352,23 +8308,20 @@ q 1 0 0 1 62.69291 158.6236 cm Q q -1 0 0 1 62.69291 158.6236 cm -Q -q -1 0 0 1 62.69291 116.6236 cm +1 0 0 1 62.69291 122.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 27 cm +1 0 0 1 6 21 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 28.82 Tm 1.797126 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (does not support ) Tj /F3 10 Tf (nargs ) Tj /F1 10 Tf (options directly \(it uses them internally, though, to implement flag) Tj T* 0 Tw .90683 Tw (recognition\). The reason it that all the use cases of interest to me are covered by ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (and did not) Tj T* 0 Tw (feel the need to increase the learning curve by adding direct support for ) Tj /F3 10 Tf (nargs) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.797126 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (does not support ) Tj /F3 10 Tf (nargs ) Tj /F1 10 Tf (options directly \(it uses them internally, though, to implement flag) Tj T* 0 Tw .90683 Tw (recognition\). The reason it that all the use cases of interest to me are covered by ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (and did not) Tj T* 0 Tw (feel the need to increase the learning curve by adding direct support for ) Tj /F3 10 Tf (nargs) Tj /F1 10 Tf (.) Tj T* ET Q Q q @@ -8378,97 +8331,87 @@ q 1 0 0 1 62.69291 116.6236 cm Q q -1 0 0 1 62.69291 116.6236 cm -Q -q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (16) Tj T* -235.3849 0 Td ET -Q -Q - -endstream - -endobj -% 'R353': class PDFStream -353 0 obj -% page stream -<< /Length 7562 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 735.0236 cm +1 0 0 1 62.69291 92.62362 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 15 cm +1 0 0 1 6 9 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 16.82 Tm 2.111318 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (does support subparsers, but you must read the ) Tj 0 0 .501961 rg (advanced usage document ) Tj 0 0 0 rg (to see how it) Tj T* 0 Tw (works.) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.111318 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (does support subparsers, but you must read the ) Tj 0 0 .501961 rg (advanced usage document ) Tj 0 0 0 rg (to see how it) Tj T* 0 Tw (works.) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 735.0236 cm +1 0 0 1 62.69291 88.86614 cm Q q -1 0 0 1 62.69291 735.0236 cm +1 0 0 1 56.69291 56.69291 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (16) Tj T* -235.3849 0 Td ET Q +Q + +endstream +endobj +% 'R353': class PDFStream +353 0 obj +% page stream +<< /Length 7017 >> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 693.0236 cm +1 0 0 1 62.69291 729.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 27 cm +1 0 0 1 6 21 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 28.82 Tm 1.111751 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (does not support actions directly. This also looks like a feature too advanced for the goals of) Tj T* 0 Tw .406651 Tw 0 0 .501961 rg (plac) Tj 0 0 0 rg (. Notice however that the ability to define your own annotation objects \(again, see the ) Tj 0 0 .501961 rg (advanced) Tj T* 0 Tw (usage document) Tj 0 0 0 rg (\) may mitigate the need for custom actions.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.111751 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (does not support actions directly. This also looks like a feature too advanced for the goals of) Tj T* 0 Tw .406651 Tw 0 0 .501961 rg (plac) Tj 0 0 0 rg (. Notice however that the ability to define your own annotation objects \(again, see the ) Tj 0 0 .501961 rg (advanced) Tj T* 0 Tw (usage document) Tj 0 0 0 rg (\) may mitigate the need for custom actions.) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 693.0236 cm -Q -q -1 0 0 1 62.69291 693.0236 cm +1 0 0 1 62.69291 729.0236 cm Q q -1 0 0 1 62.69291 675.0236 cm +1 0 0 1 62.69291 711.0236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (can leverage directly on many ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (features.) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (can leverage directly on many ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (features.) Tj T* ET Q Q q -1 0 0 1 62.69291 633.0236 cm +1 0 0 1 62.69291 669.0236 cm q -BT 1 0 0 1 0 28.82 Tm 5.575697 Tw 12 TL /F1 10 Tf 0 0 0 rg (For instance, you can make invisible an argument in the usage message simply by using) Tj T* 0 Tw 1.435976 Tw /F3 10 Tf ('==SUPPRESS==' ) Tj /F1 10 Tf (as help string \(or ) Tj /F3 10 Tf (argparse.SUPPRESS) Tj /F1 10 Tf (\). Similarly, you can use ) Tj 0 0 .501961 rg (argparse.FileType) Tj T* 0 Tw 0 0 0 rg (directly.) Tj T* ET +BT 1 0 0 1 0 26 Tm 5.575697 Tw 12 TL /F1 10 Tf 0 0 0 rg (For instance, you can make invisible an argument in the usage message simply by using) Tj T* 0 Tw 1.435976 Tw /F3 10 Tf ('==SUPPRESS==' ) Tj /F1 10 Tf (as help string \(or ) Tj /F3 10 Tf (argparse.SUPPRESS) Tj /F1 10 Tf (\). Similarly, you can use ) Tj 0 0 .501961 rg (argparse.FileType) Tj T* 0 Tw 0 0 0 rg (directly.) Tj T* ET Q Q q -1 0 0 1 62.69291 579.0236 cm +1 0 0 1 62.69291 615.0236 cm q -BT 1 0 0 1 0 40.82 Tm 1.639213 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is also possible to pass options to the underlying ) Tj /F3 10 Tf (argparse.ArgumentParser ) Tj /F1 10 Tf (object \(currently it) Tj T* 0 Tw .285529 Tw (accepts the default arguments ) Tj /F3 10 Tf (description) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (epilog) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (prog) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (usage) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (add_help) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (argument_default) Tj /F1 10 Tf (,) Tj T* 0 Tw 1.439953 Tw /F3 10 Tf (parents) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (prefix_chars) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (fromfile_prefix_chars) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (conflict_handler) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (formatter_class) Tj /F1 10 Tf (\). It) Tj T* 0 Tw (is enough to set such attributes on the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (function. For instance) Tj T* ET +BT 1 0 0 1 0 38 Tm 1.639213 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is also possible to pass options to the underlying ) Tj /F3 10 Tf (argparse.ArgumentParser ) Tj /F1 10 Tf (object \(currently it) Tj T* 0 Tw .285529 Tw (accepts the default arguments ) Tj /F3 10 Tf (description) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (epilog) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (prog) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (usage) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (add_help) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (argument_default) Tj /F1 10 Tf (,) Tj T* 0 Tw 1.439953 Tw /F3 10 Tf (parents) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (prefix_chars) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (fromfile_prefix_chars) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (conflict_handler) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (formatter_class) Tj /F1 10 Tf (\). It) Tj T* 0 Tw (is enough to set such attributes on the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (function. For instance) Tj T* ET Q Q q -1 0 0 1 62.69291 509.8236 cm +1 0 0 1 62.69291 545.8236 cm q q 1 0 0 1 0 0 cm @@ -8482,33 +8425,33 @@ n -6 -6 468.6898 60 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 41.71 Tm /F3 10 Tf 12 TL (def main\(...\):) Tj T* ( pass) Tj T* T* (main.add_help = False) Tj T* ET +BT 1 0 0 1 0 38 Tm /F3 10 Tf 12 TL (def main\(...\):) Tj T* ( pass) Tj T* T* (main.add_help = False) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 465.8236 cm +1 0 0 1 62.69291 501.8236 cm q -BT 1 0 0 1 0 28.82 Tm .239318 Tw 12 TL /F1 10 Tf 0 0 0 rg (disables the recognition of the help flag ) Tj /F3 10 Tf (-h, --help) Tj /F1 10 Tf (. This mechanism does not look particularly elegant,) Tj T* 0 Tw .566988 Tw (but it works well enough. I assume that the typical user of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (will be happy with the defaults and would) Tj T* 0 Tw (not want to change them; still it is possible if she wants to.) Tj T* ET +BT 1 0 0 1 0 26 Tm .239318 Tw 12 TL /F1 10 Tf 0 0 0 rg (disables the recognition of the help flag ) Tj /F3 10 Tf (-h, --help) Tj /F1 10 Tf (. This mechanism does not look particularly elegant,) Tj T* 0 Tw .566988 Tw (but it works well enough. I assume that the typical user of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (will be happy with the defaults and would) Tj T* 0 Tw (not want to change them; still it is possible if she wants to.) Tj T* ET Q Q q -1 0 0 1 62.69291 435.8236 cm +1 0 0 1 62.69291 471.8236 cm q -BT 1 0 0 1 0 16.82 Tm 2.391235 Tw 12 TL /F1 10 Tf 0 0 0 rg (For instance, by setting the ) Tj /F3 10 Tf (description ) Tj /F1 10 Tf (attribute, it is possible to add a comment to the usage) Tj T* 0 Tw (message \(by default the docstring of the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (function is used as description\).) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.391235 Tw 12 TL /F1 10 Tf 0 0 0 rg (For instance, by setting the ) Tj /F3 10 Tf (description ) Tj /F1 10 Tf (attribute, it is possible to add a comment to the usage) Tj T* 0 Tw (message \(by default the docstring of the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (function is used as description\).) Tj T* ET Q Q q -1 0 0 1 62.69291 405.8236 cm +1 0 0 1 62.69291 441.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL .392619 Tw (It is also possible to change the option prefix; for instance if your script must run under Windows and you) Tj T* 0 Tw (want to use "/" as option prefix you can add the line:) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .392619 Tw (It is also possible to change the option prefix; for instance if your script must run under Windows and you) Tj T* 0 Tw (want to use "/" as option prefix you can add the line:) Tj T* ET Q Q q -1 0 0 1 62.69291 372.6236 cm +1 0 0 1 62.69291 408.6236 cm q q 1 0 0 1 0 0 cm @@ -8522,26 +8465,26 @@ n -6 -6 468.6898 24 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 5.71 Tm /F3 10 Tf 12 TL (main.prefix_chars='/-') Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (main.prefix_chars='/-') Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 328.6236 cm +1 0 0 1 62.69291 364.6236 cm q -BT 1 0 0 1 0 28.82 Tm .924198 Tw 12 TL /F1 10 Tf 0 0 0 rg (The first prefix char \() Tj /F3 10 Tf (/) Tj /F1 10 Tf (\) is used as the default for the recognition of options and flags; the second prefix) Tj T* 0 Tw .26832 Tw (char \() Tj /F3 10 Tf (-) Tj /F1 10 Tf (\) is kept to keep the ) Tj /F3 10 Tf (-h/--help ) Tj /F1 10 Tf (option working: however you can disable it and reimplement it, if) Tj T* 0 Tw (you like, as seen in the ) Tj /F3 10 Tf (ishelve ) Tj /F1 10 Tf (example.) Tj T* ET +BT 1 0 0 1 0 26 Tm .924198 Tw 12 TL /F1 10 Tf 0 0 0 rg (The first prefix char \() Tj /F3 10 Tf (/) Tj /F1 10 Tf (\) is used as the default for the recognition of options and flags; the second prefix) Tj T* 0 Tw .26832 Tw (char \() Tj /F3 10 Tf (-) Tj /F1 10 Tf (\) is kept to keep the ) Tj /F3 10 Tf (-h/--help ) Tj /F1 10 Tf (option working: however you can disable it and reimplement it, if) Tj T* 0 Tw (you like, as seen in the ) Tj /F3 10 Tf (ishelve ) Tj /F1 10 Tf (example.) Tj T* ET Q Q q -1 0 0 1 62.69291 298.6236 cm +1 0 0 1 62.69291 334.6236 cm q -BT 1 0 0 1 0 16.82 Tm 7.709147 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is possible to access directly the underlying ) Tj 0 0 .501961 rg (ArgumentParser ) Tj 0 0 0 rg (object, by invoking the) Tj T* 0 Tw /F3 10 Tf (plac.parser_from ) Tj /F1 10 Tf (utility function:) Tj T* ET +BT 1 0 0 1 0 14 Tm 7.709147 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is possible to access directly the underlying ) Tj 0 0 .501961 rg (ArgumentParser ) Tj 0 0 0 rg (object, by invoking the) Tj T* 0 Tw /F3 10 Tf (plac.parser_from ) Tj /F1 10 Tf (utility function:) Tj T* ET Q Q q -1 0 0 1 62.69291 205.4236 cm +1 0 0 1 62.69291 241.4236 cm q q 1 0 0 1 0 0 cm @@ -8554,340 +8497,320 @@ q n -6 -6 468.6898 84 re B* Q q -BT 1 0 0 1 0 65.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( import plac) Tj T* (>) Tj (>) Tj (>) Tj ( def main\(arg\):) Tj T* (... pass) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( print\(plac.parser_from\(main\)\) #doctest: +ELLIPSIS) Tj T* (ArgumentParser\(prog=...\)) Tj T* ET +BT 1 0 0 1 0 62 Tm 12 TL /F3 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( import plac) Tj T* (>) Tj (>) Tj (>) Tj ( def main\(arg\):) Tj T* (... pass) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( print\(plac.parser_from\(main\)\) #doctest: +ELLIPSIS) Tj T* (ArgumentParser\(prog=...\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 161.4236 cm +1 0 0 1 62.69291 197.4236 cm q -BT 1 0 0 1 0 28.82 Tm 2.646905 Tw 12 TL /F1 10 Tf 0 0 0 rg (Internally ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (uses ) Tj /F3 10 Tf (plac.parser_from ) Tj /F1 10 Tf (and adds the parser to the main function as an) Tj T* 0 Tw .982126 Tw (attribute. When ) Tj /F3 10 Tf (plac.call\(func\) ) Tj /F1 10 Tf (is invoked multiple time, the parser is re-used and not rebuilt from) Tj T* 0 Tw (scratch again.) Tj T* ET +BT 1 0 0 1 0 26 Tm 2.646905 Tw 12 TL /F1 10 Tf 0 0 0 rg (Internally ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (uses ) Tj /F3 10 Tf (plac.parser_from ) Tj /F1 10 Tf (and adds the parser to the main function as an) Tj T* 0 Tw .982126 Tw (attribute. When ) Tj /F3 10 Tf (plac.call\(func\) ) Tj /F1 10 Tf (is invoked multiple time, the parser is re-used and not rebuilt from) Tj T* 0 Tw (scratch again.) Tj T* ET Q Q q -1 0 0 1 62.69291 131.4236 cm +1 0 0 1 62.69291 167.4236 cm q -BT 1 0 0 1 0 16.82 Tm .982765 Tw 12 TL /F1 10 Tf 0 0 0 rg (I use ) Tj /F3 10 Tf (plac.parser_from ) Tj /F1 10 Tf (in the unit tests of the module, but regular users should not need to use it,) Tj T* 0 Tw (unless they want to access ) Tj /F4 10 Tf (all ) Tj /F1 10 Tf (of the features of ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (directly without calling the main function.) Tj T* ET +BT 1 0 0 1 0 14 Tm .982765 Tw 12 TL /F1 10 Tf 0 0 0 rg (I use ) Tj /F3 10 Tf (plac.parser_from ) Tj /F1 10 Tf (in the unit tests of the module, but regular users should not need to use it,) Tj T* 0 Tw (unless they want to access ) Tj /F4 10 Tf (all ) Tj /F1 10 Tf (of the features of ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (directly without calling the main function.) Tj T* ET Q Q q -1 0 0 1 62.69291 89.42362 cm +1 0 0 1 62.69291 113.4236 cm q -BT 1 0 0 1 0 28.82 Tm 1.442126 Tw 12 TL /F1 10 Tf 0 0 0 rg (Interested readers should read the documentation of ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (to understand the meaning of the other ) Tj T* 0 Tw .771567 Tw (options. If there is a set of options that you use very often, you may consider writing a decorator adding ) Tj T* 0 Tw 1.257045 Tw (such options to the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (function for you. For simplicity, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (does not perform any magic except the) Tj T* 0 Tw ET +BT 1 0 0 1 0 38 Tm 1.442126 Tw 12 TL /F1 10 Tf 0 0 0 rg (Interested readers should read the documentation of ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (to understand the meaning of the other) Tj T* 0 Tw .771567 Tw (options. If there is a set of options that you use very often, you may consider writing a decorator adding) Tj T* 0 Tw 1.257045 Tw (such options to the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (function for you. For simplicity, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (does not perform any magic except the) Tj T* 0 Tw (addition of the ) Tj /F3 10 Tf (.p ) Tj /F1 10 Tf (attribute.) Tj T* ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (17) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (17) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R354': class PDFStream 354 0 obj % page stream -<< /Length 8202 >> +<< /Length 8241 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 753.0236 cm +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (addition of the ) Tj /F3 10 Tf (.p ) Tj /F1 10 Tf (attribute.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 723.0236 cm +1 0 0 1 62.69291 747.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (plac vs the rest of the world) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (plac vs the rest of the world) Tj T* ET Q Q q -1 0 0 1 62.69291 681.0236 cm +1 0 0 1 62.69291 705.0236 cm q -BT 1 0 0 1 0 28.82 Tm 1.866905 Tw 12 TL /F1 10 Tf 0 0 0 rg (Originally ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (boasted about being "the easiest command-line arguments parser in the world". Since) Tj T* 0 Tw .306457 Tw (then, people started pointing out to me various projects which are based on the same idea \(extracting the) Tj T* 0 Tw (parser from the main function signature\) and are arguably even easier than ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (:) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.866905 Tw 12 TL /F1 10 Tf 0 0 0 rg (Originally ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (boasted about being "the easiest command-line arguments parser in the world". Since) Tj T* 0 Tw .306457 Tw (then, people started pointing out to me various projects which are based on the same idea \(extracting the) Tj T* 0 Tw (parser from the main function signature\) and are arguably even easier than ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (:) Tj T* ET Q Q q -1 0 0 1 62.69291 675.0236 cm +1 0 0 1 62.69291 699.0236 cm Q q -1 0 0 1 62.69291 675.0236 cm +1 0 0 1 62.69291 699.0236 cm Q q -1 0 0 1 62.69291 657.0236 cm +1 0 0 1 62.69291 687.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 3 cm +1 0 0 1 6 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (opterator ) Tj 0 0 0 rg (by Dusty Phillips) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (opterator ) Tj 0 0 0 rg (by Dusty Phillips) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 657.0236 cm -Q -q -1 0 0 1 62.69291 657.0236 cm +1 0 0 1 62.69291 681.0236 cm Q q -1 0 0 1 62.69291 639.0236 cm +1 0 0 1 62.69291 669.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 3 cm +1 0 0 1 6 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (CLIArgs ) Tj 0 0 0 rg (by Pavel Panchekha) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (CLIArgs ) Tj 0 0 0 rg (by Pavel Panchekha) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 639.0236 cm +1 0 0 1 62.69291 669.0236 cm Q q 1 0 0 1 62.69291 639.0236 cm -Q q -1 0 0 1 62.69291 609.0236 cm -q -BT 1 0 0 1 0 16.82 Tm 2.136457 Tw 12 TL /F1 10 Tf 0 0 0 rg (Luckily for me none of such projects had the idea of using function annotations and ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (; as a) Tj T* 0 Tw (consequence, they are no match for the capabilities of ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (.) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.136457 Tw 12 TL /F1 10 Tf 0 0 0 rg (Luckily for me none of such projects had the idea of using function annotations and ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (; as a) Tj T* 0 Tw (consequence, they are no match for the capabilities of ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (.) Tj T* ET Q Q q -1 0 0 1 62.69291 567.0236 cm +1 0 0 1 62.69291 597.0236 cm q -BT 1 0 0 1 0 28.82 Tm 1.551163 Tw 12 TL /F1 10 Tf 0 0 0 rg (Of course, there are tons of other libraries to parse the command line. For instance ) Tj 0 0 .501961 rg (Clap ) Tj 0 0 0 rg (by Matthew) Tj T* 0 Tw 1.211567 Tw (Frazier which appeared on PyPI just the day before ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (; ) Tj 0 0 .501961 rg (Clap ) Tj 0 0 0 rg (is fine but it is certainly not easier than) Tj T* 0 Tw 0 0 .501961 rg (plac) Tj 0 0 0 rg (.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.551163 Tw 12 TL /F1 10 Tf 0 0 0 rg (Of course, there are tons of other libraries to parse the command line. For instance ) Tj 0 0 .501961 rg (Clap ) Tj 0 0 0 rg (by Matthew) Tj T* 0 Tw 1.211567 Tw (Frazier which appeared on PyPI just the day before ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (; ) Tj 0 0 .501961 rg (Clap ) Tj 0 0 0 rg (is fine but it is certainly not easier than) Tj T* 0 Tw 0 0 .501961 rg (plac) Tj 0 0 0 rg (.) Tj T* ET Q Q q -1 0 0 1 62.69291 525.0236 cm +1 0 0 1 62.69291 555.0236 cm q -BT 1 0 0 1 0 28.82 Tm .622488 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (can also be used as a replacement of the ) Tj 0 0 .501961 rg (cmd ) Tj 0 0 0 rg (module in the standard library and as such it shares) Tj T* 0 Tw .377126 Tw (many features with the module ) Tj 0 0 .501961 rg (cmd2 ) Tj 0 0 0 rg (by Catherine Devlin. However, this is completely coincidental, since) Tj T* 0 Tw (I became aware of the ) Tj 0 0 .501961 rg (cmd2 ) Tj 0 0 0 rg (module only after writing ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (.) Tj T* ET +BT 1 0 0 1 0 26 Tm .622488 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (can also be used as a replacement of the ) Tj 0 0 .501961 rg (cmd ) Tj 0 0 0 rg (module in the standard library and as such it shares) Tj T* 0 Tw .377126 Tw (many features with the module ) Tj 0 0 .501961 rg (cmd2 ) Tj 0 0 0 rg (by Catherine Devlin. However, this is completely coincidental, since) Tj T* 0 Tw (I became aware of the ) Tj 0 0 .501961 rg (cmd2 ) Tj 0 0 0 rg (module only after writing ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (.) Tj T* ET Q Q q -1 0 0 1 62.69291 495.0236 cm +1 0 0 1 62.69291 525.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (The future) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (The future) Tj T* ET Q Q q -1 0 0 1 62.69291 429.0236 cm +1 0 0 1 62.69291 459.0236 cm q -BT 1 0 0 1 0 52.82 Tm .135542 Tw 12 TL /F1 10 Tf 0 0 0 rg (Currently the core of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is around 200 lines of code, not counting blanks, comments and docstrings. I do) Tj T* 0 Tw .968626 Tw (not plan to extend the core much in the future. The idea is to keep the module short: it is and it should) Tj T* 0 Tw .11811 Tw (remain a little wrapper over ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (. Actually I have thought about contributing the core back to ) Tj 0 0 .501961 rg (argparse) Tj T* 0 Tw 2.307485 Tw 0 0 0 rg (if ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (becomes successfull and gains a reasonable number of users. For the moment it should be) Tj T* 0 Tw (considered in alpha status.) Tj T* ET +BT 1 0 0 1 0 50 Tm .135542 Tw 12 TL /F1 10 Tf 0 0 0 rg (Currently the core of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is around 200 lines of code, not counting blanks, comments and docstrings. I do) Tj T* 0 Tw .968626 Tw (not plan to extend the core much in the future. The idea is to keep the module short: it is and it should) Tj T* 0 Tw .11811 Tw (remain a little wrapper over ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (. Actually I have thought about contributing the core back to ) Tj 0 0 .501961 rg (argparse) Tj T* 0 Tw 2.307485 Tw 0 0 0 rg (if ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (becomes successfull and gains a reasonable number of users. For the moment it should be) Tj T* 0 Tw (considered in alpha status.) Tj T* ET Q Q q -1 0 0 1 62.69291 387.0236 cm +1 0 0 1 62.69291 417.0236 cm q -BT 1 0 0 1 0 28.82 Tm .927488 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that even if ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (has been designed to be simple to use for simple stuff, its power should not be) Tj T* 0 Tw 1.02186 Tw (underestimated; it is actually a quite advanced tool with a domain of applicability which far exceeds the) Tj T* 0 Tw (realm of command-line arguments parsers.) Tj T* ET +BT 1 0 0 1 0 26 Tm .927488 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that even if ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (has been designed to be simple to use for simple stuff, its power should not be) Tj T* 0 Tw 1.02186 Tw (underestimated; it is actually a quite advanced tool with a domain of applicability which far exceeds the) Tj T* 0 Tw (realm of command-line arguments parsers.) Tj T* ET Q Q q -1 0 0 1 62.69291 321.0236 cm +1 0 0 1 62.69291 351.0236 cm q -BT 1 0 0 1 0 52.82 Tm .285988 Tw 12 TL /F1 10 Tf 0 0 0 rg (Version 0.5 of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (doubled the code base and the documentation: it is based on the idea of using ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (to) Tj T* 0 Tw .408555 Tw (implement command-line interpreters, i.e. something akin to the ) Tj /F3 10 Tf (cmd ) Tj /F1 10 Tf (module in the standard library, only) Tj T* 0 Tw .49936 Tw (better. The new features of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (are described in the ) Tj 0 0 .501961 rg (advanced usage document ) Tj 0 0 0 rg (. They are implemented) Tj T* 0 Tw .313828 Tw (in a separated module \() Tj /F3 10 Tf (plac_ext.py) Tj /F1 10 Tf (\), since they require Python 2.5 to work, whereas ) Tj /F3 10 Tf (plac_core.py) Tj T* 0 Tw /F1 10 Tf (only requires Python 2.3.) Tj T* ET +BT 1 0 0 1 0 50 Tm .285988 Tw 12 TL /F1 10 Tf 0 0 0 rg (Version 0.5 of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (doubled the code base and the documentation: it is based on the idea of using ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (to) Tj T* 0 Tw .408555 Tw (implement command-line interpreters, i.e. something akin to the ) Tj /F3 10 Tf (cmd ) Tj /F1 10 Tf (module in the standard library, only) Tj T* 0 Tw .49936 Tw (better. The new features of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (are described in the ) Tj 0 0 .501961 rg (advanced usage document ) Tj 0 0 0 rg (. They are implemented) Tj T* 0 Tw .313828 Tw (in a separated module \() Tj /F3 10 Tf (plac_ext.py) Tj /F1 10 Tf (\), since they require Python 2.5 to work, whereas ) Tj /F3 10 Tf (plac_core.py) Tj T* 0 Tw /F1 10 Tf (only requires Python 2.3.) Tj T* ET Q Q q -1 0 0 1 62.69291 291.0236 cm +1 0 0 1 62.69291 321.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Trivia: the story behind the name) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Trivia: the story behind the name) Tj T* ET Q Q q -1 0 0 1 62.69291 225.0236 cm +1 0 0 1 62.69291 255.0236 cm q -BT 1 0 0 1 0 52.82 Tm .979984 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (project started very humbly: I just wanted to make easy_installable my old ) Tj 0 0 .501961 rg (optionparse ) Tj 0 0 0 rg (recipe,) Tj T* 0 Tw .565988 Tw (and to publish it on PyPI. The original name of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (was optionparser and the idea behind it was to build) Tj T* 0 Tw .603735 Tw (an ) Tj 0 0 .501961 rg (OptionParser ) Tj 0 0 0 rg (object from the docstring of the module. However, before doing that, I decided to check) Tj T* 0 Tw .244198 Tw (out the ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (module, since I knew it was going into Python 2.7 and Python 2.7 was coming out. Soon) Tj T* 0 Tw (enough I realized two things:) Tj T* ET +BT 1 0 0 1 0 50 Tm .979984 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (project started very humbly: I just wanted to make easy_installable my old ) Tj 0 0 .501961 rg (optionparse ) Tj 0 0 0 rg (recipe,) Tj T* 0 Tw .565988 Tw (and to publish it on PyPI. The original name of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (was optionparser and the idea behind it was to build) Tj T* 0 Tw .603735 Tw (an ) Tj 0 0 .501961 rg (OptionParser ) Tj 0 0 0 rg (object from the docstring of the module. However, before doing that, I decided to check) Tj T* 0 Tw .244198 Tw (out the ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (module, since I knew it was going into Python 2.7 and Python 2.7 was coming out. Soon) Tj T* 0 Tw (enough I realized two things:) Tj T* ET Q Q q -1 0 0 1 62.69291 219.0236 cm +1 0 0 1 62.69291 249.0236 cm Q q -1 0 0 1 62.69291 219.0236 cm +1 0 0 1 62.69291 249.0236 cm Q q -1 0 0 1 62.69291 189.0236 cm +1 0 0 1 62.69291 225.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 15 cm +1 0 0 1 6 9 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 16.82 Tm .103735 Tw 12 TL /F1 10 Tf 0 0 0 rg (the single greatest idea of ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (was unifying the positional arguments and the options in a single) Tj T* 0 Tw (namespace object;) Tj T* ET +BT 1 0 0 1 0 14 Tm .103735 Tw 12 TL /F1 10 Tf 0 0 0 rg (the single greatest idea of ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (was unifying the positional arguments and the options in a single) Tj T* 0 Tw (namespace object;) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 189.0236 cm -Q -q -1 0 0 1 62.69291 189.0236 cm +1 0 0 1 62.69291 219.0236 cm Q q -1 0 0 1 62.69291 159.0236 cm +1 0 0 1 62.69291 195.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 15 cm +1 0 0 1 6 9 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL 1.66748 Tw (parsing the docstring was so old-fashioned, considering the existence of functions annotations in) Tj T* 0 Tw (Python 3.) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.66748 Tw (parsing the docstring was so old-fashioned, considering the existence of functions annotations in) Tj T* 0 Tw (Python 3.) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 159.0236 cm +1 0 0 1 62.69291 195.0236 cm Q q -1 0 0 1 62.69291 159.0236 cm +1 0 0 1 62.69291 141.0236 cm +q +BT 1 0 0 1 0 38 Tm .600574 Tw 12 TL /F1 10 Tf 0 0 0 rg (Putting together these two observations with the original idea of inferring the parser I decided to build an) Tj T* 0 Tw .516905 Tw 0 0 .501961 rg (ArgumentParser ) Tj 0 0 0 rg (object from function annotations. The ) Tj /F3 10 Tf (optionparser ) Tj /F1 10 Tf (name was ruled out, since I was) Tj T* 0 Tw 2.085984 Tw (now using ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (; a name like ) Tj /F3 10 Tf (argparse_plus ) Tj /F1 10 Tf (was also ruled out, since the typical usage was) Tj T* 0 Tw (completely different from the ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (usage.) Tj T* ET +Q Q q -1 0 0 1 62.69291 105.0236 cm +1 0 0 1 62.69291 111.0236 cm q -BT 1 0 0 1 0 40.82 Tm .600574 Tw 12 TL /F1 10 Tf 0 0 0 rg (Putting together these two observations with the original idea of inferring the parser I decided to build an) Tj T* 0 Tw .516905 Tw 0 0 .501961 rg (ArgumentParser ) Tj 0 0 0 rg (object from function annotations. The ) Tj /F3 10 Tf (optionparser ) Tj /F1 10 Tf (name was ruled out, since I was) Tj T* 0 Tw 2.085984 Tw (now using ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (; a name like ) Tj /F3 10 Tf (argparse_plus ) Tj /F1 10 Tf (was also ruled out, since the typical usage was) Tj T* 0 Tw (completely different from the ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (usage.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.093876 Tw 12 TL /F1 10 Tf 0 0 0 rg (I made a research on PyPI and the name ) Tj /F4 10 Tf (clap ) Tj /F1 10 Tf (\(Command Line Arguments Parser\) was not taken, so I) Tj T* 0 Tw (renamed everything to clap. After two days a ) Tj 0 0 .501961 rg (Clap ) Tj 0 0 0 rg (module appeared on PyPI <) Tj (expletives deleted) Tj (>) Tj (!) Tj T* ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (18) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (18) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R355': class PDFStream 355 0 obj % page stream -<< /Length 5857 >> +<< /Length 5448 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 741.0236 cm q -BT 1 0 0 1 0 16.82 Tm 1.093876 Tw 12 TL /F1 10 Tf 0 0 0 rg (I made a research on PyPI and the name ) Tj /F4 10 Tf (clap ) Tj /F1 10 Tf (\(Command Line Arguments Parser\) was not taken, so I) Tj T* 0 Tw (renamed everything to clap. After two days a ) Tj 0 0 .501961 rg (Clap ) Tj 0 0 0 rg (module appeared on PyPI <) Tj (expletives deleted) Tj (>) Tj (!) Tj T* ET +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .877209 Tw (Having little imagination, I decided to rename everything again to plac, an anagram of clap: since it is a) Tj T* 0 Tw (non-existing English name, I hope nobody will steal it from me!) Tj T* ET Q Q q -1 0 0 1 62.69291 711.0236 cm +1 0 0 1 62.69291 723.0236 cm q -0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL .877209 Tw (Having little imagination, I decided to rename everything again to plac, an anagram of clap: since it is a) Tj T* 0 Tw (non-existing English name, I hope nobody will steal it from me!) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (That's all, I hope you will enjoy working with ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (!) Tj T* ET Q Q q -1 0 0 1 62.69291 693.0236 cm +1 0 0 1 62.69291 690.0236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (That's all, I hope you will enjoy working with ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (!) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Advanced usages of plac) Tj T* ET Q Q q 1 0 0 1 62.69291 660.0236 cm q -BT 1 0 0 1 0 8.435 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Advanced usages of plac) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Introduction) Tj T* ET Q Q q -1 0 0 1 62.69291 630.0236 cm +1 0 0 1 62.69291 618.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Introduction) Tj T* ET +BT 1 0 0 1 0 26 Tm .539036 Tw 12 TL /F1 10 Tf 0 0 0 rg (One of the design goals of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is to make it dead easy to write a scriptable and testable interface for an) Tj T* 0 Tw .813876 Tw (application. You can use ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (whenever you have an API with strings in input and strings in output, and) Tj T* 0 Tw (that includes a ) Tj /F4 10 Tf (huge ) Tj /F1 10 Tf (domain of applications.) Tj T* ET Q Q q -1 0 0 1 62.69291 588.0236 cm +1 0 0 1 62.69291 576.0236 cm q -BT 1 0 0 1 0 28.82 Tm .539036 Tw 12 TL /F1 10 Tf 0 0 0 rg (One of the design goals of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is to make it dead easy to write a scriptable and testable interface for an) Tj T* 0 Tw .813876 Tw (application. You can use ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (whenever you have an API with strings in input and strings in output, and) Tj T* 0 Tw (that includes a ) Tj /F4 10 Tf (huge ) Tj /F1 10 Tf (domain of applications.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.756651 Tw 12 TL /F1 10 Tf 0 0 0 rg (A string-oriented interface is a scriptable interface by construction. That means that you can define a) Tj T* 0 Tw .918735 Tw (command language for your application and that it is possible to write scripts which are interpretable by) Tj T* 0 Tw 0 0 .501961 rg (plac ) Tj 0 0 0 rg (and can be run as batch scripts.) Tj T* ET Q Q q -1 0 0 1 62.69291 546.0236 cm +1 0 0 1 62.69291 534.0236 cm q -BT 1 0 0 1 0 28.82 Tm 1.756651 Tw 12 TL /F1 10 Tf 0 0 0 rg (A string-oriented interface is a scriptable interface by construction. That means that you can define a) Tj T* 0 Tw .918735 Tw (command language for your application and that it is possible to write scripts which are interpretable by) Tj T* 0 Tw 0 0 .501961 rg (plac ) Tj 0 0 0 rg (and can be run as batch scripts.) Tj T* ET +BT 1 0 0 1 0 26 Tm .444987 Tw 12 TL /F1 10 Tf 0 0 0 rg (Actually, at the most general level, you can see ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (as a generic tool to write domain specific languages) Tj T* 0 Tw .107209 Tw (\(DSL\). With ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (you can test your application interactively as well as with batch scripts, and even with the) Tj T* 0 Tw (analogous of Python doctests for your defined language.) Tj T* ET Q Q q -1 0 0 1 62.69291 504.0236 cm +1 0 0 1 62.69291 468.0236 cm q -BT 1 0 0 1 0 28.82 Tm .444987 Tw 12 TL /F1 10 Tf 0 0 0 rg (Actually, at the most general level, you can see ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (as a generic tool to write domain specific languages) Tj T* 0 Tw .107209 Tw (\(DSL\). With ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (you can test your application interactively as well as with batch scripts, and even with the) Tj T* 0 Tw (analogous of Python doctests for your defined language.) Tj T* ET +BT 1 0 0 1 0 50 Tm .694104 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can easily replace the ) Tj /F3 10 Tf (cmd ) Tj /F1 10 Tf (module of the standard library and you could easily write an application) Tj T* 0 Tw 2.271751 Tw (like ) Tj 0 0 .501961 rg (twill ) Tj 0 0 0 rg (with ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (. Or you could use it to script your building procedure. ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (also supports parallel) Tj T* 0 Tw .907765 Tw (execution of multiple commands and can be used as task manager and monitor. It is also quite easy to) Tj T* 0 Tw 1.483488 Tw (build a GUI or a Web application on top of ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (. When speaking of things you can do with ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (, your) Tj T* 0 Tw (imagination is the only limit!) Tj T* ET Q Q q 1 0 0 1 62.69291 438.0236 cm q -BT 1 0 0 1 0 52.82 Tm .694104 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can easily replace the ) Tj /F3 10 Tf (cmd ) Tj /F1 10 Tf (module of the standard library and you could easily write an application) Tj T* 0 Tw 2.271751 Tw (like ) Tj 0 0 .501961 rg (twill ) Tj 0 0 0 rg (with ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (. Or you could use it to script your building procedure. ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (also supports parallel) Tj T* 0 Tw .907765 Tw (execution of multiple commands and can be used as task manager and monitor. It is also quite easy to) Tj T* 0 Tw 1.483488 Tw (build a GUI or a Web application on top of ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (. When speaking of things you can do with ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (, your) Tj T* 0 Tw (imagination is the only limit!) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (From scripts to interactive applications) Tj T* ET Q Q q -1 0 0 1 62.69291 408.0236 cm +1 0 0 1 62.69291 384.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (From scripts to interactive applications) Tj T* ET +BT 1 0 0 1 0 38 Tm 1.300751 Tw 12 TL /F1 10 Tf 0 0 0 rg (Command-line scripts have many advantages, but they are no substitute for interactive applications. In) Tj T* 0 Tw .088171 Tw (particular, if you have a script with a large startup time which must be run multiple times, it is best to turn it) Tj T* 0 Tw 4.582126 Tw (into an interactive application, so that the startup is performed only once. ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (provides an) Tj T* 0 Tw /F3 10 Tf (Interpreter ) Tj /F1 10 Tf (class just for this purpose.) Tj T* ET Q Q q 1 0 0 1 62.69291 354.0236 cm q -BT 1 0 0 1 0 40.82 Tm 1.300751 Tw 12 TL /F1 10 Tf 0 0 0 rg (Command-line scripts have many advantages, but they are no substitute for interactive applications. In) Tj T* 0 Tw .088171 Tw (particular, if you have a script with a large startup time which must be run multiple times, it is best to turn it) Tj T* 0 Tw 4.582126 Tw (into an interactive application, so that the startup is performed only once. ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (provides an) Tj T* 0 Tw /F3 10 Tf (Interpreter ) Tj /F1 10 Tf (class just for this purpose.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.293984 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf (Interpreter ) Tj /F1 10 Tf (class wraps the main function of a script and provides an ) Tj /F3 10 Tf (.interact ) Tj /F1 10 Tf (method to) Tj T* 0 Tw (start an interactive interpreter reading commands from the console.) Tj T* ET Q Q q 1 0 0 1 62.69291 324.0236 cm q -BT 1 0 0 1 0 16.82 Tm 1.293984 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf (Interpreter ) Tj /F1 10 Tf (class wraps the main function of a script and provides an ) Tj /F3 10 Tf (.interact ) Tj /F1 10 Tf (method to) Tj T* 0 Tw (start an interactive interpreter reading commands from the console.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.49436 Tw 12 TL /F1 10 Tf 0 0 0 rg (For instance, you can define an interactive interpreter on top of the ) Tj /F3 10 Tf (ishelve ) Tj /F1 10 Tf (script introduced in the) Tj T* 0 Tw 0 0 .501961 rg (basic documentation ) Tj 0 0 0 rg (as follows:) Tj T* ET Q Q q -1 0 0 1 62.69291 294.0236 cm -q -BT 1 0 0 1 0 16.82 Tm 1.49436 Tw 12 TL /F1 10 Tf 0 0 0 rg (For instance, you can define an interactive interpreter on top of the ) Tj /F3 10 Tf (ishelve ) Tj /F1 10 Tf (script introduced in the) Tj T* 0 Tw 0 0 .501961 rg (basic documentation ) Tj 0 0 0 rg (as follows:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 92.82362 cm +1 0 0 1 62.69291 98.82362 cm q q 1 0 0 1 0 0 cm @@ -8897,11 +8820,11 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 192 re B* +n -6 -6 468.6898 216 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 173.71 Tm /F3 10 Tf 12 TL (# shelve_interpreter.py) Tj T* (import plac, ishelve) Tj T* T* (@plac.annotations\() Tj T* ( interactive=\('start interactive interface', 'flag'\),) Tj T* ( subcommands='the commands of the underlying ishelve interpreter'\)) Tj T* (def main\(interactive, *subcommands\):) Tj T* ( """) Tj T* ( This script works both interactively and non-interactively.) Tj T* ( Use .help to see the internal commands.) Tj T* ( """) Tj T* ( if interactive:) Tj T* ( plac.Interpreter\(ishelve.main\).interact\(\)) Tj T* ( else:) Tj T* ( for out in plac.call\(ishelve.main, subcommands\):) Tj T* ET +BT 1 0 0 1 0 194 Tm /F3 10 Tf 12 TL (# shelve_interpreter.py) Tj T* (import plac, ishelve) Tj T* T* (@plac.annotations\() Tj T* ( interactive=\('start interactive interface', 'flag'\),) Tj T* ( subcommands='the commands of the underlying ishelve interpreter'\)) Tj T* (def main\(interactive, *subcommands\):) Tj T* ( """) Tj T* ( This script works both interactively and non-interactively.) Tj T* ( Use .help to see the internal commands.) Tj T* ( """) Tj T* ( if interactive:) Tj T* ( plac.Interpreter\(ishelve.main\).interact\(\)) Tj T* ( else:) Tj T* ( for out in plac.call\(ishelve.main, subcommands\):) Tj T* ( print\(out\)) Tj T* T* ET Q Q Q @@ -8911,21 +8834,20 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (19) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (19) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R356': class PDFStream 356 0 obj % page stream -<< /Length 3560 >> +<< /Length 3529 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 703.8236 cm +1 0 0 1 62.69291 727.8236 cm q q 1 0 0 1 0 0 cm @@ -8935,24 +8857,24 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 60 re B* +n -6 -6 468.6898 36 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 41.71 Tm /F3 10 Tf 12 TL ( print\(out\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( plac.call\(main\)) Tj T* ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL (if __name__ == '__main__':) Tj T* ( plac.call\(main\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 659.8236 cm +1 0 0 1 62.69291 683.8236 cm q -BT 1 0 0 1 0 28.82 Tm 2.200651 Tw 12 TL /F1 10 Tf 0 0 0 rg (A trick has been used here: the ishelve command-line interface has been hidden inside an external) Tj T* 0 Tw .917674 Tw (interface. They are distinct: for instance the external interface recognizes the ) Tj /F3 10 Tf (-h/--help ) Tj /F1 10 Tf (flag whereas) Tj T* 0 Tw (the internal interface only recognizes the ) Tj /F3 10 Tf (.help ) Tj /F1 10 Tf (command:) Tj T* ET +BT 1 0 0 1 0 26 Tm 2.200651 Tw 12 TL /F1 10 Tf 0 0 0 rg (A trick has been used here: the ishelve command-line interface has been hidden inside an external) Tj T* 0 Tw .917674 Tw (interface. They are distinct: for instance the external interface recognizes the ) Tj /F3 10 Tf (-h/--help ) Tj /F1 10 Tf (flag whereas) Tj T* 0 Tw (the internal interface only recognizes the ) Tj /F3 10 Tf (.help ) Tj /F1 10 Tf (command:) Tj T* ET Q Q q -1 0 0 1 62.69291 626.6236 cm +1 0 0 1 62.69291 650.6236 cm q q 1 0 0 1 0 0 cm @@ -8966,14 +8888,14 @@ n -6 -6 468.6898 24 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 5.71 Tm /F3 10 Tf 12 TL ($ python shelve_interpreter.py -h) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL ($ python shelve_interpreter.py -h) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 449.4236 cm +1 0 0 1 62.69291 473.4236 cm q q 1 0 0 1 0 0 cm @@ -8987,21 +8909,21 @@ n -6 -6 468.6898 168 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 149.71 Tm /F3 10 Tf 12 TL (usage: shelve_interpreter.py [-h] [-interactive]) Tj T* ( [subcommands [subcommands ...]]) Tj T* T* ( This script works both interactively and non-interactively.) Tj T* ( Use .help to see the internal commands.) Tj T* ( ) Tj T* T* (positional arguments:) Tj T* ( subcommands the commands of the underlying ishelve interpreter) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -interactive start interactive interface) Tj T* ET +BT 1 0 0 1 0 146 Tm /F3 10 Tf 12 TL (usage: shelve_interpreter.py [-h] [-interactive]) Tj T* ( [subcommands [subcommands ...]]) Tj T* T* ( This script works both interactively and non-interactively.) Tj T* ( Use .help to see the internal commands.) Tj T* ( ) Tj T* T* (positional arguments:) Tj T* ( subcommands the commands of the underlying ishelve interpreter) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -interactive start interactive interface) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 429.4236 cm +1 0 0 1 62.69291 453.4236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Thanks to this ingenuous trick, the script can be run both interactively and non-interactively:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Thanks to this ingenuous trick, the script can be run both interactively and non-interactively:) Tj T* ET Q Q q -1 0 0 1 62.69291 384.2236 cm +1 0 0 1 62.69291 408.2236 cm q q 1 0 0 1 0 0 cm @@ -9015,21 +8937,21 @@ n -6 -6 468.6898 36 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 17.71 Tm /F3 10 Tf 12 TL ($ python shelve_interpreter.py .clear # non-interactive use) Tj T* (cleared the shelve) Tj T* ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL ($ python shelve_interpreter.py .clear # non-interactive use) Tj T* (cleared the shelve) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 364.2236 cm +1 0 0 1 62.69291 388.2236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Here is an usage session:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is an usage session:) Tj T* ET Q Q q -1 0 0 1 62.69291 91.02362 cm +1 0 0 1 62.69291 103.0236 cm q q 1 0 0 1 0 0 cm @@ -9039,10 +8961,10 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 264 re B* +n -6 -6 468.6898 276 re B* Q q -BT 1 0 0 1 0 245.71 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ python shelve_interpreter.py -i # interactive use) Tj T* (A simple interface to a shelve. Use .help to see the available commands.) Tj T* (i) Tj (>) Tj ( .help) Tj T* (Commands: .help, .showall, .clear, .delete) Tj T* (<) Tj (param) Tj (>) Tj ( ...) Tj T* (<) Tj (param=value) Tj (>) Tj ( ...) Tj T* (i) Tj (>) Tj ( a=1) Tj T* (setting a=1) Tj T* (i) Tj (>) Tj ( a) Tj T* (1) Tj T* (i) Tj (>) Tj ( b=2) Tj T* (setting b=2) Tj T* (i) Tj (>) Tj ( a b) Tj T* (1) Tj T* (2) Tj T* (i) Tj (>) Tj ( .del a) Tj T* (deleted a) Tj T* (i) Tj (>) Tj ( a) Tj T* (a: not found) Tj T* (i) Tj (>) Tj ( .show) Tj T* (b=2) Tj T* ET +BT 1 0 0 1 0 254 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ python shelve_interpreter.py -i # interactive use) Tj T* (A simple interface to a shelve. Use .help to see the available commands.) Tj T* (i) Tj (>) Tj ( .help) Tj T* (Commands: .help, .showall, .clear, .delete) Tj T* (<) Tj (param) Tj (>) Tj ( ...) Tj T* (<) Tj (param=value) Tj (>) Tj ( ...) Tj T* (i) Tj (>) Tj ( a=1) Tj T* (setting a=1) Tj T* (i) Tj (>) Tj ( a) Tj T* (1) Tj T* (i) Tj (>) Tj ( b=2) Tj T* (setting b=2) Tj T* (i) Tj (>) Tj ( a b) Tj T* (1) Tj T* (2) Tj T* (i) Tj (>) Tj ( .del a) Tj T* (deleted a) Tj T* (i) Tj (>) Tj ( a) Tj T* (a: not found) Tj T* (i) Tj (>) Tj ( .show) Tj T* (b=2) Tj T* (i) Tj (>) Tj ( [CTRL-D]) Tj T* ET Q Q Q @@ -9052,72 +8974,51 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (20) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (20) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R357': class PDFStream 357 0 obj % page stream -<< /Length 5568 >> +<< /Length 5889 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 739.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -BT 1 0 0 1 0 5.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( [CTRL-D]) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 671.8236 cm +1 0 0 1 62.69291 705.0236 cm q -BT 1 0 0 1 0 52.82 Tm .256412 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf (.interact ) Tj /F1 10 Tf (method reads commands from the console and send them to the underlying interpreter,) Tj T* 0 Tw .065984 Tw (until the user send a CTRL-D command \(CTRL-Z in Windows\). There is a default argument ) Tj /F3 10 Tf (prompt='i) Tj (>) Tj T* 0 Tw .41832 Tw (' ) Tj /F1 10 Tf (which can be used to change the prompt. The text displayed at the beginning of the interactive session) Tj T* 0 Tw 1.407126 Tw (is the docstring of the main function. ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (also understands command abbreviations: in this example) Tj T* 0 Tw /F3 10 Tf (del ) Tj /F1 10 Tf (is an abbreviation for ) Tj /F3 10 Tf (delete) Tj /F1 10 Tf (. In case of ambiguous abbreviations ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (raises a ) Tj /F3 10 Tf (NameError) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 50 Tm .256412 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf (.interact ) Tj /F1 10 Tf (method reads commands from the console and send them to the underlying interpreter,) Tj T* 0 Tw .065984 Tw (until the user send a CTRL-D command \(CTRL-Z in Windows\). There is a default argument ) Tj /F3 10 Tf (prompt='i) Tj (>) Tj T* 0 Tw .41832 Tw (' ) Tj /F1 10 Tf (which can be used to change the prompt. The text displayed at the beginning of the interactive session) Tj T* 0 Tw 1.407126 Tw (is the docstring of the main function. ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (also understands command abbreviations: in this example) Tj T* 0 Tw /F3 10 Tf (del ) Tj /F1 10 Tf (is an abbreviation for ) Tj /F3 10 Tf (delete) Tj /F1 10 Tf (. In case of ambiguous abbreviations ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (raises a ) Tj /F3 10 Tf (NameError) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 62.69291 641.8236 cm +1 0 0 1 62.69291 675.0236 cm q -BT 1 0 0 1 0 16.82 Tm .847045 Tw 12 TL /F1 10 Tf 0 0 0 rg (Finally I must notice that the ) Tj /F3 10 Tf (plac.Interpreter ) Tj /F1 10 Tf (is available only if you are using a recent version of) Tj T* 0 Tw (Python \() Tj (>) Tj (= 2.5\), because it is a context manager object which uses extended generators internally.) Tj T* ET +BT 1 0 0 1 0 14 Tm .847045 Tw 12 TL /F1 10 Tf 0 0 0 rg (Finally I must notice that the ) Tj /F3 10 Tf (plac.Interpreter ) Tj /F1 10 Tf (is available only if you are using a recent version of) Tj T* 0 Tw (Python \() Tj (>) Tj (= 2.5\), because it is a context manager object which uses extended generators internally.) Tj T* ET Q Q q -1 0 0 1 62.69291 611.8236 cm +1 0 0 1 62.69291 645.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Testing a plac application) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Testing a plac application) Tj T* ET Q Q q -1 0 0 1 62.69291 581.8236 cm +1 0 0 1 62.69291 615.0236 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL 3.034269 Tw (You can conveniently test your application in interactive mode. However manual testing is a poor) Tj T* 0 Tw (substitute for automatic testing.) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 3.034269 Tw (You can conveniently test your application in interactive mode. However manual testing is a poor) Tj T* 0 Tw (substitute for automatic testing.) Tj T* ET Q Q q -1 0 0 1 62.69291 563.8236 cm +1 0 0 1 62.69291 597.0236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (In principle, one could write automatic tests for the ) Tj /F3 10 Tf (ishelve ) Tj /F1 10 Tf (application by using ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (directly:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (In principle, one could write automatic tests for the ) Tj /F3 10 Tf (ishelve ) Tj /F1 10 Tf (application by using ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (directly:) Tj T* ET Q Q q -1 0 0 1 62.69291 398.6236 cm +1 0 0 1 62.69291 431.8236 cm q q 1 0 0 1 0 0 cm @@ -9131,26 +9032,26 @@ n -6 -6 468.6898 156 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 137.71 Tm /F3 10 Tf 12 TL (# test_ishelve.py) Tj T* (import plac, ishelve) Tj T* T* (def test\(\):) Tj T* ( assert plac.call\(ishelve.main, ['.clear']\) == ['cleared the shelve']) Tj T* ( assert plac.call\(ishelve.main, ['a=1']\) == ['setting a=1']) Tj T* ( assert plac.call\(ishelve.main, ['a']\) == ['1']) Tj T* ( assert plac.call\(ishelve.main, ['.delete=a']\) == ['deleted a']) Tj T* ( assert plac.call\(ishelve.main, ['a']\) == ['a: not found']) Tj T* T* (if __name__ == '__main__':) Tj T* ( test\(\)) Tj T* ET +BT 1 0 0 1 0 134 Tm /F3 10 Tf 12 TL (# test_ishelve.py) Tj T* (import plac, ishelve) Tj T* T* (def test\(\):) Tj T* ( assert plac.call\(ishelve.main, ['.clear']\) == ['cleared the shelve']) Tj T* ( assert plac.call\(ishelve.main, ['a=1']\) == ['setting a=1']) Tj T* ( assert plac.call\(ishelve.main, ['a']\) == ['1']) Tj T* ( assert plac.call\(ishelve.main, ['.delete=a']\) == ['deleted a']) Tj T* ( assert plac.call\(ishelve.main, ['a']\) == ['a: not found']) Tj T* T* (if __name__ == '__main__':) Tj T* ( test\(\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 354.6236 cm +1 0 0 1 62.69291 387.8236 cm q -BT 1 0 0 1 0 28.82 Tm .390651 Tw 12 TL /F1 10 Tf 0 0 0 rg (However, using ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (is not especially nice. The big issue is that ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (responds to invalid) Tj T* 0 Tw 1.249987 Tw (input by printing an error message on stderr and by raising a ) Tj /F3 10 Tf (SystemExit) Tj /F1 10 Tf (: this is certainly not a nice) Tj T* 0 Tw (thing to do in a test.) Tj T* ET +BT 1 0 0 1 0 26 Tm .390651 Tw 12 TL /F1 10 Tf 0 0 0 rg (However, using ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (is not especially nice. The big issue is that ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (responds to invalid) Tj T* 0 Tw 1.249987 Tw (input by printing an error message on stderr and by raising a ) Tj /F3 10 Tf (SystemExit) Tj /F1 10 Tf (: this is certainly not a nice) Tj T* 0 Tw (thing to do in a test.) Tj T* ET Q Q q -1 0 0 1 62.69291 312.6236 cm +1 0 0 1 62.69291 345.8236 cm q -BT 1 0 0 1 0 28.82 Tm 1.616457 Tw 12 TL /F1 10 Tf 0 0 0 rg (As a consequence of this behavior it is impossible to test for invalid commands, unless you wrap the) Tj T* 0 Tw .259985 Tw /F3 10 Tf (SystemExit ) Tj /F1 10 Tf (exception by hand each time \(a possibly you do something with the error message in stderr) Tj T* 0 Tw (too\). Luckily, ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (offers a better testing support through the ) Tj /F3 10 Tf (check ) Tj /F1 10 Tf (method of ) Tj /F3 10 Tf (Interpreter ) Tj /F1 10 Tf (objects:) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.616457 Tw 12 TL /F1 10 Tf 0 0 0 rg (As a consequence of this behavior it is impossible to test for invalid commands, unless you wrap the) Tj T* 0 Tw .259985 Tw /F3 10 Tf (SystemExit ) Tj /F1 10 Tf (exception by hand each time \(a possibly you do something with the error message in stderr) Tj T* 0 Tw (too\). Luckily, ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (offers a better testing support through the ) Tj /F3 10 Tf (check ) Tj /F1 10 Tf (method of ) Tj /F3 10 Tf (Interpreter ) Tj /F1 10 Tf (objects:) Tj T* ET Q Q q -1 0 0 1 62.69291 159.4236 cm +1 0 0 1 62.69291 192.6236 cm q q 1 0 0 1 0 0 cm @@ -9164,52 +9065,57 @@ n -6 -6 468.6898 144 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 125.71 Tm /F3 10 Tf 12 TL (# test_ishelve_more.py) Tj T* (from __future__ import with_statement) Tj T* (import plac, ishelve) Tj T* T* (def test\(\):) Tj T* ( with plac.Interpreter\(ishelve.main\) as i:) Tj T* ( i.check\('.clear', 'cleared the shelve'\)) Tj T* ( i.check\('a=1', 'setting a=1'\)) Tj T* ( i.check\('a', '1'\)) Tj T* ( i.check\('.delete=a', 'deleted a'\)) Tj T* ( i.check\('a', 'a: not found'\)) Tj T* ET +BT 1 0 0 1 0 122 Tm /F3 10 Tf 12 TL (# test_ishelve_more.py) Tj T* (from __future__ import with_statement) Tj T* (import plac, ishelve) Tj T* T* (def test\(\):) Tj T* ( with plac.Interpreter\(ishelve.main\) as i:) Tj T* ( i.check\('.clear', 'cleared the shelve'\)) Tj T* ( i.check\('a=1', 'setting a=1'\)) Tj T* ( i.check\('a', '1'\)) Tj T* ( i.check\('.delete=a', 'deleted a'\)) Tj T* ( i.check\('a', 'a: not found'\)) Tj T* ET +Q Q Q Q Q +q +1 0 0 1 62.69291 136.6236 cm +q +BT 1 0 0 1 0 38 Tm 6.299974 Tw 12 TL /F1 10 Tf 0 0 0 rg (The method ) Tj /F3 10 Tf (.check\(given_input, expected_output\) ) Tj /F1 10 Tf (works on strings and raises an) Tj T* 0 Tw .971318 Tw /F3 10 Tf (AssertionError ) Tj /F1 10 Tf (if the output produced by the interpreter is different from the expected output for the) Tj T* 0 Tw 2.186905 Tw (given input. Notice that ) Tj /F3 10 Tf (AssertionError ) Tj /F1 10 Tf (is catched by tools like ) Tj /F3 10 Tf (py.test ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (nosetests ) Tj /F1 10 Tf (and) Tj T* 0 Tw (actually ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (tests are intended to be run with such tools.) Tj T* ET +Q Q q -1 0 0 1 62.69291 103.4236 cm +1 0 0 1 62.69291 94.62362 cm q -BT 1 0 0 1 0 40.82 Tm 6.299974 Tw 12 TL /F1 10 Tf 0 0 0 rg (The method ) Tj /F3 10 Tf (.check\(given_input, expected_output\) ) Tj /F1 10 Tf (works on strings and raises an) Tj T* 0 Tw .971318 Tw /F3 10 Tf (AssertionError ) Tj /F1 10 Tf (if the output produced by the interpreter is different from the expected output for the) Tj T* 0 Tw 2.186905 Tw (given input. Notice that ) Tj /F3 10 Tf (AssertionError ) Tj /F1 10 Tf (is catched by tools like ) Tj /F3 10 Tf (py.test ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (nosetests ) Tj /F1 10 Tf (and) Tj T* 0 Tw (actually ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (tests are intended to be run with such tools.) Tj T* ET +BT 1 0 0 1 0 26 Tm .239984 Tw 12 TL /F1 10 Tf 0 0 0 rg (Interpreters offer a minor syntactic advantage with respect to calling ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (directly, but they offer a ) Tj T* 0 Tw .96748 Tw /F4 10 Tf (major ) Tj /F1 10 Tf (semantic advantage when things go wrong \(read exceptions\): an ) Tj /F3 10 Tf (Interpreter ) Tj /F1 10 Tf (object internally ) Tj T* 0 Tw 1.181318 Tw (invokes something like ) Tj /F3 10 Tf (plac.call) Tj /F1 10 Tf (, but it wraps all exceptions, so that ) Tj /F3 10 Tf (i.check ) Tj /F1 10 Tf (is guaranteed not to) Tj T* 0 Tw ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (21) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (21) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R358': class PDFStream 358 0 obj % page stream -<< /Length 6085 >> +<< /Length 6354 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 717.0236 cm +1 0 0 1 62.69291 753.0236 cm q -BT 1 0 0 1 0 40.82 Tm .239984 Tw 12 TL /F1 10 Tf 0 0 0 rg (Interpreters offer a minor syntactic advantage with respect to calling ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (directly, but they offer a) Tj T* 0 Tw .96748 Tw /F4 10 Tf (major ) Tj /F1 10 Tf (semantic advantage when things go wrong \(read exceptions\): an ) Tj /F3 10 Tf (Interpreter ) Tj /F1 10 Tf (object internally) Tj T* 0 Tw 1.181318 Tw (invokes something like ) Tj /F3 10 Tf (plac.call) Tj /F1 10 Tf (, but it wraps all exceptions, so that ) Tj /F3 10 Tf (i.check ) Tj /F1 10 Tf (is guaranteed not to) Tj T* 0 Tw (raise any exception except ) Tj /F3 10 Tf (AssertionError) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (raise any exception except ) Tj /F3 10 Tf (AssertionError) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 62.69291 699.0236 cm +1 0 0 1 62.69291 735.0236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (Even the ) Tj /F3 10 Tf (SystemExit ) Tj /F1 10 Tf (exception is captured and you can write your test as) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Even the ) Tj /F3 10 Tf (SystemExit ) Tj /F1 10 Tf (exception is captured and you can write your test as) Tj T* ET Q Q q -1 0 0 1 62.69291 693.0236 cm +1 0 0 1 62.69291 729.0236 cm Q q -1 0 0 1 62.69291 681.0236 cm +1 0 0 1 62.69291 717.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET BT 1 0 0 1 0 2 Tm T* ET @@ -9217,48 +9123,48 @@ q 1 0 0 1 20 0 cm q 0 0 0 rg -BT 1 0 0 1 0 5.71 Tm /F3 10 Tf 12 TL (i.check\('-cler', 'SystemExit: unrecognized arguments: -cler'\)) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (i.check\('-cler', 'SystemExit: unrecognized arguments: -cler'\)) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 681.0236 cm +1 0 0 1 62.69291 717.0236 cm Q q -1 0 0 1 62.69291 663.0236 cm +1 0 0 1 62.69291 699.0236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (without risk of exiting from the Python interpreter.) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (without risk of exiting from the Python interpreter.) Tj T* ET Q Q q -1 0 0 1 62.69291 621.0236 cm +1 0 0 1 62.69291 657.0236 cm q -BT 1 0 0 1 0 28.82 Tm 1.422651 Tw 12 TL /F1 10 Tf 0 0 0 rg (There is a second advantage of interpreters: if the main function contains some initialization code and) Tj T* 0 Tw .454651 Tw (finalization code \() Tj /F3 10 Tf (__enter__ ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (__exit__ ) Tj /F1 10 Tf (functions\) they will be run only once at the beginning and) Tj T* 0 Tw (at the end of the interpreter loop. ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (instead ignores the initialization/finalization code.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.422651 Tw 12 TL /F1 10 Tf 0 0 0 rg (There is a second advantage of interpreters: if the main function contains some initialization code and) Tj T* 0 Tw .454651 Tw (finalization code \() Tj /F3 10 Tf (__enter__ ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (__exit__ ) Tj /F1 10 Tf (functions\) they will be run only once at the beginning and) Tj T* 0 Tw (at the end of the interpreter loop. ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (instead ignores the initialization/finalization code.) Tj T* ET Q Q q -1 0 0 1 62.69291 591.0236 cm +1 0 0 1 62.69291 627.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Plac easy tests) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Plac easy tests) Tj T* ET Q Q q -1 0 0 1 62.69291 549.0236 cm +1 0 0 1 62.69291 585.0236 cm q -BT 1 0 0 1 0 28.82 Tm 1.517126 Tw 12 TL /F1 10 Tf 0 0 0 rg (Writing your tests in terms of ) Tj /F3 10 Tf (Interpreter.check ) Tj /F1 10 Tf (is certainly an improvement over writing them in) Tj T* 0 Tw 1.807318 Tw (terms of ) Tj /F3 10 Tf (plac.call) Tj /F1 10 Tf (, but they are still too low-level for my taste. The ) Tj /F3 10 Tf (Interpreter ) Tj /F1 10 Tf (class provides) Tj T* 0 Tw (support for doctest-style tests, a.k.a. ) Tj /F4 10 Tf (plac easy tests) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.517126 Tw 12 TL /F1 10 Tf 0 0 0 rg (Writing your tests in terms of ) Tj /F3 10 Tf (Interpreter.check ) Tj /F1 10 Tf (is certainly an improvement over writing them in) Tj T* 0 Tw 1.807318 Tw (terms of ) Tj /F3 10 Tf (plac.call) Tj /F1 10 Tf (, but they are still too low-level for my taste. The ) Tj /F3 10 Tf (Interpreter ) Tj /F1 10 Tf (class provides) Tj T* 0 Tw (support for doctest-style tests, a.k.a. ) Tj /F4 10 Tf (plac easy tests) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 62.69291 507.0236 cm +1 0 0 1 62.69291 543.0236 cm q -BT 1 0 0 1 0 28.82 Tm 2.142209 Tw 12 TL /F1 10 Tf 0 0 0 rg (By using plac easy tests you can cut and paste your interactive session and turn it into a runnable) Tj T* 0 Tw .519213 Tw (automatics test. Consider for instance the following file ) Tj /F3 10 Tf (ishelve.placet ) Tj /F1 10 Tf (\(the ) Tj /F3 10 Tf (.placet ) Tj /F1 10 Tf (extension is a) Tj T* 0 Tw (mnemonic for plac easy tests\):) Tj T* ET +BT 1 0 0 1 0 26 Tm 2.142209 Tw 12 TL /F1 10 Tf 0 0 0 rg (By using plac easy tests you can cut and paste your interactive session and turn it into a runnable) Tj T* 0 Tw .519213 Tw (automatics test. Consider for instance the following file ) Tj /F3 10 Tf (ishelve.placet ) Tj /F1 10 Tf (\(the ) Tj /F3 10 Tf (.placet ) Tj /F1 10 Tf (extension is a) Tj T* 0 Tw (mnemonic for plac easy tests\):) Tj T* ET Q Q q -1 0 0 1 62.69291 329.8236 cm +1 0 0 1 62.69291 365.8236 cm q q 1 0 0 1 0 0 cm @@ -9271,26 +9177,26 @@ q n -6 -6 468.6898 168 re B* Q q -BT 1 0 0 1 0 149.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (#!ishelve.py) Tj T* (i) Tj (>) Tj ( .clear # start from a clean state) Tj T* (cleared the shelve) Tj T* (i) Tj (>) Tj ( a=1) Tj T* (setting a=1) Tj T* (i) Tj (>) Tj ( a) Tj T* (1) Tj T* (i) Tj (>) Tj ( .del a) Tj T* (deleted a) Tj T* (i) Tj (>) Tj ( a) Tj T* (a: not found) Tj T* (i) Tj (>) Tj ( .cler # spelling error) Tj T* (.cler: not found) Tj T* ET +BT 1 0 0 1 0 146 Tm 12 TL /F3 10 Tf 0 0 0 rg (#!ishelve.py) Tj T* (i) Tj (>) Tj ( .clear # start from a clean state) Tj T* (cleared the shelve) Tj T* (i) Tj (>) Tj ( a=1) Tj T* (setting a=1) Tj T* (i) Tj (>) Tj ( a) Tj T* (1) Tj T* (i) Tj (>) Tj ( .del a) Tj T* (deleted a) Tj T* (i) Tj (>) Tj ( a) Tj T* (a: not found) Tj T* (i) Tj (>) Tj ( .cler # spelling error) Tj T* (.cler: not found) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 273.8236 cm +1 0 0 1 62.69291 309.8236 cm q -BT 1 0 0 1 0 40.82 Tm .697132 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice the precence of the shebang line containing the name of the ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (tool to test \(a ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (tool is just a) Tj T* 0 Tw 1.511751 Tw (Python module with a function called ) Tj /F3 10 Tf (main) Tj /F1 10 Tf (\). The shebang is ignored by the interpreter \(it looks like a) Tj T* 0 Tw .487608 Tw (comment to it\) but it is there so that external tools \(say a test runner\) can infer the plac interpreter to use) Tj T* 0 Tw (to test the file.) Tj T* ET +BT 1 0 0 1 0 38 Tm .697132 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice the precence of the shebang line containing the name of the ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (tool to test \(a ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (tool is just a) Tj T* 0 Tw 1.511751 Tw (Python module with a function called ) Tj /F3 10 Tf (main) Tj /F1 10 Tf (\). The shebang is ignored by the interpreter \(it looks like a) Tj T* 0 Tw .487608 Tw (comment to it\) but it is there so that external tools \(say a test runner\) can infer the plac interpreter to use) Tj T* 0 Tw (to test the file.) Tj T* ET Q Q q -1 0 0 1 62.69291 243.8236 cm +1 0 0 1 62.69291 279.8236 cm q -BT 1 0 0 1 0 16.82 Tm 2.419984 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can test ) Tj /F3 10 Tf (ishelve.placet ) Tj /F1 10 Tf (file by calling the ) Tj /F3 10 Tf (.doctest ) Tj /F1 10 Tf (method of the interpreter, as in this) Tj T* 0 Tw (example:) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.419984 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can test ) Tj /F3 10 Tf (ishelve.placet ) Tj /F1 10 Tf (file by calling the ) Tj /F3 10 Tf (.doctest ) Tj /F1 10 Tf (method of the interpreter, as in this) Tj T* 0 Tw (example:) Tj T* ET Q Q q -1 0 0 1 62.69291 199.0393 cm +1 0 0 1 62.69291 235.0393 cm q q .988825 0 0 .988825 0 0 cm @@ -9304,67 +9210,72 @@ n -6 -6 474 36 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 17.71 Tm /F3 10 Tf 12 TL ($ python -c"import plac, ishelve) Tj T* (plac.Interpreter\(ishelve.main\).doctest\(open\('ishelve.placet'\), verbose=True\)") Tj T* ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL ($ python -c"import plac, ishelve) Tj T* (plac.Interpreter\(ishelve.main\).doctest\(open\('ishelve.placet'\), verbose=True\)") Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 155.0393 cm +1 0 0 1 62.69291 191.0393 cm q -BT 1 0 0 1 0 28.82 Tm 4.007109 Tw 12 TL /F1 10 Tf 0 0 0 rg (Internally ) Tj /F3 10 Tf (Interpreter.doctests ) Tj /F1 10 Tf (invokes something like ) Tj /F3 10 Tf (Interpreter.check ) Tj /F1 10 Tf (multiple times) Tj T* 0 Tw .226654 Tw (inside the same context and compare the output with the expected output: if even a check fails, the whole) Tj T* 0 Tw (test fail.) Tj T* ET +BT 1 0 0 1 0 26 Tm 4.007109 Tw 12 TL /F1 10 Tf 0 0 0 rg (Internally ) Tj /F3 10 Tf (Interpreter.doctests ) Tj /F1 10 Tf (invokes something like ) Tj /F3 10 Tf (Interpreter.check ) Tj /F1 10 Tf (multiple times) Tj T* 0 Tw .226654 Tw (inside the same context and compare the output with the expected output: if even a check fails, the whole) Tj T* 0 Tw (test fail.) Tj T* ET Q Q q -1 0 0 1 62.69291 113.0393 cm +1 0 0 1 62.69291 149.0393 cm q -BT 1 0 0 1 0 28.82 Tm .175868 Tw 12 TL /F1 10 Tf 0 0 0 rg (You should realize tha the easy tests supported by ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (are ) Tj /F4 10 Tf (not ) Tj /F1 10 Tf (unittests: they are functional tests. They) Tj T* 0 Tw 1.22936 Tw (model then user interaction and the order of the operations generally matters. The single subtests in a) Tj T* 0 Tw /F3 10 Tf (.placet ) Tj /F1 10 Tf (file are not independent and it makes sense to exit immediately at the first failure.) Tj T* ET +BT 1 0 0 1 0 26 Tm .175868 Tw 12 TL /F1 10 Tf 0 0 0 rg (You should realize tha the easy tests supported by ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (are ) Tj /F4 10 Tf (not ) Tj /F1 10 Tf (unittests: they are functional tests. They) Tj T* 0 Tw 1.22936 Tw (model then user interaction and the order of the operations generally matters. The single subtests in a) Tj T* 0 Tw /F3 10 Tf (.placet ) Tj /F1 10 Tf (file are not independent and it makes sense to exit immediately at the first failure.) Tj T* ET +Q +Q +q +1 0 0 1 62.69291 95.03932 cm +q +BT 1 0 0 1 0 38 Tm .414431 Tw 12 TL /F1 10 Tf 0 0 0 rg (The support for doctests in ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (comes nearly for free, thanks to the ) Tj 0 0 .501961 rg (shlex ) Tj 0 0 0 rg (module in the standard library, ) Tj T* 0 Tw .352765 Tw (which is able to parse simple languages as the ones you can implement with ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (. In particular, thanks to ) Tj T* 0 Tw .875984 Tw 0 0 .501961 rg (shlex) Tj 0 0 0 rg (, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is able to recognize comments \(the default comment character is ) Tj /F3 10 Tf (#) Tj /F1 10 Tf (\), escape sequences and ) Tj T* 0 Tw 1.50686 Tw (more. Look at the ) Tj 0 0 .501961 rg (shlex ) Tj 0 0 0 rg (documentation if you need to customize how the language is interpreted. For) Tj T* 0 Tw ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (22) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (22) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R359': class PDFStream 359 0 obj % page stream -<< /Length 6456 >> +<< /Length 5725 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 693.0236 cm +1 0 0 1 62.69291 741.0236 cm q -BT 1 0 0 1 0 64.82 Tm .414431 Tw 12 TL /F1 10 Tf 0 0 0 rg (The support for doctests in ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (comes nearly for free, thanks to the ) Tj 0 0 .501961 rg (shlex ) Tj 0 0 0 rg (module in the standard library,) Tj T* 0 Tw .352765 Tw (which is able to parse simple languages as the ones you can implement with ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (. In particular, thanks to) Tj T* 0 Tw .875984 Tw 0 0 .501961 rg (shlex) Tj 0 0 0 rg (, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is able to recognize comments \(the default comment character is ) Tj /F3 10 Tf (#) Tj /F1 10 Tf (\), escape sequences and) Tj T* 0 Tw 1.50686 Tw (more. Look at the ) Tj 0 0 .501961 rg (shlex ) Tj 0 0 0 rg (documentation if you need to customize how the language is interpreted. For) Tj T* 0 Tw 2.794985 Tw (more flexibility, it is even possible to pass to the interpreter a custom split function with signature) Tj T* 0 Tw /F3 10 Tf (split\(line, commentchar\)) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.794985 Tw 12 TL /F1 10 Tf 0 0 0 rg (more flexibility, it is even possible to pass to the interpreter a custom split function with signature) Tj T* 0 Tw /F3 10 Tf (split\(line, commentchar\)) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 62.69291 639.0236 cm +1 0 0 1 62.69291 687.0236 cm q -BT 1 0 0 1 0 40.82 Tm .136654 Tw 12 TL /F1 10 Tf 0 0 0 rg (In addition, I have implemented from scratch some support for line number recognition, so that if a test fail) Tj T* 0 Tw .042093 Tw (you get the line number of the failing command. This is especially useful if your tests are stored in external) Tj T* 0 Tw .610898 Tw (files, even if plac easy tests does not need to be in a file: you can just pass to the ) Tj /F3 10 Tf (.doctest ) Tj /F1 10 Tf (method a) Tj T* 0 Tw (list of strings corresponding to the lines of the file.) Tj T* ET +BT 1 0 0 1 0 38 Tm .136654 Tw 12 TL /F1 10 Tf 0 0 0 rg (In addition, I have implemented from scratch some support for line number recognition, so that if a test fail) Tj T* 0 Tw .042093 Tw (you get the line number of the failing command. This is especially useful if your tests are stored in external) Tj T* 0 Tw .610898 Tw (files, even if plac easy tests does not need to be in a file: you can just pass to the ) Tj /F3 10 Tf (.doctest ) Tj /F1 10 Tf (method a) Tj T* 0 Tw (list of strings corresponding to the lines of the file.) Tj T* ET Q Q q -1 0 0 1 62.69291 609.0236 cm +1 0 0 1 62.69291 657.0236 cm q -BT 1 0 0 1 0 16.82 Tm .653145 Tw 12 TL /F1 10 Tf 0 0 0 rg (At the present ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (does not use any code from the doctest module, but the situation may change in the) Tj T* 0 Tw (future \(it would be nice if ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (could reuse doctests directives like ELLIPSIS\).) Tj T* ET +BT 1 0 0 1 0 14 Tm .653145 Tw 12 TL /F1 10 Tf 0 0 0 rg (At the present ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (does not use any code from the doctest module, but the situation may change in the) Tj T* 0 Tw (future \(it would be nice if ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (could reuse doctests directives like ELLIPSIS\).) Tj T* ET Q Q q -1 0 0 1 62.69291 579.0236 cm +1 0 0 1 62.69291 627.0236 cm q -BT 1 0 0 1 0 16.82 Tm 1.447318 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is straighforward to integrate your ) Tj /F3 10 Tf (.placet ) Tj /F1 10 Tf (tests with standard testing tools. For instance, you can) Tj T* 0 Tw (integrate your doctests with ) Tj /F3 10 Tf (nose ) Tj /F1 10 Tf (or ) Tj /F3 10 Tf (py.test ) Tj /F1 10 Tf (as follow:) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.447318 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is straighforward to integrate your ) Tj /F3 10 Tf (.placet ) Tj /F1 10 Tf (tests with standard testing tools. For instance, you can) Tj T* 0 Tw (integrate your doctests with ) Tj /F3 10 Tf (nose ) Tj /F1 10 Tf (or ) Tj /F3 10 Tf (py.test ) Tj /F1 10 Tf (as follow:) Tj T* ET Q Q q -1 0 0 1 62.69291 391.8485 cm +1 0 0 1 62.69291 439.8485 cm q q .988825 0 0 .988825 0 0 cm @@ -9378,40 +9289,40 @@ n -6 -6 474 180 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 161.71 Tm /F3 10 Tf 12 TL (import os, shlex, plac) Tj T* T* (def test_doct\(\):) Tj T* ( """) Tj T* ( Find all the doctests in the current directory and run them with the) Tj T* ( corresponding plac interpreter \(the shebang rules!\)) Tj T* ( """) Tj T* ( placets = [f for f in os.listdir\('.'\) if f.endswith\('.placet'\)]) Tj T* ( for placet in placets:) Tj T* ( lines = list\(open\(placet\)\)) Tj T* ( assert lines[0].startswith\('#!'\), 'Missing or incorrect shebang line!') Tj T* ( firstline = lines[0][2:] # strip the shebang) Tj T* ( main = plac.import_main\(*shlex.split\(firstline\)\)) Tj T* ( yield plac.Interpreter\(main\).doctest, lines[1:]) Tj T* ET +BT 1 0 0 1 0 158 Tm /F3 10 Tf 12 TL (import os, shlex, plac) Tj T* T* (def test_doct\(\):) Tj T* ( """) Tj T* ( Find all the doctests in the current directory and run them with the) Tj T* ( corresponding plac interpreter \(the shebang rules!\)) Tj T* ( """) Tj T* ( placets = [f for f in os.listdir\('.'\) if f.endswith\('.placet'\)]) Tj T* ( for placet in placets:) Tj T* ( lines = list\(open\(placet\)\)) Tj T* ( assert lines[0].startswith\('#!'\), 'Missing or incorrect shebang line!') Tj T* ( firstline = lines[0][2:] # strip the shebang) Tj T* ( main = plac.import_main\(*shlex.split\(firstline\)\)) Tj T* ( yield plac.Interpreter\(main\).doctest, lines[1:]) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 311.8485 cm +1 0 0 1 62.69291 359.8485 cm q -BT 1 0 0 1 0 64.82 Tm 1.44811 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here you should notice that usage of ) Tj /F3 10 Tf (plac.import_main) Tj /F1 10 Tf (, an utility which is able to import the main) Tj T* 0 Tw .775703 Tw (function of the script specified in the shebang line. You can use both the full path name of the tool, or a) Tj T* 0 Tw .87686 Tw (relative path name. In this case the runner look at the environment variable ) Tj /F3 10 Tf (PLACPATH ) Tj /F1 10 Tf (and it searches) Tj T* 0 Tw 1.900651 Tw (the plac tool in the directories specified there \() Tj /F3 10 Tf (PLACPATH ) Tj /F1 10 Tf (is just a string containing directory names) Tj T* 0 Tw .56332 Tw (separated by colons\). If the variable ) Tj /F3 10 Tf (PLACPATH ) Tj /F1 10 Tf (is not defined, it just looks in the current directory. If the) Tj T* 0 Tw (plac tool is not found, an ) Tj /F3 10 Tf (ImportError ) Tj /F1 10 Tf (is raised.) Tj T* ET +BT 1 0 0 1 0 62 Tm 1.44811 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here you should notice that usage of ) Tj /F3 10 Tf (plac.import_main) Tj /F1 10 Tf (, an utility which is able to import the main) Tj T* 0 Tw .775703 Tw (function of the script specified in the shebang line. You can use both the full path name of the tool, or a) Tj T* 0 Tw .87686 Tw (relative path name. In this case the runner look at the environment variable ) Tj /F3 10 Tf (PLACPATH ) Tj /F1 10 Tf (and it searches) Tj T* 0 Tw 1.900651 Tw (the plac tool in the directories specified there \() Tj /F3 10 Tf (PLACPATH ) Tj /F1 10 Tf (is just a string containing directory names) Tj T* 0 Tw .56332 Tw (separated by colons\). If the variable ) Tj /F3 10 Tf (PLACPATH ) Tj /F1 10 Tf (is not defined, it just looks in the current directory. If the) Tj T* 0 Tw (plac tool is not found, an ) Tj /F3 10 Tf (ImportError ) Tj /F1 10 Tf (is raised.) Tj T* ET Q Q q -1 0 0 1 62.69291 281.8485 cm +1 0 0 1 62.69291 329.8485 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Plac batch scripts) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Plac batch scripts) Tj T* ET Q Q q -1 0 0 1 62.69291 239.8485 cm +1 0 0 1 62.69291 287.8485 cm q -BT 1 0 0 1 0 28.82 Tm .772093 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is pretty easy to realize that an interactive interpreter can also be used to run batch scripts: instead of) Tj T* 0 Tw .504692 Tw (reading the commands from the console, it is enough to read the commands from a file. ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (interpreters) Tj T* 0 Tw (provide an ) Tj /F3 10 Tf (.execute ) Tj /F1 10 Tf (method to perform just that.) Tj T* ET +BT 1 0 0 1 0 26 Tm .772093 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is pretty easy to realize that an interactive interpreter can also be used to run batch scripts: instead of) Tj T* 0 Tw .504692 Tw (reading the commands from the console, it is enough to read the commands from a file. ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (interpreters) Tj T* 0 Tw (provide an ) Tj /F3 10 Tf (.execute ) Tj /F1 10 Tf (method to perform just that.) Tj T* ET Q Q q -1 0 0 1 62.69291 173.8485 cm +1 0 0 1 62.69291 221.8485 cm q -BT 1 0 0 1 0 52.82 Tm .098935 Tw 12 TL /F1 10 Tf 0 0 0 rg (There is just a subtle point to notice: whereas in an interactive loop one wants to manage all exceptions, a) Tj T* 0 Tw 3.866412 Tw (batch script should not in the background in case of unexpected errors. The implementation of) Tj T* 0 Tw .103059 Tw /F3 10 Tf (Interpreter.execute ) Tj /F1 10 Tf (makes sure that any error raised by ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (internally is re-raised. In other) Tj T* 0 Tw .407045 Tw (words, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (interpreters ) Tj /F4 10 Tf (wrap the errors, but does not eat them) Tj /F1 10 Tf (: the errors are always accessible and can) Tj T* 0 Tw (be re-raised on demand.) Tj T* ET +BT 1 0 0 1 0 50 Tm .098935 Tw 12 TL /F1 10 Tf 0 0 0 rg (There is just a subtle point to notice: whereas in an interactive loop one wants to manage all exceptions, a) Tj T* 0 Tw 3.866412 Tw (batch script should not in the background in case of unexpected errors. The implementation of) Tj T* 0 Tw .103059 Tw /F3 10 Tf (Interpreter.execute ) Tj /F1 10 Tf (makes sure that any error raised by ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (internally is re-raised. In other) Tj T* 0 Tw .407045 Tw (words, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (interpreters ) Tj /F4 10 Tf (wrap the errors, but does not eat them) Tj /F1 10 Tf (: the errors are always accessible and can) Tj T* 0 Tw (be re-raised on demand.) Tj T* ET Q Q q -1 0 0 1 62.69291 143.8485 cm +1 0 0 1 62.69291 191.8485 cm q -BT 1 0 0 1 0 16.82 Tm 1.239318 Tw 12 TL /F1 10 Tf 0 0 0 rg (The exception is the case of invalid commands, which are skipped. Consider for instance the following) Tj T* 0 Tw (batch file, which contains a mispelled command \() Tj /F3 10 Tf (.dl ) Tj /F1 10 Tf (instead of ) Tj /F3 10 Tf (.del) Tj /F1 10 Tf (\):) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.239318 Tw 12 TL /F1 10 Tf 0 0 0 rg (The exception is the case of invalid commands, which are skipped. Consider for instance the following) Tj T* 0 Tw (batch file, which contains a mispelled command \() Tj /F3 10 Tf (.dl ) Tj /F1 10 Tf (instead of ) Tj /F3 10 Tf (.del) Tj /F1 10 Tf (\):) Tj T* ET Q Q q @@ -9425,11 +9336,11 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 36 re B* +n -6 -6 468.6898 84 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 17.71 Tm /F3 10 Tf 12 TL (#!ishelve.py) Tj T* (.clear ) Tj T* ET +BT 1 0 0 1 0 62 Tm /F3 10 Tf 12 TL (#!ishelve.py) Tj T* (.clear ) Tj T* (a=1 b=2) Tj T* (.show) Tj T* (.del a) Tj T* (.dl b) Tj T* ET Q Q Q @@ -9439,21 +9350,20 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (23) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (23) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R360': class PDFStream 360 0 obj % page stream -<< /Length 4430 >> +<< /Length 4551 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 691.8236 cm +1 0 0 1 62.69291 739.8236 cm q q 1 0 0 1 0 0 cm @@ -9463,24 +9373,24 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 72 re B* +n -6 -6 468.6898 24 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 53.71 Tm /F3 10 Tf 12 TL (a=1 b=2) Tj T* (.show) Tj T* (.del a) Tj T* (.dl b) Tj T* (.show) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (.show) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 659.8236 cm +1 0 0 1 62.69291 707.8236 cm q -BT 1 0 0 1 0 16.82 Tm 1.939461 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you execute the batch file, the interpreter will print a ) Tj /F3 10 Tf (.dl: not found ) Tj /F1 10 Tf (at the ) Tj /F3 10 Tf (.dl ) Tj /F1 10 Tf (line and will) Tj T* 0 Tw (continue:) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.939461 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you execute the batch file, the interpreter will print a ) Tj /F3 10 Tf (.dl: not found ) Tj /F1 10 Tf (at the ) Tj /F3 10 Tf (.dl ) Tj /F1 10 Tf (line and will) Tj T* 0 Tw (continue:) Tj T* ET Q Q q -1 0 0 1 62.69291 434.6236 cm +1 0 0 1 62.69291 482.6236 cm q q 1 0 0 1 0 0 cm @@ -9493,47 +9403,47 @@ q n -6 -6 468.6898 216 re B* Q q -BT 1 0 0 1 0 197.71 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ python -c "import plac, ishelve) Tj T* (plac.Interpreter\(ishelve.main\).execute\(open\('ishelve.plac'\), verbose=True\)") Tj T* (i) Tj (>) Tj ( .clear) Tj T* (cleared the shelve) Tj T* (i) Tj (>) Tj ( a=1 b=2) Tj T* (setting a=1) Tj T* (setting b=2) Tj T* (i) Tj (>) Tj ( .show) Tj T* (b=2) Tj T* (a=1) Tj T* (i) Tj (>) Tj ( .del a) Tj T* (deleted a) Tj T* (i) Tj (>) Tj ( .dl b) Tj T* (2) Tj T* (.dl: not found) Tj T* (i) Tj (>) Tj ( .show) Tj T* (b=2) Tj T* ET +BT 1 0 0 1 0 194 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ python -c "import plac, ishelve) Tj T* (plac.Interpreter\(ishelve.main\).execute\(open\('ishelve.plac'\), verbose=True\)") Tj T* (i) Tj (>) Tj ( .clear) Tj T* (cleared the shelve) Tj T* (i) Tj (>) Tj ( a=1 b=2) Tj T* (setting a=1) Tj T* (setting b=2) Tj T* (i) Tj (>) Tj ( .show) Tj T* (b=2) Tj T* (a=1) Tj T* (i) Tj (>) Tj ( .del a) Tj T* (deleted a) Tj T* (i) Tj (>) Tj ( .dl b) Tj T* (2) Tj T* (.dl: not found) Tj T* (i) Tj (>) Tj ( .show) Tj T* (b=2) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 390.6236 cm +1 0 0 1 62.69291 438.6236 cm q -BT 1 0 0 1 0 28.82 Tm .159988 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf (verbose ) Tj /F1 10 Tf (flag is there to show the lines which are being interpreted \(prefixed by ) Tj /F3 10 Tf (i) Tj (>) Tj /F1 10 Tf (\). This is done on) Tj T* 0 Tw 1.359988 Tw (purpose, so that you can cut and paste the output of the batch script and turn it into a ) Tj /F3 10 Tf (.placet ) Tj /F1 10 Tf (test) Tj T* 0 Tw (\(cool, isn't it?\).) Tj T* ET +BT 1 0 0 1 0 26 Tm .159988 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf (verbose ) Tj /F1 10 Tf (flag is there to show the lines which are being interpreted \(prefixed by ) Tj /F3 10 Tf (i) Tj (>) Tj /F1 10 Tf (\). This is done on) Tj T* 0 Tw 1.359988 Tw (purpose, so that you can cut and paste the output of the batch script and turn it into a ) Tj /F3 10 Tf (.placet ) Tj /F1 10 Tf (test) Tj T* 0 Tw (\(cool, isn't it?\).) Tj T* ET Q Q q -1 0 0 1 62.69291 360.6236 cm +1 0 0 1 62.69291 408.6236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Implementing subcommands) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Implementing subcommands) Tj T* ET Q Q q -1 0 0 1 62.69291 318.6236 cm +1 0 0 1 62.69291 366.6236 cm q -BT 1 0 0 1 0 28.82 Tm 1.182485 Tw 12 TL /F1 10 Tf 0 0 0 rg (When I discussed the ) Tj /F3 10 Tf (ishelve ) Tj /F1 10 Tf (implementation in the ) Tj 0 0 .501961 rg (basic documentation) Tj 0 0 0 rg (, I said that it looked like a) Tj T* 0 Tw .116655 Tw (poor man implementation of an object system as a chain of elifs; I also said that ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (was able to do much) Tj T* 0 Tw (better than that. Here I will substantiate my claim.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.182485 Tw 12 TL /F1 10 Tf 0 0 0 rg (When I discussed the ) Tj /F3 10 Tf (ishelve ) Tj /F1 10 Tf (implementation in the ) Tj 0 0 .501961 rg (basic documentation) Tj 0 0 0 rg (, I said that it looked like a) Tj T* 0 Tw .116655 Tw (poor man implementation of an object system as a chain of elifs; I also said that ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (was able to do much) Tj T* 0 Tw (better than that. Here I will substantiate my claim.) Tj T* ET Q Q q -1 0 0 1 62.69291 276.6236 cm +1 0 0 1 62.69291 324.6236 cm q -BT 1 0 0 1 0 28.82 Tm .89104 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is actually able to infer a set of subparsers from a generic container of commands. This is useful if) Tj T* 0 Tw 3.125814 Tw (you want to implement ) Tj /F4 10 Tf (subcommands ) Tj /F1 10 Tf (\(a familiar example of a command-line application featuring) Tj T* 0 Tw (subcommands is subversion\).) Tj T* ET +BT 1 0 0 1 0 26 Tm .89104 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is actually able to infer a set of subparsers from a generic container of commands. This is useful if) Tj T* 0 Tw 3.125814 Tw (you want to implement ) Tj /F4 10 Tf (subcommands ) Tj /F1 10 Tf (\(a familiar example of a command-line application featuring) Tj T* 0 Tw (subcommands is subversion\).) Tj T* ET Q Q q -1 0 0 1 62.69291 210.6236 cm +1 0 0 1 62.69291 258.6236 cm q -BT 1 0 0 1 0 52.82 Tm .015868 Tw 12 TL /F1 10 Tf 0 0 0 rg (Technically a container of commands is any object with a ) Tj /F3 10 Tf (.commands ) Tj /F1 10 Tf (attribute listing a set of functions or) Tj T* 0 Tw 2.550888 Tw (methods which are valid commands. A command container may have initialization/finalization hooks) Tj T* 0 Tw 2.55664 Tw (\() Tj /F3 10 Tf (__enter__/__exit__) Tj /F1 10 Tf (\) and dispatch hooks \() Tj /F3 10 Tf (__missing__) Tj /F1 10 Tf (, invoked for invalid command names\).) Tj T* 0 Tw 2.113828 Tw (Moreover, only when using command containers ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is able to provide automatic autocompletion of) Tj T* 0 Tw (commands.) Tj T* ET +BT 1 0 0 1 0 50 Tm .015868 Tw 12 TL /F1 10 Tf 0 0 0 rg (Technically a container of commands is any object with a ) Tj /F3 10 Tf (.commands ) Tj /F1 10 Tf (attribute listing a set of functions or) Tj T* 0 Tw 2.550888 Tw (methods which are valid commands. A command container may have initialization/finalization hooks) Tj T* 0 Tw 2.55664 Tw (\() Tj /F3 10 Tf (__enter__/__exit__) Tj /F1 10 Tf (\) and dispatch hooks \() Tj /F3 10 Tf (__missing__) Tj /F1 10 Tf (, invoked for invalid command names\).) Tj T* 0 Tw 2.113828 Tw (Moreover, only when using command containers ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is able to provide automatic autocompletion of) Tj T* 0 Tw (commands.) Tj T* ET Q Q q -1 0 0 1 62.69291 192.6236 cm +1 0 0 1 62.69291 240.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (The shelve interface can be rewritten in an object-oriented way as follows:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The shelve interface can be rewritten in an object-oriented way as follows:) Tj T* ET Q Q q @@ -9547,11 +9457,11 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 84 re B* +n -6 -6 468.6898 132 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 65.71 Tm /F3 10 Tf 12 TL (# ishelve2.py) Tj T* (import shelve, os, sys, plac) Tj T* T* (class ShelveInterface\(object\):) Tj T* ( "A minimal interface over a shelve object.") Tj T* ( commands = 'set', 'show', 'showall', 'delete') Tj T* ET +BT 1 0 0 1 0 110 Tm /F3 10 Tf 12 TL (# ishelve2.py) Tj T* (import shelve, os, sys, plac) Tj T* T* (class ShelveInterface\(object\):) Tj T* ( "A minimal interface over a shelve object.") Tj T* ( commands = 'set', 'show', 'showall', 'delete') Tj T* ( @plac.annotations\() Tj T* ( configfile=\('path name of the shelve', 'option'\)\)) Tj T* ( def __init__\(self, configfile\):) Tj T* ( self.configfile = configfile or '~/conf.shelve') Tj T* ET Q Q Q @@ -9561,21 +9471,20 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (24) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (24) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R361': class PDFStream 361 0 obj % page stream -<< /Length 4341 >> +<< /Length 4528 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 307.8236 cm +1 0 0 1 62.69291 355.8236 cm q q 1 0 0 1 0 0 cm @@ -9585,54 +9494,73 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 456 re B* +n -6 -6 468.6898 408 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 437.71 Tm /F3 10 Tf 12 TL ( @plac.annotations\() Tj T* ( configfile=\('path name of the shelve', 'option'\)\)) Tj T* ( def __init__\(self, configfile\):) Tj T* ( self.configfile = configfile or '~/conf.shelve') Tj T* ( self.fname = os.path.expanduser\(self.configfile\)) Tj T* ( self.__doc__ += '\\nOperating on %s.\\n.help to see '\\) Tj T* ( 'the available commands.\\n' % self.fname) Tj T* ( def __enter__\(self\):) Tj T* ( self.sh = shelve.open\(self.fname\)) Tj T* ( return self) Tj T* ( def __exit__\(self, etype, exc, tb\):) Tj T* ( self.sh.close\(\)) Tj T* ( def set\(self, name, value\):) Tj T* ( "set name value") Tj T* ( yield 'setting %s=%s' % \(name, value\)) Tj T* ( self.sh[name] = value) Tj T* ( def show\(self, *names\):) Tj T* ( "show given parameters") Tj T* ( for name in names:) Tj T* ( yield '%s = %s' % \(name, self.sh[name]\) # no error checking) Tj T* ( def showall\(self\):) Tj T* ( "show all parameters") Tj T* ( for name in self.sh:) Tj T* ( yield '%s = %s' % \(name, self.sh[name]\)) Tj T* ( def delete\(self, name=None\):) Tj T* ( "delete given parameter \(or everything\)") Tj T* ( if name is None:) Tj T* ( yield 'deleting everything') Tj T* ( self.sh.clear\(\)) Tj T* ( else:) Tj T* ( yield 'deleting %s' % name) Tj T* ( del self.sh[name] # no error checking) Tj T* T* (main = ShelveInterface # useful for the tests) Tj T* T* (if __name__ == '__main__':) Tj T* ( plac.Interpreter.call\(ShelveInterface\)) Tj T* ET +BT 1 0 0 1 0 386 Tm /F3 10 Tf 12 TL ( self.fname = os.path.expanduser\(self.configfile\)) Tj T* ( self.__doc__ += '\\nOperating on %s.\\n.help to see '\\) Tj T* ( 'the available commands.\\n' % self.fname) Tj T* ( def __enter__\(self\):) Tj T* ( self.sh = shelve.open\(self.fname\)) Tj T* ( return self) Tj T* ( def __exit__\(self, etype, exc, tb\):) Tj T* ( self.sh.close\(\)) Tj T* ( def set\(self, name, value\):) Tj T* ( "set name value") Tj T* ( yield 'setting %s=%s' % \(name, value\)) Tj T* ( self.sh[name] = value) Tj T* ( def show\(self, *names\):) Tj T* ( "show given parameters") Tj T* ( for name in names:) Tj T* ( yield '%s = %s' % \(name, self.sh[name]\) # no error checking) Tj T* ( def showall\(self\):) Tj T* ( "show all parameters") Tj T* ( for name in self.sh:) Tj T* ( yield '%s = %s' % \(name, self.sh[name]\)) Tj T* ( def delete\(self, name=None\):) Tj T* ( "delete given parameter \(or everything\)") Tj T* ( if name is None:) Tj T* ( yield 'deleting everything') Tj T* ( self.sh.clear\(\)) Tj T* ( else:) Tj T* ( yield 'deleting %s' % name) Tj T* ( del self.sh[name] # no error checking) Tj T* T* (main = ShelveInterface # useful for the tests) Tj T* T* (if __name__ == '__main__':) Tj T* ( plac.Interpreter.call\(ShelveInterface\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 215.8236 cm +1 0 0 1 62.69291 263.8236 cm q -BT 1 0 0 1 0 76.82 Tm .885366 Tw 12 TL /F3 10 Tf 0 0 0 rg (plac.Interpreter ) Tj /F1 10 Tf (objects wrap context manager objects consistently. In other words, if you wrap an) Tj T* 0 Tw 2.323828 Tw (object with ) Tj /F3 10 Tf (__enter__ ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (__exit__ ) Tj /F1 10 Tf (methods, they are invoked in the right order \() Tj /F3 10 Tf (__enter__) Tj T* 0 Tw .23528 Tw /F1 10 Tf (before the interpreter loop starts and ) Tj /F3 10 Tf (__exit__ ) Tj /F1 10 Tf (after the interpreter loop ends, both in the regular and in) Tj T* 0 Tw 1.916412 Tw (the exceptional case\). In our example, the methods ) Tj /F3 10 Tf (__enter__ ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (__exit__ ) Tj /F1 10 Tf (make sure the the) Tj T* 0 Tw .339398 Tw (shelve is opened and closed correctly even in the case of exceptions. Notice that I have not implemented) Tj T* 0 Tw .814104 Tw (any error checking in the ) Tj /F3 10 Tf (show ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (delete ) Tj /F1 10 Tf (methods on purpose, to verify that ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (works correctly in) Tj T* 0 Tw (the presence of exceptions.) Tj T* ET +BT 1 0 0 1 0 74 Tm .885366 Tw 12 TL /F3 10 Tf 0 0 0 rg (plac.Interpreter ) Tj /F1 10 Tf (objects wrap context manager objects consistently. In other words, if you wrap an) Tj T* 0 Tw 2.323828 Tw (object with ) Tj /F3 10 Tf (__enter__ ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (__exit__ ) Tj /F1 10 Tf (methods, they are invoked in the right order \() Tj /F3 10 Tf (__enter__) Tj T* 0 Tw .23528 Tw /F1 10 Tf (before the interpreter loop starts and ) Tj /F3 10 Tf (__exit__ ) Tj /F1 10 Tf (after the interpreter loop ends, both in the regular and in) Tj T* 0 Tw 1.916412 Tw (the exceptional case\). In our example, the methods ) Tj /F3 10 Tf (__enter__ ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (__exit__ ) Tj /F1 10 Tf (make sure the the) Tj T* 0 Tw .339398 Tw (shelve is opened and closed correctly even in the case of exceptions. Notice that I have not implemented) Tj T* 0 Tw .814104 Tw (any error checking in the ) Tj /F3 10 Tf (show ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (delete ) Tj /F1 10 Tf (methods on purpose, to verify that ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (works correctly in) Tj T* 0 Tw (the presence of exceptions.) Tj T* ET Q Q q -1 0 0 1 62.69291 137.8236 cm +1 0 0 1 62.69291 185.8236 cm q -BT 1 0 0 1 0 64.82 Tm 1.567126 Tw 12 TL /F1 10 Tf 0 0 0 rg (When working with command containers, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (automatically adds two special commands to the set of) Tj T* 0 Tw 1.176136 Tw (provided commands: ) Tj /F3 10 Tf (.help ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (.last_tb) Tj /F1 10 Tf (. The ) Tj /F3 10 Tf (.help ) Tj /F1 10 Tf (command is the easier to understand: when) Tj T* 0 Tw .39811 Tw (invoked without arguments it displays the list of available commands with the same formatting of the ) Tj 0 0 .501961 rg (cmd) Tj T* 0 Tw 1.19561 Tw 0 0 0 rg (module; when invoked with the name of a command it displays the usage message for that command.) Tj T* 0 Tw 2.33686 Tw (The ) Tj /F3 10 Tf (.last_tb ) Tj /F1 10 Tf (command is useful when debugging: in case of errors, it allows you to display the) Tj T* 0 Tw (traceback of the last executed command.) Tj T* ET +BT 1 0 0 1 0 62 Tm 1.567126 Tw 12 TL /F1 10 Tf 0 0 0 rg (When working with command containers, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (automatically adds two special commands to the set of) Tj T* 0 Tw 1.176136 Tw (provided commands: ) Tj /F3 10 Tf (.help ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (.last_tb) Tj /F1 10 Tf (. The ) Tj /F3 10 Tf (.help ) Tj /F1 10 Tf (command is the easier to understand: when) Tj T* 0 Tw .39811 Tw (invoked without arguments it displays the list of available commands with the same formatting of the ) Tj 0 0 .501961 rg (cmd) Tj T* 0 Tw 1.19561 Tw 0 0 0 rg (module; when invoked with the name of a command it displays the usage message for that command.) Tj T* 0 Tw 2.33686 Tw (The ) Tj /F3 10 Tf (.last_tb ) Tj /F1 10 Tf (command is useful when debugging: in case of errors, it allows you to display the) Tj T* 0 Tw (traceback of the last executed command.) Tj T* ET Q Q q -1 0 0 1 62.69291 119.8236 cm +1 0 0 1 62.69291 167.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Here is a session of usage on an Unix-like operating system:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is a session of usage on an Unix-like operating system:) Tj T* ET +Q +Q +q +1 0 0 1 62.69291 98.62362 cm +q +q +1 0 0 1 0 0 cm +q +1 0 0 1 6.6 6.6 cm +q +.662745 .662745 .662745 RG +.5 w +.960784 .960784 .862745 rg +n -6 -6 468.6898 60 re B* +Q +q +BT 1 0 0 1 0 38 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ python ishelve2.py) Tj T* (A minimal interface over a shelve object.) Tj T* (Operating on /home/micheles/conf.shelve.) Tj T* (.help to see the available commands.) Tj T* ET +Q +Q +Q Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (25) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (25) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R362': class PDFStream 362 0 obj % page stream -<< /Length 4233 >> +<< /Length 4494 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 374.0679 cm +1 0 0 1 62.69291 411.2133 cm q q .773863 0 0 .773863 0 0 cm @@ -9642,35 +9570,35 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 606 504 re B* +n -6 -6 606 456 re B* Q q -BT 1 0 0 1 0 485.71 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ python ishelve2.py) Tj T* (A minimal interface over a shelve object.) Tj T* (Operating on /home/micheles/conf.shelve.) Tj T* (.help to see the available commands.) Tj T* (i) Tj (>) Tj ( .help) Tj T* T* (special commands) Tj T* (================) Tj T* (.help .last_tb) Tj T* T* (custom commands) Tj T* (===============) Tj T* (delete set show showall) Tj T* T* (i) Tj (>) Tj ( delete) Tj T* (deleting everything) Tj T* (i) Tj (>) Tj ( set a pippo) Tj T* (setting a=pippo) Tj T* (i) Tj (>) Tj ( set b lippo) Tj T* (setting b=lippo) Tj T* (i) Tj (>) Tj ( showall) Tj T* (b = lippo) Tj T* (a = pippo) Tj T* (i) Tj (>) Tj ( show a b) Tj T* (a = pippo) Tj T* (b = lippo) Tj T* (i) Tj (>) Tj ( del a) Tj T* (deleting a) Tj T* (i) Tj (>) Tj ( showall) Tj T* (b = lippo) Tj T* (i) Tj (>) Tj ( delete a) Tj T* (deleting a) Tj T* (KeyError: 'a') Tj T* (i) Tj (>) Tj ( .last_tb) Tj T* ( File "/usr/local/lib/python2.6/dist-packages/plac-0.6.0-py2.6.egg/plac_ext.py", line 190, in _wrap) Tj T* ( for value in genobj:) Tj T* ( File "./ishelve2.py", line 37, in delete) Tj T* ( del self.sh[name] # no error checking) Tj T* ( File "/usr/lib/python2.6/shelve.py", line 136, in __delitem__) Tj T* ( del self.dict[key]) Tj T* (i) Tj (>) Tj T* ET +BT 1 0 0 1 0 434 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( .help) Tj T* T* (special commands) Tj T* (================) Tj T* (.help .last_tb) Tj T* T* (custom commands) Tj T* (===============) Tj T* (delete set show showall) Tj T* T* (i) Tj (>) Tj ( delete) Tj T* (deleting everything) Tj T* (i) Tj (>) Tj ( set a pippo) Tj T* (setting a=pippo) Tj T* (i) Tj (>) Tj ( set b lippo) Tj T* (setting b=lippo) Tj T* (i) Tj (>) Tj ( showall) Tj T* (b = lippo) Tj T* (a = pippo) Tj T* (i) Tj (>) Tj ( show a b) Tj T* (a = pippo) Tj T* (b = lippo) Tj T* (i) Tj (>) Tj ( del a) Tj T* (deleting a) Tj T* (i) Tj (>) Tj ( showall) Tj T* (b = lippo) Tj T* (i) Tj (>) Tj ( delete a) Tj T* (deleting a) Tj T* (KeyError: 'a') Tj T* (i) Tj (>) Tj ( .last_tb) Tj T* ( File "/usr/local/lib/python2.6/dist-packages/plac-0.6.0-py2.6.egg/plac_ext.py", line 190, in _wrap) Tj T* ( for value in genobj:) Tj T* ( File "./ishelve2.py", line 37, in delete) Tj T* ( del self.sh[name] # no error checking) Tj T* ( File "/usr/lib/python2.6/shelve.py", line 136, in __delitem__) Tj T* ( del self.dict[key]) Tj T* (i) Tj (>) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 342.0679 cm +1 0 0 1 62.69291 379.2133 cm q -BT 1 0 0 1 0 16.82 Tm 2.571235 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that in interactive mode the traceback is hidden, unless you pass the ) Tj /F3 10 Tf (verbose ) Tj /F1 10 Tf (flag to the) Tj T* 0 Tw /F3 10 Tf (Interpreter.interact ) Tj /F1 10 Tf (method.) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.571235 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that in interactive mode the traceback is hidden, unless you pass the ) Tj /F3 10 Tf (verbose ) Tj /F1 10 Tf (flag to the) Tj T* 0 Tw /F3 10 Tf (Interpreter.interact ) Tj /F1 10 Tf (method.) Tj T* ET Q Q q -1 0 0 1 62.69291 312.0679 cm +1 0 0 1 62.69291 349.2133 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (plac.Interpreter.call) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (plac.Interpreter.call) Tj T* ET Q Q q -1 0 0 1 62.69291 270.0679 cm +1 0 0 1 62.69291 307.2133 cm q -BT 1 0 0 1 0 28.82 Tm 1.066303 Tw 12 TL /F1 10 Tf 0 0 0 rg (At the core of ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (there is the ) Tj /F3 10 Tf (call ) Tj /F1 10 Tf (function which invokes a callable with the list of the arguments) Tj T* 0 Tw .937674 Tw (passed at the command-line \() Tj /F3 10 Tf (sys.argv[1:]) Tj /F1 10 Tf (\). Thanks to ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (you can launch your module by) Tj T* 0 Tw (simply adding the lines:) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.066303 Tw 12 TL /F1 10 Tf 0 0 0 rg (At the core of ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (there is the ) Tj /F3 10 Tf (call ) Tj /F1 10 Tf (function which invokes a callable with the list of the arguments) Tj T* 0 Tw .937674 Tw (passed at the command-line \() Tj /F3 10 Tf (sys.argv[1:]) Tj /F1 10 Tf (\). Thanks to ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (you can launch your module by) Tj T* 0 Tw (simply adding the lines:) Tj T* ET Q Q q -1 0 0 1 62.69291 224.8679 cm +1 0 0 1 62.69291 262.0133 cm q q 1 0 0 1 0 0 cm @@ -9684,20 +9612,20 @@ n -6 -6 468.6898 36 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 17.71 Tm /F3 10 Tf 12 TL (if __name__ == '__main__':) Tj T* ( plac.call\(main\)) Tj T* ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL (if __name__ == '__main__':) Tj T* ( plac.call\(main\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 168.8679 cm +1 0 0 1 62.69291 206.0133 cm q -BT 1 0 0 1 0 40.82 Tm .50436 Tw 12 TL /F1 10 Tf 0 0 0 rg (Everything works fine if ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (is a simple callable performing some action; however, in many cases, one) Tj T* 0 Tw .087633 Tw (has a ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf ("function" which is a actually a factory returning a command container object. For instance, in) Tj T* 0 Tw .573318 Tw (my second shelve example the main function is the class ) Tj /F3 10 Tf (ShelveInterface) Tj /F1 10 Tf (, and the two lines needed) Tj T* 0 Tw (to run the module are a bit ugly:) Tj T* ET +BT 1 0 0 1 0 38 Tm .50436 Tw 12 TL /F1 10 Tf 0 0 0 rg (Everything works fine if ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (is a simple callable performing some action; however, in many cases, one) Tj T* 0 Tw .087633 Tw (has a ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf ("function" which is a actually a factory returning a command container object. For instance, in) Tj T* 0 Tw .573318 Tw (my second shelve example the main function is the class ) Tj /F3 10 Tf (ShelveInterface) Tj /F1 10 Tf (, and the two lines needed) Tj T* 0 Tw (to run the module are a bit ugly:) Tj T* ET Q Q q -1 0 0 1 62.69291 123.6679 cm +1 0 0 1 62.69291 160.8133 cm q q 1 0 0 1 0 0 cm @@ -9711,43 +9639,42 @@ n -6 -6 468.6898 36 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 17.71 Tm /F3 10 Tf 12 TL (if __name__ == '__main__':) Tj T* ( plac.Interpreter\(plac.call\(ShelveInterface\)\).interact\(\)) Tj T* ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL (if __name__ == '__main__':) Tj T* ( plac.Interpreter\(plac.call\(ShelveInterface\)\).interact\(\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 91.66791 cm +1 0 0 1 62.69291 92.81335 cm q -BT 1 0 0 1 0 16.82 Tm .435227 Tw 12 TL /F1 10 Tf 0 0 0 rg (Moreover, now the program runs, but only in interactive mode, i.e. it is not possible to run it as a script. It ) Tj T* 0 Tw .721098 Tw (would be nice instead to be able to specify the command to execute on the command-line and have the) Tj T* 0 Tw ET +BT 1 0 0 1 0 50 Tm .435227 Tw 12 TL /F1 10 Tf 0 0 0 rg (Moreover, now the program runs, but only in interactive mode, i.e. it is not possible to run it as a script. It ) Tj T* 0 Tw .721098 Tw (would be nice instead to be able to specify the command to execute on the command-line and have the ) Tj T* 0 Tw 4.08229 Tw (interpreter start, execute the command and finish properly \(I mean by calling ) Tj /F3 10 Tf (__enter__ ) Tj /F1 10 Tf (and ) Tj T* 0 Tw .427633 Tw /F3 10 Tf (__exit__) Tj /F1 10 Tf (\) without needing user input. The the script could be called from a batch shell script working in ) Tj T* 0 Tw 2.26816 Tw (the background. In order to provide such functionality ) Tj /F3 10 Tf (plac.Interpreter ) Tj /F1 10 Tf (provides a classmethod) Tj T* 0 Tw ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (26) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (26) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R363': class PDFStream 363 0 obj % page stream -<< /Length 4718 >> +<< /Length 4603 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 693.0236 cm +1 0 0 1 62.69291 729.0236 cm q -BT 1 0 0 1 0 64.82 Tm 4.08229 Tw 12 TL /F1 10 Tf 0 0 0 rg (interpreter start, execute the command and finish properly \(I mean by calling ) Tj /F3 10 Tf (__enter__ ) Tj /F1 10 Tf (and) Tj T* 0 Tw .427633 Tw /F3 10 Tf (__exit__) Tj /F1 10 Tf (\) without needing user input. The the script could be called from a batch shell script working in) Tj T* 0 Tw 2.26816 Tw (the background. In order to provide such functionality ) Tj /F3 10 Tf (plac.Interpreter ) Tj /F1 10 Tf (provides a classmethod) Tj T* 0 Tw 1.173318 Tw (named ) Tj /F3 10 Tf (.call ) Tj /F1 10 Tf (which takes the factory, instantiates it with the arguments read from the command line,) Tj T* 0 Tw 1.517045 Tw (wraps the resulting container object as an interpreter and runs it with the rest arguments found in the) Tj T* 0 Tw (command line. Here is the code to turn the ) Tj /F3 10 Tf (ShelveInterface ) Tj /F1 10 Tf (into a script) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.173318 Tw 12 TL /F1 10 Tf 0 0 0 rg (named ) Tj /F3 10 Tf (.call ) Tj /F1 10 Tf (which takes the factory, instantiates it with the arguments read from the command line,) Tj T* 0 Tw 1.517045 Tw (wraps the resulting container object as an interpreter and runs it with the rest arguments found in the) Tj T* 0 Tw (command line. Here is the code to turn the ) Tj /F3 10 Tf (ShelveInterface ) Tj /F1 10 Tf (into a script) Tj T* ET Q Q q -1 0 0 1 62.69291 611.8236 cm +1 0 0 1 62.69291 647.8236 cm q q 1 0 0 1 0 0 cm @@ -9761,21 +9688,21 @@ n -6 -6 468.6898 72 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 53.71 Tm /F3 10 Tf 12 TL (# ishelve3.py) Tj T* (from ishelve2 import ShelveInterface as main) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.Interpreter.call\(main\)) Tj T* ET +BT 1 0 0 1 0 50 Tm /F3 10 Tf 12 TL (# ishelve3.py) Tj T* (from ishelve2 import ShelveInterface as main) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.Interpreter.call\(main\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 591.8236 cm +1 0 0 1 62.69291 627.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (and here are a few examples of usage:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (and here are a few examples of usage:) Tj T* ET Q Q q -1 0 0 1 62.69291 378.6236 cm +1 0 0 1 62.69291 414.6236 cm q q 1 0 0 1 0 0 cm @@ -9789,20 +9716,20 @@ n -6 -6 468.6898 204 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 185.71 Tm /F3 10 Tf 12 TL ($ python ishelve3.py -h) Tj T* (usage: ishelve3.py [-h] [-i] [-configfile CONFIGFILE] [args [args ...]]) Tj T* T* (positional arguments:) Tj T* ( args) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -i, --interact start interactive interpreter) Tj T* ( -configfile CONFIGFILE) Tj T* ( path name of the shelve) Tj T* T* ($ python ishelve3.py set a 1) Tj T* (setting a=1) Tj T* ($ python ishelve3.py show a) Tj T* (a = 1) Tj T* ET +BT 1 0 0 1 0 182 Tm /F3 10 Tf 12 TL ($ python ishelve3.py -h) Tj T* (usage: ishelve3.py [-h] [-i] [-configfile CONFIGFILE] [args [args ...]]) Tj T* T* (positional arguments:) Tj T* ( args) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -i, --interact start interactive interpreter) Tj T* ( -configfile CONFIGFILE) Tj T* ( path name of the shelve) Tj T* T* ($ python ishelve3.py set a 1) Tj T* (setting a=1) Tj T* ($ python ishelve3.py show a) Tj T* (a = 1) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 346.6236 cm +1 0 0 1 62.69291 382.6236 cm q -BT 1 0 0 1 0 16.82 Tm .079989 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you pass the ) Tj /F3 10 Tf (-i ) Tj /F1 10 Tf (flag in the command line, then the script will enter in interactive mode and ask the user) Tj T* 0 Tw (for the commands to execute:) Tj T* ET +BT 1 0 0 1 0 14 Tm .079989 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you pass the ) Tj /F3 10 Tf (-i ) Tj /F1 10 Tf (flag in the command line, then the script will enter in interactive mode and ask the user) Tj T* 0 Tw (for the commands to execute:) Tj T* ET Q Q q -1 0 0 1 62.69291 253.4236 cm +1 0 0 1 62.69291 289.4236 cm q q 1 0 0 1 0 0 cm @@ -9815,26 +9742,26 @@ q n -6 -6 468.6898 84 re B* Q q -BT 1 0 0 1 0 65.71 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ python ishelve3.py -i) Tj T* (A minimal interface over a shelve object.) Tj T* (Operating on /home/micheles/conf.shelve.) Tj T* (.help to see the available commands.) Tj T* T* (i) Tj (>) Tj T* ET +BT 1 0 0 1 0 62 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ python ishelve3.py -i) Tj T* (A minimal interface over a shelve object.) Tj T* (Operating on /home/micheles/conf.shelve.) Tj T* (.help to see the available commands.) Tj T* T* (i) Tj (>) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 209.4236 cm +1 0 0 1 62.69291 245.4236 cm q -BT 1 0 0 1 0 28.82 Tm .221417 Tw 12 TL /F1 10 Tf 0 0 0 rg (In a sense, I have closed the circle: at the beginning of this document I discussed how to turn a script into) Tj T* 0 Tw .784147 Tw (an interactive application \(the ) Tj /F3 10 Tf (shelve_interpreter.py ) Tj /F1 10 Tf (example\), whereas here I have show how to) Tj T* 0 Tw (turn an interactive application into a script.) Tj T* ET +BT 1 0 0 1 0 26 Tm .221417 Tw 12 TL /F1 10 Tf 0 0 0 rg (In a sense, I have closed the circle: at the beginning of this document I discussed how to turn a script into) Tj T* 0 Tw .784147 Tw (an interactive application \(the ) Tj /F3 10 Tf (shelve_interpreter.py ) Tj /F1 10 Tf (example\), whereas here I have show how to) Tj T* 0 Tw (turn an interactive application into a script.) Tj T* ET Q Q q -1 0 0 1 62.69291 191.4236 cm +1 0 0 1 62.69291 227.4236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (The complete signature of ) Tj /F3 10 Tf (plac.Interpreter.call ) Tj /F1 10 Tf (is the following:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The complete signature of ) Tj /F3 10 Tf (plac.Interpreter.call ) Tj /F1 10 Tf (is the following:) Tj T* ET Q Q q -1 0 0 1 62.69291 134.2236 cm +1 0 0 1 62.69291 170.2236 cm q q 1 0 0 1 0 0 cm @@ -9847,7 +9774,7 @@ q n -6 -6 468.6898 48 re B* Q q -BT 1 0 0 1 0 29.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (call\(factory, arglist=sys.argv[1:],) Tj T* ( commentchar='#', split=shlex.split,) Tj T* ( stdin=sys.stdin, prompt='i) Tj (>) Tj ( ', verbose=False\)) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf 0 0 0 rg (call\(factory, arglist=sys.argv[1:],) Tj T* ( commentchar='#', split=shlex.split,) Tj T* ( stdin=sys.stdin, prompt='i) Tj (>) Tj ( ', verbose=False\)) Tj T* ET Q Q Q @@ -9856,46 +9783,39 @@ Q q 1 0 0 1 62.69291 90.22362 cm q -BT 1 0 0 1 0 28.82 Tm 1.756651 Tw 12 TL /F1 10 Tf 0 0 0 rg (The factory must have a fixed number of positional arguments \(no default arguments, no varargs, no ) Tj T* 0 Tw 1.87881 Tw (kwargs\), otherwise a ) Tj /F3 10 Tf (TypeError ) Tj /F1 10 Tf (is raised: the reason is that we want to be able to distinguish the ) Tj T* 0 Tw .829984 Tw (command-line arguments needed to instantiate the factory from the rest arguments that must be sent to) Tj T* 0 Tw ET +BT 1 0 0 1 0 62 Tm 1.756651 Tw 12 TL /F1 10 Tf 0 0 0 rg (The factory must have a fixed number of positional arguments \(no default arguments, no varargs, no) Tj T* 0 Tw 1.87881 Tw (kwargs\), otherwise a ) Tj /F3 10 Tf (TypeError ) Tj /F1 10 Tf (is raised: the reason is that we want to be able to distinguish the) Tj T* 0 Tw .829984 Tw (command-line arguments needed to instantiate the factory from the rest arguments that must be sent to) Tj T* 0 Tw 2.609984 Tw (the corresponding interpreter object. It is also possible to specify a list of arguments different from) Tj T* 0 Tw .513318 Tw /F3 10 Tf (sys.argv[1:] ) Tj /F1 10 Tf (\(useful in tests\), the character to be recognized as a comment, the splitting function, the) Tj T* 0 Tw (input source and the prompt to use while in interactive mode, and a verbose flag.) Tj T* ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (27) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (27) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R364': class PDFStream 364 0 obj % page stream -<< /Length 5072 >> +<< /Length 5151 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 729.0236 cm -q -BT 1 0 0 1 0 28.82 Tm 2.609984 Tw 12 TL /F1 10 Tf 0 0 0 rg (the corresponding interpreter object. It is also possible to specify a list of arguments different from) Tj T* 0 Tw .513318 Tw /F3 10 Tf (sys.argv[1:] ) Tj /F1 10 Tf (\(useful in tests\), the character to be recognized as a comment, the splitting function, the) Tj T* 0 Tw (input source and the prompt to use while in interactive mode, and a verbose flag.) Tj T* ET -Q -Q +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 699.0236 cm +1 0 0 1 62.69291 747.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Readline support) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Readline support) Tj T* ET Q Q q -1 0 0 1 62.69291 621.0236 cm +1 0 0 1 62.69291 669.0236 cm q -BT 1 0 0 1 0 64.82 Tm 1.022485 Tw 12 TL /F1 10 Tf 0 0 0 rg (Starting from release 0.6 ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (offers full readline support. That means that if your Python was compiled) Tj T* 0 Tw 2.120697 Tw (with readline support you get autocompletion and persistent command history for free. By default all) Tj T* 0 Tw .144104 Tw (commands are autocomplete in a case sensitive way. If you want to add new words to the autocompletion) Tj T* 0 Tw .116488 Tw (set, or you want to change the location of the ) Tj /F3 10 Tf (.history ) Tj /F1 10 Tf (file, or to change the case sensitivity, the way to) Tj T* 0 Tw .18436 Tw (go is to pass a ) Tj /F3 10 Tf (plac.ReadlineInput ) Tj /F1 10 Tf (object to the interpreter. Here is an example, assuming you want) Tj T* 0 Tw (to build a database interface understanding SQL commands:) Tj T* ET +BT 1 0 0 1 0 62 Tm 1.022485 Tw 12 TL /F1 10 Tf 0 0 0 rg (Starting from release 0.6 ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (offers full readline support. That means that if your Python was compiled) Tj T* 0 Tw 2.120697 Tw (with readline support you get autocompletion and persistent command history for free. By default all) Tj T* 0 Tw .144104 Tw (commands are autocomplete in a case sensitive way. If you want to add new words to the autocompletion) Tj T* 0 Tw .116488 Tw (set, or you want to change the location of the ) Tj /F3 10 Tf (.history ) Tj /F1 10 Tf (file, or to change the case sensitivity, the way to) Tj T* 0 Tw .18436 Tw (go is to pass a ) Tj /F3 10 Tf (plac.ReadlineInput ) Tj /F1 10 Tf (object to the interpreter. Here is an example, assuming you want) Tj T* 0 Tw (to build a database interface understanding SQL commands:) Tj T* ET Q Q q -1 0 0 1 62.69291 276.2307 cm +1 0 0 1 62.69291 324.2307 cm q q .96447 0 0 .96447 0 0 cm @@ -9908,21 +9828,21 @@ q n -6 -6 486 348 re B* Q q -BT 1 0 0 1 0 329.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (import os, plac) Tj T* (from sqlalchemy.ext.sqlsoup import SqlSoup) Tj T* T* (SQLKEYWORDS = set\(['select', 'from', 'inner', 'join', 'outer', 'left', 'right']) Tj T* ( \) # and many others) Tj T* (DBTABLES = set\(['table1', 'table2']\) # you can read them from the db schema) Tj T* T* (COMPLETIONS = SQLKEYWORDS | DBTABLES) Tj T* T* (class SqlInterface\(object\):) Tj T* ( commands = ['SELECT']) Tj T* ( def __init__\(self, dsn\):) Tj T* ( self.soup = SqlSoup\(dsn\)) Tj T* ( def SELECT\(self, argstring\):) Tj T* ( sql = 'SELECT ' + argstring) Tj T* ( for row in self.soup.bind.execute\(sql\):) Tj T* ( yield str\(row\) # the formatting can be much improved) Tj T* T* (rl_input = plac.ReadlineInput\() Tj T* ( COMPLETIONS, histfile=os.path.expanduser\('~/.sql_interface.history'\), ) Tj T* ( case_sensitive=False\)) Tj T* T* (def split_on_first_space\(line, commentchar\):) Tj T* ( return line.strip\(\).split\(' ', 1\) # ignoring comments) Tj T* ( ) Tj T* (if __name__ == '__main__':) Tj T* ( plac.Interpreter.call\(SqlInterface, split=split_on_first_space,) Tj T* ( stdin=rl_input, prompt='sql) Tj (>) Tj ( '\)) Tj T* ET +BT 1 0 0 1 0 326 Tm 12 TL /F3 10 Tf 0 0 0 rg (import os, plac) Tj T* (from sqlalchemy.ext.sqlsoup import SqlSoup) Tj T* T* (SQLKEYWORDS = set\(['select', 'from', 'inner', 'join', 'outer', 'left', 'right']) Tj T* ( \) # and many others) Tj T* (DBTABLES = set\(['table1', 'table2']\) # you can read them from the db schema) Tj T* T* (COMPLETIONS = SQLKEYWORDS | DBTABLES) Tj T* T* (class SqlInterface\(object\):) Tj T* ( commands = ['SELECT']) Tj T* ( def __init__\(self, dsn\):) Tj T* ( self.soup = SqlSoup\(dsn\)) Tj T* ( def SELECT\(self, argstring\):) Tj T* ( sql = 'SELECT ' + argstring) Tj T* ( for row in self.soup.bind.execute\(sql\):) Tj T* ( yield str\(row\) # the formatting can be much improved) Tj T* T* (rl_input = plac.ReadlineInput\() Tj T* ( COMPLETIONS, histfile=os.path.expanduser\('~/.sql_interface.history'\), ) Tj T* ( case_sensitive=False\)) Tj T* T* (def split_on_first_space\(line, commentchar\):) Tj T* ( return line.strip\(\).split\(' ', 1\) # ignoring comments) Tj T* ( ) Tj T* (if __name__ == '__main__':) Tj T* ( plac.Interpreter.call\(SqlInterface, split=split_on_first_space,) Tj T* ( stdin=rl_input, prompt='sql) Tj (>) Tj ( '\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 256.2307 cm +1 0 0 1 62.69291 304.2307 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Here is an example of usage:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is an example of usage:) Tj T* ET Q Q q -1 0 0 1 62.69291 199.0307 cm +1 0 0 1 62.69291 247.0307 cm q q 1 0 0 1 0 0 cm @@ -9935,55 +9855,48 @@ q n -6 -6 468.6898 48 re B* Q q -BT 1 0 0 1 0 29.71 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ python sql_interface.py ) Tj (<) Tj (some dsn) Tj (>) Tj T* (sql) Tj (>) Tj ( SELECT a.* FROM TABLE1 AS a INNER JOIN TABLE2 AS b ON a.id = b.id) Tj T* (...) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ python sql_interface.py ) Tj (<) Tj (some dsn) Tj (>) Tj T* (sql) Tj (>) Tj ( SELECT a.* FROM TABLE1 AS a INNER JOIN TABLE2 AS b ON a.id = b.id) Tj T* (...) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 119.0307 cm +1 0 0 1 62.69291 167.0307 cm q -BT 1 0 0 1 0 64.82 Tm 1.951318 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can check that entering just ) Tj /F3 10 Tf (sel ) Tj /F1 10 Tf (and pressing TAB the readline library completes the ) Tj /F3 10 Tf (SELECT) Tj T* 0 Tw .797356 Tw /F1 10 Tf (keyword for you and makes it upper case; idem for ) Tj /F3 10 Tf (FROM) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (INNER) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (JOIN ) Tj /F1 10 Tf (and even for the names of the) Tj T* 0 Tw .256235 Tw (tables. An obvious improvement is to read the names of the tables by introspecting the database: actually) Tj T* 0 Tw 1.616654 Tw (you can even read the names of the views and of the columns, and have full autocompletion. All the) Tj T* 0 Tw 2.047251 Tw (entered commands and recorded and saved in the file ) Tj /F3 10 Tf (~/.sql_interface.history ) Tj /F1 10 Tf (when exiting) Tj T* 0 Tw (from the command-line interface.) Tj T* ET +BT 1 0 0 1 0 62 Tm 1.951318 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can check that entering just ) Tj /F3 10 Tf (sel ) Tj /F1 10 Tf (and pressing TAB the readline library completes the ) Tj /F3 10 Tf (SELECT) Tj T* 0 Tw .797356 Tw /F1 10 Tf (keyword for you and makes it upper case; idem for ) Tj /F3 10 Tf (FROM) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (INNER) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (JOIN ) Tj /F1 10 Tf (and even for the names of the) Tj T* 0 Tw .256235 Tw (tables. An obvious improvement is to read the names of the tables by introspecting the database: actually) Tj T* 0 Tw 1.616654 Tw (you can even read the names of the views and of the columns, and have full autocompletion. All the) Tj T* 0 Tw 2.047251 Tw (entered commands and recorded and saved in the file ) Tj /F3 10 Tf (~/.sql_interface.history ) Tj /F1 10 Tf (when exiting) Tj T* 0 Tw (from the command-line interface.) Tj T* ET Q Q q 1 0 0 1 62.69291 89.03071 cm q -BT 1 0 0 1 0 16.82 Tm 2.010574 Tw 12 TL /F1 10 Tf 0 0 0 rg (If the readline library is not available, my suggestion is to use the ) Tj 0 0 .501961 rg (rlwrap ) Tj 0 0 0 rg (tool which provides similar ) Tj T* 0 Tw .22561 Tw (features, at least on Unix-like platforms. ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (should also work fine on Windows with the ) Tj 0 0 .501961 rg (pyreadline ) Tj 0 0 0 rg (library) Tj T* 0 Tw ET +BT 1 0 0 1 0 62 Tm 2.010574 Tw 12 TL /F1 10 Tf 0 0 0 rg (If the readline library is not available, my suggestion is to use the ) Tj 0 0 .501961 rg (rlwrap ) Tj 0 0 0 rg (tool which provides similar) Tj T* 0 Tw .22561 Tw (features, at least on Unix-like platforms. ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (should also work fine on Windows with the ) Tj 0 0 .501961 rg (pyreadline ) Tj 0 0 0 rg (library) Tj T* 0 Tw .389989 Tw (\(I do not use Windows, so this part is very little tested: I tried it only once and it worked, but your mileage) Tj T* 0 Tw 2.206457 Tw (may vary\). For people worried about licenses, I will notice that ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (uses the readline library only if) Tj T* 0 Tw .591894 Tw (available, it does not include it and it does not rely on it in any fundamental way, so that the ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (licence) Tj T* 0 Tw (does not need to be the GPL \(actually it is a BSD do-whatever-you-want-with-it licence\).) Tj T* ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (28) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (28) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R365': class PDFStream 365 0 obj % page stream -<< /Length 5002 >> +<< /Length 4619 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 717.0236 cm -q -BT 1 0 0 1 0 40.82 Tm .389989 Tw 12 TL /F1 10 Tf 0 0 0 rg (\(I do not use Windows, so this part is very little tested: I tried it only once and it worked, but your mileage) Tj T* 0 Tw 2.206457 Tw (may vary\). For people worried about licenses, I will notice that ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (uses the readline library only if) Tj T* 0 Tw .591894 Tw (available, it does not include it and it does not rely on it in any fundamental way, so that the ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (licence) Tj T* 0 Tw (does not need to be the GPL \(actually it is a BSD do-whatever-you-want-with-it licence\).) Tj T* ET -Q -Q +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 675.0236 cm +1 0 0 1 62.69291 729.0236 cm q -BT 1 0 0 1 0 28.82 Tm .187882 Tw 12 TL /F1 10 Tf 0 0 0 rg (The interactive mode of ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (can be used as a replacement of the ) Tj 0 0 .501961 rg (cmd ) Tj 0 0 0 rg (module in the standard library. It) Tj T* 0 Tw 2.730651 Tw (is actually better than ) Tj 0 0 .501961 rg (cmd) Tj 0 0 0 rg (: for instance, the ) Tj /F3 10 Tf (.help ) Tj /F1 10 Tf (command is more powerful, since it provides) Tj T* 0 Tw (information about the arguments accepted by the given command:) Tj T* ET +BT 1 0 0 1 0 26 Tm .187882 Tw 12 TL /F1 10 Tf 0 0 0 rg (The interactive mode of ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (can be used as a replacement of the ) Tj 0 0 .501961 rg (cmd ) Tj 0 0 0 rg (module in the standard library. It) Tj T* 0 Tw 2.730651 Tw (is actually better than ) Tj 0 0 .501961 rg (cmd) Tj 0 0 0 rg (: for instance, the ) Tj /F3 10 Tf (.help ) Tj /F1 10 Tf (command is more powerful, since it provides) Tj T* 0 Tw (information about the arguments accepted by the given command:) Tj T* ET Q Q q -1 0 0 1 62.69291 365.8236 cm +1 0 0 1 62.69291 419.8236 cm q q 1 0 0 1 0 0 cm @@ -9996,32 +9909,32 @@ q n -6 -6 468.6898 300 re B* Q q -BT 1 0 0 1 0 281.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( .help set) Tj T* (usage: set name value) Tj T* T* (set name value) Tj T* T* (positional arguments:) Tj T* ( name) Tj T* ( value) Tj T* T* (i) Tj (>) Tj ( .help delete) Tj T* (usage: delete [name]) Tj T* T* (delete given parameter \(or everything\)) Tj T* T* (positional arguments:) Tj T* ( name) Tj T* T* (i) Tj (>) Tj ( .help show) Tj T* (usage: show [names [names ...]]) Tj T* T* (show given parameters) Tj T* T* (positional arguments:) Tj T* ( names) Tj T* ET +BT 1 0 0 1 0 278 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( .help set) Tj T* (usage: set name value) Tj T* T* (set name value) Tj T* T* (positional arguments:) Tj T* ( name) Tj T* ( value) Tj T* T* (i) Tj (>) Tj ( .help delete) Tj T* (usage: delete [name]) Tj T* T* (delete given parameter \(or everything\)) Tj T* T* (positional arguments:) Tj T* ( name) Tj T* T* (i) Tj (>) Tj ( .help show) Tj T* (usage: show [names [names ...]]) Tj T* T* (show given parameters) Tj T* T* (positional arguments:) Tj T* ( names) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 309.8236 cm +1 0 0 1 62.69291 363.8236 cm q -BT 1 0 0 1 0 40.82 Tm 1.959985 Tw 12 TL /F1 10 Tf 0 0 0 rg (As you can imagine, the help message is provided by the underlying ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (subparser \(there is a) Tj T* 0 Tw 2.954524 Tw (subparser for each command\). ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (commands accept options, flags, varargs, keyword arguments,) Tj T* 0 Tw .719318 Tw (arguments with defaults, arguments with a fixed number of choices, type conversion and all the features) Tj T* 0 Tw (provided of ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (which should be reimplemented from scratch using ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (.) Tj T* ET +BT 1 0 0 1 0 38 Tm 1.959985 Tw 12 TL /F1 10 Tf 0 0 0 rg (As you can imagine, the help message is provided by the underlying ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (subparser \(there is a) Tj T* 0 Tw 2.954524 Tw (subparser for each command\). ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (commands accept options, flags, varargs, keyword arguments,) Tj T* 0 Tw .719318 Tw (arguments with defaults, arguments with a fixed number of choices, type conversion and all the features) Tj T* 0 Tw (provided of ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (which should be reimplemented from scratch using ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (.) Tj T* ET Q Q q -1 0 0 1 62.69291 279.8236 cm +1 0 0 1 62.69291 333.8236 cm q -BT 1 0 0 1 0 16.82 Tm 1.78248 Tw 12 TL /F1 10 Tf 0 0 0 rg (Moreover at the moment ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (also understands command abbreviations. However, this feature may) Tj T* 0 Tw (disappear in future releases. It was meaningful in the past, when ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (did not support readline.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.78248 Tw 12 TL /F1 10 Tf 0 0 0 rg (Moreover at the moment ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (also understands command abbreviations. However, this feature may) Tj T* 0 Tw (disappear in future releases. It was meaningful in the past, when ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (did not support readline.) Tj T* ET Q Q q -1 0 0 1 62.69291 261.8236 cm +1 0 0 1 62.69291 315.8236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (Notice that if an abbreviation is ambiguous, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (warns you:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Notice that if an abbreviation is ambiguous, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (warns you:) Tj T* ET Q Q q -1 0 0 1 62.69291 216.6236 cm +1 0 0 1 62.69291 270.6236 cm q q 1 0 0 1 0 0 cm @@ -10034,49 +9947,69 @@ q n -6 -6 468.6898 36 re B* Q q -BT 1 0 0 1 0 17.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( sh) Tj T* (NameError: Ambiguous command 'sh': matching ['showall', 'show']) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( sh) Tj T* (NameError: Ambiguous command 'sh': matching ['showall', 'show']) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 186.6236 cm +1 0 0 1 62.69291 240.6236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (The plac runner) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (The plac runner) Tj T* ET Q Q q -1 0 0 1 62.69291 120.6236 cm +1 0 0 1 62.69291 174.6236 cm q -BT 1 0 0 1 0 52.82 Tm 1.531318 Tw 12 TL /F1 10 Tf 0 0 0 rg (The distribution of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (includes a runner script named ) Tj /F3 10 Tf (plac_runner.py) Tj /F1 10 Tf (, which will be installed in a) Tj T* 0 Tw .44748 Tw (suitable directory in your system by ) Tj 0 0 .501961 rg (distutils ) Tj 0 0 0 rg (\(say in ) Tj /F3 10 Tf (\\usr\\local\\bin\\plac_runner.py ) Tj /F1 10 Tf (in a Unix-like) Tj T* 0 Tw .680651 Tw (operative system\). The runner provides many facilities to run ) Tj /F3 10 Tf (.plac ) Tj /F1 10 Tf (scripts and ) Tj /F3 10 Tf (.placet ) Tj /F1 10 Tf (files, as well) Tj T* 0 Tw 1.47311 Tw (as Python modules containg a ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (object, which can be a function, a command container object or) Tj T* 0 Tw (even a command container class.) Tj T* ET +BT 1 0 0 1 0 50 Tm 1.531318 Tw 12 TL /F1 10 Tf 0 0 0 rg (The distribution of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (includes a runner script named ) Tj /F3 10 Tf (plac_runner.py) Tj /F1 10 Tf (, which will be installed in a) Tj T* 0 Tw .44748 Tw (suitable directory in your system by ) Tj 0 0 .501961 rg (distutils ) Tj 0 0 0 rg (\(say in ) Tj /F3 10 Tf (\\usr\\local\\bin\\plac_runner.py ) Tj /F1 10 Tf (in a Unix-like) Tj T* 0 Tw .680651 Tw (operative system\). The runner provides many facilities to run ) Tj /F3 10 Tf (.plac ) Tj /F1 10 Tf (scripts and ) Tj /F3 10 Tf (.placet ) Tj /F1 10 Tf (files, as well) Tj T* 0 Tw 1.47311 Tw (as Python modules containg a ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (object, which can be a function, a command container object or) Tj T* 0 Tw (even a command container class.) Tj T* ET Q Q q -1 0 0 1 62.69291 90.62362 cm +1 0 0 1 62.69291 144.6236 cm q -BT 1 0 0 1 0 16.82 Tm 1.994269 Tw 12 TL /F1 10 Tf 0 0 0 rg (For instance, suppose you want to execute a script containing commands defined in the ) Tj /F3 10 Tf (ishelve2) Tj T* 0 Tw /F1 10 Tf (module like the following one:) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.994269 Tw 12 TL /F1 10 Tf 0 0 0 rg (For instance, suppose you want to execute a script containing commands defined in the ) Tj /F3 10 Tf (ishelve2) Tj T* 0 Tw /F1 10 Tf (module like the following one:) Tj T* ET +Q +Q +q +1 0 0 1 62.69291 99.42362 cm +q +q +1 0 0 1 0 0 cm +q +1 0 0 1 6.6 6.6 cm +q +.662745 .662745 .662745 RG +.5 w +.960784 .960784 .862745 rg +n -6 -6 468.6898 36 re B* +Q +q +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL (#!ishelve2.py:ShelveInterface -c ~/conf.shelve) Tj T* (set a 1) Tj T* ET +Q +Q +Q Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (29) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (29) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R366': class PDFStream 366 0 obj % page stream -<< /Length 4243 >> +<< /Length 4545 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 703.8236 cm +1 0 0 1 62.69291 727.8236 cm q q 1 0 0 1 0 0 cm @@ -10086,24 +10019,24 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 60 re B* +n -6 -6 468.6898 36 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 41.71 Tm /F3 10 Tf 12 TL (#!ishelve2.py:ShelveInterface -c ~/conf.shelve) Tj T* (set a 1) Tj T* (del a) Tj T* (del a # intentional error) Tj T* ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL (del a) Tj T* (del a # intentional error) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 635.8236 cm +1 0 0 1 62.69291 659.8236 cm q -BT 1 0 0 1 0 52.82 Tm .575868 Tw 12 TL /F1 10 Tf 0 0 0 rg (The first line of the ) Tj /F3 10 Tf (.plac ) Tj /F1 10 Tf (script contains the name of the python module containing the plac interpreter) Tj T* 0 Tw 2.327209 Tw (and the arguments which must be passed to its main function in order to be able to instantiate an) Tj T* 0 Tw .202485 Tw (interpreter object. In this case I appended ) Tj /F3 10 Tf (:ShelveInterface ) Tj /F1 10 Tf (to the name of the module to specify the) Tj T* 0 Tw 1.030574 Tw (object that must be imported: if not specified, by default the object named 'main' is imported. The other) Tj T* 0 Tw (lines contains commands. You can run the script as follows:) Tj T* ET +BT 1 0 0 1 0 50 Tm .575868 Tw 12 TL /F1 10 Tf 0 0 0 rg (The first line of the ) Tj /F3 10 Tf (.plac ) Tj /F1 10 Tf (script contains the name of the python module containing the plac interpreter) Tj T* 0 Tw 2.327209 Tw (and the arguments which must be passed to its main function in order to be able to instantiate an) Tj T* 0 Tw .202485 Tw (interpreter object. In this case I appended ) Tj /F3 10 Tf (:ShelveInterface ) Tj /F1 10 Tf (to the name of the module to specify the) Tj T* 0 Tw 1.030574 Tw (object that must be imported: if not specified, by default the object named 'main' is imported. The other) Tj T* 0 Tw (lines contains commands. You can run the script as follows:) Tj T* ET Q Q q -1 0 0 1 62.69291 546.6505 cm +1 0 0 1 62.69291 570.6505 cm q q .952737 0 0 .952737 0 0 cm @@ -10117,31 +10050,31 @@ n -6 -6 492 84 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 65.71 Tm /F3 10 Tf 12 TL ($ plac_runner.py --batch ishelve2.plac) Tj T* (setting a=1) Tj T* (deleting a) Tj T* (Traceback \(most recent call last\):) Tj T* ( ...) Tj T* (_bsddb.DBNotFoundError: \(-30988, 'DB_NOTFOUND: No matching key/data pair found'\)) Tj T* ET +BT 1 0 0 1 0 62 Tm /F3 10 Tf 12 TL ($ plac_runner.py --batch ishelve2.plac) Tj T* (setting a=1) Tj T* (deleting a) Tj T* (Traceback \(most recent call last\):) Tj T* ( ...) Tj T* (_bsddb.DBNotFoundError: \(-30988, 'DB_NOTFOUND: No matching key/data pair found'\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 514.6505 cm +1 0 0 1 62.69291 538.6505 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL 2.79186 Tw (The last command intentionally contained an error, to show that the plac runner does not eat the) Tj T* 0 Tw (traceback.) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 2.79186 Tw (The last command intentionally contained an error, to show that the plac runner does not eat the) Tj T* 0 Tw (traceback.) Tj T* ET Q Q q -1 0 0 1 62.69291 484.6505 cm +1 0 0 1 62.69291 508.6505 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL .437633 Tw (The runner can also be used to run Python modules in interactive mode and non-interactive mode. If you) Tj T* 0 Tw (put this alias in your bashrc) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .437633 Tw (The runner can also be used to run Python modules in interactive mode and non-interactive mode. If you) Tj T* 0 Tw (put this alias in your bashrc) Tj T* ET Q Q q -1 0 0 1 62.69291 478.6505 cm +1 0 0 1 62.69291 502.6505 cm Q q -1 0 0 1 62.69291 466.6505 cm +1 0 0 1 62.69291 490.6505 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET BT 1 0 0 1 0 2 Tm T* ET @@ -10149,23 +10082,23 @@ q 1 0 0 1 20 0 cm q 0 0 0 rg -BT 1 0 0 1 0 5.71 Tm /F3 10 Tf 12 TL (alias plac="plac_runner.py") Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (alias plac="plac_runner.py") Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 466.6505 cm +1 0 0 1 62.69291 490.6505 cm Q q -1 0 0 1 62.69291 436.6505 cm +1 0 0 1 62.69291 460.6505 cm q -BT 1 0 0 1 0 16.82 Tm 2.955318 Tw 12 TL /F1 10 Tf 0 0 0 rg (\(or you define a suitable ) Tj /F3 10 Tf (plac.bat ) Tj /F1 10 Tf (script in Windows\) you can run the ) Tj /F3 10 Tf (ishelve2.py ) Tj /F1 10 Tf (script in) Tj T* 0 Tw (interactive mode as follows:) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.955318 Tw 12 TL /F1 10 Tf 0 0 0 rg (\(or you define a suitable ) Tj /F3 10 Tf (plac.bat ) Tj /F1 10 Tf (script in Windows\) you can run the ) Tj /F3 10 Tf (ishelve2.py ) Tj /F1 10 Tf (script in) Tj T* 0 Tw (interactive mode as follows:) Tj T* ET Q Q q -1 0 0 1 62.69291 259.4505 cm +1 0 0 1 62.69291 283.4505 cm q q 1 0 0 1 0 0 cm @@ -10178,20 +10111,20 @@ q n -6 -6 468.6898 168 re B* Q q -BT 1 0 0 1 0 149.71 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ plac -i ishelve2.py:ShelveInterface) Tj T* (A minimal interface over a shelve object.) Tj T* (Operating on /home/micheles/conf.shelve.) Tj T* (.help to see the available commands.) Tj T* T* (i) Tj (>) Tj ( del) Tj T* (deleting everything) Tj T* (i) Tj (>) Tj ( set a 1) Tj T* (setting a=1) Tj T* (i) Tj (>) Tj ( set b 2) Tj T* (setting b=2) Tj T* (i) Tj (>) Tj ( show b) Tj T* (b = 2) Tj T* ET +BT 1 0 0 1 0 146 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ plac -i ishelve2.py:ShelveInterface) Tj T* (A minimal interface over a shelve object.) Tj T* (Operating on /home/micheles/conf.shelve.) Tj T* (.help to see the available commands.) Tj T* T* (i) Tj (>) Tj ( del) Tj T* (deleting everything) Tj T* (i) Tj (>) Tj ( set a 1) Tj T* (setting a=1) Tj T* (i) Tj (>) Tj ( set b 2) Tj T* (setting b=2) Tj T* (i) Tj (>) Tj ( show b) Tj T* (b = 2) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 239.4505 cm +1 0 0 1 62.69291 263.4505 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (Now you can cut and paste the interactive session an turns into into a ) Tj /F3 10 Tf (.placet ) Tj /F1 10 Tf (file like the following:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Now you can cut and paste the interactive session an turns into into a ) Tj /F3 10 Tf (.placet ) Tj /F1 10 Tf (file like the following:) Tj T* ET Q Q q -1 0 0 1 62.69291 110.2505 cm +1 0 0 1 62.69291 134.2505 cm q q 1 0 0 1 0 0 cm @@ -10204,44 +10137,43 @@ q n -6 -6 468.6898 120 re B* Q q -BT 1 0 0 1 0 101.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (#!ishelve2.py:ShelveInterface -configfile=~/test.shelve) Tj T* (i) Tj (>) Tj ( del) Tj T* (deleting everything) Tj T* (i) Tj (>) Tj ( set a 1) Tj T* (setting a=1) Tj T* (i) Tj (>) Tj ( set b 2) Tj T* (setting b=2) Tj T* (i) Tj (>) Tj ( show a) Tj T* (a = 1) Tj T* ET +BT 1 0 0 1 0 98 Tm 12 TL /F3 10 Tf 0 0 0 rg (#!ishelve2.py:ShelveInterface -configfile=~/test.shelve) Tj T* (i) Tj (>) Tj ( del) Tj T* (deleting everything) Tj T* (i) Tj (>) Tj ( set a 1) Tj T* (setting a=1) Tj T* (i) Tj (>) Tj ( set b 2) Tj T* (setting b=2) Tj T* (i) Tj (>) Tj ( show a) Tj T* (a = 1) Tj T* ET Q Q Q Q Q q +1 0 0 1 62.69291 102.2505 cm +q +BT 1 0 0 1 0 14 Tm 2.145697 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that the first line specifies a test database ) Tj /F3 10 Tf (~/test.shelve) Tj /F1 10 Tf (, to avoid clobbering your default) Tj T* 0 Tw (shelve. If you mispell the arguments in the first line plac will give you an ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (error message \(just try\).) Tj T* ET +Q +Q +q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (30) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (30) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R367': class PDFStream 367 0 obj % page stream -<< /Length 5344 >> +<< /Length 4934 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 741.0236 cm -q -BT 1 0 0 1 0 16.82 Tm 2.145697 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that the first line specifies a test database ) Tj /F3 10 Tf (~/test.shelve) Tj /F1 10 Tf (, to avoid clobbering your default) Tj T* 0 Tw (shelve. If you mispell the arguments in the first line plac will give you an ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (error message \(just try\).) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 723.0236 cm +1 0 0 1 62.69291 753.0236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (You can run placets following the shebang convention directly with the plac runner:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (You can run placets following the shebang convention directly with the plac runner:) Tj T* ET Q Q q -1 0 0 1 62.69291 677.8236 cm +1 0 0 1 62.69291 707.8236 cm q q 1 0 0 1 0 0 cm @@ -10255,26 +10187,26 @@ n -6 -6 468.6898 36 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 17.71 Tm /F3 10 Tf 12 TL ($ plac --test ishelve2.placet) Tj T* (run 1 plac test\(s\)) Tj T* ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL ($ plac --test ishelve2.placet) Tj T* (run 1 plac test\(s\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 633.8236 cm +1 0 0 1 62.69291 663.8236 cm q -BT 1 0 0 1 0 28.82 Tm .32104 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you want to see the output of the tests, pass the ) Tj /F3 10 Tf (-v/--verbose ) Tj /F1 10 Tf (flag. Notice that he runner ignore the) Tj T* 0 Tw .24856 Tw (extension, so you can actually use any extension your like, but ) Tj /F4 10 Tf (it relies on the first line of the file to invoke) Tj T* 0 Tw (the corresponding plac tool with the given arguments) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 26 Tm .32104 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you want to see the output of the tests, pass the ) Tj /F3 10 Tf (-v/--verbose ) Tj /F1 10 Tf (flag. Notice that he runner ignore the) Tj T* 0 Tw .24856 Tw (extension, so you can actually use any extension your like, but ) Tj /F4 10 Tf (it relies on the first line of the file to invoke) Tj T* 0 Tw (the corresponding plac tool with the given arguments) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 62.69291 603.8236 cm +1 0 0 1 62.69291 633.8236 cm q -BT 1 0 0 1 0 16.82 Tm .537209 Tw 12 TL /F1 10 Tf 0 0 0 rg (The plac runner does not provide any test discovery facility, but you can use standard Unix tools to help.) Tj T* 0 Tw (For instance, you can run all the ) Tj /F3 10 Tf (.placet ) Tj /F1 10 Tf (files into a directory and its subdirectories as follows:) Tj T* ET +BT 1 0 0 1 0 14 Tm .537209 Tw 12 TL /F1 10 Tf 0 0 0 rg (The plac runner does not provide any test discovery facility, but you can use standard Unix tools to help.) Tj T* 0 Tw (For instance, you can run all the ) Tj /F3 10 Tf (.placet ) Tj /F1 10 Tf (files into a directory and its subdirectories as follows:) Tj T* ET Q Q q -1 0 0 1 62.69291 570.6236 cm +1 0 0 1 62.69291 600.6236 cm q q 1 0 0 1 0 0 cm @@ -10288,30 +10220,30 @@ n -6 -6 468.6898 24 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 5.71 Tm /F3 10 Tf 12 TL ($ find . -name \\*.placet | xargs plac_runner.py -t) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL ($ find . -name \\*.placet | xargs plac_runner.py -t) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 538.6236 cm +1 0 0 1 62.69291 568.6236 cm q -BT 1 0 0 1 0 16.82 Tm .760988 Tw 12 TL /F1 10 Tf 0 0 0 rg (The plac runner expects the main function of your script to return a plac tool, i.e. a function or an object) Tj T* 0 Tw (with a ) Tj /F3 10 Tf (.commands ) Tj /F1 10 Tf (attribute. It this is not the case the runner gracefully exits.) Tj T* ET +BT 1 0 0 1 0 14 Tm .760988 Tw 12 TL /F1 10 Tf 0 0 0 rg (The plac runner expects the main function of your script to return a plac tool, i.e. a function or an object) Tj T* 0 Tw (with a ) Tj /F3 10 Tf (.commands ) Tj /F1 10 Tf (attribute. It this is not the case the runner gracefully exits.) Tj T* ET Q Q q -1 0 0 1 62.69291 520.6236 cm +1 0 0 1 62.69291 550.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (It also works in non-interactive mode, if you call it as) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (It also works in non-interactive mode, if you call it as) Tj T* ET Q Q q -1 0 0 1 62.69291 514.6236 cm +1 0 0 1 62.69291 544.6236 cm Q q -1 0 0 1 62.69291 502.6236 cm +1 0 0 1 62.69291 532.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET BT 1 0 0 1 0 2 Tm T* ET @@ -10319,24 +10251,24 @@ q 1 0 0 1 20 0 cm q 0 0 0 rg -BT 1 0 0 1 0 5.71 Tm /F3 10 Tf 12 TL ($ plac module.py args ...) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL ($ plac module.py args ...) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 502.6236 cm +1 0 0 1 62.69291 532.6236 cm Q q -1 0 0 1 62.69291 484.6236 cm +1 0 0 1 62.69291 514.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Here is an example:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is an example:) Tj T* ET Q Q q -1 0 0 1 62.69291 415.4236 cm +1 0 0 1 62.69291 445.4236 cm q q 1 0 0 1 0 0 cm @@ -10350,39 +10282,39 @@ n -6 -6 468.6898 60 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 41.71 Tm /F3 10 Tf 12 TL ($ plac ishelve.py a=1) Tj T* (setting a=1) Tj T* ($ plac ishelve.py .show) Tj T* (a=1) Tj T* ET +BT 1 0 0 1 0 38 Tm /F3 10 Tf 12 TL ($ plac ishelve.py a=1) Tj T* (setting a=1) Tj T* ($ plac ishelve.py .show) Tj T* (a=1) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 383.4236 cm +1 0 0 1 62.69291 413.4236 cm q -BT 1 0 0 1 0 16.82 Tm .01561 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that in non-interactive mode the runner just invokes ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (on the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (object of the Python) Tj T* 0 Tw (module.) Tj T* ET +BT 1 0 0 1 0 14 Tm .01561 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that in non-interactive mode the runner just invokes ) Tj /F3 10 Tf (plac.call ) Tj /F1 10 Tf (on the ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (object of the Python) Tj T* 0 Tw (module.) Tj T* ET Q Q q -1 0 0 1 62.69291 353.4236 cm +1 0 0 1 62.69291 383.4236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (A non class-based example) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (A non class-based example) Tj T* ET Q Q q -1 0 0 1 62.69291 311.4236 cm +1 0 0 1 62.69291 341.4236 cm q -BT 1 0 0 1 0 28.82 Tm .907209 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (does not force you to use classes to define command containers. Even a simple function can be a) Tj T* 0 Tw 1.796651 Tw (valid command container, it is enough to add to it a ) Tj /F3 10 Tf (.commands ) Tj /F1 10 Tf (attribute and possibly ) Tj /F3 10 Tf (__enter__) Tj T* 0 Tw /F1 10 Tf (and/or ) Tj /F3 10 Tf (__exit__ ) Tj /F1 10 Tf (attributes.) Tj T* ET +BT 1 0 0 1 0 26 Tm .907209 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (does not force you to use classes to define command containers. Even a simple function can be a) Tj T* 0 Tw 1.796651 Tw (valid command container, it is enough to add to it a ) Tj /F3 10 Tf (.commands ) Tj /F1 10 Tf (attribute and possibly ) Tj /F3 10 Tf (__enter__) Tj T* 0 Tw /F1 10 Tf (and/or ) Tj /F3 10 Tf (__exit__ ) Tj /F1 10 Tf (attributes.) Tj T* ET Q Q q -1 0 0 1 62.69291 281.4236 cm +1 0 0 1 62.69291 311.4236 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL .327485 Tw (In particular, a Python module is a perfect container of commands. As an example, consider the following) Tj T* 0 Tw (module implementing a fake Version Control System:) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .327485 Tw (In particular, a Python module is a perfect container of commands. As an example, consider the following) Tj T* 0 Tw (module implementing a fake Version Control System:) Tj T* ET Q Q q -1 0 0 1 62.69291 92.22362 cm +1 0 0 1 62.69291 98.22362 cm q q 1 0 0 1 0 0 cm @@ -10392,11 +10324,11 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 180 re B* +n -6 -6 468.6898 204 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 161.71 Tm /F3 10 Tf 12 TL ("A Fake Version Control System") Tj T* T* (import plac) Tj T* T* (commands = 'checkout', 'commit', 'status') Tj T* T* (@plac.annotations\(url='url of the source code'\)) Tj T* (def checkout\(url\):) Tj T* ( "A fake checkout command") Tj T* ( return \('checkout ', url\)) Tj T* T* (@plac.annotations\(message=\('commit message', 'option'\)\)) Tj T* (def commit\(message\):) Tj T* ( "A fake commit command") Tj T* ET +BT 1 0 0 1 0 182 Tm /F3 10 Tf 12 TL ("A Fake Version Control System") Tj T* T* (import plac) Tj T* T* (commands = 'checkout', 'commit', 'status') Tj T* T* (@plac.annotations\(url='url of the source code'\)) Tj T* (def checkout\(url\):) Tj T* ( "A fake checkout command") Tj T* ( return \('checkout ', url\)) Tj T* T* (@plac.annotations\(message=\('commit message', 'option'\)\)) Tj T* (def commit\(message\):) Tj T* ( "A fake commit command") Tj T* ( return \('commit ', message\)) Tj T* T* ET Q Q Q @@ -10406,21 +10338,20 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (31) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (31) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R368': class PDFStream 368 0 obj % page stream -<< /Length 3894 >> +<< /Length 3862 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 559.8236 cm +1 0 0 1 62.69291 583.8236 cm q q 1 0 0 1 0 0 cm @@ -10430,30 +10361,30 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 204 re B* +n -6 -6 468.6898 180 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 185.71 Tm /F3 10 Tf 12 TL ( return \('commit ', message\)) Tj T* T* (@plac.annotations\(quiet=\('summary information', 'flag', 'q'\)\)) Tj T* (def status\(quiet\):) Tj T* ( "A fake status command") Tj T* ( return \('status ', quiet\)) Tj T* T* (def __missing__\(name\):) Tj T* ( return 'Command %r does not exist' % name) Tj T* T* (def __exit__\(etype, exc, tb\):) Tj T* ( "Will be called automatically at the end of the call/cmdloop") Tj T* ( if etype in \(None, GeneratorExit\): # success) Tj T* ( print\('ok'\)) Tj T* T* (main = __import__\(__name__\) # the module imports itself!) Tj T* ET +BT 1 0 0 1 0 158 Tm /F3 10 Tf 12 TL (@plac.annotations\(quiet=\('summary information', 'flag', 'q'\)\)) Tj T* (def status\(quiet\):) Tj T* ( "A fake status command") Tj T* ( return \('status ', quiet\)) Tj T* T* (def __missing__\(name\):) Tj T* ( return 'Command %r does not exist' % name) Tj T* T* (def __exit__\(etype, exc, tb\):) Tj T* ( "Will be called automatically at the end of the call/cmdloop") Tj T* ( if etype in \(None, GeneratorExit\): # success) Tj T* ( print\('ok'\)) Tj T* T* (main = __import__\(__name__\) # the module imports itself!) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 515.8236 cm +1 0 0 1 62.69291 539.8236 cm q -BT 1 0 0 1 0 28.82 Tm .431318 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that I have defined both an ) Tj /F3 10 Tf (__exit__ ) Tj /F1 10 Tf (hook and a ) Tj /F3 10 Tf (__missing__ ) Tj /F1 10 Tf (hook, invoked for non-existing) Tj T* 0 Tw .592651 Tw (commands. The real trick here is the line ) Tj /F3 10 Tf (main = __import__\(__name__\)) Tj /F1 10 Tf (, which define ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (to be) Tj T* 0 Tw (an alias for the current module.) Tj T* ET +BT 1 0 0 1 0 26 Tm .431318 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that I have defined both an ) Tj /F3 10 Tf (__exit__ ) Tj /F1 10 Tf (hook and a ) Tj /F3 10 Tf (__missing__ ) Tj /F1 10 Tf (hook, invoked for non-existing) Tj T* 0 Tw .592651 Tw (commands. The real trick here is the line ) Tj /F3 10 Tf (main = __import__\(__name__\)) Tj /F1 10 Tf (, which define ) Tj /F3 10 Tf (main ) Tj /F1 10 Tf (to be) Tj T* 0 Tw (an alias for the current module.) Tj T* ET Q Q q -1 0 0 1 62.69291 485.8236 cm +1 0 0 1 62.69291 509.8236 cm q -BT 1 0 0 1 0 16.82 Tm 1.259986 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf (vcs ) Tj /F1 10 Tf (module does not contain an ) Tj /F3 10 Tf (if __name__ == '__main__' ) Tj /F1 10 Tf (block, but you can still run it) Tj T* 0 Tw (through the plac runner \(try ) Tj /F3 10 Tf (plac vcs.py -h) Tj /F1 10 Tf (\):) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.259986 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf (vcs ) Tj /F1 10 Tf (module does not contain an ) Tj /F3 10 Tf (if __name__ == '__main__' ) Tj /F1 10 Tf (block, but you can still run it) Tj T* 0 Tw (through the plac runner \(try ) Tj /F3 10 Tf (plac vcs.py -h) Tj /F1 10 Tf (\):) Tj T* ET Q Q q -1 0 0 1 62.69291 344.6236 cm +1 0 0 1 62.69291 368.6236 cm q q 1 0 0 1 0 0 cm @@ -10467,20 +10398,20 @@ n -6 -6 468.6898 132 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 113.71 Tm /F3 10 Tf 12 TL (usage: plac_runner.py vcs.py [-h] {status,commit,checkout} ...) Tj T* T* (A Fake Version Control System) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* T* (subcommands:) Tj T* ( {status,commit,checkout}) Tj T* ( -h to get additional help) Tj T* ET +BT 1 0 0 1 0 110 Tm /F3 10 Tf 12 TL (usage: plac_runner.py vcs.py [-h] {status,commit,checkout} ...) Tj T* T* (A Fake Version Control System) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* T* (subcommands:) Tj T* ( {status,commit,checkout}) Tj T* ( -h to get additional help) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 324.6236 cm +1 0 0 1 62.69291 348.6236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (You can get help for the subcommands by postponing ) Tj /F3 10 Tf (-h ) Tj /F1 10 Tf (after the name of the command:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (You can get help for the subcommands by postponing ) Tj /F3 10 Tf (-h ) Tj /F1 10 Tf (after the name of the command:) Tj T* ET Q Q q -1 0 0 1 62.69291 207.4236 cm +1 0 0 1 62.69291 231.4236 cm q q 1 0 0 1 0 0 cm @@ -10494,23 +10425,23 @@ n -6 -6 468.6898 108 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 89.71 Tm /F3 10 Tf 12 TL ($ plac vcs.py status -h) Tj T* (usage: vcs.py status [-h] [-q]) Tj T* T* (A fake status command) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -q, --quiet summary information) Tj T* ET +BT 1 0 0 1 0 86 Tm /F3 10 Tf 12 TL ($ plac vcs.py status -h) Tj T* (usage: vcs.py status [-h] [-q]) Tj T* T* (A fake status command) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ( -q, --quiet summary information) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 175.4236 cm +1 0 0 1 62.69291 199.4236 cm q -BT 1 0 0 1 0 16.82 Tm 2.064985 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice how the docstring of the command is automatically shown in usage message, as well as the) Tj T* 0 Tw (documentation for the sub flag ) Tj /F3 10 Tf (-q) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.064985 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice how the docstring of the command is automatically shown in usage message, as well as the) Tj T* 0 Tw (documentation for the sub flag ) Tj /F3 10 Tf (-q) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 62.69291 157.4236 cm +1 0 0 1 62.69291 181.4236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Here is an example of a non-interactive session:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is an example of a non-interactive session:) Tj T* ET Q Q q @@ -10524,11 +10455,11 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* +n -6 -6 468.6898 72 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 29.71 Tm /F3 10 Tf 12 TL ($ plac vcs.py check url) Tj T* (checkout) Tj T* (url) Tj T* ET +BT 1 0 0 1 0 50 Tm /F3 10 Tf 12 TL ($ plac vcs.py check url) Tj T* (checkout) Tj T* (url) Tj T* ($ plac vcs.py st -q) Tj T* (status) Tj T* ET Q Q Q @@ -10538,21 +10469,20 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (32) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (32) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R369': class PDFStream 369 0 obj % page stream -<< /Length 5647 >> +<< /Length 5462 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 679.8236 cm +1 0 0 1 62.69291 703.8236 cm q q 1 0 0 1 0 0 cm @@ -10562,25 +10492,25 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 84 re B* +n -6 -6 468.6898 60 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 65.71 Tm /F3 10 Tf 12 TL ($ plac vcs.py st -q) Tj T* (status) Tj T* (True) Tj T* ($ plac vcs.py co) Tj T* (commit) Tj T* (None) Tj T* ET +BT 1 0 0 1 0 38 Tm /F3 10 Tf 12 TL (True) Tj T* ($ plac vcs.py co) Tj T* (commit) Tj T* (None) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 659.8236 cm +1 0 0 1 62.69291 683.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (and here is an interactive session:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (and here is an interactive session:) Tj T* ET Q Q q -1 0 0 1 62.69291 458.6236 cm +1 0 0 1 62.69291 482.6236 cm q q 1 0 0 1 0 0 cm @@ -10593,161 +10523,149 @@ q n -6 -6 468.6898 192 re B* Q q -BT 1 0 0 1 0 173.71 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ plac -i vcs.py) Tj T* (usage: plac_runner.py vcs.py [-h] {status,commit,checkout} ...) Tj T* (i) Tj (>) Tj ( check url) Tj T* (checkout) Tj T* (url) Tj T* (i) Tj (>) Tj ( st -q) Tj T* (status) Tj T* (True) Tj T* (i) Tj (>) Tj ( co) Tj T* (commit) Tj T* (None) Tj T* (i) Tj (>) Tj ( sto) Tj T* (Command 'sto' does not exist) Tj T* (i) Tj (>) Tj ( [CTRL-D]) Tj T* (ok) Tj T* ET +BT 1 0 0 1 0 170 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ plac -i vcs.py) Tj T* (usage: plac_runner.py vcs.py [-h] {status,commit,checkout} ...) Tj T* (i) Tj (>) Tj ( check url) Tj T* (checkout) Tj T* (url) Tj T* (i) Tj (>) Tj ( st -q) Tj T* (status) Tj T* (True) Tj T* (i) Tj (>) Tj ( co) Tj T* (commit) Tj T* (None) Tj T* (i) Tj (>) Tj ( sto) Tj T* (Command 'sto' does not exist) Tj T* (i) Tj (>) Tj ( [CTRL-D]) Tj T* (ok) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 426.6236 cm +1 0 0 1 62.69291 450.6236 cm q -BT 1 0 0 1 0 16.82 Tm 2.986905 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice the invocation of the ) Tj /F3 10 Tf (__missing__ ) Tj /F1 10 Tf (hook for non-existing commands. Notice also that the) Tj T* 0 Tw /F3 10 Tf (__exit__ ) Tj /F1 10 Tf (hook gets called only in interactive mode.) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.986905 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice the invocation of the ) Tj /F3 10 Tf (__missing__ ) Tj /F1 10 Tf (hook for non-existing commands. Notice also that the) Tj T* 0 Tw /F3 10 Tf (__exit__ ) Tj /F1 10 Tf (hook gets called only in interactive mode.) Tj T* ET Q Q q -1 0 0 1 62.69291 396.6236 cm +1 0 0 1 62.69291 420.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL 1.614104 Tw (If the commands are completely independent, a module is a good fit for a method container. In other) Tj T* 0 Tw (situations, it is best to use a custom class.) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.614104 Tw (If the commands are completely independent, a module is a good fit for a method container. In other) Tj T* 0 Tw (situations, it is best to use a custom class.) Tj T* ET Q Q q -1 0 0 1 62.69291 366.6236 cm +1 0 0 1 62.69291 390.6236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Writing your own plac runner) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Writing your own plac runner) Tj T* ET Q Q q -1 0 0 1 62.69291 312.6236 cm +1 0 0 1 62.69291 336.6236 cm q -BT 1 0 0 1 0 40.82 Tm .167209 Tw 12 TL /F1 10 Tf 0 0 0 rg (The runner included in the ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (distribution is intentionally kept small \(around 50 lines of code\) so that you) Tj T* 0 Tw .081294 Tw (can study it and write your own runner if want to. If you need to go to such level of detail, you should know) Tj T* 0 Tw .42061 Tw (that the most important method of the ) Tj /F3 10 Tf (Interpreter ) Tj /F1 10 Tf (class is the ) Tj /F3 10 Tf (.send ) Tj /F1 10 Tf (method, which takes strings in) Tj T* 0 Tw (input and returns a four-tuple with attributes ) Tj /F3 10 Tf (.str) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (.etype) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (.exc ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (.tb) Tj /F1 10 Tf (:) Tj T* ET +BT 1 0 0 1 0 38 Tm .167209 Tw 12 TL /F1 10 Tf 0 0 0 rg (The runner included in the ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (distribution is intentionally kept small \(around 50 lines of code\) so that you) Tj T* 0 Tw .081294 Tw (can study it and write your own runner if want to. If you need to go to such level of detail, you should know) Tj T* 0 Tw .42061 Tw (that the most important method of the ) Tj /F3 10 Tf (Interpreter ) Tj /F1 10 Tf (class is the ) Tj /F3 10 Tf (.send ) Tj /F1 10 Tf (method, which takes strings in) Tj T* 0 Tw (input and returns a four-tuple with attributes ) Tj /F3 10 Tf (.str) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (.etype) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (.exc ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (.tb) Tj /F1 10 Tf (:) Tj T* ET Q Q q -1 0 0 1 62.69291 306.6236 cm +1 0 0 1 62.69291 330.6236 cm Q q -1 0 0 1 62.69291 306.6236 cm +1 0 0 1 62.69291 330.6236 cm Q q -1 0 0 1 62.69291 288.6236 cm +1 0 0 1 62.69291 318.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 3 cm +1 0 0 1 6 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F3 10 Tf 0 0 0 rg (.str ) Tj /F1 10 Tf (is the output of the command, if successful \(a string\);) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (.str ) Tj /F1 10 Tf (is the output of the command, if successful \(a string\);) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 288.6236 cm -Q -q -1 0 0 1 62.69291 288.6236 cm +1 0 0 1 62.69291 312.6236 cm Q q -1 0 0 1 62.69291 270.6236 cm +1 0 0 1 62.69291 300.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 3 cm +1 0 0 1 6 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F3 10 Tf 0 0 0 rg (.etype ) Tj /F1 10 Tf (is the class of the exception, if the command fail;) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (.etype ) Tj /F1 10 Tf (is the class of the exception, if the command fail;) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 270.6236 cm -Q -q -1 0 0 1 62.69291 270.6236 cm +1 0 0 1 62.69291 294.6236 cm Q q -1 0 0 1 62.69291 252.6236 cm +1 0 0 1 62.69291 282.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 3 cm +1 0 0 1 6 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F3 10 Tf 0 0 0 rg (.exc ) Tj /F1 10 Tf (is the exception instance;) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (.exc ) Tj /F1 10 Tf (is the exception instance;) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 252.6236 cm -Q -q -1 0 0 1 62.69291 252.6236 cm +1 0 0 1 62.69291 276.6236 cm Q q -1 0 0 1 62.69291 234.6236 cm +1 0 0 1 62.69291 264.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 3 cm +1 0 0 1 6 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F3 10 Tf 0 0 0 rg (.tb ) Tj /F1 10 Tf (is the traceback.) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (.tb ) Tj /F1 10 Tf (is the traceback.) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 234.6236 cm -Q -q -1 0 0 1 62.69291 234.6236 cm +1 0 0 1 62.69291 264.6236 cm Q q -1 0 0 1 62.69291 192.6236 cm +1 0 0 1 62.69291 222.6236 cm q -BT 1 0 0 1 0 28.82 Tm .937485 Tw 12 TL /F1 10 Tf 0 0 0 rg (Moreover the ) Tj /F3 10 Tf (__str__ ) Tj /F1 10 Tf (representation of the output object is redefined to return the output string if the) Tj T* 0 Tw 2.686651 Tw (command was successful or the error message if the command failed \(actually it returns the error) Tj T* 0 Tw (message preceded by the name of the exception class\).) Tj T* ET +BT 1 0 0 1 0 26 Tm .937485 Tw 12 TL /F1 10 Tf 0 0 0 rg (Moreover the ) Tj /F3 10 Tf (__str__ ) Tj /F1 10 Tf (representation of the output object is redefined to return the output string if the) Tj T* 0 Tw 2.686651 Tw (command was successful or the error message if the command failed \(actually it returns the error) Tj T* 0 Tw (message preceded by the name of the exception class\).) Tj T* ET Q Q q -1 0 0 1 62.69291 174.6236 cm +1 0 0 1 62.69291 204.6236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (For instance, if you send a mispelled option to the interpreter a ) Tj /F3 10 Tf (SystemExit ) Tj /F1 10 Tf (will be trapped:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (For instance, if you send a mispelled option to the interpreter a ) Tj /F3 10 Tf (SystemExit ) Tj /F1 10 Tf (will be trapped:) Tj T* ET Q Q q -1 0 0 1 62.69291 93.42362 cm +1 0 0 1 62.69291 111.4236 cm q q 1 0 0 1 0 0 cm @@ -10757,10 +10675,10 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 72 re B* +n -6 -6 468.6898 84 re B* Q q -BT 1 0 0 1 0 53.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( import plac) Tj T* (>) Tj (>) Tj (>) Tj ( from ishelve import ishelve) Tj T* (>) Tj (>) Tj (>) Tj ( with plac.Interpreter\(ishelve\) as i:) Tj T* (... print\(i.send\('.cler'\)\)) Tj T* (...) Tj T* ET +BT 1 0 0 1 0 62 Tm 12 TL /F3 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( import plac) Tj T* (>) Tj (>) Tj (>) Tj ( from ishelve import ishelve) Tj T* (>) Tj (>) Tj (>) Tj ( with plac.Interpreter\(ishelve\) as i:) Tj T* (... print\(i.send\('.cler'\)\)) Tj T* (...) Tj T* (SystemExit: unrecognized arguments: .cler) Tj T* ET Q Q Q @@ -10770,54 +10688,33 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (33) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (33) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R370': class PDFStream 370 0 obj % page stream -<< /Length 5039 >> +<< /Length 4848 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 739.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -BT 1 0 0 1 0 5.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (SystemExit: unrecognized arguments: .cler) Tj T* ET -Q -Q -Q -Q -Q +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 707.8236 cm +1 0 0 1 62.69291 741.0236 cm q -BT 1 0 0 1 0 16.82 Tm 2.90561 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is important to invoke the ) Tj /F3 10 Tf (.send ) Tj /F1 10 Tf (method inside the context manager, otherwise you will get a) Tj T* 0 Tw /F3 10 Tf (RuntimeError) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.90561 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is important to invoke the ) Tj /F3 10 Tf (.send ) Tj /F1 10 Tf (method inside the context manager, otherwise you will get a) Tj T* 0 Tw /F3 10 Tf (RuntimeError) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 62.69291 665.8236 cm +1 0 0 1 62.69291 699.0236 cm q 0 0 0 rg -BT 1 0 0 1 0 28.82 Tm /F1 10 Tf 12 TL .29311 Tw (For instance, suppose you want to implement a graphical runner for a plac-based interpreter with two text) Tj T* 0 Tw 1.548221 Tw (widgets: one to enter the commands and one to display the results. Suppose you want to display the) Tj T* 0 Tw (errors with tracebacks in red. You will need to code something like that \(pseudocode follows\):) Tj T* ET +BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL .29311 Tw (For instance, suppose you want to implement a graphical runner for a plac-based interpreter with two text) Tj T* 0 Tw 1.548221 Tw (widgets: one to enter the commands and one to display the results. Suppose you want to display the) Tj T* 0 Tw (errors with tracebacks in red. You will need to code something like that \(pseudocode follows\):) Tj T* ET Q Q q -1 0 0 1 62.69291 428.6236 cm +1 0 0 1 62.69291 461.8236 cm q q 1 0 0 1 0 0 cm @@ -10831,33 +10728,33 @@ n -6 -6 468.6898 228 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 209.71 Tm /F3 10 Tf 12 TL (input_widget = WidgetReadingInput\(\)) Tj T* (output_widget = WidgetDisplayingOutput\(\)) Tj T* T* (def send\(interpreter, line\):) Tj T* ( out = interpreter.send\(line\)) Tj T* ( if out.tb: # there was an error) Tj T* ( output_widget.display\(out.tb, color='red'\)) Tj T* ( else:) Tj T* ( output_widget.display\(out.str\)) Tj T* T* (main = plac.import_main\(tool_path\) # get the main object) Tj T* T* (with plac.Interpreter\(main\) as i:) Tj T* ( def callback\(event\):) Tj T* ( if event.user_pressed_ENTER\(\):) Tj T* ( send\(i, input_widget.last_line\)) Tj T* ( input_widget.addcallback\(callback\)) Tj T* ( gui_mainloop.start\(\)) Tj T* ET +BT 1 0 0 1 0 206 Tm /F3 10 Tf 12 TL (input_widget = WidgetReadingInput\(\)) Tj T* (output_widget = WidgetDisplayingOutput\(\)) Tj T* T* (def send\(interpreter, line\):) Tj T* ( out = interpreter.send\(line\)) Tj T* ( if out.tb: # there was an error) Tj T* ( output_widget.display\(out.tb, color='red'\)) Tj T* ( else:) Tj T* ( output_widget.display\(out.str\)) Tj T* T* (main = plac.import_main\(tool_path\) # get the main object) Tj T* T* (with plac.Interpreter\(main\) as i:) Tj T* ( def callback\(event\):) Tj T* ( if event.user_pressed_ENTER\(\):) Tj T* ( send\(i, input_widget.last_line\)) Tj T* ( input_widget.addcallback\(callback\)) Tj T* ( gui_mainloop.start\(\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 396.6236 cm +1 0 0 1 62.69291 429.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL .102765 Tw (You can adapt the pseudocode to your GUI toolkit of choice and you can also change the file associations) Tj T* 0 Tw (in such a way that clicking on a plac tool file the graphical user interface starts.) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .102765 Tw (You can adapt the pseudocode to your GUI toolkit of choice and you can also change the file associations) Tj T* 0 Tw (in such a way that clicking on a plac tool file the graphical user interface starts.) Tj T* ET Q Q q -1 0 0 1 62.69291 366.6236 cm +1 0 0 1 62.69291 399.8236 cm q -BT 1 0 0 1 0 16.82 Tm .259988 Tw 12 TL /F1 10 Tf 0 0 0 rg (An example of GUI program built on top of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is given later on, in the paragraph ) Tj /F4 10 Tf (Managing the output of) Tj T* 0 Tw (concurrent commands ) Tj /F1 10 Tf (\(using Tkinter for simplicity and portability\).) Tj T* ET +BT 1 0 0 1 0 14 Tm .259988 Tw 12 TL /F1 10 Tf 0 0 0 rg (An example of GUI program built on top of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is given later on, in the paragraph ) Tj /F4 10 Tf (Managing the output of) Tj T* 0 Tw (concurrent commands ) Tj /F1 10 Tf (\(using Tkinter for simplicity and portability\).) Tj T* ET Q Q q -1 0 0 1 62.69291 312.6236 cm +1 0 0 1 62.69291 345.8236 cm q -BT 1 0 0 1 0 40.82 Tm 2.090651 Tw 12 TL /F1 10 Tf 0 0 0 rg (There is a final ) Tj /F4 10 Tf (caveat) Tj /F1 10 Tf (: since the plac interpreter loop is implemented via extended generators, plac) Tj T* 0 Tw .988651 Tw (interpreters are single threaded: you will get an error if you ) Tj /F3 10 Tf (.send ) Tj /F1 10 Tf (commands from separated threads.) Tj T* 0 Tw .947882 Tw (You can circumvent the problem by using a queue. If EXIT is a sentinel value to signal exiting from the) Tj T* 0 Tw (interpreter look, you can write code like this:) Tj T* ET +BT 1 0 0 1 0 38 Tm 2.090651 Tw 12 TL /F1 10 Tf 0 0 0 rg (There is a final ) Tj /F4 10 Tf (caveat) Tj /F1 10 Tf (: since the plac interpreter loop is implemented via extended generators, plac) Tj T* 0 Tw .988651 Tw (interpreters are single threaded: you will get an error if you ) Tj /F3 10 Tf (.send ) Tj /F1 10 Tf (commands from separated threads.) Tj T* 0 Tw .947882 Tw (You can circumvent the problem by using a queue. If EXIT is a sentinel value to signal exiting from the) Tj T* 0 Tw (interpreter look, you can write code like this:) Tj T* ET Q Q q -1 0 0 1 62.69291 255.4236 cm +1 0 0 1 62.69291 288.6236 cm q q 1 0 0 1 0 0 cm @@ -10871,32 +10768,32 @@ n -6 -6 468.6898 48 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 29.71 Tm /F3 10 Tf 12 TL (with interpreter:) Tj T* ( for input_value in iter\(input_queue.get, EXIT\):) Tj T* ( output_queue.put\(interpreter.send\(input_value\)\)) Tj T* ET +BT 1 0 0 1 0 26 Tm /F3 10 Tf 12 TL (with interpreter:) Tj T* ( for input_value in iter\(input_queue.get, EXIT\):) Tj T* ( output_queue.put\(interpreter.send\(input_value\)\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 223.4236 cm +1 0 0 1 62.69291 256.6236 cm q -BT 1 0 0 1 0 16.82 Tm .106098 Tw 12 TL /F1 10 Tf 0 0 0 rg (The same trick also work for processes; you could run the interpreter loop in a separate process and send) Tj T* 0 Tw (commands to it via the Queue class provided by the ) Tj 0 0 .501961 rg (multiprocessing ) Tj 0 0 0 rg (module.) Tj T* ET +BT 1 0 0 1 0 14 Tm .106098 Tw 12 TL /F1 10 Tf 0 0 0 rg (The same trick also work for processes; you could run the interpreter loop in a separate process and send) Tj T* 0 Tw (commands to it via the Queue class provided by the ) Tj 0 0 .501961 rg (multiprocessing ) Tj 0 0 0 rg (module.) Tj T* ET Q Q q -1 0 0 1 62.69291 193.4236 cm +1 0 0 1 62.69291 226.6236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Long running commands) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Long running commands) Tj T* ET Q Q q -1 0 0 1 62.69291 151.4236 cm +1 0 0 1 62.69291 184.6236 cm q -BT 1 0 0 1 0 28.82 Tm 1.434431 Tw 12 TL /F1 10 Tf 0 0 0 rg (As we saw, by default a ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (interpreter blocks until the command terminates. This is an issue, in the) Tj T* 0 Tw 1.201318 Tw (sense that it makes the interactive experience quite painful for long running commands. An example is) Tj T* 0 Tw (better than a thousand words, so consider the following fake importer:) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.434431 Tw 12 TL /F1 10 Tf 0 0 0 rg (As we saw, by default a ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (interpreter blocks until the command terminates. This is an issue, in the) Tj T* 0 Tw 1.201318 Tw (sense that it makes the interactive experience quite painful for long running commands. An example is) Tj T* 0 Tw (better than a thousand words, so consider the following fake importer:) Tj T* ET Q Q q -1 0 0 1 62.69291 94.22362 cm +1 0 0 1 62.69291 91.42362 cm q q 1 0 0 1 0 0 cm @@ -10906,11 +10803,11 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* +n -6 -6 468.6898 84 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 29.71 Tm /F3 10 Tf 12 TL (import time) Tj T* (import plac) Tj T* T* ET +BT 1 0 0 1 0 62 Tm /F3 10 Tf 12 TL (import time) Tj T* (import plac) Tj T* T* (class FakeImporter\(object\):) Tj T* ( "A fake importer with an import_file command") Tj T* ( commands = ['import_file']) Tj T* ET Q Q Q @@ -10920,21 +10817,20 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (34) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (34) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R371': class PDFStream 371 0 obj % page stream -<< /Length 4419 >> +<< /Length 4584 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 547.8236 cm +1 0 0 1 62.69291 583.8236 cm q q 1 0 0 1 0 0 cm @@ -10944,24 +10840,24 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 216 re B* +n -6 -6 468.6898 180 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 197.71 Tm /F3 10 Tf 12 TL (class FakeImporter\(object\):) Tj T* ( "A fake importer with an import_file command") Tj T* ( commands = ['import_file']) Tj T* ( def __init__\(self, dsn\):) Tj T* ( self.dsn = dsn) Tj T* ( def import_file\(self, fname\):) Tj T* ( "Import a file into the database") Tj T* ( try:) Tj T* ( for n in range\(10000\):) Tj T* ( time.sleep\(.01\)) Tj T* ( if n % 100 == 99:) Tj T* ( yield 'Imported %d lines' % \(n+1\)) Tj T* ( finally:) Tj T* ( print\('closing the file'\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( plac.Interpreter.call\(FakeImporter\)) Tj T* ET +BT 1 0 0 1 0 158 Tm /F3 10 Tf 12 TL ( def __init__\(self, dsn\):) Tj T* ( self.dsn = dsn) Tj T* ( def import_file\(self, fname\):) Tj T* ( "Import a file into the database") Tj T* ( try:) Tj T* ( for n in range\(10000\):) Tj T* ( time.sleep\(.01\)) Tj T* ( if n % 100 == 99:) Tj T* ( yield 'Imported %d lines' % \(n+1\)) Tj T* ( finally:) Tj T* ( print\('closing the file'\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( plac.Interpreter.call\(FakeImporter\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 515.8236 cm +1 0 0 1 62.69291 551.8236 cm q -BT 1 0 0 1 0 16.82 Tm 1.466457 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you run the ) Tj /F3 10 Tf (import_file ) Tj /F1 10 Tf (command, you will have to wait for 200 seconds before entering a new) Tj T* 0 Tw (command:) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.466457 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you run the ) Tj /F3 10 Tf (import_file ) Tj /F1 10 Tf (command, you will have to wait for 200 seconds before entering a new) Tj T* 0 Tw (command:) Tj T* ET Q Q q -1 0 0 1 62.69291 374.6236 cm +1 0 0 1 62.69291 410.6236 cm q q 1 0 0 1 0 0 cm @@ -10974,36 +10870,36 @@ q n -6 -6 468.6898 132 re B* Q q -BT 1 0 0 1 0 113.71 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ python importer1.py dsn) Tj T* (A fake importer with an import_file command) Tj T* (i) Tj (>) Tj ( import_file file1) Tj T* (... ) Tj (<) Tj (wait 3+ minutes) Tj (>) Tj T* (Imported 100 lines) Tj T* (Imported 200 lines) Tj T* (Imported 300 lines) Tj T* (...) Tj T* (Imported 10000 lines) Tj T* (closing the file) Tj T* ET +BT 1 0 0 1 0 110 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ python importer1.py dsn) Tj T* (A fake importer with an import_file command) Tj T* (i) Tj (>) Tj ( import_file file1) Tj T* (... ) Tj (<) Tj (wait 3+ minutes) Tj (>) Tj T* (Imported 100 lines) Tj T* (Imported 200 lines) Tj T* (Imported 300 lines) Tj T* (...) Tj T* (Imported 10000 lines) Tj T* (closing the file) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 330.6236 cm +1 0 0 1 62.69291 366.6236 cm q -BT 1 0 0 1 0 28.82 Tm .96832 Tw 12 TL /F1 10 Tf 0 0 0 rg (Being unable to enter any other command is quite annoying: in such situation one would like to run the) Tj T* 0 Tw .941318 Tw (long running commands in the background, to keep the interface responsive. ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (provides two ways to) Tj T* 0 Tw (reach this goal: threads and processes.) Tj T* ET +BT 1 0 0 1 0 26 Tm .96832 Tw 12 TL /F1 10 Tf 0 0 0 rg (Being unable to enter any other command is quite annoying: in such situation one would like to run the) Tj T* 0 Tw .941318 Tw (long running commands in the background, to keep the interface responsive. ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (provides two ways to) Tj T* 0 Tw (reach this goal: threads and processes.) Tj T* ET Q Q q -1 0 0 1 62.69291 300.6236 cm +1 0 0 1 62.69291 336.6236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Threaded commands) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Threaded commands) Tj T* ET Q Q q -1 0 0 1 62.69291 270.6236 cm +1 0 0 1 62.69291 306.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL .317988 Tw (The most familiar way to execute a task in the background \(even if not necessarily the best way\) is to run) Tj T* 0 Tw (it into a separated thread. In our example it is sufficient to replace the line) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .317988 Tw (The most familiar way to execute a task in the background \(even if not necessarily the best way\) is to run) Tj T* 0 Tw (it into a separated thread. In our example it is sufficient to replace the line) Tj T* ET Q Q q -1 0 0 1 62.69291 264.6236 cm +1 0 0 1 62.69291 300.6236 cm Q q -1 0 0 1 62.69291 252.6236 cm +1 0 0 1 62.69291 288.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET BT 1 0 0 1 0 2 Tm T* ET @@ -11011,27 +10907,27 @@ q 1 0 0 1 20 0 cm q 0 0 0 rg -BT 1 0 0 1 0 5.71 Tm /F3 10 Tf 12 TL (commands = ['import_file']) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (commands = ['import_file']) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 252.6236 cm +1 0 0 1 62.69291 288.6236 cm Q q -1 0 0 1 62.69291 234.6236 cm +1 0 0 1 62.69291 270.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (with) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (with) Tj T* ET Q Q q -1 0 0 1 62.69291 228.6236 cm +1 0 0 1 62.69291 264.6236 cm Q q -1 0 0 1 62.69291 216.6236 cm +1 0 0 1 62.69291 252.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET BT 1 0 0 1 0 2 Tm T* ET @@ -11039,23 +10935,23 @@ q 1 0 0 1 20 0 cm q 0 0 0 rg -BT 1 0 0 1 0 5.71 Tm /F3 10 Tf 12 TL (thcommands = ['import_file']) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (thcommands = ['import_file']) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 216.6236 cm +1 0 0 1 62.69291 252.6236 cm Q q -1 0 0 1 62.69291 186.6236 cm +1 0 0 1 62.69291 222.6236 cm q -BT 1 0 0 1 0 16.82 Tm 1.38311 Tw 12 TL /F1 10 Tf 0 0 0 rg (to tell to the ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (interpreter that the command ) Tj /F3 10 Tf (import_file ) Tj /F1 10 Tf (should be run into a separated thread.) Tj T* 0 Tw (Here is an example session:) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.38311 Tw 12 TL /F1 10 Tf 0 0 0 rg (to tell to the ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (interpreter that the command ) Tj /F3 10 Tf (import_file ) Tj /F1 10 Tf (should be run into a separated thread.) Tj T* 0 Tw (Here is an example session:) Tj T* ET Q Q q -1 0 0 1 62.69291 141.4236 cm +1 0 0 1 62.69291 177.4236 cm q q 1 0 0 1 0 0 cm @@ -11068,37 +10964,56 @@ q n -6 -6 468.6898 36 re B* Q q -BT 1 0 0 1 0 17.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( import_file file1) Tj T* (<) Tj (ThreadedTask 1 [import_file file1] RUNNING) Tj (>) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( import_file file1) Tj T* (<) Tj (ThreadedTask 1 [import_file file1] RUNNING) Tj (>) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 109.4236 cm +1 0 0 1 62.69291 145.4236 cm +q +BT 1 0 0 1 0 14 Tm .595777 Tw 12 TL /F1 10 Tf 0 0 0 rg (The import task started in a separated thread. You can see the progress of the task by using the special) Tj T* 0 Tw (command ) Tj /F3 10 Tf (.output) Tj /F1 10 Tf (:) Tj T* ET +Q +Q +q +1 0 0 1 62.69291 100.2236 cm +q +q +1 0 0 1 0 0 cm +q +1 0 0 1 6.6 6.6 cm +q +.662745 .662745 .662745 RG +.5 w +.960784 .960784 .862745 rg +n -6 -6 468.6898 36 re B* +Q q -BT 1 0 0 1 0 16.82 Tm .595777 Tw 12 TL /F1 10 Tf 0 0 0 rg (The import task started in a separated thread. You can see the progress of the task by using the special) Tj T* 0 Tw (command ) Tj /F3 10 Tf (.output) Tj /F1 10 Tf (:) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( .output 1) Tj T* (<) Tj (ThreadedTask 1 [import_file file1] RUNNING) Tj (>) Tj T* ET +Q +Q +Q Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (35) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (35) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R372': class PDFStream 372 0 obj % page stream -<< /Length 4933 >> +<< /Length 5077 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 703.8236 cm +1 0 0 1 62.69291 727.8236 cm q q 1 0 0 1 0 0 cm @@ -11108,24 +11023,24 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 60 re B* +n -6 -6 468.6898 36 re B* Q q -BT 1 0 0 1 0 41.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( .output 1) Tj T* (<) Tj (ThreadedTask 1 [import_file file1] RUNNING) Tj (>) Tj T* (Imported 100 lines) Tj T* (Imported 200 lines) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf 0 0 0 rg (Imported 100 lines) Tj T* (Imported 200 lines) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 683.8236 cm +1 0 0 1 62.69291 707.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (If you look after a while, you will get more lines of output:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (If you look after a while, you will get more lines of output:) Tj T* ET Q Q q -1 0 0 1 62.69291 590.6236 cm +1 0 0 1 62.69291 614.6236 cm q q 1 0 0 1 0 0 cm @@ -11138,21 +11053,21 @@ q n -6 -6 468.6898 84 re B* Q q -BT 1 0 0 1 0 65.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( .output 1) Tj T* (<) Tj (ThreadedTask 1 [import_file file1] RUNNING) Tj (>) Tj T* (Imported 100 lines) Tj T* (Imported 200 lines) Tj T* (Imported 300 lines) Tj T* (Imported 400 lines) Tj T* ET +BT 1 0 0 1 0 62 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( .output 1) Tj T* (<) Tj (ThreadedTask 1 [import_file file1] RUNNING) Tj (>) Tj T* (Imported 100 lines) Tj T* (Imported 200 lines) Tj T* (Imported 300 lines) Tj T* (Imported 400 lines) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 570.6236 cm +1 0 0 1 62.69291 594.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (If you look after a time long enough, the task will be finished:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (If you look after a time long enough, the task will be finished:) Tj T* ET Q Q q -1 0 0 1 62.69291 525.4236 cm +1 0 0 1 62.69291 549.4236 cm q q 1 0 0 1 0 0 cm @@ -11165,27 +11080,27 @@ q n -6 -6 468.6898 36 re B* Q q -BT 1 0 0 1 0 17.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( .output 1) Tj T* (<) Tj (ThreadedTask 1 [import_file file1] FINISHED) Tj (>) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( .output 1) Tj T* (<) Tj (ThreadedTask 1 [import_file file1] FINISHED) Tj (>) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 493.4236 cm +1 0 0 1 62.69291 517.4236 cm q -BT 1 0 0 1 0 16.82 Tm 1.045868 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can even skip the number argument: then ) Tj /F3 10 Tf (.output ) Tj /F1 10 Tf (will the return the output of the last launched) Tj T* 0 Tw (command \(the special commands like .output do not count\).) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.045868 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can even skip the number argument: then ) Tj /F3 10 Tf (.output ) Tj /F1 10 Tf (will the return the output of the last launched) Tj T* 0 Tw (command \(the special commands like .output do not count\).) Tj T* ET Q Q q -1 0 0 1 62.69291 475.4236 cm +1 0 0 1 62.69291 499.4236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (You can launch many tasks one after the other:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (You can launch many tasks one after the other:) Tj T* ET Q Q q -1 0 0 1 62.69291 406.2236 cm +1 0 0 1 62.69291 430.2236 cm q q 1 0 0 1 0 0 cm @@ -11198,20 +11113,20 @@ q n -6 -6 468.6898 60 re B* Q q -BT 1 0 0 1 0 41.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( import_file file2) Tj T* (<) Tj (ThreadedTask 5 [import_file file2] RUNNING) Tj (>) Tj T* (i) Tj (>) Tj ( import_file file3) Tj T* (<) Tj (ThreadedTask 6 [import_file file3] RUNNING) Tj (>) Tj T* ET +BT 1 0 0 1 0 38 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( import_file file2) Tj T* (<) Tj (ThreadedTask 5 [import_file file2] RUNNING) Tj (>) Tj T* (i) Tj (>) Tj ( import_file file3) Tj T* (<) Tj (ThreadedTask 6 [import_file file3] RUNNING) Tj (>) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 386.2236 cm +1 0 0 1 62.69291 410.2236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf (.list ) Tj /F1 10 Tf (command displays all the running tasks:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf (.list ) Tj /F1 10 Tf (command displays all the running tasks:) Tj T* ET Q Q q -1 0 0 1 62.69291 329.0236 cm +1 0 0 1 62.69291 353.0236 cm q q 1 0 0 1 0 0 cm @@ -11224,21 +11139,21 @@ q n -6 -6 468.6898 48 re B* Q q -BT 1 0 0 1 0 29.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( .list) Tj T* (<) Tj (ThreadedTask 5 [import_file file2] RUNNING) Tj (>) Tj T* (<) Tj (ThreadedTask 6 [import_file file3] RUNNING) Tj (>) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( .list) Tj T* (<) Tj (ThreadedTask 5 [import_file file2] RUNNING) Tj (>) Tj T* (<) Tj (ThreadedTask 6 [import_file file3] RUNNING) Tj (>) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 309.0236 cm +1 0 0 1 62.69291 333.0236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (It is even possible to kill a task:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (It is even possible to kill a task:) Tj T* ET Q Q q -1 0 0 1 62.69291 215.8236 cm +1 0 0 1 62.69291 239.8236 cm q q 1 0 0 1 0 0 cm @@ -11251,37 +11166,57 @@ q n -6 -6 468.6898 84 re B* Q q -BT 1 0 0 1 0 65.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( .kill 5) Tj T* (<) Tj (ThreadedTask 5 [import_file file2] TOBEKILLED) Tj (>) Tj T* (# wait a bit ...) Tj T* (closing the file) Tj T* (i) Tj (>) Tj ( .output 5) Tj T* (<) Tj (ThreadedTask 5 [import_file file2] KILLED) Tj (>) Tj T* ET +BT 1 0 0 1 0 62 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( .kill 5) Tj T* (<) Tj (ThreadedTask 5 [import_file file2] TOBEKILLED) Tj (>) Tj T* (# wait a bit ...) Tj T* (closing the file) Tj T* (i) Tj (>) Tj ( .output 5) Tj T* (<) Tj (ThreadedTask 5 [import_file file2] KILLED) Tj (>) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 123.8236 cm +1 0 0 1 62.69291 147.8236 cm +q +BT 1 0 0 1 0 74 Tm 1.100542 Tw 12 TL /F1 10 Tf 0 0 0 rg (You should notice that since at the Python level it is impossible to kill a thread, the ) Tj /F3 10 Tf (.kill ) Tj /F1 10 Tf (commands) Tj T* 0 Tw 1.793984 Tw (works by setting the status of the task to ) Tj /F3 10 Tf (TOBEKILLED) Tj /F1 10 Tf (. Internally the generator corresponding to the) Tj T* 0 Tw .632927 Tw (command is executed in the thread and the status is checked at each iteration: when the status become) Tj T* 0 Tw 2.578443 Tw /F3 10 Tf (TOBEKILLED ) Tj /F1 10 Tf (a ) Tj /F3 10 Tf (GeneratorExit ) Tj /F1 10 Tf (exception is raised and the thread terminates \(softly, so that the) Tj T* 0 Tw 2.328651 Tw /F3 10 Tf (finally ) Tj /F1 10 Tf (clause is honored\). In our example the generator is yielding back control once every 100) Tj T* 0 Tw 1.152619 Tw (iterations, i.e. every two seconds \(not much\). In order to get a responsive interface it is a good idea to) Tj T* 0 Tw (yield more often, for instance every 10 iterations \(i.e. 5 times per second\), as in the following code:) Tj T* ET +Q +Q +q +1 0 0 1 62.69291 90.62362 cm +q +q +1 0 0 1 0 0 cm +q +1 0 0 1 6.6 6.6 cm +q +.662745 .662745 .662745 RG +.5 w +.960784 .960784 .862745 rg +n -6 -6 468.6898 48 re B* +Q q -BT 1 0 0 1 0 76.82 Tm 1.100542 Tw 12 TL /F1 10 Tf 0 0 0 rg (You should notice that since at the Python level it is impossible to kill a thread, the ) Tj /F3 10 Tf (.kill ) Tj /F1 10 Tf (commands) Tj T* 0 Tw 1.793984 Tw (works by setting the status of the task to ) Tj /F3 10 Tf (TOBEKILLED) Tj /F1 10 Tf (. Internally the generator corresponding to the) Tj T* 0 Tw .632927 Tw (command is executed in the thread and the status is checked at each iteration: when the status become) Tj T* 0 Tw 2.578443 Tw /F3 10 Tf (TOBEKILLED ) Tj /F1 10 Tf (a ) Tj /F3 10 Tf (GeneratorExit ) Tj /F1 10 Tf (exception is raised and the thread terminates \(softly, so that the) Tj T* 0 Tw 2.328651 Tw /F3 10 Tf (finally ) Tj /F1 10 Tf (clause is honored\). In our example the generator is yielding back control once every 100) Tj T* 0 Tw 1.152619 Tw (iterations, i.e. every two seconds \(not much\). In order to get a responsive interface it is a good idea to) Tj T* 0 Tw (yield more often, for instance every 10 iterations \(i.e. 5 times per second\), as in the following code:) Tj T* ET +0 0 0 rg +BT 1 0 0 1 0 26 Tm /F3 10 Tf 12 TL (import time) Tj T* (import plac) Tj T* T* ET +Q +Q +Q Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (36) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (36) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R373': class PDFStream 373 0 obj % page stream -<< /Length 4291 >> +<< /Length 4725 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 487.8236 cm +1 0 0 1 62.69291 523.8236 cm q q 1 0 0 1 0 0 cm @@ -11291,40 +11226,40 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 276 re B* +n -6 -6 468.6898 240 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 257.71 Tm /F3 10 Tf 12 TL (import time) Tj T* (import plac) Tj T* T* (class FakeImporter\(object\):) Tj T* ( "A fake importer with an import_file command") Tj T* ( thcommands = ['import_file']) Tj T* ( def __init__\(self, dsn\):) Tj T* ( self.dsn = dsn) Tj T* ( def import_file\(self, fname\):) Tj T* ( "Import a file into the database") Tj T* ( try:) Tj T* ( for n in range\(10000\):) Tj T* ( time.sleep\(.02\)) Tj T* ( if n % 100 == 99: # every two seconds) Tj T* ( yield 'Imported %d lines' % \(n+1\)) Tj T* ( if n % 10 == 9: # every 0.2 seconds) Tj T* ( yield # go back and check the TOBEKILLED status) Tj T* ( finally:) Tj T* ( print\('closing the file'\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( plac.Interpreter.call\(FakeImporter\)) Tj T* ET +BT 1 0 0 1 0 218 Tm /F3 10 Tf 12 TL (class FakeImporter\(object\):) Tj T* ( "A fake importer with an import_file command") Tj T* ( thcommands = ['import_file']) Tj T* ( def __init__\(self, dsn\):) Tj T* ( self.dsn = dsn) Tj T* ( def import_file\(self, fname\):) Tj T* ( "Import a file into the database") Tj T* ( try:) Tj T* ( for n in range\(10000\):) Tj T* ( time.sleep\(.02\)) Tj T* ( if n % 100 == 99: # every two seconds) Tj T* ( yield 'Imported %d lines' % \(n+1\)) Tj T* ( if n % 10 == 9: # every 0.2 seconds) Tj T* ( yield # go back and check the TOBEKILLED status) Tj T* ( finally:) Tj T* ( print\('closing the file'\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( plac.Interpreter.call\(FakeImporter\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 457.8236 cm +1 0 0 1 62.69291 493.8236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Running commands as external processes) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Running commands as external processes) Tj T* ET Q Q q -1 0 0 1 62.69291 403.8236 cm +1 0 0 1 62.69291 439.8236 cm q -BT 1 0 0 1 0 40.82 Tm 2.30686 Tw 12 TL /F1 10 Tf 0 0 0 rg (Threads are not loved much in the Python world and actually most people prefer to use processes) Tj T* 0 Tw 3.350697 Tw (instead. For this reason ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (provides the option to execute long running commands as external) Tj T* 0 Tw .632706 Tw (processes. Unfortunately the current implementation only works in Unix-like operating systems \(including) Tj T* 0 Tw (Mac OS X\) because it relies on fork via the ) Tj 0 0 .501961 rg (multiprocessing ) Tj 0 0 0 rg (module.) Tj T* ET +BT 1 0 0 1 0 38 Tm 2.30686 Tw 12 TL /F1 10 Tf 0 0 0 rg (Threads are not loved much in the Python world and actually most people prefer to use processes) Tj T* 0 Tw 3.350697 Tw (instead. For this reason ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (provides the option to execute long running commands as external) Tj T* 0 Tw .632706 Tw (processes. Unfortunately the current implementation only works in Unix-like operating systems \(including) Tj T* 0 Tw (Mac OS X\) because it relies on fork via the ) Tj 0 0 .501961 rg (multiprocessing ) Tj 0 0 0 rg (module.) Tj T* ET Q Q q -1 0 0 1 62.69291 385.8236 cm +1 0 0 1 62.69291 421.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (In our example, to enable the feature it is sufficient to replace the line) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (In our example, to enable the feature it is sufficient to replace the line) Tj T* ET Q Q q -1 0 0 1 62.69291 379.8236 cm +1 0 0 1 62.69291 415.8236 cm Q q -1 0 0 1 62.69291 367.8236 cm +1 0 0 1 62.69291 403.8236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET BT 1 0 0 1 0 2 Tm T* ET @@ -11332,51 +11267,51 @@ q 1 0 0 1 20 0 cm q 0 0 0 rg -BT 1 0 0 1 0 5.71 Tm /F3 10 Tf 12 TL (thcommands = ['import_file']) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (thcommands = ['import_file']) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 367.8236 cm +1 0 0 1 62.69291 403.8236 cm Q q -1 0 0 1 62.69291 349.8236 cm +1 0 0 1 62.69291 385.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (with) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (with) Tj T* ET Q Q q -1 0 0 1 62.69291 343.8236 cm +1 0 0 1 62.69291 379.8236 cm Q q -1 0 0 1 62.69291 331.8236 cm +1 0 0 1 62.69291 367.8236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET BT 1 0 0 1 0 2 Tm T* ET q 1 0 0 1 20 0 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F3 10 Tf 0 0 0 rg (mpcommands = ['import_file']) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (mpcommands = ['import_file']) Tj /F1 10 Tf (.) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 331.8236 cm +1 0 0 1 62.69291 367.8236 cm Q q -1 0 0 1 62.69291 301.8236 cm +1 0 0 1 62.69291 337.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL .772619 Tw (The user experience is exactly the same as with threads and you will not see any difference at the user) Tj T* 0 Tw (interface level:) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .772619 Tw (The user experience is exactly the same as with threads and you will not see any difference at the user) Tj T* 0 Tw (interface level:) Tj T* ET Q Q q -1 0 0 1 62.69291 160.6236 cm +1 0 0 1 62.69291 196.6236 cm q q 1 0 0 1 0 0 cm @@ -11389,70 +11324,76 @@ q n -6 -6 468.6898 132 re B* Q q -BT 1 0 0 1 0 113.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( import_file file3) Tj T* (<) Tj (MPTask 1 [import_file file3] SUBMITTED) Tj (>) Tj T* (i) Tj (>) Tj ( .kill 1) Tj T* (<) Tj (MPTask 1 [import_file file3] RUNNING) Tj (>) Tj T* (closing the file) Tj T* (i) Tj (>) Tj ( .o 1) Tj T* (<) Tj (MPTask 1 [import_file file3] KILLED) Tj (>) Tj T* (Imported 100 lines) Tj T* (Imported 200 lines) Tj T* (i) Tj (>) Tj T* ET +BT 1 0 0 1 0 110 Tm 12 TL /F3 10 Tf 0 0 0 rg (i) Tj (>) Tj ( import_file file3) Tj T* (<) Tj (MPTask 1 [import_file file3] SUBMITTED) Tj (>) Tj T* (i) Tj (>) Tj ( .kill 1) Tj T* (<) Tj (MPTask 1 [import_file file3] RUNNING) Tj (>) Tj T* (closing the file) Tj T* (i) Tj (>) Tj ( .o 1) Tj T* (<) Tj (MPTask 1 [import_file file3] KILLED) Tj (>) Tj T* (Imported 100 lines) Tj T* (Imported 200 lines) Tj T* (i) Tj (>) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 104.6236 cm +1 0 0 1 62.69291 140.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 40.82 Tm /F1 10 Tf 12 TL 1.201318 Tw (Still, using processes is quite different than using threads: in particular, when using processes you can) Tj T* 0 Tw 2.313318 Tw (only yield pickleable values and you cannot re-raise an exception first raised in a different process,) Tj T* 0 Tw 1.445697 Tw (because traceback objects are not pickleable. Moreover, you cannot rely on automatic sharing of your) Tj T* 0 Tw (objects.) Tj T* ET +BT 1 0 0 1 0 38 Tm /F1 10 Tf 12 TL 1.201318 Tw (Still, using processes is quite different than using threads: in particular, when using processes you can) Tj T* 0 Tw 2.313318 Tw (only yield pickleable values and you cannot re-raise an exception first raised in a different process,) Tj T* 0 Tw 1.445697 Tw (because traceback objects are not pickleable. Moreover, you cannot rely on automatic sharing of your) Tj T* 0 Tw (objects.) Tj T* ET +Q +Q +q +1 0 0 1 62.69291 98.62362 cm +q +BT 1 0 0 1 0 26 Tm .128935 Tw 12 TL /F1 10 Tf 0 0 0 rg (On the plus side, when using processes you do not need to worry about killing a command: they are killed ) Tj T* 0 Tw .466412 Tw (immediately using a SIGTERM signal, and there is not a ) Tj /F3 10 Tf (TOBEKILLED ) Tj /F1 10 Tf (mechanism. Moreover, the killing ) Tj T* 0 Tw 1.50229 Tw (is guaranteed to be soft: internally a command receiving a SIGTERM raises a ) Tj /F3 10 Tf (TerminatedProcess) Tj T* 0 Tw ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (37) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (37) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R374': class PDFStream 374 0 obj % page stream -<< /Length 4180 >> +<< /Length 3732 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 717.0236 cm +1 0 0 1 62.69291 753.0236 cm q -BT 1 0 0 1 0 40.82 Tm .128935 Tw 12 TL /F1 10 Tf 0 0 0 rg (On the plus side, when using processes you do not need to worry about killing a command: they are killed) Tj T* 0 Tw .466412 Tw (immediately using a SIGTERM signal, and there is not a ) Tj /F3 10 Tf (TOBEKILLED ) Tj /F1 10 Tf (mechanism. Moreover, the killing) Tj T* 0 Tw 1.50229 Tw (is guaranteed to be soft: internally a command receiving a SIGTERM raises a ) Tj /F3 10 Tf (TerminatedProcess) Tj T* 0 Tw /F1 10 Tf (exception which is trapped in the generator loop, so that the command is closed properly.) Tj T* ET +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (exception which is trapped in the generator loop, so that the command is closed properly.) Tj T* ET Q Q q -1 0 0 1 62.69291 687.0236 cm +1 0 0 1 62.69291 723.0236 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL .242927 Tw (Using processes allows to take full advantage of multicore machines and it is safer than using threads, so) Tj T* 0 Tw (it is the recommended approach unless you are working on Windows.) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .242927 Tw (Using processes allows to take full advantage of multicore machines and it is safer than using threads, so) Tj T* 0 Tw (it is the recommended approach unless you are working on Windows.) Tj T* ET Q Q q -1 0 0 1 62.69291 657.0236 cm +1 0 0 1 62.69291 693.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Managing the output of concurrent commands) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Managing the output of concurrent commands) Tj T* ET Q Q q -1 0 0 1 62.69291 555.0236 cm +1 0 0 1 62.69291 591.0236 cm q -BT 1 0 0 1 0 88.82 Tm 1.895542 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (acts as a command-line task launcher and can be used as the base to build a GUI-based task) Tj T* 0 Tw .38561 Tw (launcher and task monitor. To this aim the interpreter class provides a ) Tj /F3 10 Tf (.submit ) Tj /F1 10 Tf (method which returns a) Tj T* 0 Tw 1.792339 Tw (task object and a ) Tj /F3 10 Tf (.tasks ) Tj /F1 10 Tf (method returning the list of all the tasks submitted to the interpreter. The) Tj T* 0 Tw .373516 Tw /F3 10 Tf (submit ) Tj /F1 10 Tf (method does not start the task and thus it is nonblocking. Each task has an ) Tj /F3 10 Tf (.outlist ) Tj /F1 10 Tf (attribute) Tj T* 0 Tw .106098 Tw (which is a list storing the value yielded by the generator underlying the task \(the ) Tj /F3 10 Tf (None ) Tj /F1 10 Tf (values are skipped) Tj T* 0 Tw .633318 Tw (though\): the ) Tj /F3 10 Tf (.outlist ) Tj /F1 10 Tf (grows as the task runs and more values are yielded. Accessing the ) Tj /F3 10 Tf (.outlist) Tj T* 0 Tw 1.051654 Tw /F1 10 Tf (is nonblocking and can be done freely. Finally there is a ) Tj /F3 10 Tf (.result ) Tj /F1 10 Tf (property which waits for the task to) Tj T* 0 Tw (finish and returns the last yielded value or raises an exception.) Tj T* ET +BT 1 0 0 1 0 86 Tm 1.895542 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (acts as a command-line task launcher and can be used as the base to build a GUI-based task) Tj T* 0 Tw .38561 Tw (launcher and task monitor. To this aim the interpreter class provides a ) Tj /F3 10 Tf (.submit ) Tj /F1 10 Tf (method which returns a) Tj T* 0 Tw 1.792339 Tw (task object and a ) Tj /F3 10 Tf (.tasks ) Tj /F1 10 Tf (method returning the list of all the tasks submitted to the interpreter. The) Tj T* 0 Tw .373516 Tw /F3 10 Tf (submit ) Tj /F1 10 Tf (method does not start the task and thus it is nonblocking. Each task has an ) Tj /F3 10 Tf (.outlist ) Tj /F1 10 Tf (attribute) Tj T* 0 Tw .106098 Tw (which is a list storing the value yielded by the generator underlying the task \(the ) Tj /F3 10 Tf (None ) Tj /F1 10 Tf (values are skipped) Tj T* 0 Tw .633318 Tw (though\): the ) Tj /F3 10 Tf (.outlist ) Tj /F1 10 Tf (grows as the task runs and more values are yielded. Accessing the ) Tj /F3 10 Tf (.outlist) Tj T* 0 Tw 1.051654 Tw /F1 10 Tf (is nonblocking and can be done freely. Finally there is a ) Tj /F3 10 Tf (.result ) Tj /F1 10 Tf (property which waits for the task to) Tj T* 0 Tw (finish and returns the last yielded value or raises an exception.) Tj T* ET Q Q q -1 0 0 1 62.69291 525.0236 cm +1 0 0 1 62.69291 561.0236 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL .014692 Tw (Here is some example code to visualize the output of the FakeImporter in Tkinter \(I chose Tkinter because) Tj T* 0 Tw (it is easy to use and it is in the standard library, but you can use any GUI\):) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .014692 Tw (Here is some example code to visualize the output of the FakeImporter in Tkinter \(I chose Tkinter because) Tj T* 0 Tw (it is easy to use and it is in the standard library, but you can use any GUI\):) Tj T* ET Q Q q -1 0 0 1 62.69291 155.8236 cm +1 0 0 1 62.69291 191.8236 cm q q 1 0 0 1 0 0 cm @@ -11466,7 +11407,7 @@ n -6 -6 468.6898 360 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 341.71 Tm /F3 10 Tf 12 TL (from Tkinter import *) Tj T* (from importer3 import FakeImporter) Tj T* T* (def taskwidget\(root, task, tick=500\):) Tj T* ( "A Label widget showing the output of a task every 500 ms") Tj T* ( sv = StringVar\(root\)) Tj T* ( lb = Label\(root, textvariable=sv\)) Tj T* ( def show_outlist\(\):) Tj T* ( try:) Tj T* ( out = task.outlist[-1]) Tj T* ( except IndexError: # no output yet) Tj T* ( out = '') Tj T* ( sv.set\('%s %s' % \(task, out\)\)) Tj T* ( root.after\(tick, show_outlist\)) Tj T* ( root.after\(0, show_outlist\)) Tj T* ( return lb) Tj T* T* (def monitor\(tasks\):) Tj T* ( root = Tk\(\)) Tj T* ( for task in tasks:) Tj T* ( task.run\(\)) Tj T* ( taskwidget\(root, task\).pack\(\)) Tj T* ( root.mainloop\(\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac) Tj T* ( with plac.Interpreter\(plac.call\(FakeImporter\)\) as i:) Tj T* ( tasks = [i.submit\('import_file f1'\), i.submit\('import_file f2'\)]) Tj T* ( monitor\(tasks\)) Tj T* ET +BT 1 0 0 1 0 338 Tm /F3 10 Tf 12 TL (from Tkinter import *) Tj T* (from importer3 import FakeImporter) Tj T* T* (def taskwidget\(root, task, tick=500\):) Tj T* ( "A Label widget showing the output of a task every 500 ms") Tj T* ( sv = StringVar\(root\)) Tj T* ( lb = Label\(root, textvariable=sv\)) Tj T* ( def show_outlist\(\):) Tj T* ( try:) Tj T* ( out = task.outlist[-1]) Tj T* ( except IndexError: # no output yet) Tj T* ( out = '') Tj T* ( sv.set\('%s %s' % \(task, out\)\)) Tj T* ( root.after\(tick, show_outlist\)) Tj T* ( root.after\(0, show_outlist\)) Tj T* ( return lb) Tj T* T* (def monitor\(tasks\):) Tj T* ( root = Tk\(\)) Tj T* ( for task in tasks:) Tj T* ( task.run\(\)) Tj T* ( taskwidget\(root, task\).pack\(\)) Tj T* ( root.mainloop\(\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac) Tj T* ( with plac.Interpreter\(plac.call\(FakeImporter\)\) as i:) Tj T* ( tasks = [i.submit\('import_file f1'\), i.submit\('import_file f2'\)]) Tj T* ( monitor\(tasks\)) Tj T* ET Q Q Q @@ -11476,29 +11417,28 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (38) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (38) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R375': class PDFStream 375 0 obj % page stream -<< /Length 4659 >> +<< /Length 4638 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 747.0236 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Parallel computing with plac) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Parallel computing with plac) Tj T* ET Q Q q 1 0 0 1 62.69291 633.0236 cm q -BT 1 0 0 1 0 100.82 Tm 1.174751 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is certainly not intended as a tool for parallel computing, but still you can use it to launch a set of) Tj T* 0 Tw .497984 Tw (commands and to collect the results, similarly to the MapReduce pattern popularized by Google. In order) Tj T* 0 Tw .669431 Tw (to give an example, I will consider the "Hello World" of parallel computing, i.e. the computation of pi with) Tj T* 0 Tw .537633 Tw (independent processes. There is a huge number of algorithms to compute pi; here I will describe a trivial) Tj T* 0 Tw .101567 Tw (one chosen for simplicity, not per efficienty. The trick is to consider the first quadrant of a circle with radius) Tj T* 0 Tw .602488 Tw (1 and to extract a number of points ) Tj /F3 10 Tf (\(x, y\) ) Tj /F1 10 Tf (with ) Tj /F3 10 Tf (x ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (y ) Tj /F1 10 Tf (random variables in the interval ) Tj /F3 10 Tf ([0,1]) Tj /F1 10 Tf (. The) Tj T* 0 Tw .928876 Tw (probability of extracting a number inside the quadrant \(i.e. with ) Tj /F3 10 Tf (x^2 + y^2 < 1) Tj /F1 10 Tf (\) is proportional to the) Tj T* 0 Tw .433145 Tw (area of the quadrant \(i.e. ) Tj /F3 10 Tf (pi/4) Tj /F1 10 Tf (\). The value of ) Tj /F3 10 Tf (pi ) Tj /F1 10 Tf (therefore can be extracted by multiplying by 4 the ratio) Tj T* 0 Tw (between the number of points in the quadrant versus the total number of points ) Tj /F3 10 Tf (N) Tj /F1 10 Tf (, for ) Tj /F3 10 Tf (N ) Tj /F1 10 Tf (large:) Tj T* ET +BT 1 0 0 1 0 98 Tm 1.174751 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is certainly not intended as a tool for parallel computing, but still you can use it to launch a set of) Tj T* 0 Tw .497984 Tw (commands and to collect the results, similarly to the MapReduce pattern popularized by Google. In order) Tj T* 0 Tw .669431 Tw (to give an example, I will consider the "Hello World" of parallel computing, i.e. the computation of pi with) Tj T* 0 Tw .537633 Tw (independent processes. There is a huge number of algorithms to compute pi; here I will describe a trivial) Tj T* 0 Tw .101567 Tw (one chosen for simplicity, not per efficienty. The trick is to consider the first quadrant of a circle with radius) Tj T* 0 Tw .602488 Tw (1 and to extract a number of points ) Tj /F3 10 Tf (\(x, y\) ) Tj /F1 10 Tf (with ) Tj /F3 10 Tf (x ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (y ) Tj /F1 10 Tf (random variables in the interval ) Tj /F3 10 Tf ([0,1]) Tj /F1 10 Tf (. The) Tj T* 0 Tw .928876 Tw (probability of extracting a number inside the quadrant \(i.e. with ) Tj /F3 10 Tf (x^2 + y^2 < 1) Tj /F1 10 Tf (\) is proportional to the) Tj T* 0 Tw .433145 Tw (area of the quadrant \(i.e. ) Tj /F3 10 Tf (pi/4) Tj /F1 10 Tf (\). The value of ) Tj /F3 10 Tf (pi ) Tj /F1 10 Tf (therefore can be extracted by multiplying by 4 the ratio) Tj T* 0 Tw (between the number of points in the quadrant versus the total number of points ) Tj /F3 10 Tf (N) Tj /F1 10 Tf (, for ) Tj /F3 10 Tf (N ) Tj /F1 10 Tf (large:) Tj T* ET Q Q q @@ -11515,7 +11455,7 @@ q n -6 -6 468.6898 96 re B* Q q -BT 1 0 0 1 0 77.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (def calc_pi\(N\):) Tj T* ( inside = 0) Tj T* ( for j in xrange\(N\):) Tj T* ( x, y = random\(\), random\(\)) Tj T* ( if x*x + y*y ) Tj (<) Tj ( 1:) Tj T* ( inside += 1) Tj T* ( return \(4.0 * inside\) / N) Tj T* ET +BT 1 0 0 1 0 74 Tm 12 TL /F3 10 Tf 0 0 0 rg (def calc_pi\(N\):) Tj T* ( inside = 0) Tj T* ( for j in xrange\(N\):) Tj T* ( x, y = random\(\), random\(\)) Tj T* ( if x*x + y*y ) Tj (<) Tj ( 1:) Tj T* ( inside += 1) Tj T* ( return \(4.0 * inside\) / N) Tj T* ET Q Q Q @@ -11525,13 +11465,13 @@ q 1 0 0 1 62.69291 459.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 52.82 Tm /F1 10 Tf 12 TL .046654 Tw (The algorithm is trivially parallelizable: if you have n CPUs, you can compute pi n times with N/n iterations,) Tj T* 0 Tw 1.122488 Tw (sum the results and divide the total by n. I have a Macbook with two cores, therefore I would expect a) Tj T* 0 Tw 2.347984 Tw (speedup factor of 2 with respect to a sequential computation. Moreover, I would expect a threaded) Tj T* 0 Tw 2.827984 Tw (computation to be even slower than a sequential computation, due to the GIL and the scheduling) Tj T* 0 Tw (overhead.) Tj T* ET +BT 1 0 0 1 0 50 Tm /F1 10 Tf 12 TL .046654 Tw (The algorithm is trivially parallelizable: if you have n CPUs, you can compute pi n times with N/n iterations,) Tj T* 0 Tw 1.122488 Tw (sum the results and divide the total by n. I have a Macbook with two cores, therefore I would expect a) Tj T* 0 Tw 2.347984 Tw (speedup factor of 2 with respect to a sequential computation. Moreover, I would expect a threaded) Tj T* 0 Tw 2.827984 Tw (computation to be even slower than a sequential computation, due to the GIL and the scheduling) Tj T* 0 Tw (overhead.) Tj T* ET Q Q q 1 0 0 1 62.69291 429.8236 cm q -BT 1 0 0 1 0 16.82 Tm .313984 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here is a script implementing the algorithm and working in three different modes \(parallel mode, threaded) Tj T* 0 Tw (mode and sequential mode\) depending on a ) Tj /F3 10 Tf (mode ) Tj /F1 10 Tf (option:) Tj T* ET +BT 1 0 0 1 0 14 Tm .313984 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here is a script implementing the algorithm and working in three different modes \(parallel mode, threaded) Tj T* 0 Tw (mode and sequential mode\) depending on a ) Tj /F3 10 Tf (mode ) Tj /F1 10 Tf (option:) Tj T* ET Q Q q @@ -11548,7 +11488,7 @@ q n -6 -6 468.6898 324 re B* Q q -BT 1 0 0 1 0 305.71 Tm 12 TL /F3 10 Tf 0 0 0 rg (from __future__ import with_statement) Tj T* (from random import random) Tj T* (import multiprocessing) Tj T* (import plac) Tj T* T* (class PiCalculator\(object\):) Tj T* ( """Compute pi in parallel with threads or processes""") Tj T* ( ) Tj T* ( @plac.annotations\() Tj T* ( npoints=\('number of integration points', 'positional', None, int\),) Tj T* ( mode=\('sequential|parallel|threaded', 'option', 'm', str, 'SPT'\)\)) Tj T* ( def __init__\(self, npoints, mode='S'\):) Tj T* ( self.npoints = npoints) Tj T* ( if mode == 'P':) Tj T* ( self.mpcommands = ['calc_pi']) Tj T* ( elif mode == 'T':) Tj T* ( self.thcommands = ['calc_pi']) Tj T* ( elif mode == 'S':) Tj T* ( self.commands = ['calc_pi']) Tj T* ( self.n_cpu = multiprocessing.cpu_count\(\)) Tj T* ( ) Tj T* ( def submit_tasks\(self\):) Tj T* ( self.i = plac.Interpreter\(self\).__enter__\(\) ) Tj T* ( return [self.i.submit\('calc_pi %d' % \(self.npoints / self.n_cpu\)\)) Tj T* ( for _ in range\(self.n_cpu\)]) Tj T* T* ET +BT 1 0 0 1 0 302 Tm 12 TL /F3 10 Tf 0 0 0 rg (from __future__ import with_statement) Tj T* (from random import random) Tj T* (import multiprocessing) Tj T* (import plac) Tj T* T* (class PiCalculator\(object\):) Tj T* ( """Compute pi in parallel with threads or processes""") Tj T* ( ) Tj T* ( @plac.annotations\() Tj T* ( npoints=\('number of integration points', 'positional', None, int\),) Tj T* ( mode=\('sequential|parallel|threaded', 'option', 'm', str, 'SPT'\)\)) Tj T* ( def __init__\(self, npoints, mode='S'\):) Tj T* ( self.npoints = npoints) Tj T* ( if mode == 'P':) Tj T* ( self.mpcommands = ['calc_pi']) Tj T* ( elif mode == 'T':) Tj T* ( self.thcommands = ['calc_pi']) Tj T* ( elif mode == 'S':) Tj T* ( self.commands = ['calc_pi']) Tj T* ( self.n_cpu = multiprocessing.cpu_count\(\)) Tj T* ( ) Tj T* ( def submit_tasks\(self\):) Tj T* ( self.i = plac.Interpreter\(self\).__enter__\(\) ) Tj T* ( return [self.i.submit\('calc_pi %d' % \(self.npoints / self.n_cpu\)\)) Tj T* ( for _ in range\(self.n_cpu\)]) Tj T* T* ET Q Q Q @@ -11558,19 +11498,18 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (39) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (39) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R376': class PDFStream 376 0 obj % page stream -<< /Length 3402 >> +<< /Length 3388 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 307.8236 cm q @@ -11585,7 +11524,7 @@ q n -6 -6 468.6898 456 re B* Q q -BT 1 0 0 1 0 437.71 Tm 12 TL /F3 10 Tf 0 0 0 rg ( def close\(self\):) Tj T* ( self.i.close\(\)) Tj T* T* ( @plac.annotations\() Tj T* ( npoints=\('npoints', 'positional', None, int\)\)) Tj T* ( def calc_pi\(self, npoints\):) Tj T* ( counts = 0) Tj T* ( for j in xrange\(npoints\):) Tj T* ( n, r = divmod\(j, 1000000\)) Tj T* ( if r == 0:) Tj T* ( yield '%dM iterations' % n) Tj T* ( x, y = random\(\), random\(\)) Tj T* ( if x*x + y*y ) Tj (<) Tj ( 1:) Tj T* ( counts += 1) Tj T* ( yield \(4.0 * counts\)/npoints) Tj T* T* ( def run\(self\):) Tj T* ( tasks = self.i.tasks\(\)) Tj T* ( for t in tasks:) Tj T* ( t.run\(\)) Tj T* ( try:) Tj T* ( total = 0) Tj T* ( for task in tasks:) Tj T* ( total += task.result) Tj T* ( except: # the task was killed) Tj T* ( print tasks) Tj T* ( return) Tj T* ( return total / self.n_cpu) Tj T* T* (if __name__ == '__main__':) Tj T* ( pc = plac.call\(PiCalculator\)) Tj T* ( pc.submit_tasks\(\)) Tj T* ( try:) Tj T* ( import time; t0 = time.time\(\)) Tj T* ( print '%f in %f seconds ' % \(pc.run\(\), time.time\(\) - t0\)) Tj T* ( finally:) Tj T* ( pc.close\(\)) Tj T* ET +BT 1 0 0 1 0 434 Tm 12 TL /F3 10 Tf 0 0 0 rg ( def close\(self\):) Tj T* ( self.i.close\(\)) Tj T* T* ( @plac.annotations\() Tj T* ( npoints=\('npoints', 'positional', None, int\)\)) Tj T* ( def calc_pi\(self, npoints\):) Tj T* ( counts = 0) Tj T* ( for j in xrange\(npoints\):) Tj T* ( n, r = divmod\(j, 1000000\)) Tj T* ( if r == 0:) Tj T* ( yield '%dM iterations' % n) Tj T* ( x, y = random\(\), random\(\)) Tj T* ( if x*x + y*y ) Tj (<) Tj ( 1:) Tj T* ( counts += 1) Tj T* ( yield \(4.0 * counts\)/npoints) Tj T* T* ( def run\(self\):) Tj T* ( tasks = self.i.tasks\(\)) Tj T* ( for t in tasks:) Tj T* ( t.run\(\)) Tj T* ( try:) Tj T* ( total = 0) Tj T* ( for task in tasks:) Tj T* ( total += task.result) Tj T* ( except: # the task was killed) Tj T* ( print tasks) Tj T* ( return) Tj T* ( return total / self.n_cpu) Tj T* T* (if __name__ == '__main__':) Tj T* ( pc = plac.call\(PiCalculator\)) Tj T* ( pc.submit_tasks\(\)) Tj T* ( try:) Tj T* ( import time; t0 = time.time\(\)) Tj T* ( print '%f in %f seconds ' % \(pc.run\(\), time.time\(\) - t0\)) Tj T* ( finally:) Tj T* ( pc.close\(\)) Tj T* ET Q Q Q @@ -11594,14 +11533,14 @@ Q q 1 0 0 1 62.69291 227.8236 cm q -BT 1 0 0 1 0 64.82 Tm .381797 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice the ) Tj /F3 10 Tf (submit_tasks ) Tj /F1 10 Tf (method, which instantiates and initializes a ) Tj /F3 10 Tf (plac.Interpreter ) Tj /F1 10 Tf (object and) Tj T* 0 Tw 3.38152 Tw (submits a number of commands corresponding to the number of available CPUs. The ) Tj /F3 10 Tf (calc_pi) Tj T* 0 Tw 3.796651 Tw /F1 10 Tf (command yield a log message every million of interactions, just to monitor the progress of the) Tj T* 0 Tw 1.751318 Tw (computation. The ) Tj /F3 10 Tf (run ) Tj /F1 10 Tf (method starts all the submitted commands in parallel and sums the results. It) Tj T* 0 Tw 1.17104 Tw (returns the average value of ) Tj /F3 10 Tf (pi ) Tj /F1 10 Tf (after the slowest CPU has finished its job \(if the CPUs are equal and) Tj T* 0 Tw (equally busy they should finish more or less at the same time\).) Tj T* ET +BT 1 0 0 1 0 62 Tm .381797 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice the ) Tj /F3 10 Tf (submit_tasks ) Tj /F1 10 Tf (method, which instantiates and initializes a ) Tj /F3 10 Tf (plac.Interpreter ) Tj /F1 10 Tf (object and) Tj T* 0 Tw 3.38152 Tw (submits a number of commands corresponding to the number of available CPUs. The ) Tj /F3 10 Tf (calc_pi) Tj T* 0 Tw 3.796651 Tw /F1 10 Tf (command yield a log message every million of interactions, just to monitor the progress of the) Tj T* 0 Tw 1.751318 Tw (computation. The ) Tj /F3 10 Tf (run ) Tj /F1 10 Tf (method starts all the submitted commands in parallel and sums the results. It) Tj T* 0 Tw 1.17104 Tw (returns the average value of ) Tj /F3 10 Tf (pi ) Tj /F1 10 Tf (after the slowest CPU has finished its job \(if the CPUs are equal and) Tj T* 0 Tw (equally busy they should finish more or less at the same time\).) Tj T* ET Q Q q 1 0 0 1 62.69291 209.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Here are the results on my old Macbook with Ubuntu 10.04 and Python 2.6, for 10 million of iterations:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here are the results on my old Macbook with Ubuntu 10.04 and Python 2.6, for 10 million of iterations:) Tj T* ET Q Q q @@ -11619,7 +11558,7 @@ n -6 -6 468.6898 84 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 65.71 Tm /F3 10 Tf 12 TL ($ python picalculator.py -mP 10000000 # two processes) Tj T* (3.141904 in 5.744545 seconds) Tj T* ($ python picalculator.py -mT 10000000 # two threads) Tj T* (3.141272 in 13.875645 seconds) Tj T* ($ python picalculator.py -mS 10000000 # sequential) Tj T* (3.141586 in 11.353841 seconds) Tj T* ET +BT 1 0 0 1 0 62 Tm /F3 10 Tf 12 TL ($ python picalculator.py -mP 10000000 # two processes) Tj T* (3.141904 in 5.744545 seconds) Tj T* ($ python picalculator.py -mT 10000000 # two threads) Tj T* (3.141272 in 13.875645 seconds) Tj T* ($ python picalculator.py -mS 10000000 # sequential) Tj T* (3.141586 in 11.353841 seconds) Tj T* ET Q Q Q @@ -11629,30 +11568,29 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (40) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (40) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R377': class PDFStream 377 0 obj % page stream -<< /Length 5017 >> +<< /Length 4983 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 741.0236 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL 1.711751 Tw (As you see using processes one gets a 2x speedup indeed, where the threaded mode is some 20%) Tj T* 0 Tw (slower than the sequential mode.) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.711751 Tw (As you see using processes one gets a 2x speedup indeed, where the threaded mode is some 20%) Tj T* 0 Tw (slower than the sequential mode.) Tj T* ET Q Q q 1 0 0 1 62.69291 675.0236 cm q -BT 1 0 0 1 0 52.82 Tm .167765 Tw 12 TL /F1 10 Tf 0 0 0 rg (Since the pattern submit a bunch of tasks, starts them and collect the results is so common, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (provides) Tj T* 0 Tw .493828 Tw (an utility function ) Tj /F3 10 Tf (runp\(genseq, mode='p', start=True\) ) Tj /F1 10 Tf (to start a bunch a generators and return) Tj T* 0 Tw .587765 Tw (a list of task objects. By default ) Tj /F3 10 Tf (runp ) Tj /F1 10 Tf (use processes, but you can use threads by passing ) Tj /F3 10 Tf (mode='t') Tj /F1 10 Tf (. If) Tj T* 0 Tw .422765 Tw (you do not wont to start the tasks, you can say so \() Tj /F3 10 Tf (start=False) Tj /F1 10 Tf (\). With ) Tj /F3 10 Tf (runp ) Tj /F1 10 Tf (the parallel pi calculation) Tj T* 0 Tw (becomes a one-liner:) Tj T* ET +BT 1 0 0 1 0 50 Tm .167765 Tw 12 TL /F1 10 Tf 0 0 0 rg (Since the pattern submit a bunch of tasks, starts them and collect the results is so common, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (provides) Tj T* 0 Tw .493828 Tw (an utility function ) Tj /F3 10 Tf (runp\(genseq, mode='p', start=True\) ) Tj /F1 10 Tf (to start a bunch a generators and return) Tj T* 0 Tw .587765 Tw (a list of task objects. By default ) Tj /F3 10 Tf (runp ) Tj /F1 10 Tf (use processes, but you can use threads by passing ) Tj /F3 10 Tf (mode='t') Tj /F1 10 Tf (. If) Tj T* 0 Tw .422765 Tw (you do not wont to start the tasks, you can say so \() Tj /F3 10 Tf (start=False) Tj /F1 10 Tf (\). With ) Tj /F3 10 Tf (runp ) Tj /F1 10 Tf (the parallel pi calculation) Tj T* 0 Tw (becomes a one-liner:) Tj T* ET Q Q q @@ -11670,7 +11608,7 @@ n -6 -6 480 24 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 5.71 Tm /F3 10 Tf 12 TL (sum\(task.result for task in plac.runp\(calc_pi\(N\) for i in range\(ncpus\)\)\)/ncpus) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (sum\(task.result for task in plac.runp\(calc_pi\(N\) for i in range\(ncpus\)\)\)/ncpus) Tj T* ET Q Q Q @@ -11679,13 +11617,13 @@ Q q 1 0 0 1 62.69291 612.4159 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (The plac server) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (The plac server) Tj T* ET Q Q q 1 0 0 1 62.69291 498.4159 cm q -BT 1 0 0 1 0 100.82 Tm 1.258443 Tw 12 TL /F1 10 Tf 0 0 0 rg (A command-line oriented interface can be easily converted into a socket-based interface. Starting from) Tj T* 0 Tw .930574 Tw (release 0.7 plac features a builtin server which is able to accept commands from multiple clients and to) Tj T* 0 Tw .994692 Tw (execute them. The server works by instantiating a separate interpreter for each client, so that if a client) Tj T* 0 Tw 1.08784 Tw (interpreter dies for any reason the other interpreters keep working. To avoid external dependencies the) Tj T* 0 Tw .872209 Tw (server is based on the ) Tj /F3 10 Tf (asynchat ) Tj /F1 10 Tf (module in the standard library, but it would not be difficult to replace) Tj T* 0 Tw 2.386412 Tw (the server with a different one \(for instance, a Twisted server\). Since ) Tj /F3 10 Tf (asynchat) Tj /F1 10 Tf (-based servers are) Tj T* 0 Tw .755984 Tw (asynchronous, any blocking command in the interpreter should be run in a separated process or thread.) Tj T* 0 Tw 1.157633 Tw (The default port for the ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (server is 2199, and the command to signal end-of-connection is EOF. For) Tj T* 0 Tw (instance, here is how you could manage remote import on a database \(say a SQLite db\):) Tj T* ET +BT 1 0 0 1 0 98 Tm 1.258443 Tw 12 TL /F1 10 Tf 0 0 0 rg (A command-line oriented interface can be easily converted into a socket-based interface. Starting from) Tj T* 0 Tw .930574 Tw (release 0.7 plac features a builtin server which is able to accept commands from multiple clients and to) Tj T* 0 Tw .994692 Tw (execute them. The server works by instantiating a separate interpreter for each client, so that if a client) Tj T* 0 Tw 1.08784 Tw (interpreter dies for any reason the other interpreters keep working. To avoid external dependencies the) Tj T* 0 Tw .872209 Tw (server is based on the ) Tj /F3 10 Tf (asynchat ) Tj /F1 10 Tf (module in the standard library, but it would not be difficult to replace) Tj T* 0 Tw 2.386412 Tw (the server with a different one \(for instance, a Twisted server\). Since ) Tj /F3 10 Tf (asynchat) Tj /F1 10 Tf (-based servers are) Tj T* 0 Tw .755984 Tw (asynchronous, any blocking command in the interpreter should be run in a separated process or thread.) Tj T* 0 Tw 1.157633 Tw (The default port for the ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (server is 2199, and the command to signal end-of-connection is EOF. For) Tj T* 0 Tw (instance, here is how you could manage remote import on a database \(say a SQLite db\):) Tj T* ET Q Q q @@ -11703,7 +11641,7 @@ n -6 -6 468.6898 120 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 101.71 Tm /F3 10 Tf 12 TL (import plac) Tj T* (from importer2 import FakeImporter) Tj T* T* (def main\(port=2199\):) Tj T* ( main = FakeImporter\('dsn'\)) Tj T* ( plac.Interpreter\(main\).start_server\(port\)) Tj T* ( ) Tj T* (if __name__ == '__main__':) Tj T* ( plac.call\(main\)) Tj T* ET +BT 1 0 0 1 0 98 Tm /F3 10 Tf 12 TL (import plac) Tj T* (from importer2 import FakeImporter) Tj T* T* (def main\(port=2199\):) Tj T* ( main = FakeImporter\('dsn'\)) Tj T* ( plac.Interpreter\(main\).start_server\(port\)) Tj T* ( ) Tj T* (if __name__ == '__main__':) Tj T* ( plac.call\(main\)) Tj T* ET Q Q Q @@ -11712,7 +11650,7 @@ Q q 1 0 0 1 62.69291 349.2159 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (You can connect to the server with ) Tj /F3 10 Tf (telnet ) Tj /F1 10 Tf (on port 2199, as follows:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (You can connect to the server with ) Tj /F3 10 Tf (telnet ) Tj /F1 10 Tf (on port 2199, as follows:) Tj T* ET Q Q q @@ -11729,7 +11667,7 @@ q n -6 -6 468.6898 168 re B* Q q -BT 1 0 0 1 0 149.71 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ telnet localhost 2199) Tj T* (Trying ::1...) Tj T* (Trying 127.0.0.1...) Tj T* (Connected to localhost.) Tj T* (Escape character is '^]'.) Tj T* (i) Tj (>) Tj ( import_file f1) Tj T* (i) Tj (>) Tj ( .list) Tj T* (<) Tj (ThreadedTask 1 [import_file f1] RUNNING) Tj (>) Tj T* (i) Tj (>) Tj ( .out) Tj T* (Imported 100 lines) Tj T* (Imported 200 lines) Tj T* (i) Tj (>) Tj ( EOF) Tj T* (Connection closed by foreign host.) Tj T* ET +BT 1 0 0 1 0 146 Tm 12 TL /F3 10 Tf 0 0 0 rg ($ telnet localhost 2199) Tj T* (Trying ::1...) Tj T* (Trying 127.0.0.1...) Tj T* (Connected to localhost.) Tj T* (Escape character is '^]'.) Tj T* (i) Tj (>) Tj ( import_file f1) Tj T* (i) Tj (>) Tj ( .list) Tj T* (<) Tj (ThreadedTask 1 [import_file f1] RUNNING) Tj (>) Tj T* (i) Tj (>) Tj ( .out) Tj T* (Imported 100 lines) Tj T* (Imported 200 lines) Tj T* (i) Tj (>) Tj ( EOF) Tj T* (Connection closed by foreign host.) Tj T* ET Q Q Q @@ -11738,13 +11676,13 @@ Q q 1 0 0 1 62.69291 142.0159 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Summary) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Summary) Tj T* ET Q Q q 1 0 0 1 62.69291 100.0159 cm q -BT 1 0 0 1 0 28.82 Tm 2.203318 Tw 12 TL /F1 10 Tf 0 0 0 rg (Once ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (claimed to be the easiest command-line arguments parser in the world. Having read this) Tj T* 0 Tw .673322 Tw (document you may think that it is not so easy after all. But it is a false impression. Actually the rules are) Tj T* 0 Tw (quite simple:) Tj T* ET +BT 1 0 0 1 0 26 Tm 2.203318 Tw 12 TL /F1 10 Tf 0 0 0 rg (Once ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (claimed to be the easiest command-line arguments parser in the world. Having read this) Tj T* 0 Tw .673322 Tw (document you may think that it is not so easy after all. But it is a false impression. Actually the rules are) Tj T* 0 Tw (quite simple:) Tj T* ET Q Q q @@ -11757,34 +11695,33 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (41) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (41) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R378': class PDFStream 378 0 obj % page stream -<< /Length 6620 >> +<< /Length 6425 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 747.0236 cm +1 0 0 1 62.69291 753.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 3 cm +1 0 0 1 6 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (if you want to implement a command-line script, use ) Tj /F3 10 Tf (plac.call) Tj /F1 10 Tf (;) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (if you want to implement a command-line script, use ) Tj /F3 10 Tf (plac.call) Tj /F1 10 Tf (;) Tj T* ET Q Q q @@ -11794,227 +11731,203 @@ q 1 0 0 1 62.69291 747.0236 cm Q q -1 0 0 1 62.69291 747.0236 cm -Q -q -1 0 0 1 62.69291 687.0236 cm +1 0 0 1 62.69291 699.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 45 cm +1 0 0 1 6 33 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 45 cm +1 0 0 1 23 33 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (if you want to implement a command interpreter, use ) Tj /F3 10 Tf (plac.Interpreter) Tj /F1 10 Tf (:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (if you want to implement a command interpreter, use ) Tj /F3 10 Tf (plac.Interpreter) Tj /F1 10 Tf (:) Tj T* ET Q Q q -1 0 0 1 23 39 cm +1 0 0 1 23 27 cm Q q -1 0 0 1 23 39 cm +1 0 0 1 23 27 cm Q q -1 0 0 1 23 21 cm +1 0 0 1 23 15 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 3 cm +1 0 0 1 6 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (for an interactive interpreter, call the ) Tj /F3 10 Tf (.interact ) Tj /F1 10 Tf (method;) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (for an interactive interpreter, call the ) Tj /F3 10 Tf (.interact ) Tj /F1 10 Tf (method;) Tj T* ET Q Q q Q Q q -1 0 0 1 23 21 cm -Q -q -1 0 0 1 23 21 cm +1 0 0 1 23 9 cm Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 3 cm +1 0 0 1 6 -3 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (for an batch interpreter, call the ) Tj /F3 10 Tf (.execute ) Tj /F1 10 Tf (method;) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (for an batch interpreter, call the ) Tj /F3 10 Tf (.execute ) Tj /F1 10 Tf (method;) Tj T* ET Q Q q Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm Q q -1 0 0 1 23 3 cm Q -q -Q -Q -q -1 0 0 1 62.69291 687.0236 cm Q q -1 0 0 1 62.69291 687.0236 cm +1 0 0 1 62.69291 693.0236 cm Q q -1 0 0 1 62.69291 657.0236 cm +1 0 0 1 62.69291 669.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 15 cm +1 0 0 1 6 9 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 16.82 Tm 5.126647 Tw 12 TL /F1 10 Tf 0 0 0 rg (for testing call the ) Tj /F3 10 Tf (Interpreter.check ) Tj /F1 10 Tf (method in the appropriate context or use the) Tj T* 0 Tw /F3 10 Tf (Interpreter.doctest ) Tj /F1 10 Tf (feature;) Tj T* ET +BT 1 0 0 1 0 14 Tm 5.126647 Tw 12 TL /F1 10 Tf 0 0 0 rg (for testing call the ) Tj /F3 10 Tf (Interpreter.check ) Tj /F1 10 Tf (method in the appropriate context or use the) Tj T* 0 Tw /F3 10 Tf (Interpreter.doctest ) Tj /F1 10 Tf (feature;) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 657.0236 cm -Q -q -1 0 0 1 62.69291 657.0236 cm +1 0 0 1 62.69291 663.0236 cm Q q -1 0 0 1 62.69291 627.0236 cm +1 0 0 1 62.69291 639.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 15 cm +1 0 0 1 6 9 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (4.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (4.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 16.82 Tm 1.356457 Tw 12 TL /F1 10 Tf 0 0 0 rg (if you need to go at a lower level, you may need to call the ) Tj /F3 10 Tf (Interpreter.send ) Tj /F1 10 Tf (method which) Tj T* 0 Tw (returns a \(finished\) ) Tj /F3 10 Tf (Task ) Tj /F1 10 Tf (object.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.356457 Tw 12 TL /F1 10 Tf 0 0 0 rg (if you need to go at a lower level, you may need to call the ) Tj /F3 10 Tf (Interpreter.send ) Tj /F1 10 Tf (method which) Tj T* 0 Tw (returns a \(finished\) ) Tj /F3 10 Tf (Task ) Tj /F1 10 Tf (object.) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 627.0236 cm -Q -q -1 0 0 1 62.69291 627.0236 cm +1 0 0 1 62.69291 633.0236 cm Q q -1 0 0 1 62.69291 597.0236 cm +1 0 0 1 62.69291 609.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 15 cm +1 0 0 1 6 9 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (5.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (5.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 16.82 Tm 1.469269 Tw 12 TL /F1 10 Tf 0 0 0 rg (long running command can be executed in the background as threads or processes: just declare) Tj T* 0 Tw (them in the lists ) Tj /F3 10 Tf (thcommands ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (mpcommands ) Tj /F1 10 Tf (respectively.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.469269 Tw 12 TL /F1 10 Tf 0 0 0 rg (long running command can be executed in the background as threads or processes: just declare) Tj T* 0 Tw (them in the lists ) Tj /F3 10 Tf (thcommands ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (mpcommands ) Tj /F1 10 Tf (respectively.) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 597.0236 cm -Q -q -1 0 0 1 62.69291 597.0236 cm +1 0 0 1 62.69291 603.0236 cm Q q -1 0 0 1 62.69291 567.0236 cm +1 0 0 1 62.69291 579.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 15 cm +1 0 0 1 6 9 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 5.66 0 Td (6.) Tj T* -5.66 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (6.) Tj T* -5.66 0 Td ET Q Q q -1 0 0 1 23 3 cm +1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 16.82 Tm 2.171647 Tw 12 TL /F1 10 Tf 0 0 0 rg (the ) Tj /F3 10 Tf (.start_server ) Tj /F1 10 Tf (method starts an asynchronous server on the given port number \(default) Tj T* 0 Tw (2199\)) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.171647 Tw 12 TL /F1 10 Tf 0 0 0 rg (the ) Tj /F3 10 Tf (.start_server ) Tj /F1 10 Tf (method starts an asynchronous server on the given port number \(default) Tj T* 0 Tw (2199\)) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 567.0236 cm -Q -q -1 0 0 1 62.69291 567.0236 cm +1 0 0 1 62.69291 579.0236 cm Q q -1 0 0 1 62.69291 549.0236 cm +1 0 0 1 62.69291 561.0236 cm q -BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (Moreover, remember that ) Tj /F3 10 Tf (plac_runner.py ) Tj /F1 10 Tf (is your friend.) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Moreover, remember that ) Tj /F3 10 Tf (plac_runner.py ) Tj /F1 10 Tf (is your friend.) Tj T* ET Q Q q -1 0 0 1 62.69291 520.6772 cm +1 0 0 1 62.69291 532.6772 cm n 0 14.17323 m 469.8898 14.17323 l S Q q -1 0 0 1 62.69291 490.6772 cm +1 0 0 1 62.69291 502.6772 cm q -BT 1 0 0 1 0 7.23 Tm 18 TL /F2 15 Tf 0 0 0 rg (Appendix: custom annotation objects) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Appendix: custom annotation objects) Tj T* ET Q Q q -1 0 0 1 62.69291 460.6772 cm +1 0 0 1 62.69291 472.6772 cm q -BT 1 0 0 1 0 16.82 Tm .578651 Tw 12 TL /F1 10 Tf 0 0 0 rg (Internally ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (uses an ) Tj /F3 10 Tf (Annotation ) Tj /F1 10 Tf (class to convert the tuples in the function signature into annotation) Tj T* 0 Tw (objects, i.e. objects with six attributes ) Tj /F3 10 Tf (help, kind, short, type, choices, metavar) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 14 Tm .578651 Tw 12 TL /F1 10 Tf 0 0 0 rg (Internally ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (uses an ) Tj /F3 10 Tf (Annotation ) Tj /F1 10 Tf (class to convert the tuples in the function signature into annotation) Tj T* 0 Tw (objects, i.e. objects with six attributes ) Tj /F3 10 Tf (help, kind, short, type, choices, metavar) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 62.69291 430.6772 cm +1 0 0 1 62.69291 442.6772 cm q 0 0 0 rg -BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL .083735 Tw (Advanced users can implement their own annotation objects. For instance, here is an example of how you) Tj T* 0 Tw (could implement annotations for positional arguments:) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .083735 Tw (Advanced users can implement their own annotation objects. For instance, here is an example of how you) Tj T* 0 Tw (could implement annotations for positional arguments:) Tj T* ET Q Q q -1 0 0 1 62.69291 301.4772 cm +1 0 0 1 62.69291 313.4772 cm q q 1 0 0 1 0 0 cm @@ -12028,21 +11941,21 @@ n -6 -6 468.6898 120 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 101.71 Tm /F3 10 Tf 12 TL (# annotations.py) Tj T* (class Positional\(object\):) Tj T* ( def __init__\(self, help='', type=None, choices=None, metavar=None\):) Tj T* ( self.help = help) Tj T* ( self.kind = 'positional') Tj T* ( self.abbrev = None) Tj T* ( self.type = type) Tj T* ( self.choices = choices) Tj T* ( self.metavar = metavar) Tj T* ET +BT 1 0 0 1 0 98 Tm /F3 10 Tf 12 TL (# annotations.py) Tj T* (class Positional\(object\):) Tj T* ( def __init__\(self, help='', type=None, choices=None, metavar=None\):) Tj T* ( self.help = help) Tj T* ( self.kind = 'positional') Tj T* ( self.abbrev = None) Tj T* ( self.type = type) Tj T* ( self.choices = choices) Tj T* ( self.metavar = metavar) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 281.4772 cm +1 0 0 1 62.69291 293.4772 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (You can use such annotations objects as follows:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (You can use such annotations objects as follows:) Tj T* ET Q Q q -1 0 0 1 62.69291 104.2772 cm +1 0 0 1 62.69291 116.2772 cm q q 1 0 0 1 0 0 cm @@ -12056,38 +11969,37 @@ n -6 -6 468.6898 168 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 149.71 Tm /F3 10 Tf 12 TL (# example11.py) Tj T* (import plac) Tj T* (from annotations import Positional) Tj T* T* (@plac.annotations\() Tj T* ( i=Positional\("This is an int", int\),) Tj T* ( n=Positional\("This is a float", float\),) Tj T* ( rest=Positional\("Other arguments"\)\)) Tj T* (def main\(i, n, *rest\):) Tj T* ( print\(i, n, rest\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET +BT 1 0 0 1 0 146 Tm /F3 10 Tf 12 TL (# example11.py) Tj T* (import plac) Tj T* (from annotations import Positional) Tj T* T* (@plac.annotations\() Tj T* ( i=Positional\("This is an int", int\),) Tj T* ( n=Positional\("This is a float", float\),) Tj T* ( rest=Positional\("Other arguments"\)\)) Tj T* (def main\(i, n, *rest\):) Tj T* ( print\(i, n, rest\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET +Q Q Q Q Q +q +1 0 0 1 62.69291 96.27717 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is the usage message you get:) Tj T* ET +Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (42) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (42) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R379': class PDFStream 379 0 obj % page stream -<< /Length 1367 >> +<< /Length 1222 >> stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 753.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL (Here is the usage message you get:) Tj T* ET -Q -Q +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 623.8236 cm +1 0 0 1 62.69291 643.8236 cm q q 1 0 0 1 0 0 cm @@ -12101,28 +12013,27 @@ n -6 -6 468.6898 120 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 101.71 Tm /F3 10 Tf 12 TL (usage: example11.py [-h] i n [rest [rest ...]]) Tj T* T* (positional arguments:) Tj T* ( i This is an int) Tj T* ( n This is a float) Tj T* ( rest Other arguments) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ET +BT 1 0 0 1 0 98 Tm /F3 10 Tf 12 TL (usage: example11.py [-h] i n [rest [rest ...]]) Tj T* T* (positional arguments:) Tj T* ( i This is an int) Tj T* ( n This is a float) Tj T* ( rest Other arguments) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 579.8236 cm +1 0 0 1 62.69291 599.8236 cm q -BT 1 0 0 1 0 28.82 Tm .713516 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can go on and define ) Tj /F3 10 Tf (Option ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (Flag ) Tj /F1 10 Tf (classes, if you like. Using custom annotation objects you) Tj T* 0 Tw .17528 Tw (could do advanced things like extracting the annotations from a configuration file or from a database, but I) Tj T* 0 Tw (expect such use cases to be quite rare: the default mechanism should work pretty well for most users.) Tj T* ET +BT 1 0 0 1 0 26 Tm .713516 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can go on and define ) Tj /F3 10 Tf (Option ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (Flag ) Tj /F1 10 Tf (classes, if you like. Using custom annotation objects you) Tj T* 0 Tw .17528 Tw (could do advanced things like extracting the annotations from a configuration file or from a database, but I) Tj T* 0 Tw (expect such use cases to be quite rare: the default mechanism should work pretty well for most users.) Tj T* ET Q Q q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 4.82 Tm /F1 10 Tf 12 TL 235.3849 0 Td (43) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (43) Tj T* -235.3849 0 Td ET Q Q endstream - endobj % 'R380': class PDFPageLabels 380 0 obj @@ -12632,22 +12543,22 @@ xref 0000039914 00000 n 0000040168 00000 n 0000040420 00000 n -0000040658 00000 n -0000041099 00000 n -0000041353 00000 n -0000041636 00000 n -0000041890 00000 n -0000042144 00000 n -0000042426 00000 n -0000042709 00000 n -0000042963 00000 n -0000043215 00000 n -0000043533 00000 n -0000043787 00000 n -0000044076 00000 n -0000044328 00000 n -0000044580 00000 n -0000044819 00000 n +0000040673 00000 n +0000040927 00000 n +0000041195 00000 n +0000041656 00000 n +0000041910 00000 n +0000042164 00000 n +0000042446 00000 n +0000042729 00000 n +0000042983 00000 n +0000043235 00000 n +0000043553 00000 n +0000043807 00000 n +0000044096 00000 n +0000044348 00000 n +0000044600 00000 n +0000044839 00000 n 0000045270 00000 n 0000045524 00000 n 0000045778 00000 n @@ -12681,38 +12592,38 @@ xref 0000053020 00000 n 0000053309 00000 n 0000053561 00000 n -0000053798 00000 n -0000054439 00000 n -0000054697 00000 n -0000054951 00000 n -0000055205 00000 n -0000055459 00000 n -0000055713 00000 n -0000055967 00000 n -0000056221 00000 n -0000056466 00000 n -0000056720 00000 n -0000056974 00000 n -0000057228 00000 n -0000057482 00000 n -0000057741 00000 n +0000053813 00000 n +0000054056 00000 n +0000054707 00000 n +0000054961 00000 n +0000055215 00000 n +0000055469 00000 n +0000055723 00000 n +0000055977 00000 n +0000056231 00000 n +0000056476 00000 n +0000056730 00000 n +0000056984 00000 n +0000057238 00000 n +0000057492 00000 n +0000057751 00000 n 0000058167 00000 n 0000058466 00000 n 0000058705 00000 n 0000059026 00000 n 0000059280 00000 n -0000059519 00000 n -0000059850 00000 n -0000060104 00000 n -0000060366 00000 n -0000060620 00000 n -0000060883 00000 n -0000061136 00000 n -0000061399 00000 n -0000061653 00000 n -0000061907 00000 n -0000062160 00000 n -0000062398 00000 n +0000059534 00000 n +0000059788 00000 n +0000060050 00000 n +0000060304 00000 n +0000060567 00000 n +0000060820 00000 n +0000061068 00000 n +0000061459 00000 n +0000061713 00000 n +0000061967 00000 n +0000062220 00000 n +0000062458 00000 n 0000062809 00000 n 0000063083 00000 n 0000063337 00000 n @@ -12728,184 +12639,184 @@ xref 0000066098 00000 n 0000066356 00000 n 0000066610 00000 n -0000066863 00000 n -0000067214 00000 n -0000067468 00000 n -0000067722 00000 n -0000067983 00000 n -0000068244 00000 n -0000068496 00000 n -0000068749 00000 n -0000069001 00000 n -0000069255 00000 n -0000069509 00000 n -0000069763 00000 n -0000070017 00000 n -0000070257 00000 n -0000070673 00000 n -0000070972 00000 n -0000071224 00000 n -0000071463 00000 n -0000071779 00000 n -0000072078 00000 n -0000072316 00000 n -0000072637 00000 n -0000072891 00000 n -0000073164 00000 n -0000073403 00000 n -0000073744 00000 n -0000073998 00000 n -0000074237 00000 n -0000074553 00000 n -0000074852 00000 n -0000075106 00000 n -0000075364 00000 n -0000075695 00000 n -0000075934 00000 n -0000076255 00000 n -0000076494 00000 n -0000076800 00000 n -0000077099 00000 n -0000077353 00000 n -0000077607 00000 n -0000077846 00000 n -0000078187 00000 n -0000078426 00000 n -0000078732 00000 n -0000079017 00000 n -0000079181 00000 n -0000079395 00000 n -0000079524 00000 n -0000079778 00000 n -0000079975 00000 n -0000080189 00000 n -0000080403 00000 n -0000080629 00000 n -0000080831 00000 n -0000081040 00000 n -0000081237 00000 n -0000081440 00000 n -0000081641 00000 n -0000081859 00000 n -0000082060 00000 n -0000082274 00000 n -0000082469 00000 n -0000082667 00000 n -0000082903 00000 n -0000083083 00000 n -0000083307 00000 n -0000083517 00000 n -0000083716 00000 n -0000083918 00000 n -0000084126 00000 n -0000084331 00000 n -0000084531 00000 n -0000084730 00000 n -0000084940 00000 n -0000085153 00000 n -0000085359 00000 n -0000085561 00000 n -0000085784 00000 n -0000086011 00000 n -0000086224 00000 n -0000086424 00000 n -0000086616 00000 n -0000086801 00000 n -0000087329 00000 n -0000090428 00000 n -0000100125 00000 n -0000106213 00000 n -0000110764 00000 n -0000114917 00000 n -0000118921 00000 n -0000124043 00000 n -0000128464 00000 n -0000133483 00000 n -0000139758 00000 n -0000144116 00000 n -0000148517 00000 n -0000152182 00000 n -0000156582 00000 n -0000163280 00000 n -0000169647 00000 n -0000177312 00000 n -0000185617 00000 n -0000191577 00000 n -0000195240 00000 n -0000200911 00000 n -0000207099 00000 n -0000213658 00000 n -0000218191 00000 n -0000222635 00000 n -0000226971 00000 n -0000231792 00000 n -0000236967 00000 n -0000242072 00000 n -0000246418 00000 n -0000251865 00000 n -0000255862 00000 n -0000261612 00000 n -0000266754 00000 n -0000271276 00000 n -0000276312 00000 n -0000280706 00000 n -0000284989 00000 n -0000289751 00000 n -0000293256 00000 n -0000298376 00000 n -0000305099 00000 n -0000306573 00000 n -0000307290 00000 n -0000307369 00000 n -0000307448 00000 n -0000307527 00000 n -0000307606 00000 n -0000307685 00000 n -0000307764 00000 n -0000307843 00000 n -0000307922 00000 n -0000308001 00000 n -0000308081 00000 n -0000308161 00000 n -0000308241 00000 n -0000308321 00000 n -0000308401 00000 n -0000308481 00000 n -0000308561 00000 n -0000308641 00000 n -0000308721 00000 n -0000308801 00000 n -0000308881 00000 n -0000308961 00000 n -0000309041 00000 n -0000309121 00000 n -0000309201 00000 n -0000309281 00000 n -0000309361 00000 n -0000309441 00000 n -0000309521 00000 n -0000309601 00000 n -0000309681 00000 n -0000309761 00000 n -0000309841 00000 n -0000309921 00000 n -0000310001 00000 n -0000310081 00000 n -0000310161 00000 n -0000310241 00000 n -0000310321 00000 n -0000310401 00000 n -0000310481 00000 n -0000310561 00000 n -0000310641 00000 n +0000066878 00000 n +0000067132 00000 n +0000067371 00000 n +0000067742 00000 n +0000068003 00000 n +0000068264 00000 n +0000068516 00000 n +0000068769 00000 n +0000069021 00000 n +0000069275 00000 n +0000069529 00000 n +0000069783 00000 n +0000070037 00000 n +0000070277 00000 n +0000070688 00000 n +0000070925 00000 n +0000071246 00000 n +0000071485 00000 n +0000071791 00000 n +0000072090 00000 n +0000072328 00000 n +0000072649 00000 n +0000072903 00000 n +0000073176 00000 n +0000073415 00000 n +0000073756 00000 n +0000074010 00000 n +0000074249 00000 n +0000074565 00000 n +0000074864 00000 n +0000075118 00000 n +0000075376 00000 n +0000075707 00000 n +0000075946 00000 n +0000076267 00000 n +0000076506 00000 n +0000076812 00000 n +0000077111 00000 n +0000077365 00000 n +0000077619 00000 n +0000077858 00000 n +0000078199 00000 n +0000078438 00000 n +0000078744 00000 n +0000079029 00000 n +0000079193 00000 n +0000079443 00000 n +0000079572 00000 n +0000079826 00000 n +0000080023 00000 n +0000080237 00000 n +0000080451 00000 n +0000080677 00000 n +0000080879 00000 n +0000081088 00000 n +0000081285 00000 n +0000081488 00000 n +0000081689 00000 n +0000081907 00000 n +0000082108 00000 n +0000082322 00000 n +0000082517 00000 n +0000082715 00000 n +0000082951 00000 n +0000083131 00000 n +0000083355 00000 n +0000083565 00000 n +0000083764 00000 n +0000083966 00000 n +0000084174 00000 n +0000084379 00000 n +0000084579 00000 n +0000084778 00000 n +0000084988 00000 n +0000085201 00000 n +0000085407 00000 n +0000085609 00000 n +0000085832 00000 n +0000086059 00000 n +0000086272 00000 n +0000086472 00000 n +0000086664 00000 n +0000086849 00000 n +0000087377 00000 n +0000090422 00000 n +0000099903 00000 n +0000105960 00000 n +0000110479 00000 n +0000114601 00000 n +0000118574 00000 n +0000123661 00000 n +0000128041 00000 n +0000133019 00000 n +0000139251 00000 n +0000143572 00000 n +0000147942 00000 n +0000151576 00000 n +0000155945 00000 n +0000162297 00000 n +0000168967 00000 n +0000176085 00000 n +0000184427 00000 n +0000189976 00000 n +0000193606 00000 n +0000199596 00000 n +0000206051 00000 n +0000211877 00000 n +0000216529 00000 n +0000221158 00000 n +0000225753 00000 n +0000230457 00000 n +0000235709 00000 n +0000240429 00000 n +0000245075 00000 n +0000250110 00000 n +0000254073 00000 n +0000259636 00000 n +0000264585 00000 n +0000269270 00000 n +0000274448 00000 n +0000279274 00000 n +0000283107 00000 n +0000287846 00000 n +0000291335 00000 n +0000296419 00000 n +0000302945 00000 n +0000304272 00000 n +0000304989 00000 n +0000305068 00000 n +0000305147 00000 n +0000305226 00000 n +0000305305 00000 n +0000305384 00000 n +0000305463 00000 n +0000305542 00000 n +0000305621 00000 n +0000305700 00000 n +0000305780 00000 n +0000305860 00000 n +0000305940 00000 n +0000306020 00000 n +0000306100 00000 n +0000306180 00000 n +0000306260 00000 n +0000306340 00000 n +0000306420 00000 n +0000306500 00000 n +0000306580 00000 n +0000306660 00000 n +0000306740 00000 n +0000306820 00000 n +0000306900 00000 n +0000306980 00000 n +0000307060 00000 n +0000307140 00000 n +0000307220 00000 n +0000307300 00000 n +0000307380 00000 n +0000307460 00000 n +0000307540 00000 n +0000307620 00000 n +0000307700 00000 n +0000307780 00000 n +0000307860 00000 n +0000307940 00000 n +0000308020 00000 n +0000308100 00000 n +0000308180 00000 n +0000308260 00000 n +0000308340 00000 n trailer << /ID % ReportLab generated PDF document -- digest (http://www.reportlab.com) - [(\207i\\\(\331\(e\246\374\374\337\204\202\207\020\203) (\207i\\\(\331\(e\246\374\374\337\204\202\207\020\203)] + [(Zl_\246\011Djl\226\302\266\314p\261\246\366) (Zl_\246\011Djl\226\302\266\314p\261\246\366)] /Info 299 0 R /Root 298 0 R /Size 424 >> startxref -310690 +308389 %%EOF diff --git a/plac/doc/plac.txt b/plac/doc/plac.txt new file mode 100644 index 0000000..e7083f8 --- /dev/null +++ b/plac/doc/plac.txt @@ -0,0 +1,2 @@ +.. include:: plac_core.txt +.. include:: plac_adv.txt -- cgit v1.2.1