summaryrefslogtreecommitdiff
path: root/decorator/documentation.pdf
diff options
context:
space:
mode:
Diffstat (limited to 'decorator/documentation.pdf')
-rw-r--r--decorator/documentation.pdf1655
1 files changed, 889 insertions, 766 deletions
diff --git a/decorator/documentation.pdf b/decorator/documentation.pdf
index 316d24f..c57f0ac 100644
--- a/decorator/documentation.pdf
+++ b/decorator/documentation.pdf
@@ -7,7 +7,7 @@
/F2 3 0 R
/F3 4 0 R
/F4 7 0 R
- /F5 37 0 R
+ /F5 39 0 R
/F6 41 0 R >>
endobj
% 'F1': class PDFType1Font
@@ -56,7 +56,7 @@ endobj
6 0 obj
<< /A << /S /URI
/Type /Action
- /URI (http://pypi.python.org/pypi/decorator/3.3.2) >>
+ /URI (http://pypi.python.org/pypi/decorator/3.4.0) >>
/Border [ 0
0
0 ]
@@ -82,10 +82,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 36 0 R
+ /Dest [ 38 0 R
/XYZ
62.69291
- 311.0236
+ 293.0236
0 ]
/Rect [ 62.69291
560.7736
@@ -100,10 +100,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 36 0 R
+ /Dest [ 38 0 R
/XYZ
62.69291
- 311.0236
+ 293.0236
0 ]
/Rect [ 527.0227
560.7736
@@ -118,10 +118,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 40 0 R
+ /Dest [ 43 0 R
/XYZ
62.69291
- 699.0236
+ 675.0236
0 ]
/Rect [ 62.69291
542.7736
@@ -136,10 +136,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 40 0 R
+ /Dest [ 43 0 R
/XYZ
62.69291
- 699.0236
+ 675.0236
0 ]
/Rect [ 527.0227
542.7736
@@ -154,10 +154,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 40 0 R
+ /Dest [ 43 0 R
/XYZ
62.69291
- 462.0236
+ 438.0236
0 ]
/Rect [ 62.69291
524.7736
@@ -172,10 +172,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 40 0 R
+ /Dest [ 43 0 R
/XYZ
62.69291
- 462.0236
+ 438.0236
0 ]
/Rect [ 527.0227
524.7736
@@ -190,10 +190,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 42 0 R
+ /Dest [ 44 0 R
/XYZ
62.69291
- 451.4236
+ 427.4236
0 ]
/Rect [ 62.69291
506.7736
@@ -208,10 +208,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 42 0 R
+ /Dest [ 44 0 R
/XYZ
62.69291
- 451.4236
+ 427.4236
0 ]
/Rect [ 527.0227
506.7736
@@ -226,10 +226,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 43 0 R
+ /Dest [ 45 0 R
/XYZ
62.69291
- 459.4236
+ 435.4236
0 ]
/Rect [ 62.69291
488.7736
@@ -244,10 +244,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 43 0 R
+ /Dest [ 45 0 R
/XYZ
62.69291
- 459.4236
+ 435.4236
0 ]
/Rect [ 527.0227
488.7736
@@ -262,10 +262,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 44 0 R
+ /Dest [ 46 0 R
/XYZ
62.69291
- 463.978
+ 398.778
0 ]
/Rect [ 62.69291
470.7736
@@ -280,10 +280,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 44 0 R
+ /Dest [ 46 0 R
/XYZ
62.69291
- 463.978
+ 398.778
0 ]
/Rect [ 527.0227
470.7736
@@ -298,10 +298,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 45 0 R
+ /Dest [ 47 0 R
/XYZ
62.69291
- 729.0236
+ 647.8236
0 ]
/Rect [ 62.69291
452.7736
@@ -316,10 +316,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 45 0 R
+ /Dest [ 47 0 R
/XYZ
62.69291
- 729.0236
+ 647.8236
0 ]
/Rect [ 527.0227
452.7736
@@ -334,10 +334,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 45 0 R
+ /Dest [ 48 0 R
/XYZ
62.69291
- 195.6236
+ 765.0236
0 ]
/Rect [ 62.69291
434.7736
@@ -352,10 +352,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 45 0 R
+ /Dest [ 48 0 R
/XYZ
62.69291
- 195.6236
+ 765.0236
0 ]
/Rect [ 527.0227
434.7736
@@ -370,14 +370,14 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 47 0 R
+ /Dest [ 49 0 R
/XYZ
62.69291
- 366.6236
+ 267.4236
0 ]
/Rect [ 62.69291
416.7736
- 192.2729
+ 139.9329
428.7736 ]
/Subtype /Link
/Type /Annot >>
@@ -388,10 +388,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 47 0 R
+ /Dest [ 49 0 R
/XYZ
62.69291
- 366.6236
+ 267.4236
0 ]
/Rect [ 527.0227
416.7736
@@ -406,14 +406,14 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 49 0 R
+ /Dest [ 50 0 R
/XYZ
62.69291
- 387.8236
+ 354.6236
0 ]
/Rect [ 62.69291
398.7736
- 177.1629
+ 192.2729
410.7736 ]
/Subtype /Link
/Type /Annot >>
@@ -424,10 +424,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 49 0 R
+ /Dest [ 50 0 R
/XYZ
62.69291
- 387.8236
+ 354.6236
0 ]
/Rect [ 527.0227
398.7736
@@ -445,11 +445,11 @@ endobj
/Dest [ 51 0 R
/XYZ
62.69291
- 623.8236
+ 363.8236
0 ]
/Rect [ 62.69291
380.7736
- 228.2829
+ 177.1629
392.7736 ]
/Subtype /Link
/Type /Annot >>
@@ -463,7 +463,7 @@ endobj
/Dest [ 51 0 R
/XYZ
62.69291
- 623.8236
+ 363.8236
0 ]
/Rect [ 521.4627
380.7736
@@ -478,14 +478,14 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 52 0 R
+ /Dest [ 54 0 R
/XYZ
62.69291
- 239.0236
+ 599.8236
0 ]
/Rect [ 62.69291
362.7736
- 174.3929
+ 228.2829
374.7736 ]
/Subtype /Link
/Type /Annot >>
@@ -496,10 +496,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 52 0 R
+ /Dest [ 54 0 R
/XYZ
62.69291
- 239.0236
+ 599.8236
0 ]
/Rect [ 521.4627
362.7736
@@ -514,14 +514,14 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 62 0 R
+ /Dest [ 55 0 R
/XYZ
62.69291
- 765.0236
+ 215.0236
0 ]
/Rect [ 62.69291
344.7736
- 155.4829
+ 174.3929
356.7736 ]
/Subtype /Link
/Type /Annot >>
@@ -532,10 +532,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 62 0 R
+ /Dest [ 55 0 R
/XYZ
62.69291
- 765.0236
+ 215.0236
0 ]
/Rect [ 521.4627
344.7736
@@ -550,14 +550,14 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 62 0 R
+ /Dest [ 65 0 R
/XYZ
62.69291
- 414.0236
+ 765.0236
0 ]
/Rect [ 62.69291
326.7736
- 106.5829
+ 155.4829
338.7736 ]
/Subtype /Link
/Type /Annot >>
@@ -568,10 +568,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 62 0 R
+ /Dest [ 65 0 R
/XYZ
62.69291
- 414.0236
+ 765.0236
0 ]
/Rect [ 521.4627
326.7736
@@ -580,8 +580,44 @@ endobj
/Subtype /Link
/Type /Annot >>
endobj
-% 'Page1': class PDFPage
+% 'Annot.NUMBER31': class LinkAnnotation
36 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 65 0 R
+ /XYZ
+ 62.69291
+ 414.0236
+ 0 ]
+ /Rect [ 62.69291
+ 308.7736
+ 106.5829
+ 320.7736 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER32': class LinkAnnotation
+37 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 65 0 R
+ /XYZ
+ 62.69291
+ 414.0236
+ 0 ]
+ /Rect [ 521.4627
+ 308.7736
+ 532.5827
+ 320.7736 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page1': class PDFPage
+38 0 obj
% Page dictionary
<< /Annots [ 5 0 R
6 0 R
@@ -612,13 +648,15 @@ endobj
32 0 R
33 0 R
34 0 R
- 35 0 R ]
- /Contents 82 0 R
+ 35 0 R
+ 36 0 R
+ 37 0 R ]
+ /Contents 85 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 81 0 R
+ /Parent 84 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -630,7 +668,7 @@ endobj
/Type /Page >>
endobj
% 'F5': class PDFType1Font
-37 0 obj
+39 0 obj
% Font Helvetica-Oblique
<< /BaseFont /Helvetica-Oblique
/Encoding /WinAnsiEncoding
@@ -638,8 +676,8 @@ endobj
/Subtype /Type1
/Type /Font >>
endobj
-% 'Annot.NUMBER31': class PDFDictionary
-38 0 obj
+% 'Annot.NUMBER33': class PDFDictionary
+40 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://www.python.org/moin/PythonDecoratorLibrary) >>
@@ -647,14 +685,23 @@ endobj
0
0 ]
/Rect [ 219.6428
- 387.7736
+ 363.7736
449.1728
- 399.7736 ]
+ 375.7736 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER32': class PDFDictionary
-39 0 obj
+% 'F6': class PDFType1Font
+41 0 obj
+% Font Courier-Oblique
+<< /BaseFont /Courier-Oblique
+ /Encoding /WinAnsiEncoding
+ /Name /F6
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER34': class PDFDictionary
+42 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://www.python.org/doc/2.5.2/lib/module-functools.html) >>
@@ -662,23 +709,23 @@ endobj
0
0 ]
/Rect [ 151.0486
- 154.5736
+ 130.5736
270.69
- 166.5736 ]
+ 142.5736 ]
/Subtype /Link
/Type /Annot >>
endobj
% 'Page2': class PDFPage
-40 0 obj
+43 0 obj
% Page dictionary
-<< /Annots [ 38 0 R
- 39 0 R ]
- /Contents 83 0 R
+<< /Annots [ 40 0 R
+ 42 0 R ]
+ /Contents 86 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 81 0 R
+ /Parent 84 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -689,24 +736,15 @@ endobj
/Trans << >>
/Type /Page >>
endobj
-% 'F6': class PDFType1Font
-41 0 obj
-% Font Courier-Oblique
-<< /BaseFont /Courier-Oblique
- /Encoding /WinAnsiEncoding
- /Name /F6
- /Subtype /Type1
- /Type /Font >>
-endobj
% 'Page3': class PDFPage
-42 0 obj
+44 0 obj
% Page dictionary
-<< /Contents 84 0 R
+<< /Contents 87 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 81 0 R
+ /Parent 84 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -718,14 +756,14 @@ endobj
/Type /Page >>
endobj
% 'Page4': class PDFPage
-43 0 obj
+45 0 obj
% Page dictionary
-<< /Contents 85 0 R
+<< /Contents 88 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 81 0 R
+ /Parent 84 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -737,14 +775,14 @@ endobj
/Type /Page >>
endobj
% 'Page5': class PDFPage
-44 0 obj
+46 0 obj
% Page dictionary
-<< /Contents 86 0 R
+<< /Contents 89 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 81 0 R
+ /Parent 84 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -756,14 +794,14 @@ endobj
/Type /Page >>
endobj
% 'Page6': class PDFPage
-45 0 obj
+47 0 obj
% Page dictionary
-<< /Contents 87 0 R
+<< /Contents 90 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 81 0 R
+ /Parent 84 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -775,14 +813,14 @@ endobj
/Type /Page >>
endobj
% 'Page7': class PDFPage
-46 0 obj
+48 0 obj
% Page dictionary
-<< /Contents 88 0 R
+<< /Contents 91 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 81 0 R
+ /Parent 84 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -794,14 +832,14 @@ endobj
/Type /Page >>
endobj
% 'Page8': class PDFPage
-47 0 obj
+49 0 obj
% Page dictionary
-<< /Contents 89 0 R
+<< /Contents 92 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 81 0 R
+ /Parent 84 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -812,31 +850,34 @@ endobj
/Trans << >>
/Type /Page >>
endobj
-% 'Annot.NUMBER33': class PDFDictionary
-48 0 obj
-<< /A << /S /URI
- /Type /Action
- /URI (http://bugs.python.org/issue1764286) >>
- /Border [ 0
+% 'Page9': class PDFPage
+50 0 obj
+% Page dictionary
+<< /Contents 93 0 R
+ /MediaBox [ 0
0
- 0 ]
- /Rect [ 137.6966
- 95.17362
- 180.8679
- 107.1736 ]
- /Subtype /Link
- /Type /Annot >>
+ 595.2756
+ 841.8898 ]
+ /Parent 84 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
endobj
-% 'Page9': class PDFPage
-49 0 obj
+% 'Page10': class PDFPage
+51 0 obj
% Page dictionary
-<< /Annots [ 48 0 R ]
- /Contents 90 0 R
+<< /Contents 94 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 81 0 R
+ /Parent 84 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -847,8 +888,23 @@ endobj
/Trans << >>
/Type /Page >>
endobj
-% 'Annot.NUMBER34': class PDFDictionary
-50 0 obj
+% 'Annot.NUMBER35': class PDFDictionary
+52 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://bugs.python.org/issue1764286) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 137.6966
+ 753.7736
+ 180.8679
+ 765.7736 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER36': class PDFDictionary
+53 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691) >>
@@ -856,22 +912,23 @@ endobj
0
0 ]
/Rect [ 62.69291
- 304.3736
+ 280.3736
363.4029
- 316.3736 ]
+ 292.3736 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Page10': class PDFPage
-51 0 obj
+% 'Page11': class PDFPage
+54 0 obj
% Page dictionary
-<< /Annots [ 50 0 R ]
- /Contents 91 0 R
+<< /Annots [ 52 0 R
+ 53 0 R ]
+ /Contents 95 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 81 0 R
+ /Parent 84 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -882,15 +939,15 @@ endobj
/Trans << >>
/Type /Page >>
endobj
-% 'Page11': class PDFPage
-52 0 obj
+% 'Page12': class PDFPage
+55 0 obj
% Page dictionary
-<< /Contents 92 0 R
+<< /Contents 96 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 81 0 R
+ /Parent 84 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -901,8 +958,8 @@ endobj
/Trans << >>
/Type /Page >>
endobj
-% 'Annot.NUMBER35': class PDFDictionary
-53 0 obj
+% 'Annot.NUMBER37': class PDFDictionary
+56 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://www.python.org/dev/peps/pep-0362) >>
@@ -910,22 +967,22 @@ endobj
0
0 ]
/Rect [ 301.1597
- 140.9736
+ 116.9736
317.8397
- 152.9736 ]
+ 128.9736 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Page12': class PDFPage
-54 0 obj
+% 'Page13': class PDFPage
+57 0 obj
% Page dictionary
-<< /Annots [ 53 0 R ]
- /Contents 93 0 R
+<< /Annots [ 56 0 R ]
+ /Contents 97 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 81 0 R
+ /Parent 84 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -936,15 +993,15 @@ endobj
/Trans << >>
/Type /Page >>
endobj
-% 'Page13': class PDFPage
-55 0 obj
+% 'Page14': class PDFPage
+58 0 obj
% Page dictionary
-<< /Contents 94 0 R
+<< /Contents 98 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 81 0 R
+ /Parent 84 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -955,8 +1012,8 @@ endobj
/Trans << >>
/Type /Page >>
endobj
-% 'Annot.NUMBER36': class PDFDictionary
-56 0 obj
+% 'Annot.NUMBER38': class PDFDictionary
+59 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://www.python.org/dev/peps/pep-3107/) >>
@@ -970,8 +1027,8 @@ endobj
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER37': class PDFDictionary
-57 0 obj
+% 'Annot.NUMBER39': class PDFDictionary
+60 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://www.python.org/dev/peps/pep-3107/) >>
@@ -985,8 +1042,8 @@ endobj
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER38': class PDFDictionary
-58 0 obj
+% 'Annot.NUMBER40': class PDFDictionary
+61 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://packages.python.org/distribute/) >>
@@ -1000,8 +1057,8 @@ endobj
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER39': class PDFDictionary
-59 0 obj
+% 'Annot.NUMBER41': class PDFDictionary
+62 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://docutils.sourceforge.net/) >>
@@ -1015,8 +1072,8 @@ endobj
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER40': class PDFDictionary
-60 0 obj
+% 'Annot.NUMBER42': class PDFDictionary
+63 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://pygments.org/) >>
@@ -1030,8 +1087,8 @@ endobj
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER41': class PDFDictionary
-61 0 obj
+% 'Annot.NUMBER43': class PDFDictionary
+64 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://www.phyast.pitt.edu/~micheles/python/documentation.html#class-decorators-and-decorator-factories) >>
@@ -1045,40 +1102,21 @@ endobj
/Subtype /Link
/Type /Annot >>
endobj
-% 'Page14': class PDFPage
-62 0 obj
-% Page dictionary
-<< /Annots [ 56 0 R
- 57 0 R
- 58 0 R
- 59 0 R
- 60 0 R
- 61 0 R ]
- /Contents 95 0 R
- /MediaBox [ 0
- 0
- 595.2756
- 841.8898 ]
- /Parent 81 0 R
- /Resources << /Font 1 0 R
- /ProcSet [ /PDF
- /Text
- /ImageB
- /ImageC
- /ImageI ] >>
- /Rotate 0
- /Trans << >>
- /Type /Page >>
-endobj
% 'Page15': class PDFPage
-63 0 obj
+65 0 obj
% Page dictionary
-<< /Contents 96 0 R
+<< /Annots [ 59 0 R
+ 60 0 R
+ 61 0 R
+ 62 0 R
+ 63 0 R
+ 64 0 R ]
+ /Contents 99 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 81 0 R
+ /Parent 84 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -1089,223 +1127,235 @@ endobj
/Trans << >>
/Type /Page >>
endobj
-% 'R64': class PDFCatalog
-64 0 obj
+% 'R66': class PDFCatalog
+66 0 obj
% Document Root
-<< /Outlines 66 0 R
- /PageLabels 97 0 R
+<< /Outlines 68 0 R
+ /PageLabels 100 0 R
/PageMode /UseNone
- /Pages 81 0 R
+ /Pages 84 0 R
/Type /Catalog >>
endobj
-% 'R65': class PDFInfo
-65 0 obj
+% 'R67': class PDFInfo
+67 0 obj
<< /Author (Michele Simionato)
- /CreationDate (D:20110901114326-01'00')
+ /CreationDate (D:20121018102559-01'00')
/Creator (\(unspecified\))
/Keywords ()
/Producer (ReportLab PDF Library - www.reportlab.com)
/Subject (\(unspecified\))
/Title (The decorator module) >>
endobj
-% 'R66': class PDFOutlines
-66 0 obj
-<< /Count 14
- /First 67 0 R
- /Last 80 0 R
+% 'R68': class PDFOutlines
+68 0 obj
+<< /Count 15
+ /First 69 0 R
+ /Last 83 0 R
/Type /Outlines >>
endobj
% 'Outline.0': class OutlineEntryObject
-67 0 obj
-<< /Dest [ 36 0 R
- /XYZ
- 62.69291
- 311.0236
- 0 ]
- /Next 68 0 R
- /Parent 66 0 R
- /Title (Introduction) >>
-endobj
-% 'Outline.1': class OutlineEntryObject
-68 0 obj
-<< /Dest [ 40 0 R
- /XYZ
- 62.69291
- 699.0236
- 0 ]
- /Next 69 0 R
- /Parent 66 0 R
- /Prev 67 0 R
- /Title (Definitions) >>
-endobj
-% 'Outline.2': class OutlineEntryObject
69 0 obj
-<< /Dest [ 40 0 R
+<< /Dest [ 38 0 R
/XYZ
62.69291
- 462.0236
+ 293.0236
0 ]
/Next 70 0 R
- /Parent 66 0 R
- /Prev 68 0 R
- /Title (Statement of the problem) >>
+ /Parent 68 0 R
+ /Title (Introduction) >>
endobj
-% 'Outline.3': class OutlineEntryObject
+% 'Outline.1': class OutlineEntryObject
70 0 obj
-<< /Dest [ 42 0 R
+<< /Dest [ 43 0 R
/XYZ
62.69291
- 451.4236
+ 675.0236
0 ]
/Next 71 0 R
- /Parent 66 0 R
+ /Parent 68 0 R
/Prev 69 0 R
- /Title (The solution) >>
+ /Title (Definitions) >>
endobj
-% 'Outline.4': class OutlineEntryObject
+% 'Outline.2': class OutlineEntryObject
71 0 obj
<< /Dest [ 43 0 R
/XYZ
62.69291
- 459.4236
+ 438.0236
0 ]
/Next 72 0 R
- /Parent 66 0 R
+ /Parent 68 0 R
/Prev 70 0 R
- /Title (A trace decorator) >>
+ /Title (Statement of the problem) >>
endobj
-% 'Outline.5': class OutlineEntryObject
+% 'Outline.3': class OutlineEntryObject
72 0 obj
<< /Dest [ 44 0 R
/XYZ
62.69291
- 463.978
+ 427.4236
0 ]
/Next 73 0 R
- /Parent 66 0 R
+ /Parent 68 0 R
/Prev 71 0 R
- /Title (decorator is a decorator) >>
+ /Title (The solution) >>
endobj
-% 'Outline.6': class OutlineEntryObject
+% 'Outline.4': class OutlineEntryObject
73 0 obj
<< /Dest [ 45 0 R
/XYZ
62.69291
- 729.0236
+ 435.4236
0 ]
/Next 74 0 R
- /Parent 66 0 R
+ /Parent 68 0 R
/Prev 72 0 R
- /Title (blocking) >>
+ /Title (A trace decorator) >>
endobj
-% 'Outline.7': class OutlineEntryObject
+% 'Outline.5': class OutlineEntryObject
74 0 obj
-<< /Dest [ 45 0 R
+<< /Dest [ 46 0 R
/XYZ
62.69291
- 195.6236
+ 398.778
0 ]
/Next 75 0 R
- /Parent 66 0 R
+ /Parent 68 0 R
/Prev 73 0 R
- /Title (async) >>
+ /Title (decorator is a decorator) >>
endobj
-% 'Outline.8': class OutlineEntryObject
+% 'Outline.6': class OutlineEntryObject
75 0 obj
<< /Dest [ 47 0 R
/XYZ
62.69291
- 366.6236
+ 647.8236
0 ]
/Next 76 0 R
- /Parent 66 0 R
+ /Parent 68 0 R
/Prev 74 0 R
- /Title (The FunctionMaker class) >>
+ /Title (blocking) >>
endobj
-% 'Outline.9': class OutlineEntryObject
+% 'Outline.7': class OutlineEntryObject
76 0 obj
-<< /Dest [ 49 0 R
+<< /Dest [ 48 0 R
/XYZ
62.69291
- 387.8236
+ 765.0236
0 ]
/Next 77 0 R
- /Parent 66 0 R
+ /Parent 68 0 R
/Prev 75 0 R
- /Title (Getting the source code) >>
+ /Title (async) >>
endobj
-% 'Outline.10': class OutlineEntryObject
+% 'Outline.8': class OutlineEntryObject
77 0 obj
-<< /Dest [ 51 0 R
+<< /Dest [ 49 0 R
/XYZ
62.69291
- 623.8236
+ 267.4236
0 ]
/Next 78 0 R
- /Parent 66 0 R
+ /Parent 68 0 R
/Prev 76 0 R
- /Title (Dealing with third party decorators) >>
+ /Title (contextmanager) >>
endobj
-% 'Outline.11': class OutlineEntryObject
+% 'Outline.9': class OutlineEntryObject
78 0 obj
-<< /Dest [ 52 0 R
+<< /Dest [ 50 0 R
/XYZ
62.69291
- 239.0236
+ 354.6236
0 ]
/Next 79 0 R
- /Parent 66 0 R
+ /Parent 68 0 R
/Prev 77 0 R
- /Title (Caveats and limitations) >>
+ /Title (The FunctionMaker class) >>
endobj
-% 'Outline.12': class OutlineEntryObject
+% 'Outline.10': class OutlineEntryObject
79 0 obj
-<< /Dest [ 62 0 R
+<< /Dest [ 51 0 R
/XYZ
62.69291
- 765.0236
+ 363.8236
0 ]
/Next 80 0 R
- /Parent 66 0 R
+ /Parent 68 0 R
/Prev 78 0 R
- /Title (Compatibility notes) >>
+ /Title (Getting the source code) >>
endobj
-% 'Outline.13': class OutlineEntryObject
+% 'Outline.11': class OutlineEntryObject
80 0 obj
-<< /Dest [ 62 0 R
+<< /Dest [ 54 0 R
/XYZ
62.69291
- 414.0236
+ 599.8236
0 ]
- /Parent 66 0 R
+ /Next 81 0 R
+ /Parent 68 0 R
/Prev 79 0 R
- /Title (LICENCE) >>
+ /Title (Dealing with third party decorators) >>
endobj
-% 'R81': class PDFPages
+% 'Outline.12': class OutlineEntryObject
81 0 obj
+<< /Dest [ 55 0 R
+ /XYZ
+ 62.69291
+ 215.0236
+ 0 ]
+ /Next 82 0 R
+ /Parent 68 0 R
+ /Prev 80 0 R
+ /Title (Caveats and limitations) >>
+endobj
+% 'Outline.13': class OutlineEntryObject
+82 0 obj
+<< /Dest [ 65 0 R
+ /XYZ
+ 62.69291
+ 765.0236
+ 0 ]
+ /Next 83 0 R
+ /Parent 68 0 R
+ /Prev 81 0 R
+ /Title (Compatibility notes) >>
+endobj
+% 'Outline.14': class OutlineEntryObject
+83 0 obj
+<< /Dest [ 65 0 R
+ /XYZ
+ 62.69291
+ 414.0236
+ 0 ]
+ /Parent 68 0 R
+ /Prev 82 0 R
+ /Title (LICENCE) >>
+endobj
+% 'R84': class PDFPages
+84 0 obj
% page tree
<< /Count 15
- /Kids [ 36 0 R
- 40 0 R
- 42 0 R
+ /Kids [ 38 0 R
43 0 R
44 0 R
45 0 R
46 0 R
47 0 R
+ 48 0 R
49 0 R
+ 50 0 R
51 0 R
- 52 0 R
54 0 R
55 0 R
- 62 0 R
- 63 0 R ]
+ 57 0 R
+ 58 0 R
+ 65 0 R ]
/Type /Pages >>
endobj
-% 'R82': class PDFStream
-82 0 obj
+% 'R85': class PDFStream
+85 0 obj
% page stream
-<< /Length 9160 >>
+<< /Length 9046 >>
stream
1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
q
@@ -1370,7 +1420,7 @@ q
1 0 0 1 91.03937 3 cm
q
0 0 0 rg
-BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (3.3.2 \(2011-09-01\)) Tj T* ET
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (3.4.0 \(2012-10-18\)) Tj T* ET
Q
Q
q
@@ -1413,7 +1463,7 @@ q
q
0 0 .501961 rg
0 0 .501961 RG
-BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (http://pypi.python.org/pypi/decorator/3.3.2) Tj T* ET
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (http://pypi.python.org/pypi/decorator/3.4.0) Tj T* ET
Q
Q
q
@@ -1433,8 +1483,7 @@ Q
q
1 0 0 1 91.03937 3 cm
q
-0 0 0 rg
-BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (easy_install decorator) Tj T* ET
+BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (easy_install) Tj ( ) Tj (decorator) Tj T* ET
Q
Q
q
@@ -1468,17 +1517,17 @@ 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
-1 0 0 1 62.69291 323.0236 cm
+1 0 0 1 62.69291 305.0236 cm
0 0 0 rg
BT /F1 10 Tf 12 TL ET
q
-1 0 0 1 0 237 cm
+1 0 0 1 0 255 cm
q
BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Introduction) Tj T* ET
Q
Q
q
-1 0 0 1 397.8898 237 cm
+1 0 0 1 397.8898 255 cm
q
0 0 .501961 rg
0 0 .501961 RG
@@ -1486,12 +1535,26 @@ 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 219 cm
+1 0 0 1 0 237 cm
q
BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Definitions) Tj T* ET
Q
Q
q
+1 0 0 1 397.8898 237 cm
+q
+0 0 .501961 rg
+0 0 .501961 RG
+BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (2) Tj T* -66.44 0 Td ET
+Q
+Q
+q
+1 0 0 1 0 219 cm
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Statement of the problem) Tj T* ET
+Q
+Q
+q
1 0 0 1 397.8898 219 cm
q
0 0 .501961 rg
@@ -1502,7 +1565,7 @@ Q
q
1 0 0 1 0 201 cm
q
-BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Statement of the problem) Tj T* ET
+BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (The solution) Tj T* ET
Q
Q
q
@@ -1510,13 +1573,13 @@ q
q
0 0 .501961 rg
0 0 .501961 RG
-BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (2) Tj T* -66.44 0 Td ET
+BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (3) Tj T* -66.44 0 Td ET
Q
Q
q
1 0 0 1 0 183 cm
q
-BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (The solution) Tj T* ET
+BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (A ) Tj /F3 10 Tf (trace ) Tj /F2 10 Tf (decorator) Tj T* ET
Q
Q
q
@@ -1524,13 +1587,13 @@ q
q
0 0 .501961 rg
0 0 .501961 RG
-BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (3) Tj T* -66.44 0 Td ET
+BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (4) Tj T* -66.44 0 Td ET
Q
Q
q
1 0 0 1 0 165 cm
q
-BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (A ) Tj /F3 10 Tf (trace ) Tj /F2 10 Tf (decorator) Tj T* ET
+BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (decorator ) Tj /F2 10 Tf (is a decorator) Tj T* ET
Q
Q
q
@@ -1538,13 +1601,13 @@ q
q
0 0 .501961 rg
0 0 .501961 RG
-BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (4) Tj T* -66.44 0 Td ET
+BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (5) Tj T* -66.44 0 Td ET
Q
Q
q
1 0 0 1 0 147 cm
q
-BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (decorator ) Tj /F2 10 Tf (is a decorator) Tj T* ET
+BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (blocking) Tj T* ET
Q
Q
q
@@ -1552,13 +1615,13 @@ q
q
0 0 .501961 rg
0 0 .501961 RG
-BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (5) Tj T* -66.44 0 Td ET
+BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (6) Tj T* -66.44 0 Td ET
Q
Q
q
1 0 0 1 0 129 cm
q
-BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (blocking) Tj T* ET
+BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (async) Tj T* ET
Q
Q
q
@@ -1566,13 +1629,13 @@ q
q
0 0 .501961 rg
0 0 .501961 RG
-BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (6) Tj T* -66.44 0 Td ET
+BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (7) Tj T* -66.44 0 Td ET
Q
Q
q
1 0 0 1 0 111 cm
q
-BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (async) Tj T* ET
+BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (contextmanager) Tj T* ET
Q
Q
q
@@ -1580,7 +1643,7 @@ q
q
0 0 .501961 rg
0 0 .501961 RG
-BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (6) Tj T* -66.44 0 Td ET
+BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (8) Tj T* -66.44 0 Td ET
Q
Q
q
@@ -1594,7 +1657,7 @@ q
q
0 0 .501961 rg
0 0 .501961 RG
-BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (8) Tj T* -66.44 0 Td ET
+BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (9) Tj T* -66.44 0 Td ET
Q
Q
q
@@ -1608,7 +1671,7 @@ q
q
0 0 .501961 rg
0 0 .501961 RG
-BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (9) Tj T* -66.44 0 Td ET
+BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 60.88 0 Td (10) Tj T* -60.88 0 Td ET
Q
Q
q
@@ -1622,7 +1685,7 @@ q
q
0 0 .501961 rg
0 0 .501961 RG
-BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 60.88 0 Td (10) Tj T* -60.88 0 Td ET
+BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 60.88 0 Td (11) Tj T* -60.88 0 Td ET
Q
Q
q
@@ -1636,7 +1699,7 @@ q
q
0 0 .501961 rg
0 0 .501961 RG
-BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 60.88 0 Td (11) Tj T* -60.88 0 Td ET
+BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 60.88 0 Td (12) Tj T* -60.88 0 Td ET
Q
Q
q
@@ -1650,7 +1713,7 @@ q
q
0 0 .501961 rg
0 0 .501961 RG
-BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 60.88 0 Td (14) Tj T* -60.88 0 Td ET
+BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 60.88 0 Td (15) Tj T* -60.88 0 Td ET
Q
Q
q
@@ -1664,33 +1727,33 @@ q
q
0 0 .501961 rg
0 0 .501961 RG
-BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 60.88 0 Td (14) Tj T* -60.88 0 Td ET
+BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 60.88 0 Td (15) Tj T* -60.88 0 Td ET
Q
Q
q
Q
Q
q
-1 0 0 1 62.69291 290.0236 cm
+1 0 0 1 62.69291 272.0236 cm
q
BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Introduction) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 224.0236 cm
+1 0 0 1 62.69291 206.0236 cm
q
0 0 0 rg
BT 1 0 0 1 0 50 Tm /F1 10 Tf 12 TL 3.995366 Tw (Python decorators are an interesting example of why syntactic sugar matters. In principle, their) Tj T* 0 Tw .151235 Tw (introduction in Python 2.4 changed nothing, since they do not provide any new functionality which was not) Tj T* 0 Tw 2.238555 Tw (already present in the language. In practice, their introduction has significantly changed the way we) Tj T* 0 Tw .098409 Tw (structure our programs in Python. I believe the change is for the best, and that decorators are a great idea) Tj T* 0 Tw (since:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 218.0236 cm
+1 0 0 1 62.69291 200.0236 cm
Q
q
-1 0 0 1 62.69291 218.0236 cm
+1 0 0 1 62.69291 200.0236 cm
Q
q
-1 0 0 1 62.69291 206.0236 cm
+1 0 0 1 62.69291 188.0236 cm
0 0 0 rg
BT /F1 10 Tf 12 TL ET
q
@@ -1711,10 +1774,10 @@ q
Q
Q
q
-1 0 0 1 62.69291 200.0236 cm
+1 0 0 1 62.69291 182.0236 cm
Q
q
-1 0 0 1 62.69291 188.0236 cm
+1 0 0 1 62.69291 170.0236 cm
0 0 0 rg
BT /F1 10 Tf 12 TL ET
q
@@ -1735,10 +1798,10 @@ q
Q
Q
q
-1 0 0 1 62.69291 182.0236 cm
+1 0 0 1 62.69291 164.0236 cm
Q
q
-1 0 0 1 62.69291 170.0236 cm
+1 0 0 1 62.69291 152.0236 cm
0 0 0 rg
BT /F1 10 Tf 12 TL ET
q
@@ -1759,10 +1822,10 @@ q
Q
Q
q
-1 0 0 1 62.69291 164.0236 cm
+1 0 0 1 62.69291 146.0236 cm
Q
q
-1 0 0 1 62.69291 152.0236 cm
+1 0 0 1 62.69291 134.0236 cm
0 0 0 rg
BT /F1 10 Tf 12 TL ET
q
@@ -1783,63 +1846,57 @@ q
Q
Q
q
-1 0 0 1 62.69291 152.0236 cm
+1 0 0 1 62.69291 134.0236 cm
Q
q
-1 0 0 1 62.69291 110.0236 cm
+1 0 0 1 62.69291 92.02362 cm
q
0 0 0 rg
BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL .848876 Tw (Still, as of now, writing custom decorators correctly requires some experience and it is not as easy as it) Tj T* 0 Tw 1.049269 Tw (could be. For instance, typical implementations of decorators involve nested functions, and we all know) Tj T* 0 Tw (that flat is better than nested.) Tj T* ET
Q
Q
-q
-1 0 0 1 62.69291 80.02362 cm
-q
-BT 1 0 0 1 0 14 Tm 1.093735 Tw 12 TL /F1 10 Tf 0 0 0 rg (The aim of the ) Tj /F4 10 Tf (decorator ) Tj /F1 10 Tf (module it to simplify the usage of decorators for the average programmer, ) Tj T* 0 Tw 2.456136 Tw (and to popularize decorators by showing various non-trivial examples. Of course, as all techniques,) Tj T* 0 Tw ET
-Q
-Q
endstream
endobj
-% 'R83': class PDFStream
-83 0 obj
+% 'R86': class PDFStream
+86 0 obj
% page stream
-<< /Length 6156 >>
+<< /Length 7546 >>
stream
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
+1 0 0 1 62.69291 717.0236 cm
q
-BT 1 0 0 1 0 14 Tm 2.234987 Tw 12 TL /F1 10 Tf 0 0 0 rg (decorators can be abused \(I have seen that\) and you should not try to solve every problem with a) Tj T* 0 Tw (decorator, just because you can.) Tj T* ET
+BT 1 0 0 1 0 38 Tm 1.093735 Tw 12 TL /F1 10 Tf 0 0 0 rg (The aim of the ) Tj /F4 10 Tf (decorator ) Tj /F1 10 Tf (module it to simplify the usage of decorators for the average programmer,) Tj T* 0 Tw 2.456136 Tw (and to popularize decorators by showing various non-trivial examples. Of course, as all techniques,) Tj T* 0 Tw 2.234987 Tw (decorators can be abused \(I have seen that\) and you should not try to solve every problem with a) Tj T* 0 Tw (decorator, just because you can.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 711.0236 cm
+1 0 0 1 62.69291 687.0236 cm
q
BT 1 0 0 1 0 14 Tm .13561 Tw 12 TL /F1 10 Tf 0 0 0 rg (You may find the source code for all the examples discussed here in the ) Tj /F4 10 Tf (documentation.py ) Tj /F1 10 Tf (file, which) Tj T* 0 Tw (contains this documentation in the form of doctests.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 678.0236 cm
+1 0 0 1 62.69291 654.0236 cm
q
BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Definitions) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 636.0236 cm
+1 0 0 1 62.69291 612.0236 cm
q
0 0 0 rg
BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL 2.37561 Tw (Technically speaking, any Python object which can be called with one argument can be used as a) Tj T* 0 Tw .472339 Tw (decorator. However, this definition is somewhat too large to be really useful. It is more convenient to split) Tj T* 0 Tw (the generic class of decorators in two subclasses:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 630.0236 cm
+1 0 0 1 62.69291 606.0236 cm
Q
q
-1 0 0 1 62.69291 630.0236 cm
+1 0 0 1 62.69291 606.0236 cm
Q
q
-1 0 0 1 62.69291 606.0236 cm
+1 0 0 1 62.69291 582.0236 cm
0 0 0 rg
BT /F1 10 Tf 12 TL ET
q
@@ -1859,10 +1916,10 @@ q
Q
Q
q
-1 0 0 1 62.69291 600.0236 cm
+1 0 0 1 62.69291 576.0236 cm
Q
q
-1 0 0 1 62.69291 576.0236 cm
+1 0 0 1 62.69291 552.0236 cm
0 0 0 rg
BT /F1 10 Tf 12 TL ET
q
@@ -1882,42 +1939,42 @@ q
Q
Q
q
-1 0 0 1 62.69291 576.0236 cm
+1 0 0 1 62.69291 552.0236 cm
Q
q
-1 0 0 1 62.69291 534.0236 cm
+1 0 0 1 62.69291 510.0236 cm
q
BT 1 0 0 1 0 26 Tm 2.832706 Tw 12 TL /F1 10 Tf 0 0 0 rg (Signature-changing decorators have their use: for instance the builtin classes ) Tj /F4 10 Tf (staticmethod ) Tj /F1 10 Tf (and) Tj T* 0 Tw 1.506651 Tw /F4 10 Tf (classmethod ) Tj /F1 10 Tf (are in this group, since they take functions and return descriptor objects which are not) Tj T* 0 Tw (functions, nor callables.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 504.0236 cm
+1 0 0 1 62.69291 480.0236 cm
q
0 0 0 rg
BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.735814 Tw (However, signature-preserving decorators are more common and easier to reason about; in particular) Tj T* 0 Tw (signature-preserving decorators can be composed together whereas other decorators in general cannot.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 474.0236 cm
+1 0 0 1 62.69291 450.0236 cm
q
0 0 0 rg
BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .494983 Tw (Writing signature-preserving decorators from scratch is not that obvious, especially if one wants to define) Tj T* 0 Tw (proper decorators that can accept functions with any signature. A simple example will clarify the issue.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 441.0236 cm
+1 0 0 1 62.69291 417.0236 cm
q
BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Statement of the problem) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 363.0236 cm
+1 0 0 1 62.69291 339.0236 cm
q
BT 1 0 0 1 0 62 Tm .351235 Tw 12 TL /F1 10 Tf 0 0 0 rg (A very common use case for decorators is the memoization of functions. A ) Tj /F4 10 Tf (memoize ) Tj /F1 10 Tf (decorator works by) Tj T* 0 Tw .871988 Tw (caching the result of the function call in a dictionary, so that the next time the function is called with the) Tj T* 0 Tw 2.350651 Tw (same input parameters the result is retrieved from the cache and not recomputed. There are many) Tj T* 0 Tw 2.92247 Tw (implementations of ) Tj /F4 10 Tf (memoize ) Tj /F1 10 Tf (in ) Tj 0 0 .501961 rg (http://www.python.org/moin/PythonDecoratorLibrary) Tj 0 0 0 rg (, but they do not) Tj T* 0 Tw 2.683984 Tw (preserve the signature. A simple implementation could be the following \(notice that in general it is) Tj T* 0 Tw (impossible to memoize correctly something that depends on non-hashable arguments\):) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 173.8236 cm
+1 0 0 1 62.69291 149.8236 cm
q
q
1 0 0 1 0 0 cm
@@ -1930,49 +1987,42 @@ q
n -6 -6 468.6898 180 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 158 Tm /F4 10 Tf 12 TL (def memoize_uw\(func\):) Tj T* ( func.cache = {}) Tj T* ( def memoize\(*args, **kw\):) Tj T* ( if kw: # frozenset is used to ensure hashability) Tj T* ( key = args, frozenset\(kw.iteritems\(\)\)) Tj T* ( else:) Tj T* ( key = args) Tj T* ( cache = func.cache) Tj T* ( if key in cache:) Tj T* ( return cache[key]) Tj T* ( else:) Tj T* ( cache[key] = result = func\(*args, **kw\)) Tj T* ( return result) Tj T* ( return functools.update_wrapper\(memoize, func\)) Tj T* ET
+BT 1 0 0 1 0 158 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (memoize_uw) Tj 0 0 0 rg (\() Tj (func) Tj (\):) Tj T* ( ) Tj (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj ({}) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (memoize) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj (,) Tj ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj (\):) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (if) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (kw) Tj (:) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# frozenset is used to ensure hashability) Tj /F4 10 Tf 0 0 0 rg T* ( ) Tj (key) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (args) Tj (,) Tj ( ) Tj 0 .501961 0 rg (frozenset) Tj 0 0 0 rg (\() Tj (kw) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (iteritems) Tj (\(\)\)) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (else) Tj /F4 10 Tf 0 0 0 rg (:) Tj T* ( ) Tj (key) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (args) Tj T* ( ) Tj (cache) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (if) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (key) Tj ( ) Tj /F3 10 Tf .666667 .133333 1 rg (in) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (cache) Tj (:) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (cache) Tj ([) Tj (key) Tj (]) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (else) Tj /F4 10 Tf 0 0 0 rg (:) Tj T* ( ) Tj (cache) Tj ([) Tj (key) Tj (]) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (result) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (func) Tj (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj (,) Tj ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj (\)) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (result) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (functools) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (update_wrapper) Tj (\() Tj (memoize) Tj (,) Tj ( ) Tj (func) Tj (\)) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 117.8236 cm
+1 0 0 1 62.69291 93.82362 cm
q
BT 1 0 0 1 0 38 Tm 1.801412 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here we used the ) Tj 0 0 .501961 rg (functools.update_wrapper ) Tj 0 0 0 rg (utility, which has been added in Python 2.5 expressly to) Tj T* 0 Tw .91686 Tw (simplify the definition of decorators \(in older versions of Python you need to copy the function attributes) Tj T* 0 Tw .580814 Tw /F4 10 Tf (__name__) Tj /F1 10 Tf (, ) Tj /F4 10 Tf (__doc__) Tj /F1 10 Tf (, ) Tj /F4 10 Tf (__module__ ) Tj /F1 10 Tf (and ) Tj /F4 10 Tf (__dict__ ) Tj /F1 10 Tf (from the original function to the decorated function) Tj T* 0 Tw (by hand\).) Tj T* ET
Q
Q
-q
-1 0 0 1 62.69291 87.82362 cm
-q
-BT 1 0 0 1 0 14 Tm 2.517126 Tw 12 TL /F1 10 Tf 0 0 0 rg (The implementation above works in the sense that the decorator can accept functions with generic ) Tj T* 0 Tw 1.233615 Tw (signatures; unfortunately this implementation does ) Tj /F5 10 Tf (not ) Tj /F1 10 Tf (define a signature-preserving decorator, since in) Tj T* 0 Tw ET
-Q
-Q
endstream
endobj
-% 'R84': class PDFStream
-84 0 obj
+% 'R87': class PDFStream
+87 0 obj
% page stream
-<< /Length 6791 >>
+<< /Length 8057 >>
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 62.69291 729.0236 cm
q
-BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (general ) Tj /F4 10 Tf (memoize_uw ) Tj /F1 10 Tf (returns a function with a ) Tj /F5 10 Tf (different signature ) Tj /F1 10 Tf (from the original function.) Tj T* ET
+BT 1 0 0 1 0 26 Tm 2.517126 Tw 12 TL /F1 10 Tf 0 0 0 rg (The implementation above works in the sense that the decorator can accept functions with generic) Tj T* 0 Tw 1.233615 Tw (signatures; unfortunately this implementation does ) Tj /F5 10 Tf (not ) Tj /F1 10 Tf (define a signature-preserving decorator, since in) Tj T* 0 Tw (general ) Tj /F4 10 Tf (memoize_uw ) Tj /F1 10 Tf (returns a function with a ) Tj /F5 10 Tf (different signature ) Tj /F1 10 Tf (from the original function.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 735.0236 cm
+1 0 0 1 62.69291 711.0236 cm
q
0 0 0 rg
BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Consider for instance the following case:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 665.8236 cm
+1 0 0 1 62.69291 641.8236 cm
q
q
1 0 0 1 0 0 cm
@@ -1992,13 +2042,13 @@ Q
Q
Q
q
-1 0 0 1 62.69291 633.8236 cm
+1 0 0 1 62.69291 609.8236 cm
q
BT 1 0 0 1 0 14 Tm .26311 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here the original function takes a single argument named ) Tj /F4 10 Tf (x) Tj /F1 10 Tf (, but the decorated function takes any number) Tj T* 0 Tw (of arguments and keyword arguments:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 576.6236 cm
+1 0 0 1 62.69291 552.6236 cm
q
q
1 0 0 1 0 0 cm
@@ -2018,13 +2068,13 @@ Q
Q
Q
q
-1 0 0 1 62.69291 532.6236 cm
+1 0 0 1 62.69291 508.6236 cm
q
BT 1 0 0 1 0 26 Tm .411235 Tw 12 TL /F1 10 Tf 0 0 0 rg (This means that introspection tools such as pydoc will give wrong informations about the signature of ) Tj /F4 10 Tf (f1) Tj /F1 10 Tf (.) Tj T* 0 Tw .161654 Tw (This is pretty bad: pydoc will tell you that the function accepts a generic signature ) Tj /F4 10 Tf (*args) Tj /F1 10 Tf (, ) Tj /F4 10 Tf (**kw) Tj /F1 10 Tf (, but when) Tj T* 0 Tw (you try to call the function with more than an argument, you will get an error:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 463.4236 cm
+1 0 0 1 62.69291 439.4236 cm
q
q
1 0 0 1 0 0 cm
@@ -2044,19 +2094,19 @@ Q
Q
Q
q
-1 0 0 1 62.69291 430.4236 cm
+1 0 0 1 62.69291 406.4236 cm
q
BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (The solution) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 388.4236 cm
+1 0 0 1 62.69291 364.4236 cm
q
BT 1 0 0 1 0 26 Tm 3.313984 Tw 12 TL /F1 10 Tf 0 0 0 rg (The solution is to provide a generic factory of generators, which hides the complexity of making) Tj T* 0 Tw 3.362976 Tw (signature-preserving decorators from the application programmer. The ) Tj /F4 10 Tf (decorator ) Tj /F1 10 Tf (function in the) Tj T* 0 Tw /F4 10 Tf (decorator ) Tj /F1 10 Tf (module is such a factory:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 355.2236 cm
+1 0 0 1 62.69291 331.2236 cm
q
q
1 0 0 1 0 0 cm
@@ -2076,13 +2126,13 @@ Q
Q
Q
q
-1 0 0 1 62.69291 299.2236 cm
+1 0 0 1 62.69291 275.2236 cm
q
-BT 1 0 0 1 0 38 Tm 1.716412 Tw 12 TL /F4 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf (takes two arguments, a caller function describing the functionality of the decorator and a) Tj T* 0 Tw .821984 Tw (function to be decorated; it returns the decorated function. The caller function must have signature ) Tj /F4 10 Tf (\(f,) Tj T* 0 Tw .65061 Tw (*args, **kw\) ) Tj /F1 10 Tf (and it must call the original function ) Tj /F4 10 Tf (f ) Tj /F1 10 Tf (with arguments ) Tj /F4 10 Tf (args ) Tj /F1 10 Tf (and ) Tj /F4 10 Tf (kw) Tj /F1 10 Tf (, implementing the) Tj T* 0 Tw (wanted capability, i.e. memoization in this case:) Tj T* ET
+BT 1 0 0 1 0 38 Tm 1.716412 Tw 12 TL /F4 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf (takes two arguments, a caller function describing the functionality of the decorator and a) Tj T* 0 Tw 2.594983 Tw (function to be decorated; it returns the decorated function. The caller function must have signature) Tj T* 0 Tw .19311 Tw /F4 10 Tf (\(f,) Tj ( ) Tj (*args,) Tj ( ) Tj (**kw\) ) Tj /F1 10 Tf (and it must call the original function ) Tj /F4 10 Tf (f ) Tj /F1 10 Tf (with arguments ) Tj /F4 10 Tf (args ) Tj /F1 10 Tf (and ) Tj /F4 10 Tf (kw) Tj /F1 10 Tf (, implementing) Tj T* 0 Tw (the wanted capability, i.e. memoization in this case:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 146.0236 cm
+1 0 0 1 62.69291 122.0236 cm
q
q
1 0 0 1 0 0 cm
@@ -2095,52 +2145,30 @@ q
n -6 -6 468.6898 144 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 122 Tm /F4 10 Tf 12 TL (def _memoize\(func, *args, **kw\):) Tj T* ( if kw: # frozenset is used to ensure hashability) Tj T* ( key = args, frozenset\(kw.iteritems\(\)\)) Tj T* ( else:) Tj T* ( key = args) Tj T* ( cache = func.cache # attributed added by memoize) Tj T* ( if key in cache:) Tj T* ( return cache[key]) Tj T* ( else:) Tj T* ( cache[key] = result = func\(*args, **kw\)) Tj T* ( return result) Tj T* ET
+BT 1 0 0 1 0 122 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (_memoize) Tj 0 0 0 rg (\() Tj (func) Tj (,) Tj ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj (,) Tj ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj (\):) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (if) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (kw) Tj (:) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# frozenset is used to ensure hashability) Tj /F4 10 Tf 0 0 0 rg T* ( ) Tj (key) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (args) Tj (,) Tj ( ) Tj 0 .501961 0 rg (frozenset) Tj 0 0 0 rg (\() Tj (kw) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (iteritems) Tj (\(\)\)) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (else) Tj /F4 10 Tf 0 0 0 rg (:) Tj T* ( ) Tj (key) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (args) Tj T* ( ) Tj (cache) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# attributed added by memoize) Tj /F4 10 Tf 0 0 0 rg T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (if) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (key) Tj ( ) Tj /F3 10 Tf .666667 .133333 1 rg (in) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (cache) Tj (:) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (cache) Tj ([) Tj (key) Tj (]) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (else) Tj /F4 10 Tf 0 0 0 rg (:) Tj T* ( ) Tj (cache) Tj ([) Tj (key) Tj (]) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (result) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (func) Tj (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj (,) Tj ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj (\)) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (result) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 126.0236 cm
+1 0 0 1 62.69291 102.0236 cm
q
0 0 0 rg
BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (At this point you can define your decorator as follows:) Tj T* ET
Q
Q
-q
-1 0 0 1 62.69291 80.82362 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 /F4 10 Tf 12 TL (def memoize\(f\):) Tj T* ( f.cache = {}) Tj T* ET
-Q
-Q
-Q
-Q
-Q
endstream
endobj
-% 'R85': class PDFStream
-85 0 obj
+% 'R88': class PDFStream
+88 0 obj
% page stream
-<< /Length 6759 >>
+<< /Length 7115 >>
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
+1 0 0 1 62.69291 715.8236 cm
q
q
1 0 0 1 0 0 cm
@@ -2150,31 +2178,30 @@ q
.662745 .662745 .662745 RG
.5 w
.960784 .960784 .862745 rg
-n -6 -6 468.6898 24 re B*
+n -6 -6 468.6898 48 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL ( return decorator\(_memoize, f\)) Tj T* ET
+BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (memoize) Tj 0 0 0 rg (\() Tj (f) Tj (\):) Tj T* ( ) Tj (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj ({}) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (decorator) Tj (\() Tj (_memoize) Tj (,) Tj ( ) Tj (f) Tj (\)) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 695.8236 cm
+1 0 0 1 62.69291 671.8236 cm
q
BT 1 0 0 1 0 26 Tm .12561 Tw 12 TL /F1 10 Tf 0 0 0 rg (The difference with respect to the ) Tj /F4 10 Tf (memoize_uw ) Tj /F1 10 Tf (approach, which is based on nested functions, is that the) Tj T* 0 Tw 2.59528 Tw (decorator module forces you to lift the inner function at the outer level \() Tj /F5 10 Tf (flat is better than nested) Tj /F1 10 Tf (\).) Tj T* 0 Tw (Moreover, you are forced to pass explicitly the function you want to decorate to the caller function.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 677.8236 cm
+1 0 0 1 62.69291 653.8236 cm
q
0 0 0 rg
BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is a test of usage:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 536.6236 cm
+1 0 0 1 62.69291 512.6236 cm
q
q
1 0 0 1 0 0 cm
@@ -2194,13 +2221,13 @@ Q
Q
Q
q
-1 0 0 1 62.69291 516.6236 cm
+1 0 0 1 62.69291 492.6236 cm
q
BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The signature of ) Tj /F4 10 Tf (heavy_computation ) Tj /F1 10 Tf (is the one you would expect:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 471.4236 cm
+1 0 0 1 62.69291 447.4236 cm
q
q
1 0 0 1 0 0 cm
@@ -2220,19 +2247,19 @@ Q
Q
Q
q
-1 0 0 1 62.69291 438.4236 cm
+1 0 0 1 62.69291 414.4236 cm
q
BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (A ) Tj /F3 17.5 Tf (trace ) Tj /F2 17.5 Tf (decorator) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 408.4236 cm
+1 0 0 1 62.69291 384.4236 cm
q
BT 1 0 0 1 0 14 Tm .479398 Tw 12 TL /F1 10 Tf 0 0 0 rg (As an additional example, here is how you can define a trivial ) Tj /F4 10 Tf (trace ) Tj /F1 10 Tf (decorator, which prints a message) Tj T* 0 Tw (everytime the traced function is called:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 351.2236 cm
+1 0 0 1 62.69291 327.2236 cm
q
q
1 0 0 1 0 0 cm
@@ -2245,15 +2272,14 @@ q
n -6 -6 468.6898 48 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL (def _trace\(f, *args, **kw\):) Tj T* ( print "calling %s with args %s, %s" % \(f.__name__, args, kw\)) Tj T* ( return f\(*args, **kw\)) Tj T* ET
+BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (_trace) Tj 0 0 0 rg (\() Tj (f) Tj (,) Tj ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj (,) Tj ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj (\):) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (print) Tj /F4 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("calling ) Tj /F3 10 Tf .733333 .4 .533333 rg (%s) Tj /F4 10 Tf .729412 .129412 .129412 rg ( with args ) Tj /F3 10 Tf .733333 .4 .533333 rg (%s) Tj /F4 10 Tf .729412 .129412 .129412 rg (, ) Tj /F3 10 Tf .733333 .4 .533333 rg (%s) Tj /F4 10 Tf .729412 .129412 .129412 rg (") Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (%) Tj 0 0 0 rg ( ) Tj (\() Tj (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__name__) Tj (,) Tj ( ) Tj (args) Tj (,) Tj ( ) Tj (kw) Tj (\)) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (f) Tj (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj (,) Tj ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj (\)) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 306.0236 cm
+1 0 0 1 62.69291 282.0236 cm
q
q
1 0 0 1 0 0 cm
@@ -2266,22 +2292,21 @@ q
n -6 -6 468.6898 36 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 14 Tm /F4 10 Tf 12 TL (def trace\(f\):) Tj T* ( return decorator\(_trace, f\)) Tj T* ET
+BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (trace) Tj 0 0 0 rg (\() Tj (f) Tj (\):) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (decorator) Tj (\() Tj (_trace) Tj (,) Tj ( ) Tj (f) Tj (\)) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 286.0236 cm
+1 0 0 1 62.69291 262.0236 cm
q
0 0 0 rg
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 228.8236 cm
+1 0 0 1 62.69291 204.8236 cm
q
q
1 0 0 1 0 0 cm
@@ -2301,13 +2326,13 @@ Q
Q
Q
q
-1 0 0 1 62.69291 208.8236 cm
+1 0 0 1 62.69291 184.8236 cm
q
BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (It is immediate to verify that ) Tj /F4 10 Tf (f1 ) Tj /F1 10 Tf (works) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 163.6236 cm
+1 0 0 1 62.69291 139.6236 cm
q
q
1 0 0 1 0 0 cm
@@ -2327,14 +2352,23 @@ Q
Q
Q
q
-1 0 0 1 62.69291 143.6236 cm
+1 0 0 1 62.69291 119.6236 cm
q
0 0 0 rg
BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (and it that it has the correct signature:) Tj T* ET
Q
Q
+
+endstream
+endobj
+% 'R89': class PDFStream
+89 0 obj
+% page stream
+<< /Length 8852 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
q
-1 0 0 1 62.69291 98.42362 cm
+1 0 0 1 62.69291 727.8236 cm
q
q
1 0 0 1 0 0 cm
@@ -2354,23 +2388,14 @@ Q
Q
Q
q
-1 0 0 1 62.69291 78.42362 cm
+1 0 0 1 62.69291 707.8236 cm
q
0 0 0 rg
BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The same decorator works with functions of any signature:) Tj T* ET
Q
Q
-
-endstream
-endobj
-% 'R86': class PDFStream
-86 0 obj
-% page stream
-<< /Length 8633 >>
-stream
-1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
q
-1 0 0 1 62.69291 645.178 cm
+1 0 0 1 62.69291 579.978 cm
q
q
.988825 0 0 .988825 0 0 cm
@@ -2390,14 +2415,14 @@ Q
Q
Q
q
-1 0 0 1 62.69291 625.178 cm
+1 0 0 1 62.69291 559.978 cm
q
0 0 0 rg
BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (That includes even functions with exotic signatures like the following:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 507.978 cm
+1 0 0 1 62.69291 442.778 cm
q
q
1 0 0 1 0 0 cm
@@ -2417,26 +2442,26 @@ Q
Q
Q
q
-1 0 0 1 62.69291 475.978 cm
+1 0 0 1 62.69291 410.778 cm
q
0 0 0 rg
BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .84561 Tw (Notice that the support for exotic signatures has been deprecated in Python 2.6 and removed in Python) Tj T* 0 Tw (3.0.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 442.978 cm
+1 0 0 1 62.69291 377.778 cm
q
BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (decorator ) Tj /F2 17.5 Tf (is a decorator) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 340.978 cm
+1 0 0 1 62.69291 275.778 cm
q
-BT 1 0 0 1 0 86 Tm .643876 Tw 12 TL /F1 10 Tf 0 0 0 rg (It may be annoying to write a caller function \(like the ) Tj /F4 10 Tf (_trace ) Tj /F1 10 Tf (function above\) and then a trivial wrapper) Tj T* 0 Tw 1.803615 Tw (\() Tj /F4 10 Tf (def trace\(f\): return decorator\(_trace, f\)) Tj /F1 10 Tf (\) every time. For this reason, the ) Tj /F4 10 Tf (decorator) Tj T* 0 Tw .334269 Tw /F1 10 Tf (module provides an easy shortcut to convert the caller function into a signature-preserving decorator: you) Tj T* 0 Tw 3.443735 Tw (can just call ) Tj /F4 10 Tf (decorator ) Tj /F1 10 Tf (with a single argument. In our example you can just write ) Tj /F4 10 Tf (trace =) Tj T* 0 Tw 1.056342 Tw (decorator\(_trace\)) Tj /F1 10 Tf (. The ) Tj /F4 10 Tf (decorator ) Tj /F1 10 Tf (function can also be used as a signature-changing decorator,) Tj T* 0 Tw 3.177752 Tw (just as ) Tj /F4 10 Tf (classmethod ) Tj /F1 10 Tf (and ) Tj /F4 10 Tf (staticmethod) Tj /F1 10 Tf (. However, ) Tj /F4 10 Tf (classmethod ) Tj /F1 10 Tf (and ) Tj /F4 10 Tf (staticmethod ) Tj /F1 10 Tf (return) Tj T* 0 Tw 1.693615 Tw (generic objects which are not callable, while ) Tj /F4 10 Tf (decorator ) Tj /F1 10 Tf (returns signature-preserving decorators, i.e.) Tj T* 0 Tw (functions of a single argument. For instance, you can write directly) Tj T* ET
+BT 1 0 0 1 0 86 Tm .643876 Tw 12 TL /F1 10 Tf 0 0 0 rg (It may be annoying to write a caller function \(like the ) Tj /F4 10 Tf (_trace ) Tj /F1 10 Tf (function above\) and then a trivial wrapper) Tj T* 0 Tw 1.510888 Tw (\() Tj /F4 10 Tf (def) Tj ( ) Tj (trace\(f\):) Tj ( ) Tj (return) Tj ( ) Tj (decorator\(_trace,) Tj ( ) Tj (f\)) Tj /F1 10 Tf (\) every time. For this reason, the ) Tj /F4 10 Tf (decorator) Tj T* 0 Tw .334269 Tw /F1 10 Tf (module provides an easy shortcut to convert the caller function into a signature-preserving decorator: you) Tj T* 0 Tw 7.364269 Tw (can just call ) Tj /F4 10 Tf (decorator ) Tj /F1 10 Tf (with a single argument. In our example you can just write) Tj T* 0 Tw .951647 Tw /F4 10 Tf (trace) Tj ( ) Tj (=) Tj ( ) Tj (decorator\(_trace\)) Tj /F1 10 Tf (. The ) Tj /F4 10 Tf (decorator ) Tj /F1 10 Tf (function can also be used as a signature-changing) Tj T* 0 Tw 1.077752 Tw (decorator, just as ) Tj /F4 10 Tf (classmethod ) Tj /F1 10 Tf (and ) Tj /F4 10 Tf (staticmethod) Tj /F1 10 Tf (. However, ) Tj /F4 10 Tf (classmethod ) Tj /F1 10 Tf (and ) Tj /F4 10 Tf (staticmethod) Tj T* 0 Tw .531797 Tw /F1 10 Tf (return generic objects which are not callable, while ) Tj /F4 10 Tf (decorator ) Tj /F1 10 Tf (returns signature-preserving decorators,) Tj T* 0 Tw (i.e. functions of a single argument. For instance, you can write directly) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 271.778 cm
+1 0 0 1 62.69291 206.578 cm
q
q
1 0 0 1 0 0 cm
@@ -2456,13 +2481,13 @@ Q
Q
Q
q
-1 0 0 1 62.69291 239.778 cm
+1 0 0 1 62.69291 174.578 cm
q
BT 1 0 0 1 0 14 Tm 1.806654 Tw 12 TL /F1 10 Tf 0 0 0 rg (and now ) Tj /F4 10 Tf (trace ) Tj /F1 10 Tf (will be a decorator. Actually ) Tj /F4 10 Tf (trace ) Tj /F1 10 Tf (is a ) Tj /F4 10 Tf (partial ) Tj /F1 10 Tf (object which can be used as a) Tj T* 0 Tw (decorator:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 194.578 cm
+1 0 0 1 62.69291 129.378 cm
q
q
1 0 0 1 0 0 cm
@@ -2482,14 +2507,23 @@ Q
Q
Q
q
-1 0 0 1 62.69291 174.578 cm
+1 0 0 1 62.69291 109.378 cm
q
0 0 0 rg
BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is an example of usage:) Tj T* ET
Q
Q
+
+endstream
+endobj
+% 'R90': class PDFStream
+90 0 obj
+% page stream
+<< /Length 7156 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
q
-1 0 0 1 62.69291 93.378 cm
+1 0 0 1 62.69291 691.8236 cm
q
q
1 0 0 1 0 0 cm
@@ -2508,35 +2542,26 @@ Q
Q
Q
Q
-
-endstream
-endobj
-% 'R87': class PDFStream
-87 0 obj
-% page stream
-<< /Length 5826 >>
-stream
-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
+1 0 0 1 62.69291 659.8236 cm
q
BT 1 0 0 1 0 14 Tm 2.44686 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you are using an old Python version \(Python 2.4\) the ) Tj /F4 10 Tf (decorator ) Tj /F1 10 Tf (module provides a poor man) Tj T* 0 Tw (replacement for ) Tj /F4 10 Tf (functools.partial) Tj /F1 10 Tf (.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 708.0236 cm
+1 0 0 1 62.69291 626.8236 cm
q
BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (blocking) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 666.0236 cm
+1 0 0 1 62.69291 584.8236 cm
q
BT 1 0 0 1 0 26 Tm 1.224692 Tw 12 TL /F1 10 Tf 0 0 0 rg (Sometimes one has to deal with blocking resources, such as ) Tj /F4 10 Tf (stdin) Tj /F1 10 Tf (, and sometimes it is best to have) Tj T* 0 Tw .266235 Tw (back a "busy" message than to block everything. This behavior can be implemented with a suitable family) Tj T* 0 Tw (of decorators, where the parameter is the busy message:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 488.8236 cm
+1 0 0 1 62.69291 407.6236 cm
q
q
1 0 0 1 0 0 cm
@@ -2549,21 +2574,20 @@ q
n -6 -6 468.6898 168 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 146 Tm /F4 10 Tf 12 TL (def blocking\(not_avail\):) Tj T* ( def blocking\(f, *args, **kw\):) Tj T* ( if not hasattr\(f, "thread"\): # no thread running) Tj T* ( def set_result\(\): f.result = f\(*args, **kw\)) Tj T* ( f.thread = threading.Thread\(None, set_result\)) Tj T* ( f.thread.start\(\)) Tj T* ( return not_avail) Tj T* ( elif f.thread.isAlive\(\):) Tj T* ( return not_avail) Tj T* ( else: # the thread is ended, return the stored result) Tj T* ( del f.thread) Tj T* ( return f.result) Tj T* ( return decorator\(blocking\)) Tj T* ET
+BT 1 0 0 1 0 146 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (blocking) Tj 0 0 0 rg (\() Tj (not_avail) Tj (\):) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (blocking) Tj 0 0 0 rg (\() Tj (f) Tj (,) Tj ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj (,) Tj ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj (\):) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (if) Tj /F4 10 Tf 0 0 0 rg ( ) Tj /F3 10 Tf .666667 .133333 1 rg (not) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (hasattr) Tj 0 0 0 rg (\() Tj (f) Tj (,) Tj ( ) Tj .729412 .129412 .129412 rg ("thread") Tj 0 0 0 rg (\):) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# no thread running) Tj /F4 10 Tf 0 0 0 rg T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (set_result) Tj 0 0 0 rg (\(\):) Tj ( ) Tj (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (result) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (f) Tj (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj (,) Tj ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj (\)) Tj T* ( ) Tj (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (thread) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (threading) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Thread) Tj (\() Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj ( ) Tj (set_result) Tj (\)) Tj T* ( ) Tj (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (thread) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (start) Tj (\(\)) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (not_avail) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (elif) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (thread) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (isAlive) Tj (\(\):) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (not_avail) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (else) Tj /F4 10 Tf 0 0 0 rg (:) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# the thread is ended, return the stored result) Tj /F4 10 Tf 0 0 0 rg T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (del) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (thread) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (result) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (decorator) Tj (\() Tj (blocking) Tj (\)) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 456.8236 cm
+1 0 0 1 62.69291 375.6236 cm
q
BT 1 0 0 1 0 14 Tm 1.010651 Tw 12 TL /F1 10 Tf 0 0 0 rg (Functions decorated with ) Tj /F4 10 Tf (blocking ) Tj /F1 10 Tf (will return a busy message if the resource is unavailable, and the) Tj T* 0 Tw (intended result if the resource is available. For instance:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 207.6236 cm
+1 0 0 1 62.69291 126.4236 cm
q
q
1 0 0 1 0 0 cm
@@ -2582,41 +2606,56 @@ Q
Q
Q
Q
+
+endstream
+endobj
+% 'R91': class PDFStream
+91 0 obj
+% page stream
+<< /Length 7381 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
q
-1 0 0 1 62.69291 174.6236 cm
+1 0 0 1 62.69291 744.0236 cm
q
BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (async) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 108.6236 cm
+1 0 0 1 62.69291 702.0236 cm
q
-BT 1 0 0 1 0 50 Tm 1.647485 Tw 12 TL /F1 10 Tf 0 0 0 rg (We have just seen an examples of a simple decorator factory, implemented as a function returning a) Tj T* 0 Tw .29784 Tw (decorator. For more complex situations, it is more convenient to implement decorator factories as classes) Tj T* 0 Tw .657674 Tw (returning callable objects that can be used as signature-preserving decorators. The suggested pattern to) Tj T* 0 Tw 2.109398 Tw (do that is to introduce a helper method ) Tj /F4 10 Tf (call\(self, func, *args, **kw\) ) Tj /F1 10 Tf (and to call it in the) Tj T* 0 Tw /F4 10 Tf (__call__\(self, func\) ) Tj /F1 10 Tf (method.) Tj T* ET
+0 0 0 rg
+BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL 1.647485 Tw (We have just seen an examples of a simple decorator factory, implemented as a function returning a) Tj T* 0 Tw .29784 Tw (decorator. For more complex situations, it is more convenient to implement decorator factories as classes) Tj T* 0 Tw (returning callable objects that can be converted into decorators.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 78.62362 cm
+1 0 0 1 62.69291 636.0236 cm
q
-BT 1 0 0 1 0 14 Tm .166654 Tw 12 TL /F1 10 Tf 0 0 0 rg (As an example, here I show a decorator which is able to convert a blocking function into an asynchronous ) Tj T* 0 Tw .437633 Tw (function. The function, when called, is executed in a separate thread. Moreover, it is possible to set three) Tj T* 0 Tw ET
+BT 1 0 0 1 0 50 Tm 2.853876 Tw 12 TL /F1 10 Tf 0 0 0 rg (As an example, here will I show a decorator which is able to convert a blocking function into an) Tj T* 0 Tw 2.477126 Tw (asynchronous function. The function, when called, is executed in a separate thread. Moreover, it is) Tj T* 0 Tw .288443 Tw (possible to set three callbacks ) Tj /F4 10 Tf (on_success) Tj /F1 10 Tf (, ) Tj /F4 10 Tf (on_failure ) Tj /F1 10 Tf (and ) Tj /F4 10 Tf (on_closing) Tj /F1 10 Tf (, to specify how to manage) Tj T* 0 Tw 1.854724 Tw (the function call \(of course the code here is just an example, it is not a recommended way of doing) Tj T* 0 Tw (multi-threaded programming\). The implementation is the following:) Tj T* ET
Q
Q
-
-endstream
-endobj
-% 'R88': class PDFStream
-88 0 obj
-% page stream
-<< /Length 3574 >>
-stream
-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
+1 0 0 1 62.69291 578.8236 cm
+q
+q
+1 0 0 1 0 0 cm
q
-BT 1 0 0 1 0 14 Tm .074597 Tw 12 TL /F1 10 Tf 0 0 0 rg (callbacks ) Tj /F4 10 Tf (on_success) Tj /F1 10 Tf (, ) Tj /F4 10 Tf (on_failure ) Tj /F1 10 Tf (and ) Tj /F4 10 Tf (on_closing) Tj /F1 10 Tf (, to specify how to manage the function call. The) Tj T* 0 Tw (implementation is the following:) Tj T* ET
+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 26 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (on_success) Tj 0 0 0 rg (\() Tj (result) Tj (\):) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# default implementation) Tj /F4 10 Tf 0 0 0 rg T* ( ) Tj .729412 .129412 .129412 rg ("Called on the result of the function") Tj 0 0 0 rg T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (result) Tj T* ET
+Q
+Q
+Q
Q
Q
q
-1 0 0 1 62.69291 683.8236 cm
+1 0 0 1 62.69291 521.6236 cm
q
q
1 0 0 1 0 0 cm
@@ -2629,15 +2668,14 @@ q
n -6 -6 468.6898 48 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL (def on_success\(result\): # default implementation) Tj T* ( "Called on the result of the function") Tj T* ( return result) Tj T* ET
+BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (on_failure) Tj 0 0 0 rg (\() Tj (exc_info) Tj (\):) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# default implementation) Tj /F4 10 Tf 0 0 0 rg T* ( ) Tj .729412 .129412 .129412 rg ("Called if the function fails") Tj 0 0 0 rg T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (pass) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 626.6236 cm
+1 0 0 1 62.69291 464.4236 cm
q
q
1 0 0 1 0 0 cm
@@ -2650,15 +2688,14 @@ q
n -6 -6 468.6898 48 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL (def on_failure\(exc_info\): # default implementation) Tj T* ( "Called if the function fails") Tj T* ( pass) Tj T* ET
+BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (on_closing) Tj 0 0 0 rg (\(\):) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# default implementation) Tj /F4 10 Tf 0 0 0 rg T* ( ) Tj .729412 .129412 .129412 rg ("Called at the end, both in case of success and failure") Tj 0 0 0 rg T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (pass) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 569.4236 cm
+1 0 0 1 62.69291 83.22362 cm
q
q
1 0 0 1 0 0 cm
@@ -2668,18 +2705,26 @@ q
.662745 .662745 .662745 RG
.5 w
.960784 .960784 .862745 rg
-n -6 -6 468.6898 48 re B*
+n -6 -6 468.6898 372 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL (def on_closing\(\): # default implementation) Tj T* ( "Called at the end, both in case of success and failure") Tj T* ( pass) Tj T* ET
+BT 1 0 0 1 0 350 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (class) Tj /F4 10 Tf 0 0 0 rg ( ) Tj /F3 10 Tf 0 0 1 rg (Async) Tj /F4 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj T* ( ) Tj /F6 10 Tf .729412 .129412 .129412 rg (""") Tj T* ( A decorator converting blocking functions into asynchronous) Tj T* ( functions, by using threads or processes. Examples:) Tj T* T* ( async_with_threads = Async\(threading.Thread\)) Tj T* ( async_with_processes = Async\(multiprocessing.Process\)) Tj T* ( """) Tj /F4 10 Tf 0 0 0 rg T* T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (__init__) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (,) Tj ( ) Tj (threadfactory) Tj (,) Tj ( ) Tj (on_success) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (on_success) Tj (,) Tj T* ( ) Tj (on_failure) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (on_failure) Tj (,) Tj ( ) Tj (on_closing) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (on_closing) Tj (\):) Tj T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (threadfactory) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (threadfactory) Tj T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (on_success) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (on_success) Tj T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (on_failure) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (on_failure) Tj T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (on_closing) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (on_closing) Tj T* T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (__call__) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (,) Tj ( ) Tj (func) Tj (,) Tj ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj (,) Tj ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj (\):) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (try) Tj /F4 10 Tf 0 0 0 rg (:) Tj T* ( ) Tj (counter) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (counter) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (except) Tj /F4 10 Tf 0 0 0 rg ( ) Tj /F3 10 Tf .823529 .254902 .227451 rg (AttributeError) Tj /F4 10 Tf 0 0 0 rg (:) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# instantiate the counter at the first call) Tj /F4 10 Tf 0 0 0 rg T* ( ) Tj (counter) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (counter) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (itertools) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (count) Tj (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj T* ( ) Tj (name) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (') Tj /F3 10 Tf .733333 .4 .533333 rg (%s) Tj /F4 10 Tf .729412 .129412 .129412 rg (-) Tj /F3 10 Tf .733333 .4 .533333 rg (%s) Tj /F4 10 Tf .729412 .129412 .129412 rg (') Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (%) Tj 0 0 0 rg ( ) Tj (\() Tj (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__name__) Tj (,) Tj ( ) Tj (counter) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (next) Tj (\(\)\)) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (func_wrapper) Tj 0 0 0 rg (\(\):) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (try) Tj /F4 10 Tf 0 0 0 rg (:) Tj T* ( ) Tj (result) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (func) Tj (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj (,) Tj ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj (\)) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (except) Tj /F4 10 Tf 0 0 0 rg (:) Tj T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (on_failure) Tj (\() Tj (sys) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (exc_info) Tj (\(\)\)) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (else) Tj /F4 10 Tf 0 0 0 rg (:) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (on_success) Tj (\() Tj (result) Tj (\)) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (finally) Tj /F4 10 Tf 0 0 0 rg (:) Tj T* ET
Q
Q
Q
Q
Q
+
+endstream
+endobj
+% 'R92': class PDFStream
+92 0 obj
+% page stream
+<< /Length 7221 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
q
-1 0 0 1 62.69291 128.2236 cm
+1 0 0 1 62.69291 703.8236 cm
q
q
1 0 0 1 0 0 cm
@@ -2689,40 +2734,30 @@ q
.662745 .662745 .662745 RG
.5 w
.960784 .960784 .862745 rg
-n -6 -6 468.6898 432 re B*
+n -6 -6 468.6898 60 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 410 Tm /F4 10 Tf 12 TL (class Async\(object\):) Tj T* ( """) Tj T* ( A decorator converting blocking functions into asynchronous) Tj T* ( functions, by using threads or processes. Examples:) Tj T* T* ( async_with_threads = Async\(threading.Thread\)) Tj T* ( async_with_processes = Async\(multiprocessing.Process\)) Tj T* ( """) Tj T* T* ( def __init__\(self, threadfactory\):) Tj T* ( self.threadfactory = threadfactory) Tj T* T* ( def __call__\(self, func, on_success=on_success,) Tj T* ( on_failure=on_failure, on_closing=on_closing\):) Tj T* ( # every decorated function has its own independent thread counter) Tj T* ( func.counter = itertools.count\(1\)) Tj T* ( func.on_success = on_success) Tj T* ( func.on_failure = on_failure) Tj T* ( func.on_closing = on_closing) Tj T* ( return decorator\(self.call, func\)) Tj T* T* ( def call\(self, func, *args, **kw\):) Tj T* ( def func_wrapper\(\):) Tj T* ( try:) Tj T* ( result = func\(*args, **kw\)) Tj T* ( except:) Tj T* ( func.on_failure\(sys.exc_info\(\)\)) Tj T* ( else:) Tj T* ( return func.on_success\(result\)) Tj T* ( finally:) Tj T* ( func.on_closing\(\)) Tj T* ( name = '%s-%s' % \(func.__name__, func.counter.next\(\)\)) Tj T* ( thread = self.threadfactory\(None, func_wrapper, name\)) Tj T* ( thread.start\(\)) Tj T* ( return thread) Tj T* ET
+BT 1 0 0 1 0 38 Tm 12 TL /F4 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (on_closing) Tj (\(\)) Tj T* ( ) Tj (thread) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (threadfactory) Tj (\() Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj ( ) Tj (func_wrapper) Tj (,) Tj ( ) Tj (name) Tj (\)) Tj T* ( ) Tj (thread) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (start) Tj (\(\)) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (thread) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 96.22362 cm
+1 0 0 1 62.69291 671.8236 cm
q
BT 1 0 0 1 0 14 Tm .865984 Tw 12 TL /F1 10 Tf 0 0 0 rg (The decorated function returns the current execution thread, which can be stored and checked later, for) Tj T* 0 Tw (instance to verify that the thread ) Tj /F4 10 Tf (.isAlive\(\)) Tj /F1 10 Tf (.) Tj T* ET
Q
Q
-
-endstream
-endobj
-% 'R89': class PDFStream
-89 0 obj
-% page stream
-<< /Length 7588 >>
-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
+1 0 0 1 62.69291 629.8236 cm
q
0 0 0 rg
BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL .691654 Tw (Here is an example of usage. Suppose one wants to write some data to an external resource which can) Tj T* 0 Tw .21683 Tw (be accessed by a single user at once \(for instance a printer\). Then the access to the writing function must) Tj T* 0 Tw (be locked. Here is a minimalistic example:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 575.8236 cm
+1 0 0 1 62.69291 476.6236 cm
q
q
1 0 0 1 0 0 cm
@@ -2735,20 +2770,20 @@ q
n -6 -6 468.6898 144 re B*
Q
q
-BT 1 0 0 1 0 122 Tm 12 TL /F4 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj (async) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (Async) Tj (\() Tj (threading) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Thread) Tj (\)) Tj T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj (datalist) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj ([]) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# for simplicity the written data are stored into a list.) Tj /F4 10 Tf 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@async) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (write) Tj 0 0 0 rg (\() Tj (data) Tj (\):) Tj T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# append data to the datalist by locking) Tj /F4 10 Tf 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (with) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (threading) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Lock) Tj (\(\):) Tj T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# emulate some long running operation) Tj /F4 10 Tf 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj (datalist) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (append) Tj (\() Tj (data) Tj (\)) Tj T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# other operations not requiring a lock here) Tj T* ET
+BT 1 0 0 1 0 122 Tm 12 TL /F4 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj (async) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (decorator) Tj (\() Tj (Async) Tj (\() Tj (threading) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Thread) Tj (\)\)) Tj T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj (datalist) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj ([]) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# for simplicity the written data are stored into a list.) Tj /F4 10 Tf 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@async) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (write) Tj 0 0 0 rg (\() Tj (data) Tj (\):) Tj T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# append data to the datalist by locking) Tj /F4 10 Tf 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (with) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (threading) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Lock) Tj (\(\):) Tj T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# emulate some long running operation) Tj /F4 10 Tf 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj (datalist) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (append) Tj (\() Tj (data) Tj (\)) Tj T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# other operations not requiring a lock here) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 543.8236 cm
+1 0 0 1 62.69291 444.6236 cm
q
BT 1 0 0 1 0 14 Tm .905868 Tw 12 TL /F1 10 Tf 0 0 0 rg (Each call to ) Tj /F4 10 Tf (write ) Tj /F1 10 Tf (will create a new writer thread, but there will be no synchronization problems since) Tj T* 0 Tw /F4 10 Tf (write ) Tj /F1 10 Tf (is locked.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 378.6236 cm
+1 0 0 1 62.69291 279.4236 cm
q
q
1 0 0 1 0 0 cm
@@ -2768,25 +2803,124 @@ Q
Q
Q
q
-1 0 0 1 62.69291 345.6236 cm
+1 0 0 1 62.69291 246.4236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (contextmanager) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 216.4236 cm
+q
+BT 1 0 0 1 0 14 Tm 2.685984 Tw 12 TL /F1 10 Tf 0 0 0 rg (For a long time Python had in its standard library a ) Tj /F4 10 Tf (contextmanager ) Tj /F1 10 Tf (decorator, able to convert) Tj T* 0 Tw (generator functions into ) Tj /F4 10 Tf (GeneratorContextManager ) Tj /F1 10 Tf (factories. For instance if you write) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 123.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 84 re B*
+Q
+q
+BT 1 0 0 1 0 62 Tm 12 TL /F4 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (from) Tj /F4 10 Tf 0 0 0 rg ( ) Tj /F3 10 Tf 0 0 1 rg (contextlib) Tj /F4 10 Tf 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (import) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (contextmanager) Tj T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@contextmanager) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (before_after) Tj 0 0 0 rg (\() Tj (before) Tj (,) Tj ( ) Tj (after) Tj (\):) Tj T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (print) Tj /F4 10 Tf 0 0 0 rg (\() Tj (before) Tj (\)) Tj T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (yield) Tj /F4 10 Tf 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (print) Tj /F4 10 Tf 0 0 0 rg (\() Tj (after) Tj (\)) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 91.22362 cm
+q
+BT 1 0 0 1 0 14 Tm .150888 Tw 12 TL /F1 10 Tf 0 0 0 rg (then ) Tj /F4 10 Tf (before_after ) Tj /F1 10 Tf (is a factory function returning ) Tj /F4 10 Tf (GeneratorContextManager ) Tj /F1 10 Tf (objects which can be) Tj T* 0 Tw (used with the ) Tj /F4 10 Tf (with ) Tj /F1 10 Tf (statement:) Tj T* ET
+Q
+Q
+
+endstream
+endobj
+% 'R93': class PDFStream
+93 0 obj
+% page stream
+<< /Length 7180 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 655.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 108 re B*
+Q
+q
+BT 1 0 0 1 0 86 Tm 12 TL /F4 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj (ba) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (before_after) Tj (\() Tj .729412 .129412 .129412 rg ('BEFORE') Tj 0 0 0 rg (,) Tj ( ) Tj .729412 .129412 .129412 rg ('AFTER') Tj 0 0 0 rg (\)) Tj T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (type) Tj 0 0 0 rg (\() Tj (ba) Tj (\)) Tj T* .4 .4 .4 rg (<) Tj /F3 10 Tf 0 .501961 0 rg (class) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (') Tj /F3 10 Tf 0 0 1 rg (contextlib) Tj /F4 10 Tf .4 .4 .4 rg (.) Tj 0 0 0 rg (GeneratorContextManager) Tj .729412 .129412 .129412 rg (') Tj (>) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (with) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (ba) Tj (:) Tj T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (print) Tj /F4 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('hello') Tj 0 0 0 rg T* (BEFORE) Tj T* (hello) Tj T* (AFTER) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 611.8236 cm
+q
+BT 1 0 0 1 0 26 Tm .462488 Tw 12 TL /F1 10 Tf 0 0 0 rg (Basically, it is as if the content of the ) Tj /F4 10 Tf (with ) Tj /F1 10 Tf (block was executed in the place of the ) Tj /F4 10 Tf (yield ) Tj /F1 10 Tf (expression in) Tj T* 0 Tw 2.691797 Tw (the generator function. In Python 3.2 ) Tj /F4 10 Tf (GeneratorContextManager ) Tj /F1 10 Tf (objects were enhanced with a) Tj T* 0 Tw /F4 10 Tf (__call__ ) Tj /F1 10 Tf (method, so that they can be used as decorators as in this example:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 494.6236 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 108 re B*
+Q
+q
+BT 1 0 0 1 0 86 Tm 12 TL /F4 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@ba) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (hello) Tj 0 0 0 rg (\(\):) Tj T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (print) Tj /F4 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('hello') Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj (hello) Tj (\(\)) Tj T* (BEFORE) Tj T* (hello) Tj T* (AFTER) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 366.6236 cm
+q
+BT 1 0 0 1 0 110 Tm .20561 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F4 10 Tf (ba ) Tj /F1 10 Tf (decorator is basically inserting a ) Tj /F4 10 Tf (with) Tj ( ) Tj (ba: ) Tj /F1 10 Tf (block inside the function. However there two issues:) Tj T* 0 Tw 1.402126 Tw (the first is that ) Tj /F4 10 Tf (GeneratorContextManager ) Tj /F1 10 Tf (objects are callable only in Python 3.2, so the previous) Tj T* 0 Tw .356905 Tw (example will break in older versions of Python; the second is that ) Tj /F4 10 Tf (GeneratorContextManager ) Tj /F1 10 Tf (objects) Tj T* 0 Tw .57561 Tw (do not preserve the signature of the decorated functions: the decorated ) Tj /F4 10 Tf (hello ) Tj /F1 10 Tf (function here will have a) Tj T* 0 Tw 3.990814 Tw (generic signature ) Tj /F4 10 Tf (hello\(*args,) Tj ( ) Tj (**kwargs\) ) Tj /F1 10 Tf (but will break when called with more than zero) Tj T* 0 Tw 7.708314 Tw (arguments. For such reasons the decorator module, starting with release 3.4, offers a) Tj T* 0 Tw .616647 Tw /F4 10 Tf (decorator.contextmanager ) Tj /F1 10 Tf (decorator that solves both problems and works even in Python 2.5. The) Tj T* 0 Tw .34998 Tw (usage is the same and factories decorated with ) Tj /F4 10 Tf (decorator.contextmanager ) Tj /F1 10 Tf (will returns instances of) Tj T* 0 Tw 4.152823 Tw /F4 10 Tf (ContextManager) Tj /F1 10 Tf (, a subclass of ) Tj /F4 10 Tf (contextlib.GeneratorContextManager ) Tj /F1 10 Tf (with a ) Tj /F4 10 Tf (__call__) Tj T* 0 Tw /F1 10 Tf (method acting as a signature-preserving decorator.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 333.6236 cm
q
BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (The ) Tj /F3 17.5 Tf (FunctionMaker ) Tj /F2 17.5 Tf (class) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 279.6236 cm
+1 0 0 1 62.69291 267.6236 cm
q
BT 1 0 0 1 0 50 Tm 2.241412 Tw 12 TL /F1 10 Tf 0 0 0 rg (You may wonder about how the functionality of the ) Tj /F4 10 Tf (decorator ) Tj /F1 10 Tf (module is implemented. The basic) Tj T* 0 Tw 1.545868 Tw (building block is a ) Tj /F4 10 Tf (FunctionMaker ) Tj /F1 10 Tf (class which is able to generate on the fly functions with a given) Tj T* 0 Tw .047485 Tw (name and signature from a function template passed as a string. Generally speaking, you should not need) Tj T* 0 Tw 1.164983 Tw (to resort to ) Tj /F4 10 Tf (FunctionMaker ) Tj /F1 10 Tf (when writing ordinary decorators, but it is handy in some circumstances.) Tj T* 0 Tw (You will see an example shortly, in the implementation of a cool decorator utility \() Tj /F4 10 Tf (decorator_apply) Tj /F1 10 Tf (\).) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 237.6236 cm
+1 0 0 1 62.69291 225.6236 cm
q
BT 1 0 0 1 0 26 Tm .414597 Tw 12 TL /F4 10 Tf 0 0 0 rg (FunctionMaker ) Tj /F1 10 Tf (provides a ) Tj /F4 10 Tf (.create ) Tj /F1 10 Tf (classmethod which takes as input the name, signature, and body) Tj T* 0 Tw .632927 Tw (of the function we want to generate as well as the execution environment were the function is generated) Tj T* 0 Tw (by ) Tj /F4 10 Tf (exec) Tj /F1 10 Tf (. Here is an example:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 144.4236 cm
+1 0 0 1 62.69291 132.4236 cm
q
q
1 0 0 1 0 0 cm
@@ -2806,40 +2940,34 @@ Q
Q
Q
q
-1 0 0 1 62.69291 112.4236 cm
+1 0 0 1 62.69291 100.4236 cm
q
BT 1 0 0 1 0 14 Tm .226654 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is important to notice that the function body is interpolated before being executed, so be careful with the) Tj T* 0 Tw /F4 10 Tf (% ) Tj /F1 10 Tf (sign!) Tj T* ET
Q
Q
-q
-1 0 0 1 62.69291 82.42362 cm
-q
-BT 1 0 0 1 0 14 Tm 1.995433 Tw 12 TL /F4 10 Tf 0 0 0 rg (FunctionMaker.create ) Tj /F1 10 Tf (also accepts keyword arguments and such arguments are attached to the ) Tj T* 0 Tw 1.64686 Tw (resulting function. This is useful if you want to set some function attributes, for instance the docstring) Tj T* 0 Tw ET
-Q
-Q
endstream
endobj
-% 'R90': class PDFStream
-90 0 obj
+% 'R94': class PDFStream
+94 0 obj
% page stream
-<< /Length 7391 >>
+<< /Length 7802 >>
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 62.69291 729.0236 cm
q
-BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (__doc__) Tj /F1 10 Tf (.) Tj T* ET
+BT 1 0 0 1 0 26 Tm 1.995433 Tw 12 TL /F4 10 Tf 0 0 0 rg (FunctionMaker.create ) Tj /F1 10 Tf (also accepts keyword arguments and such arguments are attached to the) Tj T* 0 Tw 1.64686 Tw (resulting function. This is useful if you want to set some function attributes, for instance the docstring) Tj T* 0 Tw /F4 10 Tf (__doc__) Tj /F1 10 Tf (.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 711.0236 cm
+1 0 0 1 62.69291 687.0236 cm
q
BT 1 0 0 1 0 26 Tm .605318 Tw 12 TL /F1 10 Tf 0 0 0 rg (For debugging/introspection purposes it may be useful to see the source code of the generated function;) Tj T* 0 Tw 2.246235 Tw (to do that, just pass the flag ) Tj /F4 10 Tf (addsource=True ) Tj /F1 10 Tf (and a ) Tj /F4 10 Tf (__source__ ) Tj /F1 10 Tf (attribute will be added to the) Tj T* 0 Tw (generated function:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 617.8236 cm
+1 0 0 1 62.69291 593.8236 cm
q
q
1 0 0 1 0 0 cm
@@ -2859,31 +2987,31 @@ Q
Q
Q
q
-1 0 0 1 62.69291 477.8236 cm
+1 0 0 1 62.69291 453.8236 cm
q
BT 1 0 0 1 0 122 Tm .870651 Tw 12 TL /F4 10 Tf 0 0 0 rg (FunctionMaker.create ) Tj /F1 10 Tf (can take as first argument a string, as in the examples before, or a function.) Tj T* 0 Tw .224985 Tw (This is the most common usage, since typically you want to decorate a pre-existing function. A framework) Tj T* 0 Tw 1.606136 Tw (author may want to use directly ) Tj /F4 10 Tf (FunctionMaker.create ) Tj /F1 10 Tf (instead of ) Tj /F4 10 Tf (decorator) Tj /F1 10 Tf (, since it gives you) Tj T* 0 Tw 1.36686 Tw (direct access to the body of the generated function. For instance, suppose you want to instrument the) Tj T* 0 Tw .372209 Tw /F4 10 Tf (__init__ ) Tj /F1 10 Tf (methods of a set of classes, by preserving their signature \(such use case is not made up; this) Tj T* 0 Tw .673828 Tw (is done in SQAlchemy and in other frameworks\). When the first argument of ) Tj /F4 10 Tf (FunctionMaker.create) Tj T* 0 Tw 3.405814 Tw /F1 10 Tf (is a function, a ) Tj /F4 10 Tf (FunctionMaker ) Tj /F1 10 Tf (object is instantiated internally, with attributes ) Tj /F4 10 Tf (args) Tj /F1 10 Tf (, ) Tj /F4 10 Tf (varargs) Tj /F1 10 Tf (,) Tj T* 0 Tw 5.509982 Tw /F4 10 Tf (keywords ) Tj /F1 10 Tf (and ) Tj /F4 10 Tf (defaults ) Tj /F1 10 Tf (which are the the return values of the standard library function) Tj T* 0 Tw .561318 Tw /F4 10 Tf (inspect.getargspec) Tj /F1 10 Tf (. For each argument in the ) Tj /F4 10 Tf (args ) Tj /F1 10 Tf (\(which is a list of strings containing the names) Tj T* 0 Tw 1.599985 Tw (of the mandatory arguments\) an attribute ) Tj /F4 10 Tf (arg0) Tj /F1 10 Tf (, ) Tj /F4 10 Tf (arg1) Tj /F1 10 Tf (, ..., ) Tj /F4 10 Tf (argN ) Tj /F1 10 Tf (is also generated. Finally, there is a) Tj T* 0 Tw /F4 10 Tf (signature ) Tj /F1 10 Tf (attribute, a string with the signature of the original function.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 399.8236 cm
+1 0 0 1 62.69291 375.8236 cm
q
BT 1 0 0 1 0 62 Tm 4.63311 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that while I do not have plans to change or remove the functionality provided in the) Tj T* 0 Tw 1.00936 Tw /F4 10 Tf (FunctionMaker ) Tj /F1 10 Tf (class, I do not guarantee that it will stay unchanged forever. For instance, right now I) Tj T* 0 Tw .791318 Tw (am using the traditional string interpolation syntax for function templates, but Python 2.6 and Python 3.0) Tj T* 0 Tw .712093 Tw (provide a newer interpolation syntax and I may use the new syntax in the future. On the other hand, the) Tj T* 0 Tw .639985 Tw (functionality provided by ) Tj /F4 10 Tf (decorator ) Tj /F1 10 Tf (has been there from version 0.1 and it is guaranteed to stay there) Tj T* 0 Tw (forever.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 366.8236 cm
+1 0 0 1 62.69291 342.8236 cm
q
BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Getting the source code) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 288.8236 cm
+1 0 0 1 62.69291 264.8236 cm
q
-BT 1 0 0 1 0 62 Tm 5.045529 Tw 12 TL /F1 10 Tf 0 0 0 rg (Internally ) Tj /F4 10 Tf (FunctionMaker.create ) Tj /F1 10 Tf (uses ) Tj /F4 10 Tf (exec ) Tj /F1 10 Tf (to generate the decorated function. Therefore) Tj T* 0 Tw 2.542126 Tw /F4 10 Tf (inspect.getsource ) Tj /F1 10 Tf (will not work for decorated functions. That means that the usual '??' trick in) Tj T* 0 Tw 2.163059 Tw (IPython will give you the \(right on the spot\) message ) Tj /F4 10 Tf (Dynamically generated function. No) Tj T* 0 Tw .563314 Tw (source code available) Tj /F1 10 Tf (. In the past I have considered this acceptable, since ) Tj /F4 10 Tf (inspect.getsource) Tj T* 0 Tw 1.790697 Tw /F1 10 Tf (does not really work even with regular decorators. In that case ) Tj /F4 10 Tf (inspect.getsource ) Tj /F1 10 Tf (gives you the) Tj T* 0 Tw (wrapper source code which is probably not what you want:) Tj T* ET
+BT 1 0 0 1 0 62 Tm 5.045529 Tw 12 TL /F1 10 Tf 0 0 0 rg (Internally ) Tj /F4 10 Tf (FunctionMaker.create ) Tj /F1 10 Tf (uses ) Tj /F4 10 Tf (exec ) Tj /F1 10 Tf (to generate the decorated function. Therefore) Tj T* 0 Tw 2.542126 Tw /F4 10 Tf (inspect.getsource ) Tj /F1 10 Tf (will not work for decorated functions. That means that the usual '??' trick in) Tj T* 0 Tw 26.45775 Tw (IPython will give you the \(right on the spot\) message) Tj T* 0 Tw .261647 Tw /F4 10 Tf (Dynamically) Tj ( ) Tj (generated) Tj ( ) Tj (function.) Tj ( ) Tj (No) Tj ( ) Tj (source) Tj ( ) Tj (code available) Tj /F1 10 Tf (. In the past I have considered) Tj T* 0 Tw .945366 Tw (this acceptable, since ) Tj /F4 10 Tf (inspect.getsource ) Tj /F1 10 Tf (does not really work even with regular decorators. In that) Tj T* 0 Tw (case ) Tj /F4 10 Tf (inspect.getsource ) Tj /F1 10 Tf (gives you the wrapper source code which is probably not what you want:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 219.6236 cm
+1 0 0 1 62.69291 195.6236 cm
q
q
1 0 0 1 0 0 cm
@@ -2896,15 +3024,14 @@ q
n -6 -6 468.6898 60 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 38 Tm /F4 10 Tf 12 TL (def identity_dec\(func\):) Tj T* ( def wrapper\(*args, **kw\):) Tj T* ( return func\(*args, **kw\)) Tj T* ( return wrapper) Tj T* ET
+BT 1 0 0 1 0 38 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (identity_dec) Tj 0 0 0 rg (\() Tj (func) Tj (\):) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (wrapper) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj (,) Tj ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj (\):) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (func) Tj (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj (,) Tj ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj (\)) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (wrapper) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 114.4236 cm
+1 0 0 1 62.69291 90.42362 cm
q
q
1 0 0 1 0 0 cm
@@ -2923,29 +3050,23 @@ Q
Q
Q
Q
-q
-1 0 0 1 62.69291 82.42362 cm
-q
-BT 1 0 0 1 0 14 Tm 1.471235 Tw 12 TL /F1 10 Tf 0 0 0 rg (\(see bug report ) Tj 0 0 .501961 rg (1764286 ) Tj 0 0 0 rg (for an explanation of what is happening\). Unfortunately the bug is still there, ) Tj T* 0 Tw 1.541235 Tw (even in Python 2.7 and 3.1. There is however a workaround. The decorator module adds an attribute) Tj T* 0 Tw ET
-Q
-Q
endstream
endobj
-% 'R91': class PDFStream
-91 0 obj
+% 'R95': class PDFStream
+95 0 obj
% page stream
-<< /Length 5339 >>
+<< /Length 7279 >>
stream
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
+1 0 0 1 62.69291 717.0236 cm
q
-BT 1 0 0 1 0 14 Tm .103984 Tw 12 TL /F4 10 Tf 0 0 0 rg (.__wrapped__ ) Tj /F1 10 Tf (to the decorated function, containing a reference to the original function. The easy way to) Tj T* 0 Tw (get the source code is to call ) Tj /F4 10 Tf (inspect.getsource ) Tj /F1 10 Tf (on the undecorated function:) Tj T* ET
+BT 1 0 0 1 0 38 Tm 1.471235 Tw 12 TL /F1 10 Tf 0 0 0 rg (\(see bug report ) Tj 0 0 .501961 rg (1764286 ) Tj 0 0 0 rg (for an explanation of what is happening\). Unfortunately the bug is still there,) Tj T* 0 Tw 1.541235 Tw (even in Python 2.7 and 3.1. There is however a workaround. The decorator module adds an attribute) Tj T* 0 Tw .103984 Tw /F4 10 Tf (.__wrapped__ ) Tj /F1 10 Tf (to the decorated function, containing a reference to the original function. The easy way to) Tj T* 0 Tw (get the source code is to call ) Tj /F4 10 Tf (inspect.getsource ) Tj /F1 10 Tf (on the undecorated function:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 635.8236 cm
+1 0 0 1 62.69291 611.8236 cm
q
q
1 0 0 1 0 0 cm
@@ -2965,19 +3086,19 @@ Q
Q
Q
q
-1 0 0 1 62.69291 602.8236 cm
+1 0 0 1 62.69291 578.8236 cm
q
BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Dealing with third party decorators) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 548.8236 cm
+1 0 0 1 62.69291 524.8236 cm
q
BT 1 0 0 1 0 38 Tm .321654 Tw 12 TL /F1 10 Tf 0 0 0 rg (Sometimes you find on the net some cool decorator that you would like to include in your code. However,) Tj T* 0 Tw .50061 Tw (more often than not the cool decorator is not signature-preserving. Therefore you may want an easy way) Tj T* 0 Tw 1.814597 Tw (to upgrade third party decorators to signature-preserving decorators without having to rewrite them in) Tj T* 0 Tw (terms of ) Tj /F4 10 Tf (decorator) Tj /F1 10 Tf (. You can use a ) Tj /F4 10 Tf (FunctionMaker ) Tj /F1 10 Tf (to implement that functionality as follows:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 431.6236 cm
+1 0 0 1 62.69291 407.6236 cm
q
q
1 0 0 1 0 0 cm
@@ -2990,27 +3111,26 @@ q
n -6 -6 468.6898 108 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 86 Tm /F4 10 Tf 12 TL (def decorator_apply\(dec, func\):) Tj T* ( """) Tj T* ( Decorate a function by preserving the signature even if dec) Tj T* ( is not a signature-preserving decorator.) Tj T* ( """) Tj T* ( return FunctionMaker.create\() Tj T* ( func, 'return decorated\(%\(signature\)s\)',) Tj T* ( dict\(decorated=dec\(func\)\), __wrapped__=func\)) Tj T* ET
+BT 1 0 0 1 0 86 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (decorator_apply) Tj 0 0 0 rg (\() Tj (dec) Tj (,) Tj ( ) Tj (func) Tj (\):) Tj T* ( ) Tj /F6 10 Tf .729412 .129412 .129412 rg (""") Tj T* ( Decorate a function by preserving the signature even if dec) Tj T* ( is not a signature-preserving decorator.) Tj T* ( """) Tj /F4 10 Tf 0 0 0 rg T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (FunctionMaker) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (create) Tj (\() Tj T* ( ) Tj (func) Tj (,) Tj ( ) Tj .729412 .129412 .129412 rg ('return decorated\() Tj /F3 10 Tf .733333 .4 .533333 rg (%\(signature\)s) Tj /F4 10 Tf .729412 .129412 .129412 rg (\)') Tj 0 0 0 rg (,) Tj T* ( ) Tj 0 .501961 0 rg (dict) Tj 0 0 0 rg (\() Tj (decorated) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (dec) Tj (\() Tj (func) Tj (\)\),) Tj ( ) Tj (__wrapped__) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (func) Tj (\)) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 399.6236 cm
+1 0 0 1 62.69291 375.6236 cm
q
BT 1 0 0 1 0 14 Tm .698314 Tw 12 TL /F4 10 Tf 0 0 0 rg (decorator_apply ) Tj /F1 10 Tf (sets the attribute ) Tj /F4 10 Tf (.__wrapped__ ) Tj /F1 10 Tf (of the generated function to the original function,) Tj T* 0 Tw (so that you can get the right source code.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 357.6236 cm
+1 0 0 1 62.69291 333.6236 cm
q
BT 1 0 0 1 0 26 Tm .13104 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that I am not providing this functionality in the ) Tj /F4 10 Tf (decorator ) Tj /F1 10 Tf (module directly since I think it is best to) Tj T* 0 Tw 2.070751 Tw (rewrite the decorator rather than adding an additional level of indirection. However, practicality beats) Tj T* 0 Tw (purity, so you can add ) Tj /F4 10 Tf (decorator_apply ) Tj /F1 10 Tf (to your toolbox and use it if you need to.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 303.6236 cm
+1 0 0 1 62.69291 279.6236 cm
q
BT 1 0 0 1 0 38 Tm 1.74881 Tw 12 TL /F1 10 Tf 0 0 0 rg (In order to give an example of usage of ) Tj /F4 10 Tf (decorator_apply) Tj /F1 10 Tf (, I will show a pretty slick decorator that) Tj T* 0 Tw 1.276651 Tw (converts a tail-recursive function in an iterative function. I have shamelessly stolen the basic idea from) Tj T* 0 Tw 43.62829 Tw (Kay Schluehr's recipe in the Python Cookbook,) Tj T* 0 Tw 0 0 .501961 rg (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691) Tj 0 0 0 rg (.) Tj T* ET
Q
@@ -3026,11 +3146,10 @@ q
.662745 .662745 .662745 RG
.5 w
.960784 .960784 .862745 rg
-n -6 -6 468.6898 216 re B*
+n -6 -6 468.6898 192 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 194 Tm /F4 10 Tf 12 TL (class TailRecursive\(object\):) Tj T* ( """) Tj T* ( tail_recursive decorator based on Kay Schluehr's recipe) Tj T* ( http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691) Tj T* ( with improvements by me and George Sakkis.) Tj T* ( """) Tj T* T* ( def __init__\(self, func\):) Tj T* ( self.func = func) Tj T* ( self.firstcall = True) Tj T* ( self.CONTINUE = object\(\) # sentinel) Tj T* T* ( def __call__\(self, *args, **kwd\):) Tj T* ( CONTINUE = self.CONTINUE) Tj T* ( if self.firstcall:) Tj T* ( func = self.func) Tj T* ( self.firstcall = False) Tj T* ET
+BT 1 0 0 1 0 170 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (class) Tj /F4 10 Tf 0 0 0 rg ( ) Tj /F3 10 Tf 0 0 1 rg (TailRecursive) Tj /F4 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj T* ( ) Tj /F6 10 Tf .729412 .129412 .129412 rg (""") Tj T* ( tail_recursive decorator based on Kay Schluehr's recipe) Tj T* ( http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691) Tj T* ( with improvements by me and George Sakkis.) Tj T* ( """) Tj /F4 10 Tf 0 0 0 rg T* T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (__init__) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (,) Tj ( ) Tj (func) Tj (\):) Tj T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (func) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (func) Tj T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (firstcall) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (True) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (CONTINUE) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\(\)) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# sentinel) Tj /F4 10 Tf 0 0 0 rg T* T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (__call__) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (,) Tj ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj (,) Tj ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kwd) Tj (\):) Tj T* ( ) Tj (CONTINUE) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (CONTINUE) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (if) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (firstcall) Tj (:) Tj T* ET
Q
Q
Q
@@ -3039,14 +3158,14 @@ Q
endstream
endobj
-% 'R92': class PDFStream
-92 0 obj
+% 'R96': class PDFStream
+96 0 obj
% page stream
-<< /Length 4367 >>
+<< /Length 7146 >>
stream
1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
q
-1 0 0 1 62.69291 607.8236 cm
+1 0 0 1 62.69291 583.8236 cm
q
q
1 0 0 1 0 0 cm
@@ -3056,25 +3175,24 @@ q
.662745 .662745 .662745 RG
.5 w
.960784 .960784 .862745 rg
-n -6 -6 468.6898 156 re B*
+n -6 -6 468.6898 180 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 134 Tm /F4 10 Tf 12 TL ( try:) Tj T* ( while True:) Tj T* ( result = func\(*args, **kwd\)) Tj T* ( if result is CONTINUE: # update arguments) Tj T* ( args, kwd = self.argskwd) Tj T* ( else: # last call) Tj T* ( return result) Tj T* ( finally:) Tj T* ( self.firstcall = True) Tj T* ( else: # return the arguments of the tail call) Tj T* ( self.argskwd = args, kwd) Tj T* ( return CONTINUE) Tj T* ET
+BT 1 0 0 1 0 158 Tm 12 TL /F4 10 Tf 0 0 0 rg ( ) Tj (func) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (func) Tj T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (firstcall) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (False) Tj 0 0 0 rg T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (try) Tj /F4 10 Tf 0 0 0 rg (:) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (while) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (True) Tj 0 0 0 rg (:) Tj T* ( ) Tj (result) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (func) Tj (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj (,) Tj ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kwd) Tj (\)) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (if) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (result) Tj ( ) Tj /F3 10 Tf .666667 .133333 1 rg (is) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (CONTINUE) Tj (:) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# update arguments) Tj /F4 10 Tf 0 0 0 rg T* ( ) Tj (args) Tj (,) Tj ( ) Tj (kwd) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (argskwd) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (else) Tj /F4 10 Tf 0 0 0 rg (:) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# last call) Tj /F4 10 Tf 0 0 0 rg T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (result) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (finally) Tj /F4 10 Tf 0 0 0 rg (:) Tj T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (firstcall) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (True) Tj 0 0 0 rg T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (else) Tj /F4 10 Tf 0 0 0 rg (:) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# return the arguments of the tail call) Tj /F4 10 Tf 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (argskwd) Tj ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj (args) Tj (,) Tj ( ) Tj (kwd) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (CONTINUE) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 587.8236 cm
+1 0 0 1 62.69291 563.8236 cm
q
0 0 0 rg
BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here the decorator is implemented as a class returning callable objects.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 542.6236 cm
+1 0 0 1 62.69291 518.6236 cm
q
q
1 0 0 1 0 0 cm
@@ -3087,22 +3205,21 @@ q
n -6 -6 468.6898 36 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 14 Tm /F4 10 Tf 12 TL (def tail_recursive\(func\):) Tj T* ( return decorator_apply\(TailRecursive, func\)) Tj T* ET
+BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (tail_recursive) Tj 0 0 0 rg (\() Tj (func) Tj (\):) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (decorator_apply) Tj (\() Tj (TailRecursive) Tj (,) Tj ( ) Tj (func) Tj (\)) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 522.6236 cm
+1 0 0 1 62.69291 498.6236 cm
q
0 0 0 rg
BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is how you apply the upgraded decorator to the good old factorial:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 441.4236 cm
+1 0 0 1 62.69291 417.4236 cm
q
q
1 0 0 1 0 0 cm
@@ -3115,15 +3232,14 @@ q
n -6 -6 468.6898 72 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 50 Tm /F4 10 Tf 12 TL (@tail_recursive) Tj T* (def factorial\(n, acc=1\):) Tj T* ( "The good old factorial") Tj T* ( if n == 0: return acc) Tj T* ( return factorial\(n-1, n*acc\)) Tj T* ET
+BT 1 0 0 1 0 50 Tm 12 TL /F4 10 Tf .666667 .133333 1 rg (@tail_recursive) Tj 0 0 0 rg T* /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (factorial) Tj 0 0 0 rg (\() Tj (n) Tj (,) Tj ( ) Tj (acc) Tj .4 .4 .4 rg (=) Tj (1) Tj 0 0 0 rg (\):) Tj T* ( ) Tj .729412 .129412 .129412 rg ("The good old factorial") Tj 0 0 0 rg T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (if) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (n) Tj ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (:) Tj ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (acc) Tj T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (factorial) Tj (\() Tj (n) Tj .4 .4 .4 rg (-) Tj (1) Tj 0 0 0 rg (,) Tj ( ) Tj (n) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (acc) Tj (\)) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 396.2236 cm
+1 0 0 1 62.69291 372.2236 cm
q
q
1 0 0 1 0 0 cm
@@ -3143,13 +3259,13 @@ Q
Q
Q
q
-1 0 0 1 62.69291 340.2236 cm
+1 0 0 1 62.69291 316.2236 cm
q
BT 1 0 0 1 0 38 Tm .188935 Tw 12 TL /F1 10 Tf 0 0 0 rg (This decorator is pretty impressive, and should give you some food for your mind ;\) Notice that there is no) Tj T* 0 Tw 1.339983 Tw (recursion limit now, and you can easily compute ) Tj /F4 10 Tf (factorial\(1001\) ) Tj /F1 10 Tf (or larger without filling the stack) Tj T* 0 Tw .909431 Tw (frame. Notice also that the decorator will not work on functions which are not tail recursive, such as the) Tj T* 0 Tw (following) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 283.0236 cm
+1 0 0 1 62.69291 259.0236 cm
q
q
1 0 0 1 0 0 cm
@@ -3162,28 +3278,27 @@ q
n -6 -6 468.6898 48 re B*
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 26 Tm /F4 10 Tf 12 TL (def fact\(n\): # this is not tail-recursive) Tj T* ( if n == 0: return 1) Tj T* ( return n * fact\(n-1\)) Tj T* ET
+BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (fact) Tj 0 0 0 rg (\() Tj (n) Tj (\):) Tj ( ) Tj /F6 10 Tf .25098 .501961 .501961 rg (# this is not tail-recursive) Tj /F4 10 Tf 0 0 0 rg T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (if) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (n) Tj ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (:) Tj ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg T* ( ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj (n) Tj ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg ( ) Tj (fact) Tj (\() Tj (n) Tj .4 .4 .4 rg (-) Tj (1) Tj 0 0 0 rg (\)) Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 251.0236 cm
+1 0 0 1 62.69291 227.0236 cm
q
0 0 0 rg
BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .541098 Tw (\(reminder: a function is tail recursive if it either returns a value without making a recursive call, or returns) Tj T* 0 Tw (directly the result of a recursive call\).) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 218.0236 cm
+1 0 0 1 62.69291 194.0236 cm
q
BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Caveats and limitations) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 188.0236 cm
+1 0 0 1 62.69291 164.0236 cm
q
0 0 0 rg
BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .474987 Tw (The first thing you should be aware of, it the fact that decorators have a performance penalty. The worse) Tj T* 0 Tw (case is shown by the following example:) Tj T* ET
@@ -3200,11 +3315,11 @@ q
.662745 .662745 .662745 RG
.5 w
.960784 .960784 .862745 rg
-n -6 -6 468.6898 96 re B*
+n -6 -6 468.6898 72 re B*
Q
q
0 0 0 rg
-BT 1 0 0 1 0 74 Tm /F4 10 Tf 12 TL ($ cat performance.sh) Tj T* (python -m timeit -s ") Tj T* (from decorator import decorator) Tj T* T* (@decorator) Tj T* (def do_nothing\(func, *args, **kw\):) Tj T* ( return func\(*args, **kw\)) Tj T* ET
+BT 1 0 0 1 0 50 Tm /F4 10 Tf 12 TL ($ cat performance.sh) Tj T* (python -m timeit -s ") Tj T* (from decorator import decorator) Tj T* T* (@decorator) Tj T* ET
Q
Q
Q
@@ -3213,14 +3328,14 @@ Q
endstream
endobj
-% 'R93': class PDFStream
-93 0 obj
+% 'R97': class PDFStream
+97 0 obj
% page stream
-<< /Length 6135 >>
+<< /Length 6291 >>
stream
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
+1 0 0 1 62.69291 607.8236 cm
q
q
1 0 0 1 0 0 cm
@@ -3230,24 +3345,24 @@ q
.662745 .662745 .662745 RG
.5 w
.960784 .960784 .862745 rg
-n -6 -6 468.6898 132 re B*
+n -6 -6 468.6898 156 re B*
Q
q
0 0 0 rg
-BT 1 0 0 1 0 110 Tm /F4 10 Tf 12 TL T* (@do_nothing) Tj T* (def f\(\):) Tj T* ( pass) Tj T* (" "f\(\)") Tj T* T* (python -m timeit -s ") Tj T* (def f\(\):) Tj T* ( pass) Tj T* (" "f\(\)") Tj T* ET
+BT 1 0 0 1 0 134 Tm /F4 10 Tf 12 TL (def do_nothing\(func, *args, **kw\):) Tj T* ( return func\(*args, **kw\)) Tj T* T* (@do_nothing) Tj T* (def f\(\):) Tj T* ( pass) Tj T* (" "f\(\)") Tj T* T* (python -m timeit -s ") Tj T* (def f\(\):) Tj T* ( pass) Tj T* (" "f\(\)") Tj T* ET
Q
Q
Q
Q
Q
q
-1 0 0 1 62.69291 599.8236 cm
+1 0 0 1 62.69291 575.8236 cm
q
BT 1 0 0 1 0 14 Tm .266235 Tw 12 TL /F1 10 Tf 0 0 0 rg (On my MacBook, using the ) Tj /F4 10 Tf (do_nothing ) Tj /F1 10 Tf (decorator instead of the plain function is more than three times) Tj T* 0 Tw (slower:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 542.6236 cm
+1 0 0 1 62.69291 518.6236 cm
q
q
1 0 0 1 0 0 cm
@@ -3268,20 +3383,20 @@ Q
Q
Q
q
-1 0 0 1 62.69291 498.6236 cm
+1 0 0 1 62.69291 474.6236 cm
q
BT 1 0 0 1 0 26 Tm 1.25832 Tw 12 TL /F1 10 Tf 0 0 0 rg (It should be noted that a real life function would probably do something more useful than ) Tj /F4 10 Tf (f ) Tj /F1 10 Tf (here, and) Tj T* 0 Tw .91811 Tw (therefore in real life the performance penalty could be completely negligible. As always, the only way to) Tj T* 0 Tw (know if there is a penalty in your specific use case is to measure it.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 468.6236 cm
+1 0 0 1 62.69291 444.6236 cm
q
0 0 0 rg
BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .867984 Tw (You should be aware that decorators will make your tracebacks longer and more difficult to understand.) Tj T* 0 Tw (Consider this example:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 411.4236 cm
+1 0 0 1 62.69291 387.4236 cm
q
q
1 0 0 1 0 0 cm
@@ -3301,13 +3416,13 @@ Q
Q
Q
q
-1 0 0 1 62.69291 379.4236 cm
+1 0 0 1 62.69291 355.4236 cm
q
BT 1 0 0 1 0 14 Tm .583318 Tw 12 TL /F1 10 Tf 0 0 0 rg (Calling ) Tj /F4 10 Tf (f\(\) ) Tj /F1 10 Tf (will give you a ) Tj /F4 10 Tf (ZeroDivisionError) Tj /F1 10 Tf (, but since the function is decorated the traceback will) Tj T* 0 Tw (be longer:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 250.2236 cm
+1 0 0 1 62.69291 226.2236 cm
q
q
1 0 0 1 0 0 cm
@@ -3327,13 +3442,13 @@ Q
Q
Q
q
-1 0 0 1 62.69291 182.2236 cm
+1 0 0 1 62.69291 158.2236 cm
q
-BT 1 0 0 1 0 50 Tm 1.05528 Tw 12 TL /F1 10 Tf 0 0 0 rg (You see here the inner call to the decorator ) Tj /F4 10 Tf (trace) Tj /F1 10 Tf (, which calls ) Tj /F4 10 Tf (f\(*args, **kw\)) Tj /F1 10 Tf (, and a reference to) Tj T* 0 Tw .265868 Tw /F4 10 Tf (File ") Tj (<) Tj (string) Tj (>) Tj (", line 2, in f) Tj /F1 10 Tf (. This latter reference is due to the fact that internally the decorator) Tj T* 0 Tw 2.053318 Tw (module uses ) Tj /F4 10 Tf (exec ) Tj /F1 10 Tf (to generate the decorated function. Notice that ) Tj /F4 10 Tf (exec ) Tj /F1 10 Tf (is ) Tj /F5 10 Tf (not ) Tj /F1 10 Tf (responsibile for the) Tj T* 0 Tw 1.507485 Tw (performance penalty, since is the called ) Tj /F5 10 Tf (only once ) Tj /F1 10 Tf (at function decoration time, and not every time the) Tj T* 0 Tw (decorated function is called.) Tj T* ET
+BT 1 0 0 1 0 50 Tm 1.05528 Tw 12 TL /F1 10 Tf 0 0 0 rg (You see here the inner call to the decorator ) Tj /F4 10 Tf (trace) Tj /F1 10 Tf (, which calls ) Tj /F4 10 Tf (f\(*args,) Tj ( ) Tj (**kw\)) Tj /F1 10 Tf (, and a reference to) Tj T* 0 Tw .076457 Tw /F4 10 Tf (File) Tj ( ) Tj (") Tj (<) Tj (string) Tj (>) Tj (",) Tj ( ) Tj (line) Tj ( ) Tj (2,) Tj ( ) Tj (in) Tj ( ) Tj (f) Tj /F1 10 Tf (. This latter reference is due to the fact that internally the decorator) Tj T* 0 Tw 2.053318 Tw (module uses ) Tj /F4 10 Tf (exec ) Tj /F1 10 Tf (to generate the decorated function. Notice that ) Tj /F4 10 Tf (exec ) Tj /F1 10 Tf (is ) Tj /F5 10 Tf (not ) Tj /F1 10 Tf (responsibile for the) Tj T* 0 Tw 1.507485 Tw (performance penalty, since is the called ) Tj /F5 10 Tf (only once ) Tj /F1 10 Tf (at function decoration time, and not every time the) Tj T* 0 Tw (decorated function is called.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 104.2236 cm
+1 0 0 1 62.69291 80.22362 cm
q
BT 1 0 0 1 0 62 Tm .932209 Tw 12 TL /F1 10 Tf 0 0 0 rg (At present, there is no clean way to avoid ) Tj /F4 10 Tf (exec) Tj /F1 10 Tf (. A clean solution would require to change the CPython) Tj T* 0 Tw .777485 Tw (implementation of functions and add an hook to make it possible to change their signature directly. That) Tj T* 0 Tw .74186 Tw (could happen in future versions of Python \(see PEP ) Tj 0 0 .501961 rg (362) Tj 0 0 0 rg (\) and then the decorator module would become) Tj T* 0 Tw 2.385318 Tw (obsolete. However, at present, even in Python 3.1 it is impossible to change the function signature) Tj T* 0 Tw .931751 Tw (directly, therefore the ) Tj /F4 10 Tf (decorator ) Tj /F1 10 Tf (module is still useful. Actually, this is one of the main reasons why I) Tj T* 0 Tw (keep maintaining the module and releasing new versions.) Tj T* ET
Q
@@ -3341,10 +3456,10 @@ Q
endstream
endobj
-% 'R94': class PDFStream
-94 0 obj
+% 'R98': class PDFStream
+98 0 obj
% page stream
-<< /Length 7992 >>
+<< /Length 8028 >>
stream
1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
q
@@ -3456,7 +3571,7 @@ Q
q
1 0 0 1 62.69291 240.2236 cm
q
-BT 1 0 0 1 0 26 Tm .194651 Tw 12 TL /F1 10 Tf 0 0 0 rg (Finally, the implementation is such that the decorated function attribute ) Tj /F4 10 Tf (.func_globals ) Tj /F1 10 Tf (is a ) Tj /F5 10 Tf (copy ) Tj /F1 10 Tf (of the) Tj T* 0 Tw 2.966136 Tw (original function attribute. Moreover the decorated function contains a ) Tj /F5 10 Tf (copy ) Tj /F1 10 Tf (of the original function) Tj T* 0 Tw (dictionary \() Tj /F4 10 Tf (vars\(decorated_f\) is not vars\(f\)) Tj /F1 10 Tf (\):) Tj T* ET
+BT 1 0 0 1 0 26 Tm .194651 Tw 12 TL /F1 10 Tf 0 0 0 rg (Finally, the implementation is such that the decorated function attribute ) Tj /F4 10 Tf (.func_globals ) Tj /F1 10 Tf (is a ) Tj /F5 10 Tf (copy ) Tj /F1 10 Tf (of the) Tj T* 0 Tw 2.966136 Tw (original function attribute. Moreover the decorated function contains a ) Tj /F5 10 Tf (copy ) Tj /F1 10 Tf (of the original function) Tj T* 0 Tw (dictionary \() Tj /F4 10 Tf (vars\(decorated_f\)) Tj ( ) Tj (is) Tj ( ) Tj (not) Tj ( ) Tj (vars\(f\)) Tj /F1 10 Tf (\):) Tj T* ET
Q
Q
q
@@ -3482,10 +3597,10 @@ Q
endstream
endobj
-% 'R95': class PDFStream
-95 0 obj
+% 'R99': class PDFStream
+99 0 obj
% page stream
-<< /Length 5888 >>
+<< /Length 6552 >>
stream
1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
q
@@ -3531,44 +3646,49 @@ BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (LICENCE) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 363.0236 cm
+1 0 0 1 62.69291 375.0236 cm
q
0 0 0 rg
-BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.328555 Tw (Redistribution and use in source and binary forms, with or without modification, are permitted provided) Tj T* 0 Tw (that the following conditions are met:) Tj T* ET
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Copyright \(c\) 2005-2012, Michele Simionato All rights reserved.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 77.82362 cm
+1 0 0 1 62.69291 345.0236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.328555 Tw (Redistribution and use in source and binary forms, with or without modification, are permitted provided) Tj T* 0 Tw (that the following conditions are met:) Tj T* ET
+Q
+Q
q
+1 0 0 1 62.69291 339.0236 cm
+Q
q
-1 0 0 1 0 0 cm
+1 0 0 1 62.69291 291.0236 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 6.6 6.6 cm
+1 0 0 1 20 0 cm
q
-.662745 .662745 .662745 RG
-.5 w
-.960784 .960784 .862745 rg
-n -6 -6 468.6898 276 re B*
+0 0 0 rg
+BT 1 0 0 1 0 38 Tm /F1 10 Tf 12 TL .830651 Tw (Redistributions of source code must retain the above copyright notice, this list of conditions and the) Tj T* 0 Tw .161647 Tw (following disclaimer. Redistributions in bytecode form must reproduce the above copyright notice, this) Tj T* 0 Tw 1.259213 Tw (list of conditions and the following disclaimer in the documentation and/or other materials provided) Tj T* 0 Tw (with the distribution.) Tj T* ET
+Q
Q
q
-0 0 0 rg
-BT 1 0 0 1 0 254 Tm /F4 10 Tf 12 TL (Copyright \(c\) 2005, Michele Simionato) Tj T* (All rights reserved.) Tj T* T* (Redistributions of source code must retain the above copyright) Tj T* (notice, this list of conditions and the following disclaimer.) Tj T* (Redistributions in bytecode form must reproduce the above copyright) Tj T* (notice, this list of conditions and the following disclaimer in) Tj T* (the documentation and/or other materials provided with the) Tj T* (distribution.) Tj T* T* (THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS) Tj T* ("AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT) Tj T* (LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR) Tj T* (A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT) Tj T* (HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,) Tj T* (INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \(INCLUDING,) Tj T* (BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS) Tj T* (OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION\) HOWEVER CAUSED AND) Tj T* (ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR) Tj T* (TORT \(INCLUDING NEGLIGENCE OR OTHERWISE\) ARISING IN ANY WAY OUT OF THE) Tj T* (USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH) Tj T* (DAMAGE.) Tj T* ET
Q
Q
+q
+1 0 0 1 62.69291 291.0236 cm
Q
+q
+1 0 0 1 62.69291 165.0236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 110 Tm /F1 10 Tf 12 TL .17998 Tw (THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND) Tj T* 0 Tw 2.911797 Tw (ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED) Tj T* 0 Tw 5.165529 Tw (WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE) Tj T* 0 Tw 1.395433 Tw (DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE) Tj T* 0 Tw 5.53122 Tw (FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL) Tj T* 0 Tw 2.705976 Tw (DAMAGES \(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR) Tj T* 0 Tw 3.868976 Tw (SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION\) HOWEVER) Tj T* 0 Tw 1.326647 Tw (CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR) Tj T* 0 Tw 1.525366 Tw (TORT \(INCLUDING NEGLIGENCE OR OTHERWISE\) ARISING IN ANY WAY OUT OF THE USE OF) Tj T* 0 Tw (THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.) Tj T* ET
Q
Q
-
-endstream
-endobj
-% 'R96': class PDFStream
-96 0 obj
-% page stream
-<< /Length 361 >>
-stream
-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
+1 0 0 1 62.69291 135.0236 cm
q
0 0 0 rg
BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .407132 Tw (If you use this software and you are happy with it, consider sending me a note, just to gratify my ego. On) Tj T* 0 Tw (the other hand, if you use this software and you are unhappy with it, send me a patch!) Tj T* ET
@@ -3577,132 +3697,132 @@ Q
endstream
endobj
-% 'R97': class PDFPageLabels
-97 0 obj
+% 'R100': class PDFPageLabels
+100 0 obj
% Document Root
<< /Nums [ 0
- 98 0 R
+ 101 0 R
1
- 99 0 R
+ 102 0 R
2
- 100 0 R
+ 103 0 R
3
- 101 0 R
+ 104 0 R
4
- 102 0 R
+ 105 0 R
5
- 103 0 R
+ 106 0 R
6
- 104 0 R
+ 107 0 R
7
- 105 0 R
+ 108 0 R
8
- 106 0 R
+ 109 0 R
9
- 107 0 R
+ 110 0 R
10
- 108 0 R
+ 111 0 R
11
- 109 0 R
+ 112 0 R
12
- 110 0 R
+ 113 0 R
13
- 111 0 R
+ 114 0 R
14
- 112 0 R ] >>
-endobj
-% 'R98': class PDFPageLabel
-98 0 obj
-% None
-<< /S /D
- /St 1 >>
-endobj
-% 'R99': class PDFPageLabel
-99 0 obj
-% None
-<< /S /D
- /St 2 >>
-endobj
-% 'R100': class PDFPageLabel
-100 0 obj
-% None
-<< /S /D
- /St 3 >>
+ 115 0 R ] >>
endobj
% 'R101': class PDFPageLabel
101 0 obj
% None
<< /S /D
- /St 4 >>
+ /St 1 >>
endobj
% 'R102': class PDFPageLabel
102 0 obj
% None
<< /S /D
- /St 5 >>
+ /St 2 >>
endobj
% 'R103': class PDFPageLabel
103 0 obj
% None
<< /S /D
- /St 6 >>
+ /St 3 >>
endobj
% 'R104': class PDFPageLabel
104 0 obj
% None
<< /S /D
- /St 7 >>
+ /St 4 >>
endobj
% 'R105': class PDFPageLabel
105 0 obj
% None
<< /S /D
- /St 8 >>
+ /St 5 >>
endobj
% 'R106': class PDFPageLabel
106 0 obj
% None
<< /S /D
- /St 9 >>
+ /St 6 >>
endobj
% 'R107': class PDFPageLabel
107 0 obj
% None
<< /S /D
- /St 10 >>
+ /St 7 >>
endobj
% 'R108': class PDFPageLabel
108 0 obj
% None
<< /S /D
- /St 11 >>
+ /St 8 >>
endobj
% 'R109': class PDFPageLabel
109 0 obj
% None
<< /S /D
- /St 12 >>
+ /St 9 >>
endobj
% 'R110': class PDFPageLabel
110 0 obj
% None
<< /S /D
- /St 13 >>
+ /St 10 >>
endobj
% 'R111': class PDFPageLabel
111 0 obj
% None
<< /S /D
- /St 14 >>
+ /St 11 >>
endobj
% 'R112': class PDFPageLabel
112 0 obj
% None
<< /S /D
+ /St 12 >>
+endobj
+% 'R113': class PDFPageLabel
+113 0 obj
+% None
+<< /S /D
+ /St 13 >>
+endobj
+% 'R114': class PDFPageLabel
+114 0 obj
+% None
+<< /S /D
+ /St 14 >>
+endobj
+% 'R115': class PDFPageLabel
+115 0 obj
+% None
+<< /S /D
/St 15 >>
endobj
xref
-0 113
+0 116
0000000000 65535 f
0000000113 00000 n
0000000271 00000 n
@@ -3739,91 +3859,94 @@ xref
0000007534 00000 n
0000007777 00000 n
0000008020 00000 n
-0000008247 00000 n
-0000008807 00000 n
-0000009002 00000 n
-0000009271 00000 n
-0000009531 00000 n
-0000009843 00000 n
-0000010019 00000 n
-0000010299 00000 n
-0000010579 00000 n
-0000010859 00000 n
-0000011139 00000 n
-0000011419 00000 n
-0000011714 00000 n
-0000011954 00000 n
-0000012270 00000 n
-0000012538 00000 n
-0000012840 00000 n
-0000013135 00000 n
-0000013380 00000 n
-0000013682 00000 n
-0000013977 00000 n
-0000014237 00000 n
-0000014497 00000 n
-0000014755 00000 n
-0000015007 00000 n
-0000015247 00000 n
-0000015554 00000 n
-0000015901 00000 n
-0000016182 00000 n
-0000016341 00000 n
-0000016626 00000 n
-0000016752 00000 n
-0000016925 00000 n
-0000017112 00000 n
-0000017312 00000 n
-0000017500 00000 n
-0000017693 00000 n
-0000017892 00000 n
-0000018076 00000 n
-0000018257 00000 n
-0000018456 00000 n
-0000018656 00000 n
-0000018868 00000 n
-0000019068 00000 n
-0000019264 00000 n
-0000019416 00000 n
-0000019651 00000 n
-0000028910 00000 n
-0000035165 00000 n
-0000042055 00000 n
-0000048913 00000 n
-0000057645 00000 n
-0000063570 00000 n
-0000067243 00000 n
-0000074930 00000 n
-0000082420 00000 n
-0000087858 00000 n
-0000092324 00000 n
-0000098558 00000 n
-0000106649 00000 n
-0000112636 00000 n
-0000113099 00000 n
-0000113392 00000 n
-0000113469 00000 n
-0000113547 00000 n
-0000113626 00000 n
-0000113705 00000 n
-0000113784 00000 n
-0000113863 00000 n
-0000113942 00000 n
-0000114021 00000 n
-0000114100 00000 n
-0000114180 00000 n
-0000114260 00000 n
-0000114340 00000 n
-0000114420 00000 n
-0000114500 00000 n
+0000008263 00000 n
+0000008506 00000 n
+0000008733 00000 n
+0000009311 00000 n
+0000009506 00000 n
+0000009762 00000 n
+0000009953 00000 n
+0000010213 00000 n
+0000010523 00000 n
+0000010803 00000 n
+0000011083 00000 n
+0000011363 00000 n
+0000011643 00000 n
+0000011923 00000 n
+0000012203 00000 n
+0000012484 00000 n
+0000012779 00000 n
+0000013034 00000 n
+0000013302 00000 n
+0000013613 00000 n
+0000013908 00000 n
+0000014153 00000 n
+0000014455 00000 n
+0000014750 00000 n
+0000015010 00000 n
+0000015270 00000 n
+0000015528 00000 n
+0000015780 00000 n
+0000016020 00000 n
+0000016327 00000 n
+0000016674 00000 n
+0000016834 00000 n
+0000017119 00000 n
+0000017245 00000 n
+0000017418 00000 n
+0000017605 00000 n
+0000017805 00000 n
+0000017993 00000 n
+0000018186 00000 n
+0000018385 00000 n
+0000018569 00000 n
+0000018750 00000 n
+0000018940 00000 n
+0000019140 00000 n
+0000019340 00000 n
+0000019552 00000 n
+0000019752 00000 n
+0000019948 00000 n
+0000020100 00000 n
+0000020335 00000 n
+0000029480 00000 n
+0000037125 00000 n
+0000045281 00000 n
+0000052495 00000 n
+0000061446 00000 n
+0000068701 00000 n
+0000076181 00000 n
+0000083501 00000 n
+0000090780 00000 n
+0000098681 00000 n
+0000106059 00000 n
+0000113304 00000 n
+0000119694 00000 n
+0000127821 00000 n
+0000134477 00000 n
+0000134774 00000 n
+0000134853 00000 n
+0000134932 00000 n
+0000135011 00000 n
+0000135090 00000 n
+0000135169 00000 n
+0000135248 00000 n
+0000135327 00000 n
+0000135406 00000 n
+0000135485 00000 n
+0000135565 00000 n
+0000135645 00000 n
+0000135725 00000 n
+0000135805 00000 n
+0000135885 00000 n
trailer
<< /ID
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
- [(z\354v,\321\373&\377\031\261\360~3\304]u) (z\354v,\321\373&\377\031\261\360~3\304]u)]
+ [(%\2119\\+X\235\026\270\000 \364\017F\214k) (%\2119\\+X\235\026\270\000 \364\017F\214k)]
- /Info 65 0 R
- /Root 64 0 R
- /Size 113 >>
+ /Info 67 0 R
+ /Root 66 0 R
+ /Size 116 >>
startxref
-114549
+135934
%%EOF