From 8608a4672a5c4ae390040d56ef049980a144c280 Mon Sep 17 00:00:00 2001 From: Michele Simionato Date: Sun, 15 Jan 2017 10:06:58 +0100 Subject: Tested with Python 3.6 --- .travis.yml | 1 + CHANGES.md | 4 + LICENSE.txt | 2 +- documentation.pdf | 1143 ++++++++++++++++++++++---------------------- src/decorator.py | 39 +- src/tests/documentation.py | 49 +- 6 files changed, 617 insertions(+), 621 deletions(-) diff --git a/.travis.yml b/.travis.yml index b74e64e..1047353 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ python: - "3.3" - "3.4" - "3.5" + - "3.6" install: - python setup.py install diff --git a/CHANGES.md b/CHANGES.md index 2564d99..39ec31a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,10 @@ HISTORY ## Unreleased +## 4.0.11 (2017-01-15) + +Small improvements to the documentation and tested with Python 3.6 + ## 4.0.10 (2016-06-07) Improved the documentation thanks to Tony Goodchild (zearin) who also diff --git a/LICENSE.txt b/LICENSE.txt index 88e0bcc..e9fe3d9 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2005-2015, Michele Simionato +Copyright (c) 2005-2017, Michele Simionato All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/documentation.pdf b/documentation.pdf index f0699db..eba7cbb 100644 --- a/documentation.pdf +++ b/documentation.pdf @@ -8,149 +8,149 @@ endobj << /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >> endobj 3 0 obj -<< /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font >> +<< /BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font >> endobj 4 0 obj -<< /BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font >> +<< /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font >> endobj 5 0 obj -<< /A << /S /URI /Type /Action /URI (mailto:michele.simionato@gmail.com) >> /Border [ 0 0 0 ] /Rect [ 153.7323 704.0236 289.4623 716.0236 ] /Subtype /Link /Type /Annot >> +<< /A << /S /URI /Type /Action /URI (mailto:michele.simionato@gmail.com) >> /Border [ 0 0 0 ] /Rect [ 153.7323 708.7736 289.4623 720.7736 ] /Subtype /Link /Type /Annot >> endobj 6 0 obj -<< /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/decorator/4.0.10) >> /Border [ 0 0 0 ] /Rect [ 153.7323 659.7736 343.8423 671.7736 ] /Subtype /Link /Type /Annot >> +<< /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/decorator/4.0.11) >> /Border [ 0 0 0 ] /Rect [ 153.7323 663.7736 343.8423 675.7736 ] /Subtype /Link /Type /Annot >> endobj 7 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 52 0 R /XYZ 62.69291 765.0236 0 ] /Rect [ 62.69291 560.0236 121.0229 572.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 52 0 R /XYZ 62.69291 765.0236 0 ] /Rect [ 62.69291 564.0236 121.0229 576.0236 ] /Subtype /Link /Type /Annot >> endobj 8 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 52 0 R /XYZ 62.69291 765.0236 0 ] /Rect [ 527.0227 560.7736 532.5827 572.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 52 0 R /XYZ 62.69291 765.0236 0 ] /Rect [ 527.0227 564.7736 532.5827 576.7736 ] /Subtype /Link /Type /Annot >> endobj 9 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 52 0 R /XYZ 62.69291 582.0236 0 ] /Rect [ 62.69291 542.0236 118.4129 554.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 52 0 R /XYZ 62.69291 582.0236 0 ] /Rect [ 62.69291 546.0236 176.7729 558.0236 ] /Subtype /Link /Type /Annot >> endobj 10 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 52 0 R /XYZ 62.69291 582.0236 0 ] /Rect [ 527.0227 542.7736 532.5827 554.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 52 0 R /XYZ 62.69291 582.0236 0 ] /Rect [ 527.0227 546.7736 532.5827 558.7736 ] /Subtype /Link /Type /Annot >> endobj 11 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 52 0 R /XYZ 62.69291 315.0236 0 ] /Rect [ 62.69291 524.0236 182.7229 536.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 52 0 R /XYZ 62.69291 315.0236 0 ] /Rect [ 62.69291 528.0236 182.7229 540.0236 ] /Subtype /Link /Type /Annot >> endobj 12 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 52 0 R /XYZ 62.69291 315.0236 0 ] /Rect [ 527.0227 524.7736 532.5827 536.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 52 0 R /XYZ 62.69291 315.0236 0 ] /Rect [ 527.0227 528.7736 532.5827 540.7736 ] /Subtype /Link /Type /Annot >> endobj 13 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 58 0 R /XYZ 62.69291 699.0236 0 ] /Rect [ 62.69291 506.0236 114.3629 518.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 58 0 R /XYZ 62.69291 699.0236 0 ] /Rect [ 62.69291 510.0236 114.3629 522.0236 ] /Subtype /Link /Type /Annot >> endobj 14 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 58 0 R /XYZ 62.69291 699.0236 0 ] /Rect [ 527.0227 506.7736 532.5827 518.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 58 0 R /XYZ 62.69291 699.0236 0 ] /Rect [ 527.0227 510.7736 532.5827 522.7736 ] /Subtype /Link /Type /Annot >> endobj 15 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 58 0 R /XYZ 62.69291 436.0236 0 ] /Rect [ 62.69291 488.0236 183.2629 500.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 58 0 R /XYZ 62.69291 436.0236 0 ] /Rect [ 62.69291 492.0236 183.2629 504.0236 ] /Subtype /Link /Type /Annot >> endobj 16 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 58 0 R /XYZ 62.69291 436.0236 0 ] /Rect [ 527.0227 488.7736 532.5827 500.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 58 0 R /XYZ 62.69291 436.0236 0 ] /Rect [ 527.0227 492.7736 532.5827 504.7736 ] /Subtype /Link /Type /Annot >> endobj 17 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 59 0 R /XYZ 62.69291 282.2236 0 ] /Rect [ 62.69291 470.0236 122.1429 482.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 59 0 R /XYZ 62.69291 282.2236 0 ] /Rect [ 62.69291 474.0236 122.1429 486.0236 ] /Subtype /Link /Type /Annot >> endobj 18 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 59 0 R /XYZ 62.69291 282.2236 0 ] /Rect [ 527.0227 470.7736 532.5827 482.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 59 0 R /XYZ 62.69291 282.2236 0 ] /Rect [ 527.0227 474.7736 532.5827 486.7736 ] /Subtype /Link /Type /Annot >> endobj 19 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 62.69291 226.2236 0 ] /Rect [ 62.69291 452.0236 69.91291 464.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 62.69291 226.2236 0 ] /Rect [ 62.69291 456.0236 69.91291 468.0236 ] /Subtype /Link /Type /Annot >> endobj 20 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 62.69291 226.2236 0 ] /Rect [ 72.69291 452.0236 102.6929 464.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 62.69291 226.2236 0 ] /Rect [ 72.69291 456.0236 102.6929 468.0236 ] /Subtype /Link /Type /Annot >> endobj 21 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 62.69291 226.2236 0 ] /Rect [ 108.6929 452.0236 154.8129 464.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 62.69291 226.2236 0 ] /Rect [ 108.6929 456.0236 154.8129 468.0236 ] /Subtype /Link /Type /Annot >> endobj 22 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 62.69291 226.2236 0 ] /Rect [ 527.0227 452.7736 532.5827 464.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 62.69291 226.2236 0 ] /Rect [ 527.0227 456.7736 532.5827 468.7736 ] /Subtype /Link /Type /Annot >> endobj 23 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 62 0 R /XYZ 62.69291 359.0236 0 ] /Rect [ 62.69291 434.0236 164.3629 446.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 62 0 R /XYZ 62.69291 359.0236 0 ] /Rect [ 62.69291 438.0236 164.3629 450.0236 ] /Subtype /Link /Type /Annot >> endobj 24 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 62 0 R /XYZ 62.69291 359.0236 0 ] /Rect [ 527.0227 434.7736 532.5827 446.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 62 0 R /XYZ 62.69291 359.0236 0 ] /Rect [ 527.0227 438.7736 532.5827 450.7736 ] /Subtype /Link /Type /Annot >> endobj 25 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 63 0 R /XYZ 62.69291 528.6236 0 ] /Rect [ 62.69291 416.0236 176.6929 428.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 63 0 R /XYZ 62.69291 528.6236 0 ] /Rect [ 62.69291 420.0236 176.6929 432.0236 ] /Subtype /Link /Type /Annot >> endobj 26 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 63 0 R /XYZ 62.69291 528.6236 0 ] /Rect [ 527.0227 416.7736 532.5827 428.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 63 0 R /XYZ 62.69291 528.6236 0 ] /Rect [ 527.0227 420.7736 532.5827 432.7736 ] /Subtype /Link /Type /Annot >> endobj 27 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 64 0 R /XYZ 62.69291 715.8236 0 ] /Rect [ 62.69291 398.0236 110.6929 410.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 64 0 R /XYZ 62.69291 715.8236 0 ] /Rect [ 62.69291 402.0236 110.6929 414.0236 ] /Subtype /Link /Type /Annot >> endobj 28 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 64 0 R /XYZ 62.69291 715.8236 0 ] /Rect [ 527.0227 398.7736 532.5827 410.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 64 0 R /XYZ 62.69291 715.8236 0 ] /Rect [ 527.0227 402.7736 532.5827 414.7736 ] /Subtype /Link /Type /Annot >> endobj 29 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 64 0 R /XYZ 62.69291 170.4236 0 ] /Rect [ 62.69291 380.0236 146.6929 392.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 64 0 R /XYZ 62.69291 170.4236 0 ] /Rect [ 62.69291 384.0236 146.6929 396.0236 ] /Subtype /Link /Type /Annot >> endobj 30 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 64 0 R /XYZ 62.69291 170.4236 0 ] /Rect [ 527.0227 380.7736 532.5827 392.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 64 0 R /XYZ 62.69291 170.4236 0 ] /Rect [ 527.0227 384.7736 532.5827 396.7736 ] /Subtype /Link /Type /Annot >> endobj 31 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 65 0 R /XYZ 62.69291 288.6236 0 ] /Rect [ 62.69291 362.0236 139.9329 374.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 65 0 R /XYZ 62.69291 288.6236 0 ] /Rect [ 62.69291 366.0236 139.9329 378.0236 ] /Subtype /Link /Type /Annot >> endobj 32 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 65 0 R /XYZ 62.69291 288.6236 0 ] /Rect [ 527.0227 362.7736 532.5827 374.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 65 0 R /XYZ 62.69291 288.6236 0 ] /Rect [ 527.0227 366.7736 532.5827 378.7736 ] /Subtype /Link /Type /Annot >> endobj 33 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 66 0 R /XYZ 62.69291 300.6236 0 ] /Rect [ 62.69291 344.0236 80.47291 356.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 66 0 R /XYZ 62.69291 300.6236 0 ] /Rect [ 62.69291 348.0236 80.47291 360.0236 ] /Subtype /Link /Type /Annot >> endobj 34 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 66 0 R /XYZ 62.69291 300.6236 0 ] /Rect [ 83.25291 344.0236 161.2529 356.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 66 0 R /XYZ 62.69291 300.6236 0 ] /Rect [ 83.25291 348.0236 161.2529 360.0236 ] /Subtype /Link /Type /Annot >> endobj 35 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 66 0 R /XYZ 62.69291 300.6236 0 ] /Rect [ 167.2529 344.0236 192.2729 356.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 66 0 R /XYZ 62.69291 300.6236 0 ] /Rect [ 167.2529 348.0236 192.2729 360.0236 ] /Subtype /Link /Type /Annot >> endobj 36 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 66 0 R /XYZ 62.69291 300.6236 0 ] /Rect [ 521.4627 344.7736 532.5827 356.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 66 0 R /XYZ 62.69291 300.6236 0 ] /Rect [ 521.4627 348.7736 532.5827 360.7736 ] /Subtype /Link /Type /Annot >> endobj 37 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 67 0 R /XYZ 62.69291 213.4236 0 ] /Rect [ 62.69291 326.0236 177.1629 338.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 67 0 R /XYZ 62.69291 213.4236 0 ] /Rect [ 62.69291 330.0236 177.1629 342.0236 ] /Subtype /Link /Type /Annot >> endobj 38 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 67 0 R /XYZ 62.69291 213.4236 0 ] /Rect [ 521.4627 326.7736 532.5827 338.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 67 0 R /XYZ 62.69291 213.4236 0 ] /Rect [ 521.4627 330.7736 532.5827 342.7736 ] /Subtype /Link /Type /Annot >> endobj 39 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 69 0 R /XYZ 62.69291 374.2236 0 ] /Rect [ 62.69291 308.0236 228.8329 320.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 69 0 R /XYZ 62.69291 374.2236 0 ] /Rect [ 62.69291 312.0236 228.8329 324.0236 ] /Subtype /Link /Type /Annot >> endobj 40 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 69 0 R /XYZ 62.69291 374.2236 0 ] /Rect [ 521.4627 308.7736 532.5827 320.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 69 0 R /XYZ 62.69291 374.2236 0 ] /Rect [ 521.4627 312.7736 532.5827 324.7736 ] /Subtype /Link /Type /Annot >> endobj 41 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 72 0 R /XYZ 62.69291 585.8236 0 ] /Rect [ 62.69291 290.0236 144.3729 302.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 72 0 R /XYZ 62.69291 585.8236 0 ] /Rect [ 62.69291 294.0236 144.3729 306.0236 ] /Subtype /Link /Type /Annot >> endobj 42 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 72 0 R /XYZ 62.69291 585.8236 0 ] /Rect [ 521.4627 290.7736 532.5827 302.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 72 0 R /XYZ 62.69291 585.8236 0 ] /Rect [ 521.4627 294.7736 532.5827 306.7736 ] /Subtype /Link /Type /Annot >> endobj 43 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 75 0 R /XYZ 62.69291 191.0236 0 ] /Rect [ 62.69291 272.0236 251.0829 284.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 75 0 R /XYZ 62.69291 191.0236 0 ] /Rect [ 62.69291 276.0236 251.0829 288.0236 ] /Subtype /Link /Type /Annot >> endobj 44 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 75 0 R /XYZ 62.69291 191.0236 0 ] /Rect [ 521.4627 272.7736 532.5827 284.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 75 0 R /XYZ 62.69291 191.0236 0 ] /Rect [ 521.4627 276.7736 532.5827 288.7736 ] /Subtype /Link /Type /Annot >> endobj 45 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 79 0 R /XYZ 62.69291 210.6236 0 ] /Rect [ 62.69291 254.0236 174.3929 266.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 79 0 R /XYZ 62.69291 210.6236 0 ] /Rect [ 62.69291 258.0236 174.3929 270.0236 ] /Subtype /Link /Type /Annot >> endobj 46 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 79 0 R /XYZ 62.69291 210.6236 0 ] /Rect [ 521.4627 254.7736 532.5827 266.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 79 0 R /XYZ 62.69291 210.6236 0 ] /Rect [ 521.4627 258.7736 532.5827 270.7736 ] /Subtype /Link /Type /Annot >> endobj 47 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 82 0 R /XYZ 62.69291 518.6236 0 ] /Rect [ 62.69291 236.0236 106.0329 248.0236 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 83 0 R /XYZ 62.69291 458.6236 0 ] /Rect [ 62.69291 240.0236 179.3829 252.0236 ] /Subtype /Link /Type /Annot >> endobj 48 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 82 0 R /XYZ 62.69291 518.6236 0 ] /Rect [ 521.4627 236.7736 532.5827 248.7736 ] /Subtype /Link /Type /Annot >> +<< /Border [ 0 0 0 ] /Contents () /Dest [ 83 0 R /XYZ 62.69291 458.6236 0 ] /Rect [ 521.4627 240.7736 532.5827 252.7736 ] /Subtype /Link /Type /Annot >> endobj 49 0 obj << /Annots [ 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R 24 0 R 25 0 R 26 0 R 27 0 R 28 0 R 29 0 R 30 0 R 31 0 R 32 0 R 33 0 R 34 0 R 35 0 R 36 0 R 37 0 R 38 0 R 39 0 R 40 0 R 41 0 R 42 0 R 43 0 R 44 0 R - 45 0 R 46 0 R 47 0 R 48 0 R ] /Contents 106 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 + 45 0 R 46 0 R 47 0 R 48 0 R ] /Contents 107 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 50 0 obj @@ -160,7 +160,7 @@ endobj << /A << /S /URI /Type /Action /URI (http://pythonwheels.com/) >> /Border [ 0 0 0 ] /Rect [ 106.4829 630.0236 133.6029 642.0236 ] /Subtype /Link /Type /Annot >> endobj 52 0 obj -<< /Annots [ 51 0 R ] /Contents 107 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 +<< /Annots [ 51 0 R ] /Contents 108 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 53 0 obj @@ -179,191 +179,197 @@ endobj << /A << /S /URI /Type /Action /URI (https://docs.python.org/3/library/functools.html#functools.update_wrapper) >> /Border [ 0 0 0 ] /Rect [ 135.8454 115.8236 251.406 127.8236 ] /Subtype /Link /Type /Annot >> endobj 58 0 obj -<< /Annots [ 54 0 R 57 0 R ] /Contents 108 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 +<< /Annots [ 54 0 R 57 0 R ] /Contents 109 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 59 0 obj -<< /Contents 109 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> +<< /Contents 110 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 60 0 obj -<< /Contents 110 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> +<< /Contents 111 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 61 0 obj << /A << /S /URI /Type /Action /URI (http://www.python.org/dev/peps/pep-3107/) >> /Border [ 0 0 0 ] /Rect [ 221.7378 320.0236 311.5253 332.0236 ] /Subtype /Link /Type /Annot >> endobj 62 0 obj -<< /Annots [ 61 0 R ] /Contents 111 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 +<< /Annots [ 61 0 R ] /Contents 112 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 63 0 obj -<< /Contents 112 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> +<< /Contents 113 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 64 0 obj -<< /Contents 113 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> +<< /Contents 114 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 65 0 obj -<< /Contents 114 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> +<< /Contents 115 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 66 0 obj -<< /Contents 115 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> +<< /Contents 116 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 67 0 obj -<< /Contents 116 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> +<< /Contents 117 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 68 0 obj << /A << /S /URI /Type /Action /URI (http://bugs.python.org/issue1764286) >> /Border [ 0 0 0 ] /Rect [ 136.4599 557.4236 175.8823 569.4236 ] /Subtype /Link /Type /Annot >> endobj 69 0 obj -<< /Annots [ 68 0 R ] /Contents 117 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 +<< /Annots [ 68 0 R ] /Contents 118 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 70 0 obj << /A << /S /URI /Type /Action /URI (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691) >> /Border [ 0 0 0 ] /Rect [ 62.69291 717.0236 363.4029 729.0236 ] /Subtype /Link /Type /Annot >> endobj 71 0 obj -<< /Annots [ 70 0 R ] /Contents 118 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 +<< /Annots [ 70 0 R ] /Contents 119 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 72 0 obj -<< /Contents 119 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> +<< /Contents 120 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 73 0 obj -<< /Contents 120 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> +<< /Contents 121 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 74 0 obj << /A << /S /URI /Type /Action /URI (http://www.python.org/2.3/mro.html) >> /Border [ 0 0 0 ] /Rect [ 355.0506 215.0236 381.347 227.0236 ] /Subtype /Link /Type /Annot >> endobj 75 0 obj -<< /Annots [ 74 0 R ] /Contents 121 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 +<< /Annots [ 74 0 R ] /Contents 122 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 76 0 obj << /A << /S /URI /Type /Action /URI (http://www.python.org/2.3/mro.html) >> /Border [ 0 0 0 ] /Rect [ 284.1108 618.6236 309.8555 630.6236 ] /Subtype /Link /Type /Annot >> endobj 77 0 obj -<< /Annots [ 76 0 R ] /Contents 122 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 +<< /Annots [ 76 0 R ] /Contents 123 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 78 0 obj -<< /Contents 123 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> +<< /Contents 124 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 79 0 obj -<< /Contents 124 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> +<< /Contents 125 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 80 0 obj -<< /Contents 125 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> +<< /Contents 126 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 81 0 obj -<< /Contents 126 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> +<< /A << /S /URI /Type /Action /URI (https://wrapt.readthedocs.io/en/latest/) >> /Border [ 0 0 0 ] /Rect [ 298.9329 585.0236 323.3829 597.0236 ] /Subtype /Link /Type /Annot >> endobj 82 0 obj -<< /Contents 127 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 105 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> +<< /Annots [ 81 0 R ] /Contents 127 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 + /Trans << >> /Type /Page >> endobj 83 0 obj -<< /Outlines 85 0 R /PageLabels 128 0 R /PageMode /UseNone /Pages 105 0 R /Type /Catalog >> +<< /Contents 128 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 106 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> + /Type /Page >> endobj 84 0 obj -<< /Author (Michele Simionato) /CreationDate (D:20160211093653-01'00') /Creator (\(unspecified\)) /Keywords () /Producer (ReportLab PDF Library - www.reportlab.com) /Subject (\(unspecified\)) - /Title (The decorator module) >> +<< /Outlines 86 0 R /PageLabels 129 0 R /PageMode /UseNone /Pages 106 0 R /Type /Catalog >> endobj 85 0 obj -<< /Count 19 /First 86 0 R /Last 104 0 R /Type /Outlines >> +<< /Author () /CreationDate (D:20170115100338-01'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20170115100338-01'00') /Producer (ReportLab PDF Library - www.reportlab.com) + /Subject (\(unspecified\)) /Title () /Trapped /False >> endobj 86 0 obj -<< /Dest [ 52 0 R /XYZ 62.69291 765.0236 0 ] /Next 87 0 R /Parent 85 0 R /Title (Introduction) >> +<< /Count 19 /First 87 0 R /Last 105 0 R /Type /Outlines >> endobj 87 0 obj -<< /Dest [ 52 0 R /XYZ 62.69291 582.0236 0 ] /Next 88 0 R /Parent 85 0 R /Prev 86 0 R /Title (What's New) >> +<< /Dest [ 52 0 R /XYZ 62.69291 765.0236 0 ] /Next 88 0 R /Parent 86 0 R /Title (Introduction) >> endobj 88 0 obj -<< /Dest [ 52 0 R /XYZ 62.69291 315.0236 0 ] /Next 89 0 R /Parent 85 0 R /Prev 87 0 R /Title (Usefulness of decorators) >> +<< /Dest [ 52 0 R /XYZ 62.69291 582.0236 0 ] /Next 89 0 R /Parent 86 0 R /Prev 87 0 R /Title (What's New in version 4) >> endobj 89 0 obj -<< /Dest [ 58 0 R /XYZ 62.69291 699.0236 0 ] /Next 90 0 R /Parent 85 0 R /Prev 88 0 R /Title (Definitions) >> +<< /Dest [ 52 0 R /XYZ 62.69291 315.0236 0 ] /Next 90 0 R /Parent 86 0 R /Prev 88 0 R /Title (Usefulness of decorators) >> endobj 90 0 obj -<< /Dest [ 58 0 R /XYZ 62.69291 436.0236 0 ] /Next 91 0 R /Parent 85 0 R /Prev 89 0 R /Title (Statement of the problem) >> +<< /Dest [ 58 0 R /XYZ 62.69291 699.0236 0 ] /Next 91 0 R /Parent 86 0 R /Prev 89 0 R /Title (Definitions) >> endobj 91 0 obj -<< /Dest [ 59 0 R /XYZ 62.69291 282.2236 0 ] /Next 92 0 R /Parent 85 0 R /Prev 90 0 R /Title (The solution) >> +<< /Dest [ 58 0 R /XYZ 62.69291 436.0236 0 ] /Next 92 0 R /Parent 86 0 R /Prev 90 0 R /Title (Statement of the problem) >> endobj 92 0 obj -<< /Dest [ 60 0 R /XYZ 62.69291 226.2236 0 ] /Next 93 0 R /Parent 85 0 R /Prev 91 0 R /Title (A trace decorator) >> +<< /Dest [ 59 0 R /XYZ 62.69291 282.2236 0 ] /Next 93 0 R /Parent 86 0 R /Prev 91 0 R /Title (The solution) >> endobj 93 0 obj -<< /Dest [ 62 0 R /XYZ 62.69291 359.0236 0 ] /Next 94 0 R /Parent 85 0 R /Prev 92 0 R /Title (Function annotations) >> +<< /Dest [ 60 0 R /XYZ 62.69291 226.2236 0 ] /Next 94 0 R /Parent 86 0 R /Prev 92 0 R /Title (A trace decorator) >> endobj 94 0 obj -<< /Dest [ 63 0 R /XYZ 62.69291 528.6236 0 ] /Next 95 0 R /Parent 85 0 R /Prev 93 0 R /Title (decorator.decorator) >> +<< /Dest [ 62 0 R /XYZ 62.69291 359.0236 0 ] /Next 95 0 R /Parent 86 0 R /Prev 93 0 R /Title (Function annotations) >> endobj 95 0 obj -<< /Dest [ 64 0 R /XYZ 62.69291 715.8236 0 ] /Next 96 0 R /Parent 85 0 R /Prev 94 0 R /Title (blocking) >> +<< /Dest [ 63 0 R /XYZ 62.69291 528.6236 0 ] /Next 96 0 R /Parent 86 0 R /Prev 94 0 R /Title (decorator.decorator) >> endobj 96 0 obj -<< /Dest [ 64 0 R /XYZ 62.69291 170.4236 0 ] /Next 97 0 R /Parent 85 0 R /Prev 95 0 R /Title (decorator\(cls\)) >> +<< /Dest [ 64 0 R /XYZ 62.69291 715.8236 0 ] /Next 97 0 R /Parent 86 0 R /Prev 95 0 R /Title (blocking) >> endobj 97 0 obj -<< /Dest [ 65 0 R /XYZ 62.69291 288.6236 0 ] /Next 98 0 R /Parent 85 0 R /Prev 96 0 R /Title (contextmanager) >> +<< /Dest [ 64 0 R /XYZ 62.69291 170.4236 0 ] /Next 98 0 R /Parent 86 0 R /Prev 96 0 R /Title (decorator\(cls\)) >> endobj 98 0 obj -<< /Dest [ 66 0 R /XYZ 62.69291 300.6236 0 ] /Next 99 0 R /Parent 85 0 R /Prev 97 0 R /Title (The FunctionMaker class) >> +<< /Dest [ 65 0 R /XYZ 62.69291 288.6236 0 ] /Next 99 0 R /Parent 86 0 R /Prev 97 0 R /Title (contextmanager) >> endobj 99 0 obj -<< /Dest [ 67 0 R /XYZ 62.69291 213.4236 0 ] /Next 100 0 R /Parent 85 0 R /Prev 98 0 R /Title (Getting the source code) >> +<< /Dest [ 66 0 R /XYZ 62.69291 300.6236 0 ] /Next 100 0 R /Parent 86 0 R /Prev 98 0 R /Title (The FunctionMaker class) >> endobj 100 0 obj -<< /Dest [ 69 0 R /XYZ 62.69291 374.2236 0 ] /Next 101 0 R /Parent 85 0 R /Prev 99 0 R /Title (Dealing with third-party decorators) >> +<< /Dest [ 67 0 R /XYZ 62.69291 213.4236 0 ] /Next 101 0 R /Parent 86 0 R /Prev 99 0 R /Title (Getting the source code) >> endobj 101 0 obj -<< /Dest [ 72 0 R /XYZ 62.69291 585.8236 0 ] /Next 102 0 R /Parent 85 0 R /Prev 100 0 R /Title (Multiple dispatch) >> +<< /Dest [ 69 0 R /XYZ 62.69291 374.2236 0 ] /Next 102 0 R /Parent 86 0 R /Prev 100 0 R /Title (Dealing with third-party decorators) >> endobj 102 0 obj -<< /Dest [ 75 0 R /XYZ 62.69291 191.0236 0 ] /Next 103 0 R /Parent 85 0 R /Prev 101 0 R /Title (Generic functions and virtual ancestors) >> +<< /Dest [ 72 0 R /XYZ 62.69291 585.8236 0 ] /Next 103 0 R /Parent 86 0 R /Prev 101 0 R /Title (Multiple dispatch) >> endobj 103 0 obj -<< /Dest [ 79 0 R /XYZ 62.69291 210.6236 0 ] /Next 104 0 R /Parent 85 0 R /Prev 102 0 R /Title (Caveats and limitations) >> +<< /Dest [ 75 0 R /XYZ 62.69291 191.0236 0 ] /Next 104 0 R /Parent 86 0 R /Prev 102 0 R /Title (Generic functions and virtual ancestors) >> endobj 104 0 obj -<< /Dest [ 82 0 R /XYZ 62.69291 518.6236 0 ] /Parent 85 0 R /Prev 103 0 R /Title (LICENSE) >> +<< /Dest [ 79 0 R /XYZ 62.69291 210.6236 0 ] /Next 105 0 R /Parent 86 0 R /Prev 103 0 R /Title (Caveats and limitations) >> endobj 105 0 obj +<< /Dest [ 83 0 R /XYZ 62.69291 458.6236 0 ] /Parent 86 0 R /Prev 104 0 R /Title (LICENSE \(2-clause BSD\)) >> +endobj +106 0 obj << /Count 22 /Kids [ 49 0 R 52 0 R 58 0 R 59 0 R 60 0 R 62 0 R 63 0 R 64 0 R 65 0 R 66 0 R 67 0 R 69 0 R 71 0 R 72 0 R 73 0 R 75 0 R 77 0 R 78 0 R 79 0 R 80 0 R - 81 0 R 82 0 R ] /Type /Pages >> + 82 0 R 83 0 R ] /Type /Pages >> endobj -106 0 obj -<< /Length 7565 >> +107 0 obj +<< /Length 7707 >> 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 q -BT 1 0 0 1 0 4 Tm 118.8249 0 Td 24 TL /F2 20 Tf 0 0 0 rg (The ) Tj /F3 20 Tf 0 0 0 rg (decorator ) Tj /F2 20 Tf 0 0 0 rg (module) Tj T* -118.8249 0 Td ET +BT 1 0 0 1 0 14 Tm 178.5449 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module) Tj T* 0 Tw (=============================================================) Tj T* ET Q Q q -1 0 0 1 62.69291 716.0236 cm +1 0 0 1 62.69291 735.0236 cm +Q +q +1 0 0 1 62.69291 720.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 36.93937 0 Td (Author:) Tj T* -36.93937 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 36.93937 0 Td (Author:) Tj T* -36.93937 0 Td ET Q Q q @@ -377,55 +383,57 @@ q Q Q q -1 0 0 1 62.69291 701.0236 cm +1 0 0 1 62.69291 705.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 39.69937 0 Td (E-mail:) Tj T* -39.69937 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 39.69937 0 Td (E-mail:) Tj T* -39.69937 0 Td ET Q Q q 1 0 0 1 91.03937 3 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (michele.simionato@gmail.com) Tj T* ET +0 0 .501961 rg +0 0 .501961 RG +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (michele.simionato@gmail.com) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 686.0236 cm +1 0 0 1 62.69291 690.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 33.02937 0 Td (Version:) Tj T* -33.02937 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 33.02937 0 Td (Version:) Tj T* -33.02937 0 Td ET Q Q q 1 0 0 1 91.03937 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (4.0.10 \(2016-02-11\)) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (4.0.11 \(2017-01-15\)) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 671.0236 cm +1 0 0 1 62.69291 675.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 25.81937 0 Td (Supports:) Tj T* -25.81937 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 25.81937 0 Td (Supports:) Tj T* -25.81937 0 Td ET Q Q q @@ -439,14 +447,14 @@ q Q Q q -1 0 0 1 62.69291 644.0236 cm +1 0 0 1 62.69291 648.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 14 Tm /F2 10 Tf 12 TL 25.25937 0 Td (Download) Tj T* 21.11 0 Td (page:) Tj T* -46.36937 0 Td ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL 25.25937 0 Td (Download) Tj T* 21.11 0 Td (page:) Tj T* -46.36937 0 Td ET Q Q q @@ -454,41 +462,41 @@ 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/4.0.10) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (http://pypi.python.org/pypi/decorator/4.0.11) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 629.0236 cm +1 0 0 1 62.69291 633.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 16.91937 0 Td (Installation:) Tj T* -16.91937 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 16.91937 0 Td (Installation:) Tj T* -16.91937 0 Td ET Q Q q 1 0 0 1 91.03937 3 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (pip) Tj ( ) Tj (install) Tj ( ) Tj (decorator) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 0 rg (pip) Tj ( ) Tj (install) Tj ( ) Tj (decorator) Tj T* ET Q Q q Q Q q -1 0 0 1 62.69291 614.0236 cm +1 0 0 1 62.69291 618.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 32.46937 0 Td (License:) Tj T* -32.46937 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 32.46937 0 Td (License:) Tj T* -32.46937 0 Td ET Q Q q @@ -502,19 +510,19 @@ q Q Q q -1 0 0 1 62.69291 581.0236 cm +1 0 0 1 62.69291 585.0236 cm q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Contents) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Contents) Tj T* ET Q Q q -1 0 0 1 62.69291 233.0236 cm +1 0 0 1 62.69291 237.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q 1 0 0 1 0 327 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Introduction) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (Introduction) Tj T* ET Q Q q @@ -522,13 +530,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 /F3 10 Tf 12 TL 66.44 0 Td (2) Tj T* -66.44 0 Td ET Q Q q 1 0 0 1 0 309 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (What's New) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (What's New in version 4) Tj T* ET Q Q q @@ -536,13 +544,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 /F3 10 Tf 12 TL 66.44 0 Td (2) Tj T* -66.44 0 Td ET Q Q q 1 0 0 1 0 291 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Usefulness of decorators) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (Usefulness of decorators) Tj T* ET Q Q q @@ -550,13 +558,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 /F3 10 Tf 12 TL 66.44 0 Td (2) Tj T* -66.44 0 Td ET Q Q q 1 0 0 1 0 273 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Definitions) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (Definitions) Tj T* ET Q Q q @@ -564,13 +572,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 /F3 10 Tf 12 TL 66.44 0 Td (3) Tj T* -66.44 0 Td ET Q Q q 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 (Statement of the problem) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (Statement of the problem) Tj T* ET Q Q q @@ -578,13 +586,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 /F3 10 Tf 12 TL 66.44 0 Td (3) Tj T* -66.44 0 Td ET Q Q q 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 (The solution) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (The solution) Tj T* ET Q Q q @@ -592,13 +600,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 /F3 10 Tf 12 TL 66.44 0 Td (4) 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 (A ) Tj /F3 10 Tf 0 0 0 rg (trace ) Tj /F2 10 Tf 0 0 .501961 rg (decorator) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (A ) Tj /F2 10 Tf 0 0 0 rg (trace ) Tj /F3 10 Tf 0 0 .501961 rg (decorator) Tj T* ET Q Q q @@ -606,13 +614,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 /F3 10 Tf 12 TL 66.44 0 Td (5) Tj T* -66.44 0 Td ET Q 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 (Function annotations) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (Function annotations) Tj T* ET Q Q q @@ -620,13 +628,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 /F3 10 Tf 12 TL 66.44 0 Td (6) 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 /F3 10 Tf 0 0 0 rg (decorator.decorator) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 0 rg (decorator.decorator) Tj T* ET Q Q q @@ -634,13 +642,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 (7) Tj T* -66.44 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 66.44 0 Td (7) 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 /F3 10 Tf 0 0 0 rg (blocking) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 0 rg (blocking) Tj T* ET Q Q q @@ -648,13 +656,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 (8) Tj T* -66.44 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 66.44 0 Td (8) 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 0 rg (decorator\(cls\)) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 0 rg (decorator\(cls\)) Tj T* ET Q Q q @@ -662,13 +670,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 (8) Tj T* -66.44 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 66.44 0 Td (8) 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 /F2 10 Tf 0 0 .501961 rg (contextmanager) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (contextmanager) Tj T* ET Q Q q @@ -676,13 +684,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 (9) Tj T* -66.44 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 66.44 0 Td (9) 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 /F2 10 Tf 0 0 .501961 rg (The ) Tj /F3 10 Tf 0 0 0 rg (FunctionMaker ) Tj /F2 10 Tf 0 0 .501961 rg (class) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (The ) Tj /F2 10 Tf 0 0 0 rg (FunctionMaker ) Tj /F3 10 Tf 0 0 .501961 rg (class) Tj T* ET Q Q q @@ -690,13 +698,13 @@ 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 /F3 10 Tf 12 TL 60.88 0 Td (10) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 93 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Getting the source code) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (Getting the source code) Tj T* ET Q Q q @@ -704,13 +712,13 @@ 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 /F3 10 Tf 12 TL 60.88 0 Td (11) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 75 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Dealing with third-party decorators) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (Dealing with third-party decorators) Tj T* ET Q Q q @@ -718,13 +726,13 @@ 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 (12) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 60.88 0 Td (12) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 57 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Multiple dispatch) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (Multiple dispatch) Tj T* ET Q Q q @@ -732,13 +740,13 @@ 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 /F3 10 Tf 12 TL 60.88 0 Td (14) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 39 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Generic functions and virtual ancestors) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (Generic functions and virtual ancestors) Tj T* ET Q Q q @@ -746,13 +754,13 @@ 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 (16) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 60.88 0 Td (16) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 21 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Caveats and limitations) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (Caveats and limitations) Tj T* ET Q Q q @@ -760,13 +768,13 @@ 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 (19) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 60.88 0 Td (19) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 3 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (LICENSE) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 .501961 rg (LICENSE \(2-clause BSD\)) Tj T* ET Q Q q @@ -774,7 +782,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 (22) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 60.88 0 Td (22) Tj T* -60.88 0 Td ET Q Q q @@ -783,26 +791,26 @@ Q endstream endobj -107 0 obj -<< /Length 8201 >> +108 0 obj +<< /Length 8214 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 744.0236 cm q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Introduction) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Introduction) Tj T* ET Q Q q 1 0 0 1 62.69291 594.0236 cm q -BT 1 0 0 1 0 134 Tm .201654 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module is over ten years old, but still alive and kicking. It is used by several frameworks) Tj T* 0 Tw 1.401098 Tw (\(IPython, scipy, authkit, pylons, pycuda, sugar, ...\) and has been stable for a ) Tj /F4 10 Tf (long ) Tj /F1 10 Tf (time. It is your best) Tj T* 0 Tw 1.50686 Tw (option if you want to preserve the signature of decorated functions in a consistent way across Python) Tj T* 0 Tw .103876 Tw (releases. Version 4.0 is fully compatible with the past, except for one thing: support for Python 2.4 and 2.5) Tj T* 0 Tw 1.399431 Tw (has been dropped. That decision made it possible to use a single code base both for Python 2.X and) Tj T* 0 Tw 6.201984 Tw (Python 3.X. This is a ) Tj /F4 10 Tf (huge ) Tj /F1 10 Tf (bonus, since I could remove over 2,000 lines of duplicated) Tj T* 0 Tw .485366 Tw (documentation/doctests. Having to maintain separate docs for Python 2 and Python 3 effectively stopped) Tj T* 0 Tw .075542 Tw (any development on the module for several years. Moreover, it is now trivial to distribute the module as an) Tj T* 0 Tw .999987 Tw (universal ) Tj 0 0 .501961 rg (wheel ) Tj 0 0 0 rg (since 2to3 is no more required. Since Python 2.5 has been released 9 years ago, I felt) Tj T* 0 Tw .829461 Tw (that it was reasonable to drop the support for it. If you need to support ancient versions of Python, stick) Tj T* 0 Tw .639985 Tw (with the decorator module version 3.4.2. The current version supports all Python releases from 2.6 up to) Tj T* 0 Tw (3.5.) Tj T* ET +BT 1 0 0 1 0 134 Tm .201654 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module is over ten years old, but still alive and kicking. It is used by several frameworks) Tj T* 0 Tw 1.401098 Tw (\(IPython, scipy, authkit, pylons, pycuda, sugar, ...\) and has been stable for a ) Tj /F4 10 Tf (long ) Tj /F1 10 Tf (time. It is your best) Tj T* 0 Tw 1.50686 Tw (option if you want to preserve the signature of decorated functions in a consistent way across Python) Tj T* 0 Tw .103876 Tw (releases. Version 4.0 is fully compatible with the past, except for one thing: support for Python 2.4 and 2.5) Tj T* 0 Tw 1.399431 Tw (has been dropped. That decision made it possible to use a single code base both for Python 2.X and) Tj T* 0 Tw 6.201984 Tw (Python 3.X. This is a ) Tj /F4 10 Tf (huge ) Tj /F1 10 Tf (bonus, since I could remove over 2,000 lines of duplicated) Tj T* 0 Tw .485366 Tw (documentation/doctests. Having to maintain separate docs for Python 2 and Python 3 effectively stopped) Tj T* 0 Tw .075542 Tw (any development on the module for several years. Moreover, it is now trivial to distribute the module as an) Tj T* 0 Tw .999987 Tw (universal ) Tj 0 0 .501961 rg (wheel ) Tj 0 0 0 rg (since 2to3 is no more required. Since Python 2.5 has been released 9 years ago, I felt) Tj T* 0 Tw .829461 Tw (that it was reasonable to drop the support for it. If you need to support ancient versions of Python, stick) Tj T* 0 Tw .639985 Tw (with the decorator module version 3.4.2. The current version supports all Python releases from 2.6 up to) Tj T* 0 Tw (3.6.) Tj T* ET Q Q q 1 0 0 1 62.69291 561.0236 cm q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (What's New) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (What's New in version 4) Tj T* ET Q Q q @@ -825,7 +833,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 26 Tm .35061 Tw 12 TL /F2 10 Tf 0 0 0 rg (New documentation ) Tj /F1 10 Tf (There is now a single manual for all Python versions, so I took the opportunity) Tj T* 0 Tw 1.471751 Tw (to overhaul the documentation. So, even if you are a long-time user, you may want to revisit the) Tj T* 0 Tw (docs, since several examples have been improved.) Tj T* ET +BT 1 0 0 1 0 26 Tm .35061 Tw 12 TL /F3 10 Tf 0 0 0 rg (New documentation ) Tj /F1 10 Tf (There is now a single manual for all Python versions, so I took the opportunity) Tj T* 0 Tw 1.471751 Tw (to overhaul the documentation. So, even if you are a long-time user, you may want to revisit the) Tj T* 0 Tw (docs, since several examples have been improved.) Tj T* ET Q Q q @@ -848,7 +856,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 26 Tm 3.56998 Tw 12 TL /F2 10 Tf 0 0 0 rg (Packaging improvements ) Tj /F1 10 Tf (The code is now also available in wheel format. Integration with) Tj T* 0 Tw .965697 Tw (setuptools has improved and you can run the tests with the command ) Tj /F3 10 Tf 0 0 0 rg (python) Tj ( ) Tj (setup.py) Tj ( ) Tj (test) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (too.) Tj T* ET +BT 1 0 0 1 0 26 Tm 3.56998 Tw 12 TL /F3 10 Tf 0 0 0 rg (Packaging improvements ) Tj /F1 10 Tf (The code is now also available in wheel format. Integration with) Tj T* 0 Tw .965697 Tw (setuptools has improved and you can run the tests with the command ) Tj /F2 10 Tf 0 0 0 rg (python) Tj ( ) Tj (setup.py) Tj ( ) Tj (test) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (too.) Tj T* ET Q Q q @@ -871,7 +879,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 26 Tm 1.526905 Tw 12 TL /F2 10 Tf 0 0 0 rg (Code changes ) Tj /F1 10 Tf (A new utility function ) Tj /F3 10 Tf 0 0 0 rg (decorate\(func,) Tj ( ) Tj (caller\) ) Tj /F1 10 Tf 0 0 0 rg (has been added. It does the) Tj T* 0 Tw 1.357674 Tw (same job that was performed by the older ) Tj /F3 10 Tf 0 0 0 rg (decorator\(caller,) Tj ( ) Tj (func\)) Tj /F1 10 Tf 0 0 0 rg (. The old functionality is) Tj T* 0 Tw (now deprecated and no longer documented, but still available for now.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.526905 Tw 12 TL /F3 10 Tf 0 0 0 rg (Code changes ) Tj /F1 10 Tf (A new utility function ) Tj /F2 10 Tf 0 0 0 rg (decorate\(func,) Tj ( ) Tj (caller\) ) Tj /F1 10 Tf 0 0 0 rg (has been added. It does the) Tj T* 0 Tw 1.357674 Tw (same job that was performed by the older ) Tj /F2 10 Tf 0 0 0 rg (decorator\(caller,) Tj ( ) Tj (func\)) Tj /F1 10 Tf 0 0 0 rg (. The old functionality is) Tj T* 0 Tw (now deprecated and no longer documented, but still available for now.) Tj T* ET Q Q q @@ -894,7 +902,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 86 Tm 3.035433 Tw 12 TL /F2 10 Tf 0 0 0 rg (New experimental feature ) Tj /F1 10 Tf (The decorator module now includes an implementation of generic) Tj T* 0 Tw 5.271797 Tw (functions \(sometimes called "multiple dispatch functions"\). The API is designed to mimic) Tj T* 0 Tw 2.276976 Tw /F3 10 Tf 0 0 0 rg (functools.singledispatch ) Tj /F1 10 Tf 0 0 0 rg (\(added in Python 3.4\), but the implementation is much simpler.) Tj T* 0 Tw 1.284597 Tw (Moreover, all decorators involved preserve the signature of the decorated functions. For now, this) Tj T* 0 Tw .518651 Tw (exists mostly to demonstrate the power of the module. In the future it could be enhanced/optimized;) Tj T* 0 Tw 1.30881 Tw (however, its API could change. \(Such is the fate of experimental features!\) In any case, it is very) Tj T* 0 Tw .778988 Tw (short and compact \(less then 100 lines\), so you can extract it for your own use. Take it as food for) Tj T* 0 Tw (thought.) Tj T* ET +BT 1 0 0 1 0 86 Tm 3.035433 Tw 12 TL /F3 10 Tf 0 0 0 rg (New experimental feature ) Tj /F1 10 Tf (The decorator module now includes an implementation of generic) Tj T* 0 Tw 5.271797 Tw (functions \(sometimes called "multiple dispatch functions"\). The API is designed to mimic) Tj T* 0 Tw 2.276976 Tw /F2 10 Tf 0 0 0 rg (functools.singledispatch ) Tj /F1 10 Tf 0 0 0 rg (\(added in Python 3.4\), but the implementation is much simpler.) Tj T* 0 Tw 1.284597 Tw (Moreover, all decorators involved preserve the signature of the decorated functions. For now, this) Tj T* 0 Tw .518651 Tw (exists mostly to demonstrate the power of the module. In the future it could be enhanced/optimized;) Tj T* 0 Tw 1.30881 Tw (however, its API could change. \(Such is the fate of experimental features!\) In any case, it is very) Tj T* 0 Tw .778988 Tw (short and compact \(less then 100 lines\), so you can extract it for your own use. Take it as food for) Tj T* 0 Tw (thought.) Tj T* ET Q Q q @@ -906,7 +914,7 @@ Q q 1 0 0 1 62.69291 294.0236 cm q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Usefulness of decorators) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Usefulness of decorators) Tj T* ET Q Q q @@ -1028,13 +1036,13 @@ Q q 1 0 0 1 62.69291 84.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 /F3 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (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 +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 /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (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 -108 0 obj +109 0 obj << /Length 11857 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -1047,13 +1055,13 @@ Q q 1 0 0 1 62.69291 711.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 /F3 10 Tf 0 0 0 rg (documentation.py ) Tj /F1 10 Tf 0 0 0 rg (file, which) Tj T* 0 Tw (contains the documentation you are reading in the form of doctests.) Tj T* ET +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 /F2 10 Tf 0 0 0 rg (documentation.py ) Tj /F1 10 Tf 0 0 0 rg (file, which) Tj T* 0 Tw (contains the documentation you are reading in the form of doctests.) Tj T* ET Q Q q 1 0 0 1 62.69291 678.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 +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Definitions) Tj T* ET Q Q q @@ -1066,7 +1074,7 @@ Q q 1 0 0 1 62.69291 620.0236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (signature-preserving ) Tj /F2 10 Tf (decorators:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (signature-preserving ) Tj /F3 10 Tf (decorators:) Tj T* ET Q Q q @@ -1086,7 +1094,7 @@ Q q 1 0 0 1 62.69291 577.0236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (signature-changing ) Tj /F2 10 Tf (decorators:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (signature-changing ) Tj /F3 10 Tf (decorators:) Tj T* ET Q Q q @@ -1107,13 +1115,13 @@ Q q 1 0 0 1 62.69291 508.0236 cm q -BT 1 0 0 1 0 26 Tm 1.926342 Tw 12 TL /F2 10 Tf 0 0 0 rg (Signature-changing ) Tj /F1 10 Tf (decorators have their use: for instance, the builtin classes ) Tj /F3 10 Tf 0 0 0 rg (staticmethod ) Tj /F1 10 Tf 0 0 0 rg (and) Tj T* 0 Tw 2.051412 Tw /F3 10 Tf 0 0 0 rg (classmethod ) Tj /F1 10 Tf 0 0 0 rg (are in this group. They take functions and return descriptor objects which are neither) Tj T* 0 Tw (functions, nor callables.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.926342 Tw 12 TL /F3 10 Tf 0 0 0 rg (Signature-changing ) Tj /F1 10 Tf (decorators have their use: for instance, the builtin classes ) Tj /F2 10 Tf 0 0 0 rg (staticmethod ) Tj /F1 10 Tf 0 0 0 rg (and) Tj T* 0 Tw 2.051412 Tw /F2 10 Tf 0 0 0 rg (classmethod ) Tj /F1 10 Tf 0 0 0 rg (are in this group. They take functions and return descriptor objects which are neither) Tj T* 0 Tw (functions, nor callables.) Tj T* ET Q Q q 1 0 0 1 62.69291 478.0236 cm q -BT 1 0 0 1 0 14 Tm .618443 Tw 12 TL /F1 10 Tf 0 0 0 rg (Still, ) Tj /F2 10 Tf (signature-preserving ) Tj /F1 10 Tf (decorators are more common, and easier to reason about. In particular, they) Tj T* 0 Tw (can be composed together, whereas other decorators generally cannot.) Tj T* ET +BT 1 0 0 1 0 14 Tm .618443 Tw 12 TL /F1 10 Tf 0 0 0 rg (Still, ) Tj /F3 10 Tf (signature-preserving ) Tj /F1 10 Tf (decorators are more common, and easier to reason about. In particular, they) Tj T* 0 Tw (can be composed together, whereas other decorators generally cannot.) Tj T* ET Q Q q @@ -1126,19 +1134,19 @@ Q q 1 0 0 1 62.69291 415.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 +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Statement of the problem) Tj T* ET Q Q q 1 0 0 1 62.69291 373.0236 cm q -BT 1 0 0 1 0 26 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 /F3 10 Tf 0 0 0 rg (memoize ) Tj /F1 10 Tf 0 0 0 rg (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 (same input parameters the result is retrieved from the cache and not recomputed.) Tj T* ET +BT 1 0 0 1 0 26 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 /F2 10 Tf 0 0 0 rg (memoize ) Tj /F1 10 Tf 0 0 0 rg (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 (same input parameters the result is retrieved from the cache and not recomputed.) Tj T* ET Q Q q 1 0 0 1 62.69291 331.0236 cm q -BT 1 0 0 1 0 26 Tm .28497 Tw 12 TL /F1 10 Tf 0 0 0 rg (There are many implementations of ) Tj /F3 10 Tf 0 0 0 rg (memoize ) Tj /F1 10 Tf 0 0 0 rg (in ) Tj 0 0 .501961 rg (http://www.python.org/moin/PythonDecoratorLibrary) Tj 0 0 0 rg (, but) Tj T* 0 Tw .15311 Tw (they do not preserve the signature. In recent versions of Python you can find a sophisticated ) Tj /F3 10 Tf 0 0 0 rg (lru_cache) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (decorator in the standard library's ) Tj /F3 10 Tf 0 0 0 rg (functools) Tj /F1 10 Tf 0 0 0 rg (. Here I am just interested in giving an example.) Tj T* ET +BT 1 0 0 1 0 26 Tm .28497 Tw 12 TL /F1 10 Tf 0 0 0 rg (There are many implementations of ) Tj /F2 10 Tf 0 0 0 rg (memoize ) Tj /F1 10 Tf 0 0 0 rg (in ) Tj 0 0 .501961 rg (http://www.python.org/moin/PythonDecoratorLibrary) Tj 0 0 0 rg (, but) Tj T* 0 Tw .15311 Tw (they do not preserve the signature. In recent versions of Python you can find a sophisticated ) Tj /F2 10 Tf 0 0 0 rg (lru_cache) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (decorator in the standard library's ) Tj /F2 10 Tf 0 0 0 rg (functools) Tj /F1 10 Tf 0 0 0 rg (. Here I am just interested in giving an example.) Tj T* ET Q Q q @@ -1315,7 +1323,7 @@ n 258 0 6 12 re f* n 270 0 24 12 re f* .960784 .960784 .862745 rg n 294 0 6 12 re f* -BT 1 0 0 1 0 134 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (memoize_uw) Tj 0 0 0 rg (\() Tj 0 0 0 rg (func) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg ({}) Tj 0 0 0 rg T* T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 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 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# frozenset is used to ensure hashability) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (frozenset) Tj 0 0 0 rg (\() Tj 0 0 0 rg (kw) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (items) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (else) Tj /F3 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (not) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ([) Tj 0 0 0 rg (key) Tj 0 0 0 rg (]) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ([) Tj 0 0 0 rg (key) Tj 0 0 0 rg (]) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (functools) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (update_wrapper) Tj 0 0 0 rg (\() Tj 0 0 0 rg (memoize) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 134 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (memoize_uw) Tj 0 0 0 rg (\() Tj 0 0 0 rg (func) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg ({}) Tj 0 0 0 rg T* T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 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 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# frozenset is used to ensure hashability) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (frozenset) Tj 0 0 0 rg (\() Tj 0 0 0 rg (kw) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (items) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (else) Tj /F2 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (not) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ([) Tj 0 0 0 rg (key) Tj 0 0 0 rg (]) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ([) Tj 0 0 0 rg (key) Tj 0 0 0 rg (]) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (functools) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (update_wrapper) Tj 0 0 0 rg (\() Tj 0 0 0 rg (memoize) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -1324,13 +1332,13 @@ Q q 1 0 0 1 62.69291 91.82362 cm q -BT 1 0 0 1 0 26 Tm .50061 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here I used the ) Tj 0 0 .501961 rg (functools.update_wrapper ) Tj 0 0 0 rg (utility, which was added in Python 2.5 to simplify the writing of) Tj T* 0 Tw 2.954524 Tw (decorators. \(Previously, you needed to manually copy the function attributes ) Tj /F3 10 Tf 0 0 0 rg (__name__) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F3 10 Tf 0 0 0 rg (__doc__) Tj /F1 10 Tf 0 0 0 rg (,) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (__module__) Tj /F1 10 Tf 0 0 0 rg (, and ) Tj /F3 10 Tf 0 0 0 rg (__dict__ ) Tj /F1 10 Tf 0 0 0 rg (to the decorated function by hand.\)) Tj T* ET +BT 1 0 0 1 0 26 Tm .50061 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here I used the ) Tj 0 0 .501961 rg (functools.update_wrapper ) Tj 0 0 0 rg (utility, which was added in Python 2.5 to simplify the writing of) Tj T* 0 Tw 2.954524 Tw (decorators. \(Previously, you needed to manually copy the function attributes ) Tj /F2 10 Tf 0 0 0 rg (__name__) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F2 10 Tf 0 0 0 rg (__doc__) Tj /F1 10 Tf 0 0 0 rg (,) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (__module__) Tj /F1 10 Tf 0 0 0 rg (, and ) Tj /F2 10 Tf 0 0 0 rg (__dict__ ) Tj /F1 10 Tf 0 0 0 rg (to the decorated function by hand.\)) Tj T* ET Q Q endstream endobj -109 0 obj +110 0 obj << /Length 13392 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -1385,7 +1393,7 @@ n 96 12 6 12 re f* n 24 0 36 12 re f* .960784 .960784 .862745 rg n 66 0 6 12 re f* -BT 1 0 0 1 0 50 Tm 12 TL /F3 10 Tf .666667 .133333 1 rg (@memoize_uw) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f1) Tj 0 0 0 rg (\() Tj 0 0 0 rg (x) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .729412 .129412 .129412 rg ("Simulate some long computation") Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (x) Tj T* ET +BT 1 0 0 1 0 50 Tm 12 TL /F2 10 Tf .666667 .133333 1 rg (@memoize_uw) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f1) Tj 0 0 0 rg (\() Tj 0 0 0 rg (x) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .729412 .129412 .129412 rg ("Simulate some long computation") Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (x) Tj T* ET Q Q Q @@ -1394,7 +1402,7 @@ Q q 1 0 0 1 62.69291 627.8236 cm q -BT 1 0 0 1 0 26 Tm 1.239318 Tw 12 TL /F1 10 Tf 0 0 0 rg (This works insofar as the decorator accepts functions with generic signatures. Unfortunately, it is ) Tj /F4 10 Tf (not ) Tj /F1 10 Tf (a) Tj T* 0 Tw .33816 Tw (signature-preserving decorator, since ) Tj /F3 10 Tf 0 0 0 rg (memoize_uw ) Tj /F1 10 Tf 0 0 0 rg (generally returns a function with a ) Tj /F4 10 Tf (different signature) Tj T* 0 Tw /F1 10 Tf (from the original.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.239318 Tw 12 TL /F1 10 Tf 0 0 0 rg (This works insofar as the decorator accepts functions with generic signatures. Unfortunately, it is ) Tj /F4 10 Tf (not ) Tj /F1 10 Tf (a) Tj T* 0 Tw .33816 Tw (signature-preserving decorator, since ) Tj /F2 10 Tf 0 0 0 rg (memoize_uw ) Tj /F1 10 Tf 0 0 0 rg (generally returns a function with a ) Tj /F4 10 Tf (different signature) Tj T* 0 Tw /F1 10 Tf (from the original.) Tj T* ET Q Q q @@ -1448,7 +1456,7 @@ n 96 12 6 12 re f* n 24 0 36 12 re f* .960784 .960784 .862745 rg n 66 0 6 12 re f* -BT 1 0 0 1 0 50 Tm 12 TL /F3 10 Tf .666667 .133333 1 rg (@memoize_uw) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f1) Tj 0 0 0 rg (\() Tj 0 0 0 rg (x) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .729412 .129412 .129412 rg ("Simulate some long computation") Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (x) Tj T* ET +BT 1 0 0 1 0 50 Tm 12 TL /F2 10 Tf .666667 .133333 1 rg (@memoize_uw) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f1) Tj 0 0 0 rg (\() Tj 0 0 0 rg (x) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .729412 .129412 .129412 rg ("Simulate some long computation") Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (x) Tj T* ET Q Q Q @@ -1457,7 +1465,7 @@ Q q 1 0 0 1 62.69291 496.6236 cm q -BT 1 0 0 1 0 14 Tm .08936 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here, the original function takes a single argument named ) Tj /F3 10 Tf 0 0 0 rg (x) Tj /F1 10 Tf 0 0 0 rg (, but the decorated function takes any number) Tj T* 0 Tw (of arguments and keyword arguments:) Tj T* ET +BT 1 0 0 1 0 14 Tm .08936 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here, the original function takes a single argument named ) Tj /F2 10 Tf 0 0 0 rg (x) Tj /F1 10 Tf 0 0 0 rg (, but the decorated function takes any number) Tj T* 0 Tw (of arguments and keyword arguments:) Tj T* ET Q Q q @@ -1542,7 +1550,7 @@ n 318 0 6 12 re f* n 324 0 24 12 re f* .960784 .960784 .862745 rg n 348 0 6 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (from) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (decorator) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (import) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (getargspec) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# akin to inspect.getargspec) Tj /F3 10 Tf 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (getargspec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f1) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* 0 0 0 rg (ArgSpec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (args) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ([],) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varargs) Tj .4 .4 .4 rg (=) Tj .729412 .129412 .129412 rg ('args') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varkw) Tj .4 .4 .4 rg (=) Tj .729412 .129412 .129412 rg ('kw') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (defaults) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (from) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (decorator) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (import) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (getargspec) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# akin to inspect.getargspec) Tj /F2 10 Tf 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (getargspec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f1) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* 0 0 0 rg (ArgSpec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (args) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ([],) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varargs) Tj .4 .4 .4 rg (=) Tj .729412 .129412 .129412 rg ('args') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varkw) Tj .4 .4 .4 rg (=) Tj .729412 .129412 .129412 rg ('kw') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (defaults) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -1551,7 +1559,7 @@ Q q 1 0 0 1 62.69291 395.4236 cm q -BT 1 0 0 1 0 26 Tm 1.08061 Tw 12 TL /F1 10 Tf 0 0 0 rg (This means that introspection tools \(like ) Tj /F3 10 Tf 0 0 0 rg (pydoc) Tj /F1 10 Tf 0 0 0 rg (\) will give false information about the signature of ) Tj /F3 10 Tf 0 0 0 rg (f1 ) Tj /F1 10 Tf 0 0 0 rg (--) Tj T* 0 Tw 1.562765 Tw (unless you are using Python 3.5. This is pretty bad: ) Tj /F3 10 Tf 0 0 0 rg (pydoc ) Tj /F1 10 Tf 0 0 0 rg (will tell you that the function accepts the) Tj T* 0 Tw (generic signature ) Tj /F3 10 Tf 0 0 0 rg (*args,) Tj ( ) Tj (**kw) Tj /F1 10 Tf 0 0 0 rg (, but calling the function with more than one argument raises an error:) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.08061 Tw 12 TL /F1 10 Tf 0 0 0 rg (This means that introspection tools \(like ) Tj /F2 10 Tf 0 0 0 rg (pydoc) Tj /F1 10 Tf 0 0 0 rg (\) will give false information about the signature of ) Tj /F2 10 Tf 0 0 0 rg (f1 ) Tj /F1 10 Tf 0 0 0 rg (--) Tj T* 0 Tw 1.562765 Tw (unless you are using Python 3.5. This is pretty bad: ) Tj /F2 10 Tf 0 0 0 rg (pydoc ) Tj /F1 10 Tf 0 0 0 rg (will tell you that the function accepts the) Tj T* 0 Tw (generic signature ) Tj /F2 10 Tf 0 0 0 rg (*args,) Tj ( ) Tj (**kw) Tj /F1 10 Tf 0 0 0 rg (, but calling the function with more than one argument raises an error:) Tj T* ET Q Q q @@ -1628,7 +1636,7 @@ n 318 0 6 12 re f* n 330 0 30 12 re f* .960784 .960784 .862745 rg n 360 0 6 12 re f* -BT 1 0 0 1 0 38 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg (Traceback) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (most) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (recent) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (call) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (last) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg T* /F6 10 Tf .823529 .254902 .227451 rg (TypeError) Tj /F3 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (takes) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (exactly) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (positional) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argument) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (2) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (given) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 38 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg (Traceback) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (most) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (recent) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (call) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (last) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg T* /F6 10 Tf .823529 .254902 .227451 rg (TypeError) Tj /F2 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (takes) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (exactly) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (positional) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argument) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (2) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (given) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -1637,19 +1645,19 @@ Q q 1 0 0 1 62.69291 294.2236 cm q -BT 1 0 0 1 0 14 Tm 2.163307 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that ) Tj /F3 10 Tf 0 0 0 rg (inspect.getargspec ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F3 10 Tf 0 0 0 rg (inspect.getfullargspec ) Tj /F1 10 Tf 0 0 0 rg (will give the wrong signature.) Tj T* 0 Tw (This even occurs in Python 3.5, although both functions were deprecated in that release.) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.163307 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that ) Tj /F2 10 Tf 0 0 0 rg (inspect.getargspec ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F2 10 Tf 0 0 0 rg (inspect.getfullargspec ) Tj /F1 10 Tf 0 0 0 rg (will give the wrong signature.) Tj T* 0 Tw (This even occurs in Python 3.5, although both functions were deprecated in that release.) Tj T* ET Q Q q 1 0 0 1 62.69291 261.2236 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 +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (The solution) Tj T* ET Q Q q 1 0 0 1 62.69291 219.2236 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.962976 Tw (signature-preserving decorators from the application programmer. The ) Tj /F3 10 Tf 0 0 0 rg (decorate ) Tj /F1 10 Tf 0 0 0 rg (function in the) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module is such a factory:) Tj T* ET +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.962976 Tw (signature-preserving decorators from the application programmer. The ) Tj /F2 10 Tf 0 0 0 rg (decorate ) Tj /F1 10 Tf 0 0 0 rg (function in the) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module is such a factory:) Tj T* ET Q Q q @@ -1680,7 +1688,7 @@ n 54 0 54 12 re f* n 114 0 36 12 re f* .960784 .960784 .862745 rg n 156 0 48 12 re f* -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (from) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (decorator) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (import) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (decorate) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (from) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (decorator) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (import) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (decorate) Tj T* ET Q Q Q @@ -1689,7 +1697,7 @@ Q q 1 0 0 1 62.69291 166.0236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (decorate ) Tj /F1 10 Tf 0 0 0 rg (takes two arguments:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 0 rg (decorate ) Tj /F1 10 Tf 0 0 0 rg (takes two arguments:) Tj T* ET Q Q q @@ -1749,13 +1757,13 @@ Q q 1 0 0 1 62.69291 100.0236 cm q -BT 1 0 0 1 0 14 Tm .134692 Tw 12 TL /F1 10 Tf 0 0 0 rg (The caller function must have signature ) Tj /F3 10 Tf 0 0 0 rg (\(f,) Tj ( ) Tj (*args,) Tj ( ) Tj (**kw\)) Tj /F1 10 Tf 0 0 0 rg (, and it must call the original function ) Tj /F3 10 Tf 0 0 0 rg (f ) Tj /F1 10 Tf 0 0 0 rg (with) Tj T* 0 Tw (arguments ) Tj /F3 10 Tf 0 0 0 rg (args ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F3 10 Tf 0 0 0 rg (kw) Tj /F1 10 Tf 0 0 0 rg (, implementing the wanted capability \(in this case, memoization\):) Tj T* ET +BT 1 0 0 1 0 14 Tm .134692 Tw 12 TL /F1 10 Tf 0 0 0 rg (The caller function must have signature ) Tj /F2 10 Tf 0 0 0 rg (\(f,) Tj ( ) Tj (*args,) Tj ( ) Tj (**kw\)) Tj /F1 10 Tf 0 0 0 rg (, and it must call the original function ) Tj /F2 10 Tf 0 0 0 rg (f ) Tj /F1 10 Tf 0 0 0 rg (with) Tj T* 0 Tw (arguments ) Tj /F2 10 Tf 0 0 0 rg (args ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F2 10 Tf 0 0 0 rg (kw) Tj /F1 10 Tf 0 0 0 rg (, implementing the wanted capability \(in this case, memoization\):) Tj T* ET Q Q endstream endobj -110 0 obj +111 0 obj << /Length 19366 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -1893,7 +1901,7 @@ n 96 0 6 12 re f* n 102 0 18 12 re f* .960784 .960784 .862745 rg n 120 0 6 12 re f* -BT 1 0 0 1 0 98 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (_memoize) Tj 0 0 0 rg (\() Tj 0 0 0 rg (func) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# frozenset is used to ensure hashability) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (frozenset) Tj 0 0 0 rg (\() Tj 0 0 0 rg (kw) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (items) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (else) Tj /F3 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# attribute added by memoize) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (not) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ([) Tj 0 0 0 rg (key) Tj 0 0 0 rg (]) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ([) Tj 0 0 0 rg (key) Tj 0 0 0 rg (]) Tj T* ET +BT 1 0 0 1 0 98 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (_memoize) Tj 0 0 0 rg (\() Tj 0 0 0 rg (func) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# frozenset is used to ensure hashability) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (frozenset) Tj 0 0 0 rg (\() Tj 0 0 0 rg (kw) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (items) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (else) Tj /F2 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# attribute added by memoize) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (not) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ([) Tj 0 0 0 rg (key) Tj 0 0 0 rg (]) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ([) Tj 0 0 0 rg (key) Tj 0 0 0 rg (]) Tj T* ET Q Q Q @@ -1964,7 +1972,7 @@ n 126 0 6 12 re f* n 138 0 48 12 re f* .960784 .960784 .862745 rg n 186 0 6 12 re f* -BT 1 0 0 1 0 86 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (memoize) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F7 10 Tf .729412 .129412 .129412 rg (""") Tj T* ( A simple memoize implementation. It works by adding a .cache dictionary) Tj T* ( to the decorated function. The cache will grow indefinitely, so it is) Tj T* ( your responsability to clear it, if needed.) Tj T* ( """) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg ({}) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (decorate) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (_memoize) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 86 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (memoize) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F7 10 Tf .729412 .129412 .129412 rg (""") Tj T* ( A simple memoize implementation. It works by adding a .cache dictionary) Tj T* ( to the decorated function. The cache will grow indefinitely, so it is) Tj T* ( your responsibility to clear it, if needed.) Tj T* ( """) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg ({}) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (decorate) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (_memoize) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -1973,7 +1981,7 @@ Q q 1 0 0 1 62.69291 462.6236 cm q -BT 1 0 0 1 0 26 Tm 1.255697 Tw 12 TL /F1 10 Tf 0 0 0 rg (The difference from the nested function approach of ) Tj /F3 10 Tf 0 0 0 rg (memoize_uw ) Tj /F1 10 Tf 0 0 0 rg (is that the decorator module forces) Tj T* 0 Tw .391567 Tw (you to lift the inner function to the outer level. Moreover, you are forced to explicitly pass the function you) Tj T* 0 Tw (want to decorate; there are no closures.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.255697 Tw 12 TL /F1 10 Tf 0 0 0 rg (The difference from the nested function approach of ) Tj /F2 10 Tf 0 0 0 rg (memoize_uw ) Tj /F1 10 Tf 0 0 0 rg (is that the decorator module forces) Tj T* 0 Tw .391567 Tw (you to lift the inner function to the outer level. Moreover, you are forced to explicitly pass the function you) Tj T* 0 Tw (want to decorate; there are no closures.) Tj T* ET Q Q q @@ -2069,7 +2077,7 @@ n 162 12 18 12 re f* n 186 12 252 12 re f* .960784 .960784 .862745 rg n 0 0 24 12 re f* -BT 1 0 0 1 0 110 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@memoize) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (heavy_computation) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("done") Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (heavy_computation) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# the first time it will take 2 seconds) Tj /F3 10 Tf 0 0 0 rg T* 0 0 0 rg (done) Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (heavy_computation) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# the second time it will be instantaneous) Tj /F3 10 Tf 0 0 0 rg T* 0 0 0 rg (done) Tj T* ET +BT 1 0 0 1 0 110 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@memoize) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (heavy_computation) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("done") Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (heavy_computation) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# the first time it will take 2 seconds) Tj /F2 10 Tf 0 0 0 rg T* 0 0 0 rg (done) Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (heavy_computation) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# the second time it will be instantaneous) Tj /F2 10 Tf 0 0 0 rg T* 0 0 0 rg (done) Tj T* ET Q Q Q @@ -2078,7 +2086,7 @@ Q q 1 0 0 1 62.69291 283.4236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The signature of ) Tj /F3 10 Tf 0 0 0 rg (heavy_computation ) Tj /F1 10 Tf 0 0 0 rg (is the one you would expect:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The signature of ) Tj /F2 10 Tf 0 0 0 rg (heavy_computation ) Tj /F1 10 Tf 0 0 0 rg (is the one you would expect:) Tj T* ET Q Q q @@ -2147,7 +2155,7 @@ n 306 0 6 12 re f* n 312 0 24 12 re f* .960784 .960784 .862745 rg n 336 0 6 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (getargspec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (heavy_computation) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* 0 0 0 rg (ArgSpec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (args) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ([],) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varargs) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varkw) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (defaults) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (getargspec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (heavy_computation) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* 0 0 0 rg (ArgSpec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (args) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ([],) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varargs) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varkw) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (defaults) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -2156,13 +2164,13 @@ Q q 1 0 0 1 62.69291 205.2236 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 0 0 0 rg (trace ) Tj /F2 17.5 Tf 0 0 0 rg (decorator) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (A ) Tj /F2 17.5 Tf 0 0 0 rg (trace ) Tj /F3 17.5 Tf 0 0 0 rg (decorator) Tj T* ET Q Q q 1 0 0 1 62.69291 175.2236 cm q -BT 1 0 0 1 0 14 Tm .969986 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here is an example of how to define a simple ) Tj /F3 10 Tf 0 0 0 rg (trace ) Tj /F1 10 Tf 0 0 0 rg (decorator, which prints a message whenever the) Tj T* 0 Tw (traced function is called:) Tj T* ET +BT 1 0 0 1 0 14 Tm .969986 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here is an example of how to define a simple ) Tj /F2 10 Tf 0 0 0 rg (trace ) Tj /F1 10 Tf 0 0 0 rg (decorator, which prints a message whenever the) Tj T* 0 Tw (traced function is called:) Tj T* ET Q Q q @@ -2309,7 +2317,7 @@ n 120 0 12 12 re f* n 132 0 12 12 re f* .960784 .960784 .862745 rg n 144 0 6 12 re f* -BT 1 0 0 1 0 38 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (_trace) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (kwstr) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (', ') Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (join) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg (') Tj /F6 10 Tf .733333 .4 .533333 rg (%r) Tj /F3 10 Tf .729412 .129412 .129412 rg (: ) Tj /F6 10 Tf .733333 .4 .533333 rg (%r) Tj /F3 10 Tf .729412 .129412 .129412 rg (') Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (%) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (k) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kw) Tj 0 0 0 rg ([) Tj 0 0 0 rg (k) Tj 0 0 0 rg (]\)) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (for) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (k) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (sorted) Tj 0 0 0 rg (\() Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ("calling ) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F3 10 Tf .729412 .129412 .129412 rg ( with args ) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F3 10 Tf .729412 .129412 .129412 rg (, {) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F3 10 Tf .729412 .129412 .129412 rg (}") Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (%) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__name__) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kwstr) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 38 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (_trace) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (kwstr) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (', ') Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (join) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg (') Tj /F6 10 Tf .733333 .4 .533333 rg (%r) Tj /F2 10 Tf .729412 .129412 .129412 rg (: ) Tj /F6 10 Tf .733333 .4 .533333 rg (%r) Tj /F2 10 Tf .729412 .129412 .129412 rg (') Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (%) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (k) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kw) Tj 0 0 0 rg ([) Tj 0 0 0 rg (k) Tj 0 0 0 rg (]\)) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (for) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (k) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (sorted) Tj 0 0 0 rg (\() Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ("calling ) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F2 10 Tf .729412 .129412 .129412 rg ( with args ) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F2 10 Tf .729412 .129412 .129412 rg (, {) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F2 10 Tf .729412 .129412 .129412 rg (}") Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (%) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__name__) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kwstr) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -2318,7 +2326,7 @@ Q endstream endobj -111 0 obj +112 0 obj << /Length 19970 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -2360,7 +2368,7 @@ n 126 0 6 12 re f* n 138 0 36 12 re f* .960784 .960784 .862745 rg n 174 0 6 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (trace) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (decorate) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (_trace) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (trace) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (decorate) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (_trace) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -2411,7 +2419,7 @@ n 72 12 12 12 re f* n 0 0 18 12 re f* .960784 .960784 .862745 rg n 48 0 24 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@trace) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f1) Tj 0 0 0 rg (\() Tj 0 0 0 rg (x) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (pass) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@trace) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f1) Tj 0 0 0 rg (\() Tj 0 0 0 rg (x) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (pass) Tj T* ET Q Q Q @@ -2420,7 +2428,7 @@ Q q 1 0 0 1 62.69291 630.6236 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 /F3 10 Tf 0 0 0 rg (f1 ) Tj /F1 10 Tf 0 0 0 rg (works...) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (It is immediate to verify that ) Tj /F2 10 Tf 0 0 0 rg (f1 ) Tj /F1 10 Tf 0 0 0 rg (works...) Tj T* ET Q Q q @@ -2467,7 +2475,7 @@ n 132 0 6 12 re f* n 138 0 18 12 re f* .960784 .960784 .862745 rg n 162 0 12 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg (calling) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (with) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (,\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg ({}) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg (calling) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (with) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (,\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg ({}) Tj T* ET Q Q Q @@ -2550,7 +2558,7 @@ n 324 0 6 12 re f* n 330 0 24 12 re f* .960784 .960784 .862745 rg n 354 0 6 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (getargspec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f1) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* 0 0 0 rg (ArgSpec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (args) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ([) Tj .729412 .129412 .129412 rg ('x') Tj 0 0 0 rg (],) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varargs) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varkw) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (defaults) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (getargspec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f1) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* 0 0 0 rg (ArgSpec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (args) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ([) Tj .729412 .129412 .129412 rg ('x') Tj 0 0 0 rg (],) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varargs) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varkw) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (defaults) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -2741,7 +2749,7 @@ n 414 0 6 12 re f* n 426 0 6 12 re f* .960784 .960784 .862745 rg n 432 0 12 12 re f* -BT 1 0 0 1 0 98 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@trace) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f) Tj 0 0 0 rg (\() Tj 0 0 0 rg (x) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (y) Tj .4 .4 .4 rg (=) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (z) Tj .4 .4 .4 rg (=) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (pass) Tj /F3 10 Tf 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (3) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg (calling) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (with) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (3) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg ({}) Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (getargspec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* 0 0 0 rg (ArgSpec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (args) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ([) Tj .729412 .129412 .129412 rg ('x') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('y') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('z') Tj 0 0 0 rg (],) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varargs) Tj .4 .4 .4 rg (=) Tj .729412 .129412 .129412 rg ('args') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varkw) Tj .4 .4 .4 rg (=) Tj .729412 .129412 .129412 rg ('kw') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (defaults) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (\)\)) Tj T* ET +BT 1 0 0 1 0 98 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@trace) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f) Tj 0 0 0 rg (\() Tj 0 0 0 rg (x) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (y) Tj .4 .4 .4 rg (=) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (z) Tj .4 .4 .4 rg (=) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (pass) Tj /F2 10 Tf 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (3) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg (calling) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (with) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (3) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg ({}) Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (getargspec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* 0 0 0 rg (ArgSpec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (args) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ([) Tj .729412 .129412 .129412 rg ('x') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('y') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('z') Tj 0 0 0 rg (],) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varargs) Tj .4 .4 .4 rg (=) Tj .729412 .129412 .129412 rg ('args') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varkw) Tj .4 .4 .4 rg (=) Tj .729412 .129412 .129412 rg ('kw') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (defaults) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (\)\)) Tj T* ET Q Q Q @@ -2750,13 +2758,13 @@ Q q 1 0 0 1 62.69291 338.0236 cm q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Function annotations) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Function annotations) Tj T* ET Q Q q 1 0 0 1 62.69291 296.0236 cm q -BT 1 0 0 1 0 26 Tm .287485 Tw 12 TL /F1 10 Tf 0 0 0 rg (Python 3 introduced the concept of ) Tj 0 0 .501961 rg (function annotations) Tj 0 0 0 rg (: the ability to annotate the signature of a function) Tj T* 0 Tw 1.089069 Tw (with additional information, stored in a dictionary named ) Tj /F3 10 Tf 0 0 0 rg (__annotations__) Tj /F1 10 Tf 0 0 0 rg (. The ) Tj /F3 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module) Tj T* 0 Tw (\(starting from release 3.3\) will understand and preserve these annotations.) Tj T* ET +BT 1 0 0 1 0 26 Tm .287485 Tw 12 TL /F1 10 Tf 0 0 0 rg (Python 3 introduced the concept of ) Tj 0 0 .501961 rg (function annotations) Tj 0 0 0 rg (: the ability to annotate the signature of a function) Tj T* 0 Tw 1.089069 Tw (with additional information, stored in a dictionary named ) Tj /F2 10 Tf 0 0 0 rg (__annotations__) Tj /F1 10 Tf 0 0 0 rg (. The ) Tj /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module) Tj T* 0 Tw (\(starting from release 3.3\) will understand and preserve these annotations.) Tj T* ET Q Q q @@ -2850,7 +2858,7 @@ n 252 12 12 12 re f* n 0 0 18 12 re f* .960784 .960784 .862745 rg n 48 0 24 12 re f* -BT 1 0 0 1 0 38 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@trace) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f) Tj 0 0 0 rg (\() Tj 0 0 0 rg (x) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('the first argument') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (y) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('default argument') Tj .4 .4 .4 rg (=) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (z) Tj .4 .4 .4 rg (=) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (,) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('varargs') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('kwargs') Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (pass) Tj T* ET +BT 1 0 0 1 0 38 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@trace) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f) Tj 0 0 0 rg (\() Tj 0 0 0 rg (x) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('the first argument') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (y) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('default argument') Tj .4 .4 .4 rg (=) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (z) Tj .4 .4 .4 rg (=) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (,) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('varargs') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('kwargs') Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (pass) Tj T* ET Q Q Q @@ -2859,7 +2867,7 @@ Q q 1 0 0 1 62.69291 176.8236 cm q -BT 1 0 0 1 0 14 Tm 2.530888 Tw 12 TL /F1 10 Tf 0 0 0 rg (In order to introspect functions with annotations, one needs the utility ) Tj /F3 10 Tf 0 0 0 rg (inspect.getfullargspec) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (\(introduced in Python 3, then deprecated in Python 3.5, in favor of ) Tj /F3 10 Tf 0 0 0 rg (inspect.signature) Tj /F1 10 Tf 0 0 0 rg (\):) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.530888 Tw 12 TL /F1 10 Tf 0 0 0 rg (In order to introspect functions with annotations, one needs the utility ) Tj /F2 10 Tf 0 0 0 rg (inspect.getfullargspec) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (\(introduced in Python 3, then deprecated in Python 3.5, in favor of ) Tj /F2 10 Tf 0 0 0 rg (inspect.signature) Tj /F1 10 Tf 0 0 0 rg (\):) Tj T* ET Q Q q @@ -2948,7 +2956,7 @@ n 66 12 6 12 re f* n 72 12 42 12 re f* .960784 .960784 .862745 rg n 0 0 36 12 re f* -BT 1 0 0 1 0 62 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (from) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (inspect) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (import) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (getfullargspec) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argspec) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (getfullargspec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argspec) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (args) Tj 0 0 0 rg T* 0 0 0 rg ([) Tj .729412 .129412 .129412 rg ('x') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('y') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('z') Tj 0 0 0 rg (]) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argspec) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (varargs) Tj 0 0 0 rg T* .729412 .129412 .129412 rg ('args') Tj 0 0 0 rg T* ET +BT 1 0 0 1 0 62 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (from) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (inspect) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (import) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (getfullargspec) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argspec) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (getfullargspec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argspec) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (args) Tj 0 0 0 rg T* 0 0 0 rg ([) Tj .729412 .129412 .129412 rg ('x') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('y') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('z') Tj 0 0 0 rg (]) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argspec) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (varargs) Tj 0 0 0 rg T* .729412 .129412 .129412 rg ('args') Tj 0 0 0 rg T* ET Q Q Q @@ -2957,7 +2965,7 @@ Q endstream endobj -112 0 obj +113 0 obj << /Length 17086 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -3037,7 +3045,7 @@ n 24 0 42 12 re f* n 66 0 6 12 re f* .960784 .960784 .862745 rg n 72 0 84 12 re f* -BT 1 0 0 1 0 74 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argspec) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (varkw) Tj 0 0 0 rg T* .729412 .129412 .129412 rg ('kw') Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argspec) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (defaults) Tj 0 0 0 rg T* 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argspec) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (kwonlyargs) Tj 0 0 0 rg T* 0 0 0 rg ([]) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argspec) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (kwonlydefaults) Tj T* ET +BT 1 0 0 1 0 74 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argspec) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (varkw) Tj 0 0 0 rg T* .729412 .129412 .129412 rg ('kw') Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argspec) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (defaults) Tj 0 0 0 rg T* 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argspec) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (kwonlyargs) Tj 0 0 0 rg T* 0 0 0 rg ([]) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (argspec) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (kwonlydefaults) Tj T* ET Q Q Q @@ -3046,7 +3054,7 @@ Q q 1 0 0 1 62.69291 647.8236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (You can check that the ) Tj /F3 10 Tf 0 0 0 rg (__annotations__ ) Tj /F1 10 Tf 0 0 0 rg (dictionary is preserved:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (You can check that the ) Tj /F2 10 Tf 0 0 0 rg (__annotations__ ) Tj /F1 10 Tf 0 0 0 rg (dictionary is preserved:) Tj T* ET Q Q q @@ -3089,7 +3097,7 @@ n 228 12 6 12 re f* n 234 12 90 12 re f* .960784 .960784 .862745 rg n 0 0 24 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__annotations__) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (is) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__wrapped__) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__annotations__) Tj 0 0 0 rg T* 0 .501961 0 rg (True) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__annotations__) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (is) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__wrapped__) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__annotations__) Tj 0 0 0 rg T* 0 .501961 0 rg (True) Tj T* ET Q Q Q @@ -3098,31 +3106,31 @@ Q q 1 0 0 1 62.69291 570.6236 cm q -BT 1 0 0 1 0 14 Tm .61152 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here ) Tj /F3 10 Tf 0 0 0 rg (f.__wrapped__ ) Tj /F1 10 Tf 0 0 0 rg (is the original undecorated function. This attribute exists for consistency with the) Tj T* 0 Tw (behavior of ) Tj /F3 10 Tf 0 0 0 rg (functools.update_wrapper) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET +BT 1 0 0 1 0 14 Tm .61152 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here ) Tj /F2 10 Tf 0 0 0 rg (f.__wrapped__ ) Tj /F1 10 Tf 0 0 0 rg (is the original undecorated function. This attribute exists for consistency with the) Tj T* 0 Tw (behavior of ) Tj /F2 10 Tf 0 0 0 rg (functools.update_wrapper) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET Q Q q 1 0 0 1 62.69291 540.6236 cm q -BT 1 0 0 1 0 14 Tm 1.233828 Tw 12 TL /F1 10 Tf 0 0 0 rg (Another attribute copied from the original function is ) Tj /F3 10 Tf 0 0 0 rg (__qualname__) Tj /F1 10 Tf 0 0 0 rg (, the qualified name. This attribute) Tj T* 0 Tw (was introduced in Python 3.3.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.233828 Tw 12 TL /F1 10 Tf 0 0 0 rg (Another attribute copied from the original function is ) Tj /F2 10 Tf 0 0 0 rg (__qualname__) Tj /F1 10 Tf 0 0 0 rg (, the qualified name. This attribute) Tj T* 0 Tw (was introduced in Python 3.3.) Tj T* ET Q Q q 1 0 0 1 62.69291 507.6236 cm q -BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (decorator.decorator) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (decorator.decorator) Tj T* ET Q Q q 1 0 0 1 62.69291 453.6236 cm q -BT 1 0 0 1 0 38 Tm 2.022339 Tw 12 TL /F1 10 Tf 0 0 0 rg (It can become tedious to write a caller function \(like the above ) Tj /F3 10 Tf 0 0 0 rg (_trace ) Tj /F1 10 Tf 0 0 0 rg (example\) and then a trivial) Tj T* 0 Tw 4.834524 Tw (wrapper \() Tj /F3 10 Tf 0 0 0 rg (def) Tj ( ) Tj (trace\(f\):) Tj ( ) Tj (return) Tj ( ) Tj (decorate\(f,) Tj ( ) Tj (_trace\)) Tj /F1 10 Tf 0 0 0 rg (\) every time. Not to worry! The) Tj T* 0 Tw 1.123059 Tw /F3 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module provides an easy shortcut to convert the caller function into a signature-preserving) Tj T* 0 Tw (decorator.) Tj T* ET +BT 1 0 0 1 0 38 Tm 2.022339 Tw 12 TL /F1 10 Tf 0 0 0 rg (It can become tedious to write a caller function \(like the above ) Tj /F2 10 Tf 0 0 0 rg (_trace ) Tj /F1 10 Tf 0 0 0 rg (example\) and then a trivial) Tj T* 0 Tw 4.834524 Tw (wrapper \() Tj /F2 10 Tf 0 0 0 rg (def) Tj ( ) Tj (trace\(f\):) Tj ( ) Tj (return) Tj ( ) Tj (decorate\(f,) Tj ( ) Tj (_trace\)) Tj /F1 10 Tf 0 0 0 rg (\) every time. Not to worry! The) Tj T* 0 Tw 1.123059 Tw /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module provides an easy shortcut to convert the caller function into a signature-preserving) Tj T* 0 Tw (decorator.) Tj T* ET Q Q q 1 0 0 1 62.69291 435.6236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (It is the ) Tj /F3 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (function:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (It is the ) Tj /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (function:) Tj T* ET Q Q q @@ -3193,7 +3201,7 @@ n 270 0 24 12 re f* n 300 0 6 12 re f* .960784 .960784 .862745 rg n 312 0 54 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (from) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (decorator) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (import) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (decorator) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (decorator) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__doc__) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg (decorator) Tj 0 0 0 rg (\() Tj 0 0 0 rg (caller) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (converts) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (a) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (caller) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (function) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (into) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (a) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (decorator) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (from) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (decorator) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (import) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (decorator) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (decorator) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__doc__) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg (decorator) Tj 0 0 0 rg (\() Tj 0 0 0 rg (caller) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (converts) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (a) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (caller) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (function) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (into) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (a) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (decorator) Tj T* ET Q Q Q @@ -3202,7 +3210,7 @@ Q q 1 0 0 1 62.69291 334.4236 cm q -BT 1 0 0 1 0 26 Tm .978443 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (function can be used as a signature-changing decorator, just like ) Tj /F3 10 Tf 0 0 0 rg (classmethod ) Tj /F1 10 Tf 0 0 0 rg (and) Tj T* 0 Tw .656342 Tw /F3 10 Tf 0 0 0 rg (staticmethod) Tj /F1 10 Tf 0 0 0 rg (. But ) Tj /F3 10 Tf 0 0 0 rg (classmethod ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F3 10 Tf 0 0 0 rg (staticmethod ) Tj /F1 10 Tf 0 0 0 rg (return generic objects which are not callable.) Tj T* 0 Tw (Instead, ) Tj /F3 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (returns signature-preserving decorators \(i.e. functions with a single argument\).) Tj T* ET +BT 1 0 0 1 0 26 Tm .978443 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (function can be used as a signature-changing decorator, just like ) Tj /F2 10 Tf 0 0 0 rg (classmethod ) Tj /F1 10 Tf 0 0 0 rg (and) Tj T* 0 Tw .656342 Tw /F2 10 Tf 0 0 0 rg (staticmethod) Tj /F1 10 Tf 0 0 0 rg (. But ) Tj /F2 10 Tf 0 0 0 rg (classmethod ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F2 10 Tf 0 0 0 rg (staticmethod ) Tj /F1 10 Tf 0 0 0 rg (return generic objects which are not callable.) Tj T* 0 Tw (Instead, ) Tj /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (returns signature-preserving decorators \(i.e. functions with a single argument\).) Tj T* ET Q Q q @@ -3372,7 +3380,7 @@ n 144 0 12 12 re f* n 156 0 12 12 re f* .960784 .960784 .862745 rg n 168 0 6 12 re f* -BT 1 0 0 1 0 50 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@decorator) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (trace) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kwstr) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (', ') Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (join) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg (') Tj /F6 10 Tf .733333 .4 .533333 rg (%r) Tj /F3 10 Tf .729412 .129412 .129412 rg (: ) Tj /F6 10 Tf .733333 .4 .533333 rg (%r) Tj /F3 10 Tf .729412 .129412 .129412 rg (') Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (%) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (k) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kw) Tj 0 0 0 rg ([) Tj 0 0 0 rg (k) Tj 0 0 0 rg (]\)) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (for) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (k) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (sorted) Tj 0 0 0 rg (\() Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ("calling ) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F3 10 Tf .729412 .129412 .129412 rg ( with args ) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F3 10 Tf .729412 .129412 .129412 rg (, {) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F3 10 Tf .729412 .129412 .129412 rg (}") Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (%) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__name__) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kwstr) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 50 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@decorator) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (trace) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kwstr) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (', ') Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (join) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg (') Tj /F6 10 Tf .733333 .4 .533333 rg (%r) Tj /F2 10 Tf .729412 .129412 .129412 rg (: ) Tj /F6 10 Tf .733333 .4 .533333 rg (%r) Tj /F2 10 Tf .729412 .129412 .129412 rg (') Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (%) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (k) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kw) Tj 0 0 0 rg ([) Tj 0 0 0 rg (k) Tj 0 0 0 rg (]\)) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (for) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (k) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (sorted) Tj 0 0 0 rg (\() Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ("calling ) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F2 10 Tf .729412 .129412 .129412 rg ( with args ) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F2 10 Tf .729412 .129412 .129412 rg (, {) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F2 10 Tf .729412 .129412 .129412 rg (}") Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (%) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__name__) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kwstr) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -3381,7 +3389,7 @@ Q q 1 0 0 1 62.69291 215.2236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (And ) Tj /F3 10 Tf 0 0 0 rg (trace ) Tj /F1 10 Tf 0 0 0 rg (is now a decorator!) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (And ) Tj /F2 10 Tf 0 0 0 rg (trace ) Tj /F1 10 Tf 0 0 0 rg (is now a decorator!) Tj T* ET Q Q q @@ -3422,7 +3430,7 @@ n 120 0 6 12 re f* n 126 0 18 12 re f* .960784 .960784 .862745 rg n 144 0 6 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (trace) Tj 0 0 0 rg T* .4 .4 .4 rg (<) Tj 0 0 0 rg (function) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (trace) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (at) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (x) Tj .4 .4 .4 rg (...) Tj (>) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (trace) Tj 0 0 0 rg T* .4 .4 .4 rg (<) Tj 0 0 0 rg (function) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (trace) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (at) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (x) Tj .4 .4 .4 rg (...) Tj (>) Tj T* ET Q Q Q @@ -3467,7 +3475,7 @@ n 48 12 24 12 re f* n 72 12 18 12 re f* .960784 .960784 .862745 rg n 96 12 24 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@trace) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (func) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (pass) Tj /F3 10 Tf 0 0 0 rg T* T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@trace) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (func) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (pass) Tj /F2 10 Tf 0 0 0 rg T* T* ET Q Q Q @@ -3476,7 +3484,7 @@ Q endstream endobj -113 0 obj +114 0 obj << /Length 17621 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -3516,7 +3524,7 @@ n 108 0 24 12 re f* n 138 0 18 12 re f* .960784 .960784 .862745 rg n 162 0 12 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* 0 0 0 rg (calling) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (with) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg ({}) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* 0 0 0 rg (calling) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (with) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg ({}) Tj T* ET Q Q Q @@ -3525,13 +3533,13 @@ Q q 1 0 0 1 62.69291 694.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 +BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (blocking) Tj T* ET Q Q q 1 0 0 1 62.69291 652.8236 cm q -BT 1 0 0 1 0 26 Tm .767633 Tw 12 TL /F1 10 Tf 0 0 0 rg (Sometimes one has to deal with blocking resources, such as ) Tj /F3 10 Tf 0 0 0 rg (stdin) Tj /F1 10 Tf 0 0 0 rg (. Sometimes it is better to receive a) Tj T* 0 Tw 3.004269 Tw ("busy" message than just blocking everything. This can be accomplished with a suitable family of) Tj T* 0 Tw (decorators, where the parameter is the busy message:) Tj T* ET +BT 1 0 0 1 0 26 Tm .767633 Tw 12 TL /F1 10 Tf 0 0 0 rg (Sometimes one has to deal with blocking resources, such as ) Tj /F2 10 Tf 0 0 0 rg (stdin) Tj /F1 10 Tf 0 0 0 rg (. Sometimes it is better to receive a) Tj T* 0 Tw 3.004269 Tw ("busy" message than just blocking everything. This can be accomplished with a suitable family of) Tj T* 0 Tw (decorators, where the parameter is the busy message:) Tj T* ET Q Q q @@ -3718,7 +3726,7 @@ n 120 0 6 12 re f* n 126 0 54 12 re f* .960784 .960784 .862745 rg n 180 0 6 12 re f* -BT 1 0 0 1 0 158 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (blocking) Tj 0 0 0 rg (\() Tj 0 0 0 rg (not_avail) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (_blocking) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (not) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (hasattr) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("thread") Tj 0 0 0 rg (\):) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# no thread running) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (set_result) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (result) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (thread) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (threading) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Thread) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (set_result) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (thread) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (start) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (not_avail) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (elif) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (thread) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (isAlive) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (not_avail) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (else) Tj /F3 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# the thread is ended, return the stored result) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (del) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (thread) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (result) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (decorator) Tj 0 0 0 rg (\() Tj 0 0 0 rg (_blocking) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 158 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (blocking) Tj 0 0 0 rg (\() Tj 0 0 0 rg (not_avail) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (_blocking) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (not) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (hasattr) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("thread") Tj 0 0 0 rg (\):) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# no thread running) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (set_result) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (result) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (thread) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (threading) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Thread) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (set_result) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (thread) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (start) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (not_avail) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (elif) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (thread) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (isAlive) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (not_avail) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (else) Tj /F2 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# the thread is ended, return the stored result) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (del) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (thread) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (result) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (decorator) Tj 0 0 0 rg (\() Tj 0 0 0 rg (_blocking) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -3727,7 +3735,7 @@ Q q 1 0 0 1 62.69291 431.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 /F3 10 Tf 0 0 0 rg (blocking ) Tj /F1 10 Tf 0 0 0 rg (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 +BT 1 0 0 1 0 14 Tm 1.010651 Tw 12 TL /F1 10 Tf 0 0 0 rg (Functions decorated with ) Tj /F2 10 Tf 0 0 0 rg (blocking ) Tj /F1 10 Tf 0 0 0 rg (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 @@ -3928,7 +3936,7 @@ n 114 12 18 12 re f* n 0 0 24 12 re f* .960784 .960784 .862745 rg n 30 0 24 12 re f* -BT 1 0 0 1 0 218 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@blocking) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ("Please wait ...") Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (read_data) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (3) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# simulate a blocking resource) Tj /F3 10 Tf 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("some data") Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (read_data) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# data is not available yet) Tj /F3 10 Tf 0 0 0 rg T* 0 0 0 rg (Please) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (wait) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (read_data) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# data is not available yet) Tj /F3 10 Tf 0 0 0 rg T* 0 0 0 rg (Please) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (wait) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (read_data) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# data is not available yet) Tj /F3 10 Tf 0 0 0 rg T* 0 0 0 rg (Please) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (wait) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1.1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# after 3.1 seconds, data is available) Tj /F3 10 Tf 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (read_data) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* 0 0 0 rg (some) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (data) Tj T* ET +BT 1 0 0 1 0 218 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@blocking) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ("Please wait ...") Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (read_data) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (3) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# simulate a blocking resource) Tj /F2 10 Tf 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("some data") Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (read_data) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# data is not available yet) Tj /F2 10 Tf 0 0 0 rg T* 0 0 0 rg (Please) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (wait) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (read_data) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# data is not available yet) Tj /F2 10 Tf 0 0 0 rg T* 0 0 0 rg (Please) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (wait) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (read_data) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# data is not available yet) Tj /F2 10 Tf 0 0 0 rg T* 0 0 0 rg (Please) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (wait) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1.1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# after 3.1 seconds, data is available) Tj /F2 10 Tf 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (read_data) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* 0 0 0 rg (some) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (data) Tj T* ET Q Q Q @@ -3937,13 +3945,13 @@ Q q 1 0 0 1 62.69291 149.4236 cm q -BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (decorator\(cls\)) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (decorator\(cls\)) Tj T* ET Q Q q 1 0 0 1 62.69291 107.4236 cm q -BT 1 0 0 1 0 26 Tm .441163 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (facility can also produce a decorator starting from a class with the signature of a caller.) Tj T* 0 Tw .041654 Tw (In such a case the produced generator is able to convert functions into factories to create instances of that) Tj T* 0 Tw (class.) Tj T* ET +BT 1 0 0 1 0 26 Tm .441163 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (facility can also produce a decorator starting from a class with the signature of a caller.) Tj T* 0 Tw .041654 Tw (In such a case the produced generator is able to convert functions into factories to create instances of that) Tj T* 0 Tw (class.) Tj T* ET Q Q q @@ -3956,14 +3964,14 @@ Q endstream endobj -114 0 obj +115 0 obj << /Length 18239 >> 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 q -BT 1 0 0 1 0 14 Tm .143318 Tw 12 TL /F1 10 Tf 0 0 0 rg (\(This is similar to the approach used in the ) Tj /F3 10 Tf 0 0 0 rg (concurrent.futures ) Tj /F1 10 Tf 0 0 0 rg (package. But I don't recommend that) Tj T* 0 Tw (you implement futures this way; this is just an example.\)) Tj T* ET +BT 1 0 0 1 0 14 Tm .143318 Tw 12 TL /F1 10 Tf 0 0 0 rg (\(This is similar to the approach used in the ) Tj /F2 10 Tf 0 0 0 rg (concurrent.futures ) Tj /F1 10 Tf 0 0 0 rg (package. But I don't recommend that) Tj T* 0 Tw (you implement futures this way; this is just an example.\)) Tj T* ET Q Q q @@ -4206,7 +4214,7 @@ n 90 0 24 12 re f* n 114 0 6 12 re f* .960784 .960784 .862745 rg n 120 0 42 12 re f* -BT 1 0 0 1 0 230 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (Future) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (threading) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Thread) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F7 10 Tf .729412 .129412 .129412 rg (""") Tj T* ( A class converting blocking functions into asynchronous) Tj T* ( functions by using threads.) Tj T* ( """) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 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 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (try) Tj /F3 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (counter) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (counter) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (except) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .823529 .254902 .227451 rg (AttributeError) Tj /F3 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# instantiate the counter at the first call) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj 0 0 0 rg (counter) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (counter) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (itertools) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (count) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (name) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (') Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F3 10 Tf .729412 .129412 .129412 rg (-) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F3 10 Tf .729412 .129412 .129412 rg (') Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (%) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__name__) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (next) Tj 0 0 0 rg (\() Tj 0 0 0 rg (counter) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (func_wrapper) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (_result) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (super) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Future) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (\)) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__init__) Tj 0 0 0 rg (\() Tj 0 0 0 rg (target) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (func_wrapper) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (name) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (name) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (start) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (result) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (join) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (_result) Tj T* ET +BT 1 0 0 1 0 230 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (Future) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (threading) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Thread) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F7 10 Tf .729412 .129412 .129412 rg (""") Tj T* ( A class converting blocking functions into asynchronous) Tj T* ( functions by using threads.) Tj T* ( """) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 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 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (try) Tj /F2 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (counter) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (counter) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (except) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .823529 .254902 .227451 rg (AttributeError) Tj /F2 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# instantiate the counter at the first call) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj 0 0 0 rg (counter) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (counter) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (itertools) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (count) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (name) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (') Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F2 10 Tf .729412 .129412 .129412 rg (-) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F2 10 Tf .729412 .129412 .129412 rg (') Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (%) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__name__) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (next) Tj 0 0 0 rg (\() Tj 0 0 0 rg (counter) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (func_wrapper) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (_result) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (super) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Future) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (\)) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__init__) Tj 0 0 0 rg (\() Tj 0 0 0 rg (target) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (func_wrapper) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (name) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (name) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (start) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (result) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (join) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (_result) Tj T* ET Q Q Q @@ -4215,7 +4223,7 @@ Q q 1 0 0 1 62.69291 447.8236 cm q -BT 1 0 0 1 0 14 Tm 1.477318 Tw 12 TL /F1 10 Tf 0 0 0 rg (The decorated function returns a ) Tj /F3 10 Tf 0 0 0 rg (Future ) Tj /F1 10 Tf 0 0 0 rg (object. It has a ) Tj /F3 10 Tf 0 0 0 rg (.result\(\) ) Tj /F1 10 Tf 0 0 0 rg (method which blocks until the) Tj T* 0 Tw (underlying thread finishes and returns the final result.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.477318 Tw 12 TL /F1 10 Tf 0 0 0 rg (The decorated function returns a ) Tj /F2 10 Tf 0 0 0 rg (Future ) Tj /F1 10 Tf 0 0 0 rg (object. It has a ) Tj /F2 10 Tf 0 0 0 rg (.result\(\) ) Tj /F1 10 Tf 0 0 0 rg (method which blocks until the) Tj T* 0 Tw (underlying thread finishes and returns the final result.) Tj T* ET Q Q q @@ -4349,7 +4357,7 @@ n 150 12 36 12 re f* n 186 12 12 12 re f* .960784 .960784 .862745 rg n 0 0 6 12 re f* -BT 1 0 0 1 0 98 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@decorator) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Future) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (long_running) Tj 0 0 0 rg (\() Tj 0 0 0 rg (x) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (.) Tj .4 .4 .4 rg (5) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (x) Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (fut1) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (long_running) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (fut2) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (long_running) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (fut1) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (result) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (+) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (fut2) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (result) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* .4 .4 .4 rg (3) Tj T* ET +BT 1 0 0 1 0 98 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@decorator) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Future) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (long_running) Tj 0 0 0 rg (\() Tj 0 0 0 rg (x) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (time) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (sleep) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (.) Tj .4 .4 .4 rg (5) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (x) Tj 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (fut1) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (long_running) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (fut2) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (long_running) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (fut1) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (result) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (+) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (fut2) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (result) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* .4 .4 .4 rg (3) Tj T* ET Q Q Q @@ -4358,13 +4366,13 @@ Q q 1 0 0 1 62.69291 267.6236 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 +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (contextmanager) Tj T* ET Q Q q 1 0 0 1 62.69291 237.6236 cm q -BT 1 0 0 1 0 14 Tm .604147 Tw 12 TL /F1 10 Tf 0 0 0 rg (Python's standard library has the ) Tj /F3 10 Tf 0 0 0 rg (contextmanager ) Tj /F1 10 Tf 0 0 0 rg (decorator, which converts a generator function into) Tj T* 0 Tw (a ) Tj /F3 10 Tf 0 0 0 rg (GeneratorContextManager ) Tj /F1 10 Tf 0 0 0 rg (factory. For instance, if you write this...) Tj T* ET +BT 1 0 0 1 0 14 Tm .604147 Tw 12 TL /F1 10 Tf 0 0 0 rg (Python's standard library has the ) Tj /F2 10 Tf 0 0 0 rg (contextmanager ) Tj /F1 10 Tf 0 0 0 rg (decorator, which converts a generator function into) Tj T* 0 Tw (a ) Tj /F2 10 Tf 0 0 0 rg (GeneratorContextManager ) Tj /F1 10 Tf 0 0 0 rg (factory. For instance, if you write this...) Tj T* ET Q Q q @@ -4443,7 +4451,7 @@ n 78 0 6 12 re f* n 84 0 30 12 re f* .960784 .960784 .862745 rg n 114 0 6 12 re f* -BT 1 0 0 1 0 62 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (from) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (contextlib) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (import) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (contextmanager) Tj 0 0 0 rg 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 /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (before_after) Tj 0 0 0 rg (\() Tj 0 0 0 rg (before) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (after) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (before) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (yield) Tj /F3 10 Tf 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (after) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 62 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (from) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (contextlib) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (import) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (contextmanager) Tj 0 0 0 rg 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 /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (before_after) Tj 0 0 0 rg (\() Tj 0 0 0 rg (before) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (after) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (before) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (yield) Tj /F2 10 Tf 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (after) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -4452,14 +4460,14 @@ Q q 1 0 0 1 62.69291 112.4236 cm q -BT 1 0 0 1 0 14 Tm 1.221976 Tw 12 TL /F1 10 Tf 0 0 0 rg (...then ) Tj /F3 10 Tf 0 0 0 rg (before_after ) Tj /F1 10 Tf 0 0 0 rg (is a factory function that returns ) Tj /F3 10 Tf 0 0 0 rg (GeneratorContextManager ) Tj /F1 10 Tf 0 0 0 rg (objects, which) Tj T* 0 Tw (provide the use of the ) Tj /F3 10 Tf 0 0 0 rg (with ) Tj /F1 10 Tf 0 0 0 rg (statement:) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.221976 Tw 12 TL /F1 10 Tf 0 0 0 rg (...then ) Tj /F2 10 Tf 0 0 0 rg (before_after ) Tj /F1 10 Tf 0 0 0 rg (is a factory function that returns ) Tj /F2 10 Tf 0 0 0 rg (GeneratorContextManager ) Tj /F1 10 Tf 0 0 0 rg (objects, which) Tj T* 0 Tw (provide the use of the ) Tj /F2 10 Tf 0 0 0 rg (with ) Tj /F1 10 Tf 0 0 0 rg (statement:) Tj T* ET Q Q endstream endobj -115 0 obj -<< /Length 10880 >> +116 0 obj +<< /Length 10884 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q @@ -4512,7 +4520,7 @@ n 0 24 36 12 re f* n 0 12 30 12 re f* .960784 .960784 .862745 rg n 0 0 30 12 re f* -BT 1 0 0 1 0 50 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (with) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (before_after) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('BEFORE') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('AFTER') Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('hello') Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg (BEFORE) Tj 0 0 0 rg T* 0 0 0 rg (hello) Tj 0 0 0 rg T* 0 0 0 rg (AFTER) Tj T* ET +BT 1 0 0 1 0 50 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (with) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (before_after) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('BEFORE') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('AFTER') Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('hello') Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg (BEFORE) Tj 0 0 0 rg T* 0 0 0 rg (hello) Tj 0 0 0 rg T* 0 0 0 rg (AFTER) Tj T* ET Q Q Q @@ -4521,13 +4529,13 @@ Q q 1 0 0 1 62.69291 659.8236 cm q -BT 1 0 0 1 0 14 Tm .462488 Tw 12 TL /F1 10 Tf 0 0 0 rg (Basically, it is as if the content of the ) Tj /F3 10 Tf 0 0 0 rg (with ) Tj /F1 10 Tf 0 0 0 rg (block was executed in the place of the ) Tj /F3 10 Tf 0 0 0 rg (yield ) Tj /F1 10 Tf 0 0 0 rg (expression in) Tj T* 0 Tw (the generator function.) Tj T* ET +BT 1 0 0 1 0 14 Tm .462488 Tw 12 TL /F1 10 Tf 0 0 0 rg (Basically, it is as if the content of the ) Tj /F2 10 Tf 0 0 0 rg (with ) Tj /F1 10 Tf 0 0 0 rg (block was executed in the place of the ) Tj /F2 10 Tf 0 0 0 rg (yield ) Tj /F1 10 Tf 0 0 0 rg (expression in) Tj T* 0 Tw (the generator function.) Tj T* ET Q Q q 1 0 0 1 62.69291 629.8236 cm q -BT 1 0 0 1 0 14 Tm .32998 Tw 12 TL /F1 10 Tf 0 0 0 rg (In Python 3.2, ) Tj /F3 10 Tf 0 0 0 rg (GeneratorContextManager ) Tj /F1 10 Tf 0 0 0 rg (objects were enhanced with a ) Tj /F3 10 Tf 0 0 0 rg (__call__ ) Tj /F1 10 Tf 0 0 0 rg (method, so that) Tj T* 0 Tw (they can be used as decorators, like so:) Tj T* ET +BT 1 0 0 1 0 14 Tm .32998 Tw 12 TL /F1 10 Tf 0 0 0 rg (In Python 3.2, ) Tj /F2 10 Tf 0 0 0 rg (GeneratorContextManager ) Tj /F1 10 Tf 0 0 0 rg (objects were enhanced with a ) Tj /F2 10 Tf 0 0 0 rg (__call__ ) Tj /F1 10 Tf 0 0 0 rg (method, so that) Tj T* 0 Tw (they can be used as decorators, like so:) Tj T* ET Q Q q @@ -4588,7 +4596,7 @@ n 0 24 36 12 re f* n 0 12 30 12 re f* .960784 .960784 .862745 rg n 0 0 30 12 re f* -BT 1 0 0 1 0 86 Tm 12 TL /F3 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 /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (hello) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('hello') Tj 0 0 0 rg (\)) 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 0 0 0 rg (hello) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* 0 0 0 rg (BEFORE) Tj 0 0 0 rg T* 0 0 0 rg (hello) Tj 0 0 0 rg T* 0 0 0 rg (AFTER) Tj T* ET +BT 1 0 0 1 0 86 Tm 12 TL /F2 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 /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (hello) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('hello') Tj 0 0 0 rg (\)) 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 0 0 0 rg (hello) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* 0 0 0 rg (BEFORE) Tj 0 0 0 rg T* 0 0 0 rg (hello) Tj 0 0 0 rg T* 0 0 0 rg (AFTER) Tj T* ET Q Q Q @@ -4597,14 +4605,14 @@ Q q 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 ) Tj /F3 10 Tf 0 0 0 rg (ba ) Tj /F1 10 Tf 0 0 0 rg (decorator basically inserts a ) Tj /F3 10 Tf 0 0 0 rg (with) Tj ( ) Tj (ba: ) Tj /F1 10 Tf 0 0 0 rg (block inside the function.) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F2 10 Tf 0 0 0 rg (ba ) Tj /F1 10 Tf 0 0 0 rg (decorator basically inserts a ) Tj /F2 10 Tf 0 0 0 rg (with) Tj ( ) Tj (ba: ) Tj /F1 10 Tf 0 0 0 rg (block inside the function.) Tj T* ET Q Q q 1 0 0 1 62.69291 474.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (However, there two issues:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (However, there are two issues:) Tj T* ET Q Q q @@ -4627,7 +4635,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 26 Tm 2.209979 Tw 12 TL /F3 10 Tf 0 0 0 rg (GeneratorContextManager ) Tj /F1 10 Tf 0 0 0 rg (objects are only callable in Python 3.2, so the previous example) Tj T* 0 Tw .369983 Tw (breaks in older versions of Python. \(You can solve this by installing ) Tj /F3 10 Tf 0 0 0 rg (contextlib2) Tj /F1 10 Tf 0 0 0 rg (, which backports) Tj T* 0 Tw (the Python 3 functionality to Python 2.\)) Tj T* ET +BT 1 0 0 1 0 26 Tm 2.209979 Tw 12 TL /F2 10 Tf 0 0 0 rg (GeneratorContextManager ) Tj /F1 10 Tf 0 0 0 rg (objects are only callable in Python 3.2, so the previous example) Tj T* 0 Tw .369983 Tw (breaks in older versions of Python. \(You can solve this by installing ) Tj /F2 10 Tf 0 0 0 rg (contextlib2) Tj /F1 10 Tf 0 0 0 rg (, which backports) Tj T* 0 Tw (the Python 3 functionality to Python 2.\)) Tj T* ET Q Q q @@ -4650,7 +4658,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 26 Tm .085433 Tw 12 TL /F3 10 Tf 0 0 0 rg (GeneratorContextManager ) Tj /F1 10 Tf 0 0 0 rg (objects do not preserve the signature of the decorated functions. The) Tj T* 0 Tw .643615 Tw (decorated ) Tj /F3 10 Tf 0 0 0 rg (hello ) Tj /F1 10 Tf 0 0 0 rg (function above will have the generic signature ) Tj /F3 10 Tf 0 0 0 rg (hello\(*args,) Tj ( ) Tj (**kwargs\)) Tj /F1 10 Tf 0 0 0 rg (, but) Tj T* 0 Tw (fails if called with more than zero arguments.) Tj T* ET +BT 1 0 0 1 0 26 Tm .085433 Tw 12 TL /F2 10 Tf 0 0 0 rg (GeneratorContextManager ) Tj /F1 10 Tf 0 0 0 rg (objects do not preserve the signature of the decorated functions. The) Tj T* 0 Tw .643615 Tw (decorated ) Tj /F2 10 Tf 0 0 0 rg (hello ) Tj /F1 10 Tf 0 0 0 rg (function above will have the generic signature ) Tj /F2 10 Tf 0 0 0 rg (hello\(*args,) Tj ( ) Tj (**kwargs\)) Tj /F1 10 Tf 0 0 0 rg (, but) Tj T* 0 Tw (fails if called with more than zero arguments.) Tj T* ET Q Q q @@ -4662,31 +4670,31 @@ Q q 1 0 0 1 62.69291 312.6236 cm q -BT 1 0 0 1 0 62 Tm 12.45089 Tw 12 TL /F1 10 Tf 0 0 0 rg (For these reasons, the ) Tj /F4 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module, starting from release 3.4, offers a) Tj T* 0 Tw .774524 Tw /F3 10 Tf 0 0 0 rg (decorator.contextmanager ) Tj /F1 10 Tf 0 0 0 rg (decorator that solves both problems, ) Tj /F4 10 Tf (and ) Tj /F1 10 Tf (works in all supported Python) Tj T* 0 Tw .989069 Tw (versions. Its usage is identical, and factories decorated with ) Tj /F3 10 Tf 0 0 0 rg (decorator.contextmanager ) Tj /F1 10 Tf 0 0 0 rg (will return) Tj T* 0 Tw 21.31872 Tw (instances of ) Tj /F3 10 Tf 0 0 0 rg (ContextManager) Tj /F1 10 Tf 0 0 0 rg (, a subclass of the standard library's) Tj T* 0 Tw 3.514252 Tw /F3 10 Tf 0 0 0 rg (contextlib.GeneratorContextManager ) Tj /F1 10 Tf 0 0 0 rg (class. The subclass includes an improved ) Tj /F3 10 Tf 0 0 0 rg (__call__) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (method, which acts as a signature-preserving decorator.) Tj T* ET +BT 1 0 0 1 0 62 Tm 12.45089 Tw 12 TL /F1 10 Tf 0 0 0 rg (For these reasons, the ) Tj /F4 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module, starting from release 3.4, offers a) Tj T* 0 Tw .774524 Tw /F2 10 Tf 0 0 0 rg (decorator.contextmanager ) Tj /F1 10 Tf 0 0 0 rg (decorator that solves both problems, ) Tj /F4 10 Tf (and ) Tj /F1 10 Tf (works in all supported Python) Tj T* 0 Tw .989069 Tw (versions. Its usage is identical, and factories decorated with ) Tj /F2 10 Tf 0 0 0 rg (decorator.contextmanager ) Tj /F1 10 Tf 0 0 0 rg (will return) Tj T* 0 Tw 21.31872 Tw (instances of ) Tj /F2 10 Tf 0 0 0 rg (ContextManager) Tj /F1 10 Tf 0 0 0 rg (, a subclass of the standard library's) Tj T* 0 Tw 3.514252 Tw /F2 10 Tf 0 0 0 rg (contextlib.GeneratorContextManager ) Tj /F1 10 Tf 0 0 0 rg (class. The subclass includes an improved ) Tj /F2 10 Tf 0 0 0 rg (__call__) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (method, which acts as a signature-preserving decorator.) Tj T* ET Q Q q 1 0 0 1 62.69291 279.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 0 0 0 rg (FunctionMaker ) Tj /F2 17.5 Tf 0 0 0 rg (class) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (The ) Tj /F2 17.5 Tf 0 0 0 rg (FunctionMaker ) Tj /F3 17.5 Tf 0 0 0 rg (class) Tj T* ET Q Q q 1 0 0 1 62.69291 237.6236 cm q -BT 1 0 0 1 0 26 Tm 1.567126 Tw 12 TL /F1 10 Tf 0 0 0 rg (You may wonder how the functionality of the ) Tj /F3 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module is implemented. The basic building) Tj T* 0 Tw .233318 Tw (block is a ) Tj /F3 10 Tf 0 0 0 rg (FunctionMaker ) Tj /F1 10 Tf 0 0 0 rg (class. It generates on-the-fly functions with a given name and signature from) Tj T* 0 Tw (a function template passed as a string.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.567126 Tw 12 TL /F1 10 Tf 0 0 0 rg (You may wonder how the functionality of the ) Tj /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module is implemented. The basic building) Tj T* 0 Tw .233318 Tw (block is a ) Tj /F2 10 Tf 0 0 0 rg (FunctionMaker ) Tj /F1 10 Tf 0 0 0 rg (class. It generates on-the-fly functions with a given name and signature from) Tj T* 0 Tw (a function template passed as a string.) Tj T* ET Q Q q 1 0 0 1 62.69291 195.6236 cm q -BT 1 0 0 1 0 26 Tm .612126 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you're just writing ordinary decorators, then you probably won't need to use ) Tj /F3 10 Tf 0 0 0 rg (FunctionMaker ) Tj /F1 10 Tf 0 0 0 rg (directly.) Tj T* 0 Tw .603516 Tw (But in some circumstances, it can be handy. You will see an example shortly--in the implementation of a) Tj T* 0 Tw (cool decorator utility \() Tj /F3 10 Tf 0 0 0 rg (decorator_apply) Tj /F1 10 Tf 0 0 0 rg (\).) Tj T* ET +BT 1 0 0 1 0 26 Tm .612126 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you're just writing ordinary decorators, then you probably won't need to use ) Tj /F2 10 Tf 0 0 0 rg (FunctionMaker ) Tj /F1 10 Tf 0 0 0 rg (directly.) Tj T* 0 Tw .603516 Tw (But in some circumstances, it can be handy. You will see an example shortly--in the implementation of a) Tj T* 0 Tw (cool decorator utility \() Tj /F2 10 Tf 0 0 0 rg (decorator_apply) Tj /F1 10 Tf 0 0 0 rg (\).) Tj T* ET Q Q q 1 0 0 1 62.69291 153.6236 cm q -BT 1 0 0 1 0 26 Tm .865814 Tw 12 TL /F3 10 Tf 0 0 0 rg (FunctionMaker ) Tj /F1 10 Tf 0 0 0 rg (provides the ) Tj /F3 10 Tf 0 0 0 rg (.create ) Tj /F1 10 Tf 0 0 0 rg (classmethod, which accepts the ) Tj /F4 10 Tf (name) Tj /F1 10 Tf (, ) Tj /F4 10 Tf (signature) Tj /F1 10 Tf (, and ) Tj /F4 10 Tf (body ) Tj /F1 10 Tf (of) Tj T* 0 Tw .637485 Tw (the function you want to generate, as well as the execution environment where the function is generated) Tj T* 0 Tw (by ) Tj /F3 10 Tf 0 0 0 rg (exec) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET +BT 1 0 0 1 0 26 Tm .865814 Tw 12 TL /F2 10 Tf 0 0 0 rg (FunctionMaker ) Tj /F1 10 Tf 0 0 0 rg (provides the ) Tj /F2 10 Tf 0 0 0 rg (.create ) Tj /F1 10 Tf 0 0 0 rg (classmethod, which accepts the ) Tj /F4 10 Tf (name) Tj /F1 10 Tf (, ) Tj /F4 10 Tf (signature) Tj /F1 10 Tf (, and ) Tj /F4 10 Tf (body ) Tj /F1 10 Tf (of) Tj T* 0 Tw .637485 Tw (the function you want to generate, as well as the execution environment where the function is generated) Tj T* 0 Tw (by ) Tj /F2 10 Tf 0 0 0 rg (exec) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET Q Q q @@ -4750,7 +4758,7 @@ n 108 12 6 12 re f* n 120 12 12 12 re f* .960784 .960784 .862745 rg n 132 12 6 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# a function with a generic signature) Tj /F3 10 Tf 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# a function with a generic signature) Tj /F2 10 Tf 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* T* ET Q Q Q @@ -4759,8 +4767,8 @@ Q endstream endobj -116 0 obj -<< /Length 17445 >> +117 0 obj +<< /Length 17440 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q @@ -4845,7 +4853,7 @@ n 24 0 6 12 re f* n 30 0 6 12 re f* .960784 .960784 .862745 rg n 42 0 12 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (FunctionMaker) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (create) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('f1\(a, b\)') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('f\(a, b\)') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (dict) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj 0 0 0 rg ({}) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (FunctionMaker) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (create) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('f1\(a, b\)') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('f\(a, b\)') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (dict) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg (\() Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj 0 0 0 rg ({}) Tj T* ET Q Q Q @@ -4854,19 +4862,19 @@ Q q 1 0 0 1 62.69291 683.8236 cm q -BT 1 0 0 1 0 14 Tm .116098 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is important to notice that the function body is interpolated before being executed; ) Tj /F2 10 Tf (be careful ) Tj /F1 10 Tf (with the ) Tj /F3 10 Tf 0 0 0 rg (%) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (sign!) Tj T* ET +BT 1 0 0 1 0 14 Tm .116098 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is important to notice that the function body is interpolated before being executed; ) Tj /F3 10 Tf (be careful ) Tj /F1 10 Tf (with the ) Tj /F2 10 Tf 0 0 0 rg (%) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (sign!) Tj T* ET Q Q q 1 0 0 1 62.69291 641.8236 cm q -BT 1 0 0 1 0 26 Tm .22816 Tw 12 TL /F3 10 Tf 0 0 0 rg (FunctionMaker.create ) Tj /F1 10 Tf 0 0 0 rg (also accepts keyword arguments. The keyword arguments are attached to the) Tj T* 0 Tw 3.385984 Tw (generated function. This is useful if you want to set some function attributes \(e.g., the docstring) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (__doc__) Tj /F1 10 Tf 0 0 0 rg (\).) Tj T* ET +BT 1 0 0 1 0 26 Tm .22816 Tw 12 TL /F2 10 Tf 0 0 0 rg (FunctionMaker.create ) Tj /F1 10 Tf 0 0 0 rg (also accepts keyword arguments. The keyword arguments are attached to the) Tj T* 0 Tw 3.385984 Tw (generated function. This is useful if you want to set some function attributes \(e.g., the docstring) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (__doc__) Tj /F1 10 Tf 0 0 0 rg (\).) Tj T* ET Q Q q 1 0 0 1 62.69291 611.8236 cm q -BT 1 0 0 1 0 14 Tm .419984 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 (To do this, just pass ) Tj /F3 10 Tf 0 0 0 rg (addsource=True) Tj /F1 10 Tf 0 0 0 rg (, and the generated function will get a ) Tj /F3 10 Tf 0 0 0 rg (__source__ ) Tj /F1 10 Tf 0 0 0 rg (attribute:) Tj T* ET +BT 1 0 0 1 0 14 Tm .419984 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 (To do this, just pass ) Tj /F2 10 Tf 0 0 0 rg (addsource=True) Tj /F1 10 Tf 0 0 0 rg (, and the generated function will get a ) Tj /F2 10 Tf 0 0 0 rg (__source__ ) Tj /F1 10 Tf 0 0 0 rg (attribute:) Tj T* ET Q Q q @@ -4981,7 +4989,7 @@ n 0 0 6 12 re f* n 6 0 54 12 re f* .960784 .960784 .862745 rg n 60 0 6 12 re f* -BT 1 0 0 1 0 62 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (FunctionMaker) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (create) Tj 0 0 0 rg (\() Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('f1\(a, b\)') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('f\(a, b\)') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (dict) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (addsource) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (True) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (f1) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__source__) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f1) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (<) Tj 0 0 0 rg (BLANKLINE) Tj .4 .4 .4 rg (>) Tj T* ET +BT 1 0 0 1 0 62 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (FunctionMaker) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (create) Tj 0 0 0 rg (\() Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('f1\(a, b\)') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('f\(a, b\)') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (dict) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (addsource) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (True) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (f1) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__source__) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f1) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (<) Tj 0 0 0 rg (BLANKLINE) Tj .4 .4 .4 rg (>) Tj T* ET Q Q Q @@ -4990,19 +4998,19 @@ Q q 1 0 0 1 62.69291 486.6236 cm q -BT 1 0 0 1 0 14 Tm 1.344985 Tw 12 TL /F1 10 Tf 0 0 0 rg (The first argument to ) Tj /F3 10 Tf 0 0 0 rg (FunctionMaker.create ) Tj /F1 10 Tf 0 0 0 rg (can be a string \(as above\), or a function. This is the) Tj T* 0 Tw (most common usage, since you typically decorate pre-existing functions.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.344985 Tw 12 TL /F1 10 Tf 0 0 0 rg (The first argument to ) Tj /F2 10 Tf 0 0 0 rg (FunctionMaker.create ) Tj /F1 10 Tf 0 0 0 rg (can be a string \(as above\), or a function. This is the) Tj T* 0 Tw (most common usage, since you typically decorate pre-existing functions.) Tj T* ET Q Q q 1 0 0 1 62.69291 456.6236 cm q -BT 1 0 0 1 0 14 Tm .955366 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you're writing a framework, however, you may want to use ) Tj /F3 10 Tf 0 0 0 rg (FunctionMaker.create ) Tj /F1 10 Tf 0 0 0 rg (directly, rather) Tj T* 0 Tw (than ) Tj /F3 10 Tf 0 0 0 rg (decorator) Tj /F1 10 Tf 0 0 0 rg (, because it gives you direct access to the body of the generated function.) Tj T* ET +BT 1 0 0 1 0 14 Tm .955366 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you're writing a framework, however, you may want to use ) Tj /F2 10 Tf 0 0 0 rg (FunctionMaker.create ) Tj /F1 10 Tf 0 0 0 rg (directly, rather) Tj T* 0 Tw (than ) Tj /F2 10 Tf 0 0 0 rg (decorator) Tj /F1 10 Tf 0 0 0 rg (, because it gives you direct access to the body of the generated function.) Tj T* ET Q Q q 1 0 0 1 62.69291 414.6236 cm q -BT 1 0 0 1 0 26 Tm .494985 Tw 12 TL /F1 10 Tf 0 0 0 rg (For instance, suppose you want to instrument the ) Tj /F3 10 Tf 0 0 0 rg (__init__ ) Tj /F1 10 Tf 0 0 0 rg (methods of a set of classes, by preserving) Tj T* 0 Tw .66881 Tw (their signature. \(This use case is not made up. This is done by SQAlchemy, and other frameworks, too.\)) Tj T* 0 Tw (Here is what happens:) Tj T* ET +BT 1 0 0 1 0 26 Tm .494985 Tw 12 TL /F1 10 Tf 0 0 0 rg (For instance, suppose you want to instrument the ) Tj /F2 10 Tf 0 0 0 rg (__init__ ) Tj /F1 10 Tf 0 0 0 rg (methods of a set of classes, by preserving) Tj T* 0 Tw .66881 Tw (their signature. \(This use case is not made up. This is done by SQAlchemy, and other frameworks, too.\)) Tj T* 0 Tw (Here is what happens:) Tj T* ET Q Q q @@ -5025,7 +5033,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 26 Tm 1.861647 Tw 12 TL /F1 10 Tf 0 0 0 rg (If first argument of ) Tj /F3 10 Tf 0 0 0 rg (FunctionMaker.create ) Tj /F1 10 Tf 0 0 0 rg (is a function, an instance of ) Tj /F3 10 Tf 0 0 0 rg (FunctionMaker ) Tj /F1 10 Tf 0 0 0 rg (is) Tj T* 0 Tw 1.694147 Tw (created with the attributes ) Tj /F3 10 Tf 0 0 0 rg (args) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F3 10 Tf 0 0 0 rg (varargs) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F3 10 Tf 0 0 0 rg (keywords) Tj /F1 10 Tf 0 0 0 rg (, and ) Tj /F3 10 Tf 0 0 0 rg (defaults) Tj /F1 10 Tf 0 0 0 rg (. \(These mirror the return) Tj T* 0 Tw (values of the standard library's ) Tj /F3 10 Tf 0 0 0 rg (inspect.getargspec) Tj /F1 10 Tf 0 0 0 rg (.\)) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.861647 Tw 12 TL /F1 10 Tf 0 0 0 rg (If first argument of ) Tj /F2 10 Tf 0 0 0 rg (FunctionMaker.create ) Tj /F1 10 Tf 0 0 0 rg (is a function, an instance of ) Tj /F2 10 Tf 0 0 0 rg (FunctionMaker ) Tj /F1 10 Tf 0 0 0 rg (is) Tj T* 0 Tw 1.694147 Tw (created with the attributes ) Tj /F2 10 Tf 0 0 0 rg (args) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F2 10 Tf 0 0 0 rg (varargs) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F2 10 Tf 0 0 0 rg (keywords) Tj /F1 10 Tf 0 0 0 rg (, and ) Tj /F2 10 Tf 0 0 0 rg (defaults) Tj /F1 10 Tf 0 0 0 rg (. \(These mirror the return) Tj T* 0 Tw (values of the standard library's ) Tj /F2 10 Tf 0 0 0 rg (inspect.getargspec) Tj /F1 10 Tf 0 0 0 rg (.\)) Tj T* ET Q Q q @@ -5048,7 +5056,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 14 Tm .707209 Tw 12 TL /F1 10 Tf 0 0 0 rg (For each item in ) Tj /F3 10 Tf 0 0 0 rg (args ) Tj /F1 10 Tf 0 0 0 rg (\(a list of strings of the names of all required arguments\), an attribute ) Tj /F3 10 Tf 0 0 0 rg (arg0) Tj /F1 10 Tf 0 0 0 rg (,) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (arg1) Tj /F1 10 Tf 0 0 0 rg (, ..., ) Tj /F3 10 Tf 0 0 0 rg (argN ) Tj /F1 10 Tf 0 0 0 rg (is also generated.) Tj T* ET +BT 1 0 0 1 0 14 Tm .707209 Tw 12 TL /F1 10 Tf 0 0 0 rg (For each item in ) Tj /F2 10 Tf 0 0 0 rg (args ) Tj /F1 10 Tf 0 0 0 rg (\(a list of strings of the names of all required arguments\), an attribute ) Tj /F2 10 Tf 0 0 0 rg (arg0) Tj /F1 10 Tf 0 0 0 rg (,) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (arg1) Tj /F1 10 Tf 0 0 0 rg (, ..., ) Tj /F2 10 Tf 0 0 0 rg (argN ) Tj /F1 10 Tf 0 0 0 rg (is also generated.) Tj T* ET Q Q q @@ -5071,7 +5079,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Finally, there is a ) Tj /F3 10 Tf 0 0 0 rg (signature ) Tj /F1 10 Tf 0 0 0 rg (attribute, which is a string with the signature of the original function.) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Finally, there is a ) Tj /F2 10 Tf 0 0 0 rg (signature ) Tj /F1 10 Tf 0 0 0 rg (attribute, which is a string with the signature of the original function.) Tj T* ET Q Q q @@ -5083,7 +5091,7 @@ Q q 1 0 0 1 62.69291 294.6236 cm q -BT 1 0 0 1 0 14 Tm 6.134147 Tw 12 TL /F2 10 Tf 0 0 0 rg (NOTE: ) Tj /F1 10 Tf (You should not pass signature strings with default arguments \(e.g., something like) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg ('f1\(a,) Tj ( ) Tj (b=None\)') Tj /F1 10 Tf 0 0 0 rg (\). Just pass ) Tj /F3 10 Tf 0 0 0 rg ('f1\(a,) Tj ( ) Tj (b\)') Tj /F1 10 Tf 0 0 0 rg (, followed by a tuple of defaults:) Tj T* ET +BT 1 0 0 1 0 14 Tm 6.134147 Tw 12 TL /F3 10 Tf 0 0 0 rg (NOTE: ) Tj /F1 10 Tf (You should not pass signature strings with default arguments \(e.g., something like) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg ('f1\(a,) Tj ( ) Tj (b=None\)') Tj /F1 10 Tf 0 0 0 rg (\). Just pass ) Tj /F2 10 Tf 0 0 0 rg ('f1\(a,) Tj ( ) Tj (b\)') Tj /F1 10 Tf 0 0 0 rg (, followed by a tuple of defaults:) Tj T* ET Q Q q @@ -5220,7 +5228,7 @@ n 360 0 6 12 re f* n 366 0 24 12 re f* .960784 .960784 .862745 rg n 390 0 18 12 re f* -BT 1 0 0 1 0 38 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (FunctionMaker) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (create) Tj 0 0 0 rg (\() Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('f1\(a, b\)') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('f\(a, b\)') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (dict) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (addsource) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (True) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (defaults) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (getargspec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f1) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* 0 0 0 rg (ArgSpec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (args) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ([) Tj .729412 .129412 .129412 rg ('a') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('b') Tj 0 0 0 rg (],) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varargs) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varkw) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (defaults) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,\)\)) Tj T* ET +BT 1 0 0 1 0 38 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f1) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (FunctionMaker) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (create) Tj 0 0 0 rg (\() Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('f1\(a, b\)') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('f\(a, b\)') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (dict) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (addsource) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (True) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (defaults) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (getargspec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f1) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* 0 0 0 rg (ArgSpec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (args) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ([) Tj .729412 .129412 .129412 rg ('a') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('b') Tj 0 0 0 rg (],) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varargs) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (varkw) Tj .4 .4 .4 rg (=) Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (defaults) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (None) Tj 0 0 0 rg (,\)\)) Tj T* ET Q Q Q @@ -5229,25 +5237,25 @@ Q q 1 0 0 1 62.69291 192.4236 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 +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Getting the source code) Tj T* ET Q Q q 1 0 0 1 62.69291 138.4236 cm q -BT 1 0 0 1 0 38 Tm 4.73664 Tw 12 TL /F1 10 Tf 0 0 0 rg (Internally, ) Tj /F3 10 Tf 0 0 0 rg (FunctionMaker.create ) Tj /F1 10 Tf 0 0 0 rg (uses ) Tj /F3 10 Tf 0 0 0 rg (exec ) Tj /F1 10 Tf 0 0 0 rg (to generate the decorated function. Therefore) Tj T* 0 Tw 1.488555 Tw /F3 10 Tf 0 0 0 rg (inspect.getsource ) Tj /F1 10 Tf 0 0 0 rg (will not work for decorated functions. In IPython, this means that the usual ) Tj /F3 10 Tf 0 0 0 rg (??) Tj T* 0 Tw 11.06361 Tw /F1 10 Tf 0 0 0 rg (trick will give you the \(right on the spot\) message ) Tj /F3 10 Tf 0 0 0 rg (Dynamically) Tj ( ) Tj (generated) Tj T* 0 Tw (function.) Tj ( ) Tj (No) Tj ( ) Tj (source) Tj ( ) Tj (code) Tj ( ) Tj (available) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET +BT 1 0 0 1 0 38 Tm 4.73664 Tw 12 TL /F1 10 Tf 0 0 0 rg (Internally, ) Tj /F2 10 Tf 0 0 0 rg (FunctionMaker.create ) Tj /F1 10 Tf 0 0 0 rg (uses ) Tj /F2 10 Tf 0 0 0 rg (exec ) Tj /F1 10 Tf 0 0 0 rg (to generate the decorated function. Therefore) Tj T* 0 Tw 1.488555 Tw /F2 10 Tf 0 0 0 rg (inspect.getsource ) Tj /F1 10 Tf 0 0 0 rg (will not work for decorated functions. In IPython, this means that the usual ) Tj /F2 10 Tf 0 0 0 rg (??) Tj T* 0 Tw 11.06361 Tw /F1 10 Tf 0 0 0 rg (trick will give you the \(right on the spot\) message ) Tj /F2 10 Tf 0 0 0 rg (Dynamically) Tj ( ) Tj (generated) Tj T* 0 Tw (function.) Tj ( ) Tj (No) Tj ( ) Tj (source) Tj ( ) Tj (code) Tj ( ) Tj (available) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET Q Q q 1 0 0 1 62.69291 96.42362 cm q -BT 1 0 0 1 0 26 Tm 1.43284 Tw 12 TL /F1 10 Tf 0 0 0 rg (In the past, I have considered this acceptable, since ) Tj /F3 10 Tf 0 0 0 rg (inspect.getsource ) Tj /F1 10 Tf 0 0 0 rg (does not really work with) Tj T* 0 Tw .143059 Tw ("regular" decorators. In those cases, ) Tj /F3 10 Tf 0 0 0 rg (inspect.getsource ) Tj /F1 10 Tf 0 0 0 rg (gives you the wrapper source code, which is) Tj T* 0 Tw (probably not what you want:) Tj T* ET +BT 1 0 0 1 0 26 Tm .251412 Tw 12 TL /F1 10 Tf 0 0 0 rg (In the past, I considered this acceptable, since ) Tj /F2 10 Tf 0 0 0 rg (inspect.getsource ) Tj /F1 10 Tf 0 0 0 rg (does not really work with "regular") Tj T* 0 Tw .133059 Tw (decorators. In those cases, ) Tj /F2 10 Tf 0 0 0 rg (inspect.getsource ) Tj /F1 10 Tf 0 0 0 rg (gives you the wrapper source code, which is probably) Tj T* 0 Tw (not what you want:) Tj T* ET Q Q endstream endobj -117 0 obj +118 0 obj << /Length 16333 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -5315,7 +5323,7 @@ n 186 12 6 12 re f* n 24 0 36 12 re f* .960784 .960784 .862745 rg n 66 0 42 12 re f* -BT 1 0 0 1 0 38 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (identity_dec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (func) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 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 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (wrapper) Tj T* ET +BT 1 0 0 1 0 38 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (identity_dec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (func) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 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 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (wrapper) Tj T* ET Q Q Q @@ -5371,7 +5379,7 @@ n 138 0 12 12 re f* n 150 0 12 12 re f* .960784 .960784 .862745 rg n 162 0 6 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 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 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 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 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -5465,7 +5473,7 @@ n 0 0 6 12 re f* n 6 0 54 12 re f* .960784 .960784 .862745 rg n 60 0 6 12 re f* -BT 1 0 0 1 0 50 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (import) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (inspect) Tj /F3 10 Tf 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (inspect) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (getsource) Tj 0 0 0 rg (\() Tj 0 0 0 rg (example) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 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 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (<) Tj 0 0 0 rg (BLANKLINE) Tj .4 .4 .4 rg (>) Tj T* ET +BT 1 0 0 1 0 50 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (import) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (inspect) Tj /F2 10 Tf 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (inspect) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (getsource) Tj 0 0 0 rg (\() Tj 0 0 0 rg (example) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 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 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (<) Tj 0 0 0 rg (BLANKLINE) Tj .4 .4 .4 rg (>) Tj T* ET Q Q Q @@ -5480,7 +5488,7 @@ Q q 1 0 0 1 62.69291 503.4236 cm q -BT 1 0 0 1 0 26 Tm .429983 Tw 12 TL /F1 10 Tf 0 0 0 rg (However, there is a workaround. The decorated function has the ) Tj /F3 10 Tf 0 0 0 rg (__wrapped__ ) Tj /F1 10 Tf 0 0 0 rg (attribute, pointing to the) Tj T* 0 Tw 2.523318 Tw (original function. The simplest way to get the source code is to call ) Tj /F3 10 Tf 0 0 0 rg (inspect.getsource ) Tj /F1 10 Tf 0 0 0 rg (on the) Tj T* 0 Tw (undecorated function:) Tj T* ET +BT 1 0 0 1 0 26 Tm .429983 Tw 12 TL /F1 10 Tf 0 0 0 rg (However, there is a workaround. The decorated function has the ) Tj /F2 10 Tf 0 0 0 rg (__wrapped__ ) Tj /F1 10 Tf 0 0 0 rg (attribute, pointing to the) Tj T* 0 Tw 2.523318 Tw (original function. The simplest way to get the source code is to call ) Tj /F2 10 Tf 0 0 0 rg (inspect.getsource ) Tj /F1 10 Tf 0 0 0 rg (on the) Tj T* 0 Tw (undecorated function:) Tj T* ET Q Q q @@ -5587,7 +5595,7 @@ n 0 0 6 12 re f* n 6 0 54 12 re f* .960784 .960784 .862745 rg n 60 0 6 12 re f* -BT 1 0 0 1 0 86 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (inspect) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (getsource) Tj 0 0 0 rg (\() Tj 0 0 0 rg (factorial) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__wrapped__) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* .666667 .133333 1 rg (@tail_recursive) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (factorial) Tj 0 0 0 rg (\() Tj 0 0 0 rg (n) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (acc) Tj .4 .4 .4 rg (=) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .729412 .129412 .129412 rg ("The good old factorial") Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (n) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (acc) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (factorial) Tj 0 0 0 rg (\() Tj 0 0 0 rg (n) Tj .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (n) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (acc) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (<) Tj 0 0 0 rg (BLANKLINE) Tj .4 .4 .4 rg (>) Tj T* ET +BT 1 0 0 1 0 86 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (inspect) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (getsource) Tj 0 0 0 rg (\() Tj 0 0 0 rg (factorial) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (__wrapped__) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* .666667 .133333 1 rg (@tail_recursive) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (factorial) Tj 0 0 0 rg (\() Tj 0 0 0 rg (n) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (acc) Tj .4 .4 .4 rg (=) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .729412 .129412 .129412 rg ("The good old factorial") Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (n) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (acc) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (factorial) Tj 0 0 0 rg (\() Tj 0 0 0 rg (n) Tj .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (n) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (acc) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (<) Tj 0 0 0 rg (BLANKLINE) Tj .4 .4 .4 rg (>) Tj T* ET Q Q Q @@ -5596,19 +5604,19 @@ Q q 1 0 0 1 62.69291 353.2236 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 +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Dealing with third-party decorators) Tj T* ET Q Q q 1 0 0 1 62.69291 299.2236 cm q -BT 1 0 0 1 0 38 Tm .321654 Tw 12 TL /F1 10 Tf 0 0 0 rg (Sometimes on the net you find some cool decorator that you would like to include in your code. However,) Tj T* 0 Tw 1.451163 Tw (more often than not, the cool decorator is not signature-preserving. What you need is an easy way to) Tj T* 0 Tw 2.19748 Tw (upgrade third party decorators to signature-preserving decorators... ) Tj /F4 10 Tf (without ) Tj /F1 10 Tf (having to rewrite them in) Tj T* 0 Tw (terms of ) Tj /F3 10 Tf 0 0 0 rg (decorator) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET +BT 1 0 0 1 0 38 Tm .321654 Tw 12 TL /F1 10 Tf 0 0 0 rg (Sometimes on the net you find some cool decorator that you would like to include in your code. However,) Tj T* 0 Tw 1.451163 Tw (more often than not, the cool decorator is not signature-preserving. What you need is an easy way to) Tj T* 0 Tw 2.19748 Tw (upgrade third party decorators to signature-preserving decorators... ) Tj /F4 10 Tf (without ) Tj /F1 10 Tf (having to rewrite them in) Tj T* 0 Tw (terms of ) Tj /F2 10 Tf 0 0 0 rg (decorator) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET Q Q q 1 0 0 1 62.69291 281.2236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (You can use a ) Tj /F3 10 Tf 0 0 0 rg (FunctionMaker ) Tj /F1 10 Tf 0 0 0 rg (to implement that functionality as follows:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (You can use a ) Tj /F2 10 Tf 0 0 0 rg (FunctionMaker ) Tj /F1 10 Tf 0 0 0 rg (to implement that functionality as follows:) Tj T* ET Q Q q @@ -5693,7 +5701,7 @@ n 264 0 6 12 re f* n 270 0 24 12 re f* .960784 .960784 .862745 rg n 294 0 6 12 re f* -BT 1 0 0 1 0 86 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (decorator_apply) Tj 0 0 0 rg (\() Tj 0 0 0 rg (dec) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F7 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 /F3 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (FunctionMaker) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (create) Tj 0 0 0 rg (\() Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('return decfunc\() Tj /F6 10 Tf .733333 .4 .533333 rg (%\(signature\)s) Tj /F3 10 Tf .729412 .129412 .129412 rg (\)') Tj 0 0 0 rg (,) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (dict) Tj 0 0 0 rg (\() Tj 0 0 0 rg (decfunc) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (dec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (func) Tj 0 0 0 rg (\)\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (__wrapped__) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 86 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (decorator_apply) Tj 0 0 0 rg (\() Tj 0 0 0 rg (dec) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F7 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 /F2 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (FunctionMaker) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (create) Tj 0 0 0 rg (\() Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('return decfunc\() Tj /F6 10 Tf .733333 .4 .533333 rg (%\(signature\)s) Tj /F2 10 Tf .729412 .129412 .129412 rg (\)') Tj 0 0 0 rg (,) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (dict) Tj 0 0 0 rg (\() Tj 0 0 0 rg (decfunc) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (dec) Tj 0 0 0 rg (\() Tj 0 0 0 rg (func) Tj 0 0 0 rg (\)\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (__wrapped__) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -5702,26 +5710,26 @@ Q q 1 0 0 1 62.69291 120.0236 cm q -BT 1 0 0 1 0 26 Tm .25248 Tw 12 TL /F3 10 Tf 0 0 0 rg (decorator_apply ) Tj /F1 10 Tf 0 0 0 rg (sets the generated function's ) Tj /F3 10 Tf 0 0 0 rg (__wrapped__ ) Tj /F1 10 Tf 0 0 0 rg (attribute to the original function, so you) Tj T* 0 Tw 2.934724 Tw (can get the right source code. If you are using a Python later than 3.2, you should also set the) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (__qualname__ ) Tj /F1 10 Tf 0 0 0 rg (attribute to preserve the qualified name of the original function.) Tj T* ET +BT 1 0 0 1 0 26 Tm .25248 Tw 12 TL /F2 10 Tf 0 0 0 rg (decorator_apply ) Tj /F1 10 Tf 0 0 0 rg (sets the generated function's ) Tj /F2 10 Tf 0 0 0 rg (__wrapped__ ) Tj /F1 10 Tf 0 0 0 rg (attribute to the original function, so you) Tj T* 0 Tw 2.934724 Tw (can get the right source code. If you are using a Python later than 3.2, you should also set the) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (__qualname__ ) Tj /F1 10 Tf 0 0 0 rg (attribute to preserve the qualified name of the original function.) Tj T* ET Q Q q 1 0 0 1 62.69291 78.02362 cm q -BT 1 0 0 1 0 26 Tm .601654 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that I am not providing this functionality in the ) Tj /F3 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module directly, since I think it is best) Tj T* 0 Tw .015984 Tw (to rewrite the decorator instead of adding another level of indirection. However, practicality beats purity, so) Tj T* 0 Tw (you can add ) Tj /F3 10 Tf 0 0 0 rg (decorator_apply ) Tj /F1 10 Tf 0 0 0 rg (to your toolbox and use it if you need to.) Tj T* ET +BT 1 0 0 1 0 26 Tm .601654 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that I am not providing this functionality in the ) Tj /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module directly, since I think it is best) Tj T* 0 Tw .015984 Tw (to rewrite the decorator instead of adding another level of indirection. However, practicality beats purity, so) Tj T* 0 Tw (you can add ) Tj /F2 10 Tf 0 0 0 rg (decorator_apply ) Tj /F1 10 Tf 0 0 0 rg (to your toolbox and use it if you need to.) Tj T* ET Q Q endstream endobj -118 0 obj +119 0 obj << /Length 16332 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 717.0236 cm q -BT 1 0 0 1 0 38 Tm 2.067485 Tw 12 TL /F1 10 Tf 0 0 0 rg (To give a good example for ) Tj /F3 10 Tf 0 0 0 rg (decorator_apply) Tj /F1 10 Tf 0 0 0 rg (, I will show a pretty slick decorator that converts a) Tj T* 0 Tw 1.96284 Tw (tail-recursive function into an iterative function. I have shamelessly stolen the core concept from Kay) Tj T* 0 Tw 56.35595 Tw (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 +BT 1 0 0 1 0 38 Tm 2.067485 Tw 12 TL /F1 10 Tf 0 0 0 rg (To give a good example for ) Tj /F2 10 Tf 0 0 0 rg (decorator_apply) Tj /F1 10 Tf 0 0 0 rg (, I will show a pretty slick decorator that converts a) Tj T* 0 Tw 1.96284 Tw (tail-recursive function into an iterative function. I have shamelessly stolen the core concept from Kay) Tj T* 0 Tw 56.35595 Tw (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 Q q @@ -5972,7 +5980,7 @@ n 198 12 18 12 re f* n 72 0 36 12 re f* .960784 .960784 .862745 rg n 114 0 48 12 re f* -BT 1 0 0 1 0 338 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (TailRecursive) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F7 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 /F3 10 Tf 0 0 0 rg T* T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 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 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (func) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (firstcall) Tj 0 0 0 rg ( ) 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 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# sentinel) Tj /F3 10 Tf 0 0 0 rg T* T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 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 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kwd) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (CONTINUE) Tj 0 0 0 rg ( ) 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 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (firstcall) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg ( ) 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 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (firstcall) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (False) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (try) Tj /F3 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (while) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (True) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (result) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kwd) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (result) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (is) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (CONTINUE) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# update arguments) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kwd) Tj 0 0 0 rg ( ) 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 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (else) Tj /F3 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# last call) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (result) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (finally) Tj /F3 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (firstcall) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (True) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (else) Tj /F3 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# return the arguments of the tail call) Tj /F3 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 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kwd) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (CONTINUE) Tj T* ET +BT 1 0 0 1 0 338 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (TailRecursive) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F7 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 /F2 10 Tf 0 0 0 rg T* T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 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 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (func) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (firstcall) Tj 0 0 0 rg ( ) 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 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# sentinel) Tj /F2 10 Tf 0 0 0 rg T* T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 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 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kwd) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (CONTINUE) Tj 0 0 0 rg ( ) 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 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (firstcall) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg ( ) 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 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (firstcall) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (False) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (try) Tj /F2 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (while) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (True) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (result) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kwd) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (result) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (is) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (CONTINUE) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# update arguments) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kwd) Tj 0 0 0 rg ( ) 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 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (else) Tj /F2 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# last call) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (result) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (finally) Tj /F2 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (firstcall) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (True) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (else) Tj /F2 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# return the arguments of the tail call) Tj /F2 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 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (kwd) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (CONTINUE) Tj T* ET Q Q Q @@ -6023,7 +6031,7 @@ n 240 0 6 12 re f* n 252 0 24 12 re f* .960784 .960784 .862745 rg n 276 0 6 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (tail_recursive) Tj 0 0 0 rg (\() Tj 0 0 0 rg (func) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (decorator_apply) Tj 0 0 0 rg (\() Tj 0 0 0 rg (TailRecursive) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (tail_recursive) Tj 0 0 0 rg (\() Tj 0 0 0 rg (func) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (decorator_apply) Tj 0 0 0 rg (\() Tj 0 0 0 rg (TailRecursive) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -6108,7 +6116,7 @@ n 162 0 6 12 re f* n 168 0 18 12 re f* .960784 .960784 .862745 rg n 186 0 6 12 re f* -BT 1 0 0 1 0 62 Tm 12 TL /F3 10 Tf .666667 .133333 1 rg (@tail_recursive) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (factorial) Tj 0 0 0 rg (\() Tj 0 0 0 rg (n) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (acc) Tj .4 .4 .4 rg (=) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .729412 .129412 .129412 rg ("The good old factorial") Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (n) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (acc) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (factorial) Tj 0 0 0 rg (\() Tj 0 0 0 rg (n) Tj .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (n) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (acc) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 62 Tm 12 TL /F2 10 Tf .666667 .133333 1 rg (@tail_recursive) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (factorial) Tj 0 0 0 rg (\() Tj 0 0 0 rg (n) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (acc) Tj .4 .4 .4 rg (=) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .729412 .129412 .129412 rg ("The good old factorial") Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (n) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (acc) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (factorial) Tj 0 0 0 rg (\() Tj 0 0 0 rg (n) Tj .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (n) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (acc) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -6148,7 +6156,7 @@ n 120 12 6 12 re f* n 126 12 12 12 re f* .960784 .960784 .862745 rg n 0 0 12 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (factorial) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (4) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (24) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (factorial) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (4) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (24) Tj T* ET Q Q Q @@ -6164,14 +6172,14 @@ Q endstream endobj -119 0 obj -<< /Length 12130 >> +120 0 obj +<< /Length 12369 >> 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 q -BT 1 0 0 1 0 14 Tm 2.452126 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that there is no recursion limit now; you can easily compute ) Tj /F3 10 Tf 0 0 0 rg (factorial\(1001\) ) Tj /F1 10 Tf 0 0 0 rg (\(or larger\)) Tj T* 0 Tw (without filling the stack frame.) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.452126 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that there is no recursion limit now; you can easily compute ) Tj /F2 10 Tf 0 0 0 rg (factorial\(1001\) ) Tj /F1 10 Tf 0 0 0 rg (\(or larger\)) Tj T* 0 Tw (without filling the stack frame.) Tj T* ET Q Q q @@ -6238,7 +6246,7 @@ n 126 0 6 12 re f* n 132 0 6 12 re f* .960784 .960784 .862745 rg n 138 0 6 12 re f* -BT 1 0 0 1 0 38 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (fact) Tj 0 0 0 rg (\() Tj 0 0 0 rg (n) Tj 0 0 0 rg (\):) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# this is not tail-recursive) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (n) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (n) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (fact) Tj 0 0 0 rg (\() Tj 0 0 0 rg (n) Tj .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 38 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (fact) Tj 0 0 0 rg (\() Tj 0 0 0 rg (n) Tj 0 0 0 rg (\):) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# this is not tail-recursive) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (n) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (n) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (fact) Tj 0 0 0 rg (\() Tj 0 0 0 rg (n) Tj .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -6247,7 +6255,7 @@ Q q 1 0 0 1 62.69291 633.8236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 0 rg (Reminder: ) Tj /F1 10 Tf (A function is ) Tj /F4 10 Tf (tail recursive ) Tj /F1 10 Tf (if it does either of the following:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (Reminder: ) Tj /F1 10 Tf (A function is ) Tj /F4 10 Tf (tail recursive ) Tj /F1 10 Tf (if it does either of the following:) Tj T* ET Q Q q @@ -6307,13 +6315,13 @@ Q q 1 0 0 1 62.69291 564.8236 cm q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Multiple dispatch) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Multiple dispatch) Tj T* ET Q Q q 1 0 0 1 62.69291 522.8236 cm q -BT 1 0 0 1 0 26 Tm 1.494983 Tw 12 TL /F1 10 Tf 0 0 0 rg (There has been talk of implementing multiple dispatch functions \(i.e. "generic functions"\) in Python for) Tj T* 0 Tw .596303 Tw (over ten years. Last year, something concrete was done for the first time. As of Python 3.4, we have the) Tj T* 0 Tw (decorator ) Tj /F3 10 Tf 0 0 0 rg (functools.singledispatch ) Tj /F1 10 Tf 0 0 0 rg (to implement generic functions!) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.494983 Tw 12 TL /F1 10 Tf 0 0 0 rg (There has been talk of implementing multiple dispatch functions \(i.e. "generic functions"\) in Python for) Tj T* 0 Tw .596303 Tw (over ten years. Last year, something concrete was done for the first time. As of Python 3.4, we have the) Tj T* 0 Tw (decorator ) Tj /F2 10 Tf 0 0 0 rg (functools.singledispatch ) Tj /F1 10 Tf 0 0 0 rg (to implement generic functions!) Tj T* ET Q Q q @@ -6325,7 +6333,7 @@ Q q 1 0 0 1 62.69291 450.8236 cm q -BT 1 0 0 1 0 26 Tm .373059 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module provides the decorator factory ) Tj /F3 10 Tf 0 0 0 rg (dispatch_on) Tj /F1 10 Tf 0 0 0 rg (, which can be used to implement) Tj T* 0 Tw .888555 Tw (generic functions dispatching on ) Tj /F4 10 Tf (any ) Tj /F1 10 Tf (argument. Moreover, it can manage dispatching on more than one) Tj T* 0 Tw (argument. \(And, of course, it is signature-preserving.\)) Tj T* ET +BT 1 0 0 1 0 26 Tm .373059 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module provides the decorator factory ) Tj /F2 10 Tf 0 0 0 rg (dispatch_on) Tj /F1 10 Tf 0 0 0 rg (, which can be used to implement) Tj T* 0 Tw .888555 Tw (generic functions dispatching on ) Tj /F4 10 Tf (any ) Tj /F1 10 Tf (argument. Moreover, it can manage dispatching on more than one) Tj T* 0 Tw (argument. \(And, of course, it is signature-preserving.\)) Tj T* ET Q Q q @@ -6338,7 +6346,7 @@ Q q 1 0 0 1 62.69291 390.8236 cm q -BT 1 0 0 1 0 14 Tm .703828 Tw 12 TL /F1 10 Tf 0 0 0 rg (Suppose you have an ) Tj /F3 10 Tf 0 0 0 rg (XMLWriter ) Tj /F1 10 Tf 0 0 0 rg (class, which is instantiated with some configuration parameters, and) Tj T* 0 Tw (has the ) Tj /F3 10 Tf 0 0 0 rg (.write ) Tj /F1 10 Tf 0 0 0 rg (method which serializes objects to XML:) Tj T* ET +BT 1 0 0 1 0 14 Tm .703828 Tw 12 TL /F1 10 Tf 0 0 0 rg (Suppose you have an ) Tj /F2 10 Tf 0 0 0 rg (XMLWriter ) Tj /F1 10 Tf 0 0 0 rg (class, which is instantiated with some configuration parameters, and) Tj T* 0 Tw (has the ) Tj /F2 10 Tf 0 0 0 rg (.write ) Tj /F1 10 Tf 0 0 0 rg (method which serializes objects to XML:) Tj T* ET Q Q q @@ -6427,7 +6435,7 @@ n 228 0 6 12 re f* n 234 0 18 12 re f* .960784 .960784 .862745 rg n 252 0 12 12 re f* -BT 1 0 0 1 0 74 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (XMLWriter) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 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 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (config) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cfg) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (config) Tj 0 0 0 rg T* T* ( ) Tj .666667 .133333 1 rg (@dispatch_on) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('obj') Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (write) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (raise) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .823529 .254902 .227451 rg (NotImplementedError) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (type) Tj 0 0 0 rg (\() Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\)\)) Tj T* ET +BT 1 0 0 1 0 74 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (XMLWriter) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 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 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (config) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 .501961 0 rg (self) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cfg) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (config) Tj 0 0 0 rg T* T* ( ) Tj .666667 .133333 1 rg (@dispatch_on) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('obj') Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (write) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (raise) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .823529 .254902 .227451 rg (NotImplementedError) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (type) Tj 0 0 0 rg (\() Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\)\)) Tj T* ET Q Q Q @@ -6436,24 +6444,23 @@ Q q 1 0 0 1 62.69291 241.6236 cm q -BT 1 0 0 1 0 26 Tm 4.17561 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here, you want to dispatch on the ) Tj /F4 10 Tf (second ) Tj /F1 10 Tf (argument; the first is already taken by ) Tj /F3 10 Tf 0 0 0 rg (self) Tj /F1 10 Tf 0 0 0 rg (. The) Tj T* 0 Tw .147126 Tw /F3 10 Tf 0 0 0 rg (dispatch_on ) Tj /F1 10 Tf 0 0 0 rg (decorator factory allows you to specify the dispatch argument simplpy by passing its name) Tj T* 0 Tw (as a string. \(Note that if you mispell the name you will get an error.\)) Tj T* ET +BT 1 0 0 1 0 26 Tm 4.17561 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here, you want to dispatch on the ) Tj /F4 10 Tf (second ) Tj /F1 10 Tf (argument; the first is already taken by ) Tj /F2 10 Tf 0 0 0 rg (self) Tj /F1 10 Tf 0 0 0 rg (. The) Tj T* 0 Tw .544269 Tw /F2 10 Tf 0 0 0 rg (dispatch_on ) Tj /F1 10 Tf 0 0 0 rg (decorator factory allows you to specify the dispatch argument simply by passing its name) Tj T* 0 Tw (as a string. \(Note that if you misspell the name you will get an error.\)) Tj T* ET Q Q q -1 0 0 1 62.69291 211.6236 cm +1 0 0 1 62.69291 199.6236 cm q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.092209 Tw (The decorated function decorated is turned into a generic function, and it is called if there are no more) Tj T* 0 Tw (specialized implementations.) Tj T* ET +BT 1 0 0 1 0 26 Tm 2.55683 Tw 12 TL /F1 10 Tf 0 0 0 rg (The decorated function ) Tj /F4 10 Tf 0 0 0 rg (write ) Tj /F1 10 Tf 0 0 0 rg (is turned into a generic function \( ) Tj /F4 10 Tf 0 0 0 rg (write ) Tj /F1 10 Tf 0 0 0 rg (is a function at the idea it is) Tj T* 0 Tw .678488 Tw (decorated; it will be turned into a method later, at class instantiation time\), and it is called if there are no) Tj T* 0 Tw (more specialized implementations.) Tj T* ET Q Q q -1 0 0 1 62.69291 181.6236 cm +1 0 0 1 62.69291 169.6236 cm q -BT 1 0 0 1 0 14 Tm 1.033314 Tw 12 TL /F1 10 Tf 0 0 0 rg (Usually, default functions should raise a ) Tj /F3 10 Tf 0 0 0 rg (NotImplementedError) Tj /F1 10 Tf 0 0 0 rg (, thus forcing people to register some) Tj T* 0 Tw (implementation. You can perform the registration with a decorator:) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.033314 Tw 12 TL /F1 10 Tf 0 0 0 rg (Usually, default functions should raise a ) Tj /F2 10 Tf 0 0 0 rg (NotImplementedError) Tj /F1 10 Tf 0 0 0 rg (, thus forcing people to register some) Tj T* 0 Tw (implementation. You can perform the registration with a decorator:) Tj T* ET Q Q q -1 0 0 1 62.69291 124.4236 cm +1 0 0 1 62.69291 112.4236 cm q q 1 0 0 1 0 0 cm @@ -6512,14 +6519,14 @@ n 174 0 6 12 re f* n 186 0 6 12 re f* .960784 .960784 .862745 rg n 198 0 18 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .666667 .133333 1 rg (@XMLWriter.write.register) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (float) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (writefloat) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (') Tj (<) Tj (float) Tj (>) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F3 10 Tf .729412 .129412 .129412 rg (<) Tj (/float) Tj (>) Tj (') Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (%) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (obj) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .666667 .133333 1 rg (@XMLWriter.write.register) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (float) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (writefloat) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (') Tj (<) Tj (float) Tj (>) Tj /F6 10 Tf .733333 .4 .533333 rg (%s) Tj /F2 10 Tf .729412 .129412 .129412 rg (<) Tj (/float) Tj (>) Tj (') Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (%) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (obj) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 104.4236 cm +1 0 0 1 62.69291 92.42362 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Now XMLWriter can serialize floats:) Tj T* ET @@ -6528,7 +6535,7 @@ Q endstream endobj -120 0 obj +121 0 obj << /Length 15213 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -6596,7 +6603,7 @@ n 72 0 36 12 re f* n 108 0 6 12 re f* .960784 .960784 .862745 rg n 114 0 6 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (writer) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (XMLWriter) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (writer) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (write) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (2.3) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .729412 .129412 .129412 rg (') Tj (<) Tj (float) Tj (>) Tj (2.3) Tj (<) Tj (/float) Tj (>) Tj (') Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (writer) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (XMLWriter) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (writer) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (write) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (2.3) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .729412 .129412 .129412 rg (') Tj (<) Tj (float) Tj (>) Tj (2.3) Tj (<) Tj (/float) Tj (>) Tj (') Tj T* ET Q Q Q @@ -6639,7 +6646,7 @@ n 24 0 42 12 re f* n 72 0 6 12 re f* .960784 .960784 .862745 rg n 84 0 6 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (Rock) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (ordinal) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (Rock) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (ordinal) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj T* ET Q Q Q @@ -6675,7 +6682,7 @@ n 24 0 42 12 re f* n 72 0 6 12 re f* .960784 .960784 .862745 rg n 84 0 6 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (Paper) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (ordinal) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (Paper) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (ordinal) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj T* ET Q Q Q @@ -6711,7 +6718,7 @@ n 24 0 42 12 re f* n 72 0 6 12 re f* .960784 .960784 .862745 rg n 84 0 6 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (Scissors) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (ordinal) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (2) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (Scissors) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (ordinal) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (2) Tj T* ET Q Q Q @@ -6720,7 +6727,7 @@ Q q 1 0 0 1 62.69291 480.2236 cm q -BT 1 0 0 1 0 26 Tm .293735 Tw 12 TL /F1 10 Tf 0 0 0 rg (I have added an ordinal to the Rock-Paper-Scissors classes to simplify the implementation. The idea is to) Tj T* 0 Tw 1.606235 Tw (define a generic function \() Tj /F3 10 Tf 0 0 0 rg (win\(a, b\)) Tj /F1 10 Tf 0 0 0 rg (\) of two arguments corresponding to the ) Tj /F4 10 Tf (moves ) Tj /F1 10 Tf (of the first and) Tj T* 0 Tw (second players. The ) Tj /F4 10 Tf (moves ) Tj /F1 10 Tf (are instances of the classes Rock, Paper, and Scissors.) Tj T* ET +BT 1 0 0 1 0 26 Tm .293735 Tw 12 TL /F1 10 Tf 0 0 0 rg (I have added an ordinal to the Rock-Paper-Scissors classes to simplify the implementation. The idea is to) Tj T* 0 Tw 1.606235 Tw (define a generic function \() Tj /F2 10 Tf 0 0 0 rg (win\(a, b\)) Tj /F1 10 Tf 0 0 0 rg (\) of two arguments corresponding to the ) Tj /F4 10 Tf (moves ) Tj /F1 10 Tf (of the first and) Tj T* 0 Tw (second players. The ) Tj /F4 10 Tf (moves ) Tj /F1 10 Tf (are instances of the classes Rock, Paper, and Scissors.) Tj T* ET Q Q q @@ -6855,7 +6862,7 @@ n 264 0 6 12 re f* n 270 0 6 12 re f* .960784 .960784 .862745 rg n 276 0 18 12 re f* -BT 1 0 0 1 0 74 Tm 12 TL /F3 10 Tf .666667 .133333 1 rg (@dispatch_on) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('a') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('b') Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (a) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (ordinal) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (ordinal) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (elif) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (a) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (ordinal) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (ordinal) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (-) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (b) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (a) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (raise) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .823529 .254902 .227451 rg (NotImplementedError) Tj /F3 10 Tf 0 0 0 rg (\(\() Tj 0 .501961 0 rg (type) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (\),) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (type) Tj 0 0 0 rg (\() Tj 0 0 0 rg (b) Tj 0 0 0 rg (\)\)\)) Tj T* ET +BT 1 0 0 1 0 74 Tm 12 TL /F2 10 Tf .666667 .133333 1 rg (@dispatch_on) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('a') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('b') Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (a) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (ordinal) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (ordinal) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (elif) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (a) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (ordinal) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (ordinal) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (-) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (b) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (a) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (raise) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .823529 .254902 .227451 rg (NotImplementedError) Tj /F2 10 Tf 0 0 0 rg (\(\() Tj 0 .501961 0 rg (type) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (\),) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (type) Tj 0 0 0 rg (\() Tj 0 0 0 rg (b) Tj 0 0 0 rg (\)\)\)) Tj T* ET Q Q Q @@ -6907,7 +6914,7 @@ n 24 0 36 12 re f* n 66 0 6 12 re f* .960784 .960784 .862745 rg n 72 0 6 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .666667 .133333 1 rg (@win.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (winRockPaper) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .666667 .133333 1 rg (@win.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (winRockPaper) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj T* ET Q Q Q @@ -6959,7 +6966,7 @@ n 24 0 36 12 re f* n 66 0 6 12 re f* .960784 .960784 .862745 rg n 72 0 6 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .666667 .133333 1 rg (@win.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (winPaperScissors) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .666667 .133333 1 rg (@win.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (winPaperScissors) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj T* ET Q Q Q @@ -7009,7 +7016,7 @@ n 144 12 12 12 re f* n 24 0 36 12 re f* .960784 .960784 .862745 rg n 66 0 6 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .666667 .133333 1 rg (@win.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (winRockScissors) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .666667 .133333 1 rg (@win.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (winRockScissors) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj T* ET Q Q Q @@ -7025,7 +7032,7 @@ Q endstream endobj -121 0 obj +122 0 obj << /Length 13979 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -7229,7 +7236,7 @@ n 144 12 18 12 re f* n 0 0 6 12 re f* .960784 .960784 .862745 rg n 6 0 6 12 re f* -BT 1 0 0 1 0 206 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (1) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (1) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (1) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (0) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (0) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (0) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj T* ET +BT 1 0 0 1 0 206 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (1) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (1) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (1) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (0) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (0) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (0) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (-) Tj .4 .4 .4 rg (1) Tj T* ET Q Q Q @@ -7238,7 +7245,7 @@ Q q 1 0 0 1 62.69291 503.8236 cm q -BT 1 0 0 1 0 14 Tm .76528 Tw 12 TL /F1 10 Tf 0 0 0 rg (The point of generic functions is that they play well with subclassing. For instance, suppose we define a) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (StrongRock) Tj /F1 10 Tf 0 0 0 rg (, which does not lose against Paper:) Tj T* ET +BT 1 0 0 1 0 14 Tm .76528 Tw 12 TL /F1 10 Tf 0 0 0 rg (The point of generic functions is that they play well with subclassing. For instance, suppose we define a) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (StrongRock) Tj /F1 10 Tf 0 0 0 rg (, which does not lose against Paper:) Tj T* ET Q Q q @@ -7267,7 +7274,7 @@ n 102 12 24 12 re f* n 126 12 12 12 re f* .960784 .960784 .862745 rg n 24 0 24 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (StrongRock) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (pass) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (StrongRock) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (Rock) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (pass) Tj T* ET Q Q Q @@ -7317,7 +7324,7 @@ n 162 12 12 12 re f* n 24 0 36 12 re f* .960784 .960784 .862745 rg n 66 0 6 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .666667 .133333 1 rg (@win.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (StrongRock) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (winStrongRockPaper) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .666667 .133333 1 rg (@win.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (StrongRock) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Paper) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (winStrongRockPaper) Tj 0 0 0 rg (\() Tj 0 0 0 rg (a) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (b) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj T* ET Q Q Q @@ -7364,7 +7371,7 @@ n 132 12 48 12 re f* n 180 12 18 12 re f* .960784 .960784 .862745 rg n 0 0 6 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (StrongRock) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (1) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj 0 0 0 rg (\() Tj 0 0 0 rg (StrongRock) Tj 0 0 0 rg (\(\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (1) Tj T* ET Q Q Q @@ -7373,7 +7380,7 @@ Q q 1 0 0 1 62.69291 304.2236 cm q -BT 1 0 0 1 0 14 Tm 12.49998 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can introspect the precedence used by the dispath algorithm by calling) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (.dispatch_info\(*types\)) Tj /F1 10 Tf 0 0 0 rg (:) Tj T* ET +BT 1 0 0 1 0 14 Tm 12.49998 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can introspect the precedence used by the dispath algorithm by calling) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (.dispatch_info\(*types\)) Tj /F1 10 Tf 0 0 0 rg (:) Tj T* ET Q Q q @@ -7432,7 +7439,7 @@ n 216 0 6 12 re f* n 228 0 60 12 re f* .960784 .960784 .862745 rg n 288 0 12 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (dispatch_info) Tj 0 0 0 rg (\() Tj 0 0 0 rg (StrongRock) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg ([\() Tj .729412 .129412 .129412 rg ('StrongRock') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('Scissors') Tj 0 0 0 rg (\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('Rock') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('Scissors') Tj 0 0 0 rg (\)]) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (win) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (dispatch_info) Tj 0 0 0 rg (\() Tj 0 0 0 rg (StrongRock) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (Scissors) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg ([\() Tj .729412 .129412 .129412 rg ('StrongRock') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('Scissors') Tj 0 0 0 rg (\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('Rock') Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('Scissors') Tj 0 0 0 rg (\)]) Tj T* ET Q Q Q @@ -7441,13 +7448,13 @@ Q q 1 0 0 1 62.69291 203.0236 cm q -BT 1 0 0 1 0 38 Tm 1.871412 Tw 12 TL /F1 10 Tf 0 0 0 rg (Since there is no direct implementation for \() Tj /F3 10 Tf 0 0 0 rg (StrongRock) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F3 10 Tf 0 0 0 rg (Scissors) Tj /F1 10 Tf 0 0 0 rg (\), the dispatcher will look at the) Tj T* 0 Tw .156412 Tw (implementation for \() Tj /F3 10 Tf 0 0 0 rg (Rock) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F3 10 Tf 0 0 0 rg (Scissors) Tj /F1 10 Tf 0 0 0 rg (\) which is available. Internally, the algorithm is doing a cross product) Tj T* 0 Tw 2.966412 Tw (of the class precedence lists \(or ) Tj /F4 10 Tf (Method Resolution Orders) Tj /F1 10 Tf (, ) Tj 0 0 .501961 rg (MRO ) Tj 0 0 0 rg (for short\) of ) Tj /F3 10 Tf 0 0 0 rg (StrongRock ) Tj /F1 10 Tf 0 0 0 rg (and) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (Scissors) Tj /F1 10 Tf 0 0 0 rg (, respectively.) Tj T* ET +BT 1 0 0 1 0 38 Tm 1.871412 Tw 12 TL /F1 10 Tf 0 0 0 rg (Since there is no direct implementation for \() Tj /F2 10 Tf 0 0 0 rg (StrongRock) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F2 10 Tf 0 0 0 rg (Scissors) Tj /F1 10 Tf 0 0 0 rg (\), the dispatcher will look at the) Tj T* 0 Tw .156412 Tw (implementation for \() Tj /F2 10 Tf 0 0 0 rg (Rock) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F2 10 Tf 0 0 0 rg (Scissors) Tj /F1 10 Tf 0 0 0 rg (\) which is available. Internally, the algorithm is doing a cross product) Tj T* 0 Tw 2.966412 Tw (of the class precedence lists \(or ) Tj /F4 10 Tf (Method Resolution Orders) Tj /F1 10 Tf (, ) Tj 0 0 .501961 rg (MRO ) Tj 0 0 0 rg (for short\) of ) Tj /F2 10 Tf 0 0 0 rg (StrongRock ) Tj /F1 10 Tf 0 0 0 rg (and) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (Scissors) Tj /F1 10 Tf 0 0 0 rg (, respectively.) Tj T* ET Q Q q 1 0 0 1 62.69291 170.0236 cm q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Generic functions and virtual ancestors) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Generic functions and virtual ancestors) Tj T* ET Q Q q @@ -7467,7 +7474,7 @@ Q endstream endobj -122 0 obj +123 0 obj << /Length 13212 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -7509,7 +7516,7 @@ n 120 12 12 12 re f* n 48 0 36 12 re f* .960784 .960784 .862745 rg n 90 0 6 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (WithLength) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (__len__) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (WithLength) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (__len__) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj T* ET Q Q Q @@ -7518,7 +7525,7 @@ Q q 1 0 0 1 62.69291 683.8236 cm q -BT 1 0 0 1 0 14 Tm .327633 Tw 12 TL /F1 10 Tf 0 0 0 rg (This class defines a ) Tj /F3 10 Tf 0 0 0 rg (__len__ ) Tj /F1 10 Tf 0 0 0 rg (method, and is therefore considered to be a subclass of the abstract base) Tj T* 0 Tw (class ) Tj /F3 10 Tf 0 0 0 rg (collections.Sized) Tj /F1 10 Tf 0 0 0 rg (:) Tj T* ET +BT 1 0 0 1 0 14 Tm .327633 Tw 12 TL /F1 10 Tf 0 0 0 rg (This class defines a ) Tj /F2 10 Tf 0 0 0 rg (__len__ ) Tj /F1 10 Tf 0 0 0 rg (method, and is therefore considered to be a subclass of the abstract base) Tj T* 0 Tw (class ) Tj /F2 10 Tf 0 0 0 rg (collections.Sized) Tj /F1 10 Tf 0 0 0 rg (:) Tj T* ET Q Q q @@ -7559,7 +7566,7 @@ n 234 12 30 12 re f* n 264 12 6 12 re f* .960784 .960784 .862745 rg n 0 0 24 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (issubclass) Tj 0 0 0 rg (\() Tj 0 0 0 rg (WithLength) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Sized) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 .501961 0 rg (True) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (issubclass) Tj 0 0 0 rg (\() Tj 0 0 0 rg (WithLength) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Sized) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 .501961 0 rg (True) Tj T* ET Q Q Q @@ -7568,7 +7575,7 @@ Q q 1 0 0 1 62.69291 594.6236 cm q -BT 1 0 0 1 0 26 Tm 2.414651 Tw 12 TL /F1 10 Tf 0 0 0 rg (However, ) Tj /F3 10 Tf 0 0 0 rg (collections.Sized ) Tj /F1 10 Tf 0 0 0 rg (is not in the ) Tj 0 0 .501961 rg (MRO ) Tj 0 0 0 rg (of ) Tj /F3 10 Tf 0 0 0 rg (WithLength) Tj /F1 10 Tf 0 0 0 rg (; it is not a true ancestor. Any) Tj T* 0 Tw .57284 Tw (implementation of generic functions \(even with single dispatch\) must go through some contorsion to take) Tj T* 0 Tw (into account the virtual ancestors.) Tj T* ET +BT 1 0 0 1 0 26 Tm 2.414651 Tw 12 TL /F1 10 Tf 0 0 0 rg (However, ) Tj /F2 10 Tf 0 0 0 rg (collections.Sized ) Tj /F1 10 Tf 0 0 0 rg (is not in the ) Tj 0 0 .501961 rg (MRO ) Tj 0 0 0 rg (of ) Tj /F2 10 Tf 0 0 0 rg (WithLength) Tj /F1 10 Tf 0 0 0 rg (; it is not a true ancestor. Any) Tj T* 0 Tw .57284 Tw (implementation of generic functions \(even with single dispatch\) must go through some contorsion to take) Tj T* 0 Tw (into account the virtual ancestors.) Tj T* ET Q Q q @@ -7624,7 +7631,7 @@ n 204 0 6 12 re f* n 210 0 18 12 re f* .960784 .960784 .862745 rg n 228 0 12 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .666667 .133333 1 rg (@dispatch_on) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('obj') Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (get_length) Tj 0 0 0 rg (\() Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (raise) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .823529 .254902 .227451 rg (NotImplementedError) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (type) Tj 0 0 0 rg (\() Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\)\)) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .666667 .133333 1 rg (@dispatch_on) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('obj') Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (get_length) Tj 0 0 0 rg (\() Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (raise) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .823529 .254902 .227451 rg (NotImplementedError) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (type) Tj 0 0 0 rg (\() Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\)\)) Tj T* ET Q Q Q @@ -7683,7 +7690,7 @@ n 84 0 6 12 re f* n 90 0 18 12 re f* .960784 .960784 .862745 rg n 108 0 6 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .666667 .133333 1 rg (@get_length.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Sized) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (get_length_sized) Tj 0 0 0 rg (\() Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (len) Tj 0 0 0 rg (\() Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .666667 .133333 1 rg (@get_length.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Sized) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (get_length_sized) Tj 0 0 0 rg (\() Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 .501961 0 rg (len) Tj 0 0 0 rg (\() Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q @@ -7692,7 +7699,7 @@ Q q 1 0 0 1 62.69291 422.2236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (...then ) Tj /F3 10 Tf 0 0 0 rg (get_length ) Tj /F1 10 Tf 0 0 0 rg (must be defined on ) Tj /F3 10 Tf 0 0 0 rg (WithLength ) Tj /F1 10 Tf 0 0 0 rg (instances...) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (...then ) Tj /F2 10 Tf 0 0 0 rg (get_length ) Tj /F1 10 Tf 0 0 0 rg (must be defined on ) Tj /F2 10 Tf 0 0 0 rg (WithLength ) Tj /F1 10 Tf 0 0 0 rg (instances...) Tj T* ET Q Q q @@ -7725,7 +7732,7 @@ n 90 12 60 12 re f* n 150 12 18 12 re f* .960784 .960784 .862745 rg n 0 0 6 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (get_length) Tj 0 0 0 rg (\() Tj 0 0 0 rg (WithLength) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (0) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (get_length) Tj 0 0 0 rg (\() Tj 0 0 0 rg (WithLength) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* .4 .4 .4 rg (0) Tj T* ET Q Q Q @@ -7734,19 +7741,19 @@ Q q 1 0 0 1 62.69291 357.0236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (...even if ) Tj /F3 10 Tf 0 0 0 rg (collections.Sized ) Tj /F1 10 Tf 0 0 0 rg (is not a true ancestor of ) Tj /F3 10 Tf 0 0 0 rg (WithLength) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (...even if ) Tj /F2 10 Tf 0 0 0 rg (collections.Sized ) Tj /F1 10 Tf 0 0 0 rg (is not a true ancestor of ) Tj /F2 10 Tf 0 0 0 rg (WithLength) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET Q Q q 1 0 0 1 62.69291 339.0236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Of course, this is a contrived example--you could just use the builtin ) Tj /F3 10 Tf 0 0 0 rg (len) Tj /F1 10 Tf 0 0 0 rg (--but you should get the idea.) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Of course, this is a contrived example--you could just use the builtin ) Tj /F2 10 Tf 0 0 0 rg (len) Tj /F1 10 Tf 0 0 0 rg (--but you should get the idea.) Tj T* ET Q Q q 1 0 0 1 62.69291 297.0236 cm q -BT 1 0 0 1 0 26 Tm .001567 Tw 12 TL /F1 10 Tf 0 0 0 rg (Since in Python it is possible to consider any instance of ) Tj /F3 10 Tf 0 0 0 rg (ABCMeta ) Tj /F1 10 Tf 0 0 0 rg (as a virtual ancestor of any other class) Tj T* 0 Tw .21152 Tw (\(it is enough to register it as ) Tj /F3 10 Tf 0 0 0 rg (ancestor.register\(cls\)) Tj /F1 10 Tf 0 0 0 rg (\), any implementation of generic functions must) Tj T* 0 Tw (be aware of the registration mechanism.) Tj T* ET +BT 1 0 0 1 0 26 Tm .001567 Tw 12 TL /F1 10 Tf 0 0 0 rg (Since in Python it is possible to consider any instance of ) Tj /F2 10 Tf 0 0 0 rg (ABCMeta ) Tj /F1 10 Tf 0 0 0 rg (as a virtual ancestor of any other class) Tj T* 0 Tw .21152 Tw (\(it is enough to register it as ) Tj /F2 10 Tf 0 0 0 rg (ancestor.register\(cls\)) Tj /F1 10 Tf 0 0 0 rg (\), any implementation of generic functions must) Tj T* 0 Tw (be aware of the registration mechanism.) Tj T* ET Q Q q @@ -7802,7 +7809,7 @@ n 120 12 12 12 re f* n 48 0 36 12 re f* .960784 .960784 .862745 rg n 90 0 6 12 re f* -BT 1 0 0 1 0 50 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (SomeSet) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Sized) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# methods that make SomeSet set-like) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# not shown ...) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (__len__) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj T* ET +BT 1 0 0 1 0 50 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (class) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (SomeSet) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Sized) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# methods that make SomeSet set-like) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# not shown ...) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (__len__) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj T* ET Q Q Q @@ -7811,13 +7818,13 @@ Q q 1 0 0 1 62.69291 165.8236 cm q -BT 1 0 0 1 0 14 Tm 2.169982 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here, the author of ) Tj /F3 10 Tf 0 0 0 rg (SomeSet ) Tj /F1 10 Tf 0 0 0 rg (made a mistake by inheriting from ) Tj /F3 10 Tf 0 0 0 rg (collections.Sized ) Tj /F1 10 Tf 0 0 0 rg (\(instead of) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (collections.Set) Tj /F1 10 Tf 0 0 0 rg (\).) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.169982 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here, the author of ) Tj /F2 10 Tf 0 0 0 rg (SomeSet ) Tj /F1 10 Tf 0 0 0 rg (made a mistake by inheriting from ) Tj /F2 10 Tf 0 0 0 rg (collections.Sized ) Tj /F1 10 Tf 0 0 0 rg (\(instead of) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (collections.Set) Tj /F1 10 Tf 0 0 0 rg (\).) Tj T* ET Q Q q 1 0 0 1 62.69291 135.8236 cm q -BT 1 0 0 1 0 14 Tm 3.139318 Tw 12 TL /F1 10 Tf 0 0 0 rg (This is not a problem. You can register ) Tj /F4 10 Tf (a posteriori) Tj /F1 10 Tf ( ) Tj /F3 10 Tf 0 0 0 rg (collections.Set ) Tj /F1 10 Tf 0 0 0 rg (as a virtual ancestor of) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (SomeSet) Tj /F1 10 Tf 0 0 0 rg (:) Tj T* ET +BT 1 0 0 1 0 14 Tm 3.139318 Tw 12 TL /F1 10 Tf 0 0 0 rg (This is not a problem. You can register ) Tj /F4 10 Tf (a posteriori) Tj /F1 10 Tf ( ) Tj /F2 10 Tf 0 0 0 rg (collections.Set ) Tj /F1 10 Tf 0 0 0 rg (as a virtual ancestor of) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (SomeSet) Tj /F1 10 Tf 0 0 0 rg (:) Tj T* ET Q Q q @@ -7884,7 +7891,7 @@ n 216 12 18 12 re f* n 234 12 6 12 re f* .960784 .960784 .862745 rg n 0 0 24 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (_) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Set) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (SomeSet) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (issubclass) Tj 0 0 0 rg (\() Tj 0 0 0 rg (SomeSet) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Set) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 .501961 0 rg (True) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (_) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Set) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (SomeSet) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (issubclass) Tj 0 0 0 rg (\() Tj 0 0 0 rg (SomeSet) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Set) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 .501961 0 rg (True) Tj T* ET Q Q Q @@ -7893,14 +7900,14 @@ Q endstream endobj -123 0 obj +124 0 obj << /Length 12132 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 753.0236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Now, let's define an implementation of ) Tj /F3 10 Tf 0 0 0 rg (get_length ) Tj /F1 10 Tf 0 0 0 rg (specific to set:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Now, let's define an implementation of ) Tj /F2 10 Tf 0 0 0 rg (get_length ) Tj /F1 10 Tf 0 0 0 rg (specific to set:) Tj T* ET Q Q q @@ -7943,7 +7950,7 @@ n 132 12 12 12 re f* n 24 0 36 12 re f* .960784 .960784 .862745 rg n 66 0 6 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .666667 .133333 1 rg (@get_length.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Set) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (get_length_set) Tj 0 0 0 rg (\() Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .666667 .133333 1 rg (@get_length.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Set) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (get_length_set) Tj 0 0 0 rg (\() Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj T* ET Q Q Q @@ -7952,7 +7959,7 @@ Q q 1 0 0 1 62.69291 663.8236 cm q -BT 1 0 0 1 0 14 Tm .530697 Tw 12 TL /F1 10 Tf 0 0 0 rg (The current implementation \(and ) Tj /F3 10 Tf 0 0 0 rg (functools.singledispatch ) Tj /F1 10 Tf 0 0 0 rg (too\) is able to discern that a ) Tj /F3 10 Tf 0 0 0 rg (Set ) Tj /F1 10 Tf 0 0 0 rg (is a) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (Sized ) Tj /F1 10 Tf 0 0 0 rg (object, by looking at the class registry, so it uses the more specific implementation for ) Tj /F3 10 Tf 0 0 0 rg (Set) Tj /F1 10 Tf 0 0 0 rg (:) Tj T* ET +BT 1 0 0 1 0 14 Tm .530697 Tw 12 TL /F1 10 Tf 0 0 0 rg (The current implementation \(and ) Tj /F2 10 Tf 0 0 0 rg (functools.singledispatch ) Tj /F1 10 Tf 0 0 0 rg (too\) is able to discern that a ) Tj /F2 10 Tf 0 0 0 rg (Set ) Tj /F1 10 Tf 0 0 0 rg (is a) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (Sized ) Tj /F1 10 Tf 0 0 0 rg (object, by looking at the class registry, so it uses the more specific implementation for ) Tj /F2 10 Tf 0 0 0 rg (Set) Tj /F1 10 Tf 0 0 0 rg (:) Tj T* ET Q Q q @@ -7987,7 +7994,7 @@ n 132 12 18 12 re f* n 162 12 282 12 re f* .960784 .960784 .862745 rg n 0 0 6 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (get_length) Tj 0 0 0 rg (\() Tj 0 0 0 rg (SomeSet) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# NB: the implementation for Sized would give 0) Tj /F3 10 Tf 0 0 0 rg T* .4 .4 .4 rg (1) Tj T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (get_length) Tj 0 0 0 rg (\() Tj 0 0 0 rg (SomeSet) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# NB: the implementation for Sized would give 0) Tj /F2 10 Tf 0 0 0 rg T* .4 .4 .4 rg (1) Tj T* ET Q Q Q @@ -7996,7 +8003,7 @@ Q q 1 0 0 1 62.69291 574.6236 cm q -BT 1 0 0 1 0 26 Tm 3.503735 Tw 12 TL /F1 10 Tf 0 0 0 rg (Sometimes it is not clear how to dispatch. For instance, consider a class ) Tj /F3 10 Tf 0 0 0 rg (C ) Tj /F1 10 Tf 0 0 0 rg (registered both as) Tj T* 0 Tw 6.013307 Tw /F3 10 Tf 0 0 0 rg (collections.Iterable ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F3 10 Tf 0 0 0 rg (collections.Sized) Tj /F1 10 Tf 0 0 0 rg (, and defines a generic function ) Tj /F3 10 Tf 0 0 0 rg (g ) Tj /F1 10 Tf 0 0 0 rg (with) Tj T* 0 Tw (implementations for both ) Tj /F3 10 Tf 0 0 0 rg (collections.Iterable) Tj /F1 10 Tf 0 0 0 rg ( ) Tj /F4 10 Tf (and) Tj /F1 10 Tf ( ) Tj /F3 10 Tf 0 0 0 rg (collections.Sized) Tj /F1 10 Tf 0 0 0 rg (:) Tj T* ET +BT 1 0 0 1 0 26 Tm 3.503735 Tw 12 TL /F1 10 Tf 0 0 0 rg (Sometimes it is not clear how to dispatch. For instance, consider a class ) Tj /F2 10 Tf 0 0 0 rg (C ) Tj /F1 10 Tf 0 0 0 rg (registered both as) Tj T* 0 Tw 6.013307 Tw /F2 10 Tf 0 0 0 rg (collections.Iterable ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F2 10 Tf 0 0 0 rg (collections.Sized) Tj /F1 10 Tf 0 0 0 rg (, and defines a generic function ) Tj /F2 10 Tf 0 0 0 rg (g ) Tj /F1 10 Tf 0 0 0 rg (with) Tj T* 0 Tw (implementations for both ) Tj /F2 10 Tf 0 0 0 rg (collections.Iterable) Tj /F1 10 Tf 0 0 0 rg ( ) Tj /F4 10 Tf (and) Tj /F1 10 Tf ( ) Tj /F2 10 Tf 0 0 0 rg (collections.Sized) Tj /F1 10 Tf 0 0 0 rg (:) Tj T* ET Q Q q @@ -8119,7 +8126,7 @@ n 36 0 6 12 re f* n 42 0 18 12 re f* .960784 .960784 .862745 rg n 72 0 324 12 re f* -BT 1 0 0 1 0 182 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (singledispatch_example1) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (singledispatch) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (dispatch_on) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('obj') Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* T* ( ) Tj .666667 .133333 1 rg (@singledispatch) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (g) Tj 0 0 0 rg (\() Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (raise) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .823529 .254902 .227451 rg (NotImplementedError) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (type) Tj 0 0 0 rg (\() Tj 0 0 0 rg (g) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* T* ( ) Tj .666667 .133333 1 rg (@g.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Sized) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (g_sized) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("sized") Tj 0 0 0 rg T* T* ( ) Tj .666667 .133333 1 rg (@g.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Iterable) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (g_iterable) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("iterable") Tj 0 0 0 rg T* T* ( ) Tj 0 0 0 rg (g) Tj 0 0 0 rg (\() Tj 0 0 0 rg (C) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# RuntimeError: Ambiguous dispatch: Iterable or Sized?) Tj T* ET +BT 1 0 0 1 0 182 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (singledispatch_example1) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (singledispatch) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (dispatch_on) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('obj') Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* T* ( ) Tj .666667 .133333 1 rg (@singledispatch) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (g) Tj 0 0 0 rg (\() Tj 0 0 0 rg (obj) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (raise) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .823529 .254902 .227451 rg (NotImplementedError) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (type) Tj 0 0 0 rg (\() Tj 0 0 0 rg (g) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg T* T* ( ) Tj .666667 .133333 1 rg (@g.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Sized) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (g_sized) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("sized") Tj 0 0 0 rg T* T* ( ) Tj .666667 .133333 1 rg (@g.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (collections) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Iterable) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (g_iterable) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("iterable") Tj 0 0 0 rg T* T* ( ) Tj 0 0 0 rg (g) Tj 0 0 0 rg (\() Tj 0 0 0 rg (C) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# RuntimeError: Ambiguous dispatch: Iterable or Sized?) Tj T* ET Q Q Q @@ -8128,7 +8135,7 @@ Q q 1 0 0 1 62.69291 317.4236 cm q -BT 1 0 0 1 0 26 Tm .052651 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is impossible to decide which implementation to use, since the ancestors are independent. The following) Tj T* 0 Tw 1.397318 Tw (function will raise a ) Tj /F3 10 Tf 0 0 0 rg (RuntimeError ) Tj /F1 10 Tf 0 0 0 rg (when called. This is consistent with the "refuse the temptation to) Tj T* 0 Tw (guess" philosophy. ) Tj /F3 10 Tf 0 0 0 rg (functools.singledispatch ) Tj /F1 10 Tf 0 0 0 rg (would raise a similar error.) Tj T* ET +BT 1 0 0 1 0 26 Tm .052651 Tw 12 TL /F1 10 Tf 0 0 0 rg (It is impossible to decide which implementation to use, since the ancestors are independent. The following) Tj T* 0 Tw 1.397318 Tw (function will raise a ) Tj /F2 10 Tf 0 0 0 rg (RuntimeError ) Tj /F1 10 Tf 0 0 0 rg (when called. This is consistent with the "refuse the temptation to) Tj T* 0 Tw (guess" philosophy. ) Tj /F2 10 Tf 0 0 0 rg (functools.singledispatch ) Tj /F1 10 Tf 0 0 0 rg (would raise a similar error.) Tj T* ET Q Q q @@ -8195,13 +8202,13 @@ Q q 1 0 0 1 62.69291 197.4236 cm q -BT 1 0 0 1 0 14 Tm .539431 Tw 12 TL /F1 10 Tf 0 0 0 rg (So the ) Tj /F3 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module prefers to raise an error in the face of ambiguity. This is the same approach) Tj T* 0 Tw (taken by the standard library.) Tj T* ET +BT 1 0 0 1 0 14 Tm .539431 Tw 12 TL /F1 10 Tf 0 0 0 rg (So the ) Tj /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (module prefers to raise an error in the face of ambiguity. This is the same approach) Tj T* 0 Tw (taken by the standard library.) Tj T* ET Q Q q 1 0 0 1 62.69291 143.4236 cm q -BT 1 0 0 1 0 38 Tm .143516 Tw 12 TL /F1 10 Tf 0 0 0 rg (However, it should be noted that the ) Tj /F4 10 Tf (dispatch algorithm ) Tj /F1 10 Tf (used by the decorator module is different from the) Tj T* 0 Tw .476098 Tw (one used by the standard library, so in certain cases you will get different answers. The difference is that) Tj T* 0 Tw 1.98816 Tw /F3 10 Tf 0 0 0 rg (functools.singledispatch ) Tj /F1 10 Tf 0 0 0 rg (tries to insert the virtual ancestors ) Tj /F4 10 Tf (before ) Tj /F1 10 Tf (the base classes, whereas) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (decorator.dispatch_on ) Tj /F1 10 Tf 0 0 0 rg (tries to insert them ) Tj /F4 10 Tf (after ) Tj /F1 10 Tf (the base classes.) Tj T* ET +BT 1 0 0 1 0 38 Tm .143516 Tw 12 TL /F1 10 Tf 0 0 0 rg (However, it should be noted that the ) Tj /F4 10 Tf (dispatch algorithm ) Tj /F1 10 Tf (used by the decorator module is different from the) Tj T* 0 Tw .476098 Tw (one used by the standard library, so in certain cases you will get different answers. The difference is that) Tj T* 0 Tw 1.98816 Tw /F2 10 Tf 0 0 0 rg (functools.singledispatch ) Tj /F1 10 Tf 0 0 0 rg (tries to insert the virtual ancestors ) Tj /F4 10 Tf (before ) Tj /F1 10 Tf (the base classes, whereas) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (decorator.dispatch_on ) Tj /F1 10 Tf 0 0 0 rg (tries to insert them ) Tj /F4 10 Tf (after ) Tj /F1 10 Tf (the base classes.) Tj T* ET Q Q q @@ -8233,7 +8240,7 @@ n 24 12 138 12 re f* n 162 12 18 12 re f* .960784 .960784 .862745 rg n 24 0 294 12 re f* -BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (singledispatch_example2) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# adapted from functools.singledispatch test case) Tj /F3 10 Tf 0 0 0 rg T* ET +BT 1 0 0 1 0 14 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (singledispatch_example2) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# adapted from functools.singledispatch test case) Tj /F2 10 Tf 0 0 0 rg T* ET Q Q Q @@ -8242,8 +8249,8 @@ Q endstream endobj -124 0 obj -<< /Length 13751 >> +125 0 obj +<< /Length 13672 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q @@ -8444,7 +8451,7 @@ n 66 0 6 12 re f* n 72 0 6 12 re f* .960784 .960784 .862745 rg n 84 0 6 12 re f* -BT 1 0 0 1 0 302 Tm 12 TL /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (singledispatch) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (dispatch_on) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('arg') Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (class) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (S) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (pass) Tj /F3 10 Tf 0 0 0 rg T* T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (class) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (V) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (c) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Sized) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (S) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (__len__) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg T* T* ( ) Tj .666667 .133333 1 rg (@singledispatch) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (g) Tj 0 0 0 rg (\() Tj 0 0 0 rg (arg) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("base") Tj 0 0 0 rg T* T* ( ) Tj .666667 .133333 1 rg (@g.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (S) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (g_s) Tj 0 0 0 rg (\() Tj 0 0 0 rg (arg) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("s") Tj 0 0 0 rg T* T* ( ) Tj .666667 .133333 1 rg (@g.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (c) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Container) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (g_container) Tj 0 0 0 rg (\() Tj 0 0 0 rg (arg) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("container") Tj 0 0 0 rg T* T* ( ) Tj 0 0 0 rg (v) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (V) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (assert) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (g) Tj 0 0 0 rg (\() Tj 0 0 0 rg (v) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("s") Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (c) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Container) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (V) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# add c.Container to the virtual mro of V) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (assert) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (g) Tj 0 0 0 rg (\() Tj 0 0 0 rg (v) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("s") Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# since the virtual mro is V, Sized, S, Container) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (g) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (V) Tj T* ET +BT 1 0 0 1 0 302 Tm 12 TL /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (singledispatch) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (dispatch_on) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('arg') Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (class) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (S) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 .501961 0 rg (object) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (pass) Tj /F2 10 Tf 0 0 0 rg T* T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (class) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf 0 0 1 rg (V) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (c) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Sized) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (S) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (__len__) Tj 0 0 0 rg (\() Tj 0 .501961 0 rg (self) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg T* T* ( ) Tj .666667 .133333 1 rg (@singledispatch) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (g) Tj 0 0 0 rg (\() Tj 0 0 0 rg (arg) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("base") Tj 0 0 0 rg T* T* ( ) Tj .666667 .133333 1 rg (@g.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (S) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (g_s) Tj 0 0 0 rg (\() Tj 0 0 0 rg (arg) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("s") Tj 0 0 0 rg T* T* ( ) Tj .666667 .133333 1 rg (@g.register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (c) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Container) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (g_container) Tj 0 0 0 rg (\() Tj 0 0 0 rg (arg) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("container") Tj 0 0 0 rg T* T* ( ) Tj 0 0 0 rg (v) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (V) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (assert) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (g) Tj 0 0 0 rg (\() Tj 0 0 0 rg (v) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("s") Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (c) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (Container) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (register) Tj 0 0 0 rg (\() Tj 0 0 0 rg (V) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# add c.Container to the virtual mro of V) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (assert) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (g) Tj 0 0 0 rg (\() Tj 0 0 0 rg (v) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("s") Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# since the virtual mro is V, Sized, S, Container) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (g) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (V) Tj T* ET Q Q Q @@ -8453,13 +8460,13 @@ Q q 1 0 0 1 62.69291 395.8236 cm q -BT 1 0 0 1 0 26 Tm 10.88816 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you play with this example and replace the ) Tj /F3 10 Tf 0 0 0 rg (singledispatch ) Tj /F1 10 Tf 0 0 0 rg (definition with) Tj T* 0 Tw 1.50816 Tw /F3 10 Tf 0 0 0 rg (functools.singledispatch) Tj /F1 10 Tf 0 0 0 rg (, the assertion will break: ) Tj /F3 10 Tf 0 0 0 rg (g ) Tj /F1 10 Tf 0 0 0 rg (will return ) Tj /F3 10 Tf 0 0 0 rg ("container" ) Tj /F1 10 Tf 0 0 0 rg (instead of ) Tj /F3 10 Tf 0 0 0 rg ("s") Tj /F1 10 Tf 0 0 0 rg (,) Tj T* 0 Tw (because ) Tj /F3 10 Tf 0 0 0 rg (functools.singledispatch ) Tj /F1 10 Tf 0 0 0 rg (will insert the ) Tj /F3 10 Tf 0 0 0 rg (Container ) Tj /F1 10 Tf 0 0 0 rg (class right before ) Tj /F3 10 Tf 0 0 0 rg (S) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET +BT 1 0 0 1 0 26 Tm 10.88816 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you play with this example and replace the ) Tj /F2 10 Tf 0 0 0 rg (singledispatch ) Tj /F1 10 Tf 0 0 0 rg (definition with) Tj T* 0 Tw 1.50816 Tw /F2 10 Tf 0 0 0 rg (functools.singledispatch) Tj /F1 10 Tf 0 0 0 rg (, the assertion will break: ) Tj /F2 10 Tf 0 0 0 rg (g ) Tj /F1 10 Tf 0 0 0 rg (will return ) Tj /F2 10 Tf 0 0 0 rg ("container" ) Tj /F1 10 Tf 0 0 0 rg (instead of ) Tj /F2 10 Tf 0 0 0 rg ("s") Tj /F1 10 Tf 0 0 0 rg (,) Tj T* 0 Tw (because ) Tj /F2 10 Tf 0 0 0 rg (functools.singledispatch ) Tj /F1 10 Tf 0 0 0 rg (will insert the ) Tj /F2 10 Tf 0 0 0 rg (Container ) Tj /F1 10 Tf 0 0 0 rg (class right before ) Tj /F2 10 Tf 0 0 0 rg (S) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET Q Q q 1 0 0 1 62.69291 341.8236 cm q -BT 1 0 0 1 0 38 Tm .528935 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that here I am not making any bold claim such as "the standard library algorithm is wrong and my) Tj T* 0 Tw 1.082209 Tw (algorithm is right" or viceversa. It just point out that there are some subtle differences. The only way to) Tj T* 0 Tw .43881 Tw (understand what is really happening here is to scratch your head by looking at the implementations. I will) Tj T* 0 Tw (just notice that ) Tj /F3 10 Tf 0 0 0 rg (.dispatch_info ) Tj /F1 10 Tf 0 0 0 rg (is quite essential to see the class precedence list used by algorithm:) Tj T* ET +BT 1 0 0 1 0 38 Tm .528935 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that here I am not making any bold claim such as "the standard library algorithm is wrong and my) Tj T* 0 Tw 1.082209 Tw (algorithm is right" or viceversa. It just point out that there are some subtle differences. The only way to) Tj T* 0 Tw .43881 Tw (understand what is really happening here is to scratch your head by looking at the implementations. I will) Tj T* 0 Tw (just notice that ) Tj /F2 10 Tf 0 0 0 rg (.dispatch_info ) Tj /F1 10 Tf 0 0 0 rg (is quite essential to see the class precedence list used by algorithm:) Tj T* ET Q Q q @@ -8536,7 +8543,7 @@ n 174 0 6 12 re f* n 180 0 66 12 re f* .960784 .960784 .862745 rg n 246 0 18 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (g) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (V) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (singledispatch_example2) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (g) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (dispatch_info) Tj 0 0 0 rg (\() Tj 0 0 0 rg (V) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg ([\() Tj .729412 .129412 .129412 rg ('V') Tj 0 0 0 rg (,\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('Sized') Tj 0 0 0 rg (,\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('S') Tj 0 0 0 rg (,\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('Container') Tj 0 0 0 rg (,\)]) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (g) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (V) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (singledispatch_example2) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (g) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (dispatch_info) Tj 0 0 0 rg (\() Tj 0 0 0 rg (V) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg ([\() Tj .729412 .129412 .129412 rg ('V') Tj 0 0 0 rg (,\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('Sized') Tj 0 0 0 rg (,\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('S') Tj 0 0 0 rg (,\),) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj .729412 .129412 .129412 rg ('Container') Tj 0 0 0 rg (,\)]) Tj T* ET Q Q Q @@ -8545,26 +8552,26 @@ Q q 1 0 0 1 62.69291 252.6236 cm q -BT 1 0 0 1 0 14 Tm 1.825814 Tw 12 TL /F1 10 Tf 0 0 0 rg (The current implementation does not implement any kind of cooperation between implementations. In) Tj T* 0 Tw (other words, nothing is akin either to call-next-method in Lisp, or to ) Tj /F3 10 Tf 0 0 0 rg (super ) Tj /F1 10 Tf 0 0 0 rg (in Python.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.825814 Tw 12 TL /F1 10 Tf 0 0 0 rg (The current implementation does not implement any kind of cooperation between implementations. In) Tj T* 0 Tw (other words, nothing is akin either to call-next-method in Lisp, or to ) Tj /F2 10 Tf 0 0 0 rg (super ) Tj /F1 10 Tf 0 0 0 rg (in Python.) Tj T* ET Q Q q 1 0 0 1 62.69291 222.6236 cm q -BT 1 0 0 1 0 14 Tm 1.533984 Tw 12 TL /F1 10 Tf 0 0 0 rg (Finally, let me notice that the decorator module implementation does not use any cache, whereas the) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (singledispatch ) Tj /F1 10 Tf 0 0 0 rg (implementation does.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.533984 Tw 12 TL /F1 10 Tf 0 0 0 rg (Finally, let me notice that the decorator module implementation does not use any cache, whereas the) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (singledispatch ) Tj /F1 10 Tf 0 0 0 rg (implementation does.) Tj T* ET Q Q q 1 0 0 1 62.69291 189.6236 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 +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Caveats and limitations) Tj T* ET Q Q q 1 0 0 1 62.69291 159.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .413876 Tw (One thing you should be aware of is the performance penalty of decorators. The worse case is shown by) Tj T* 0 Tw (the following example:) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .259431 Tw (One thing you should be aware of, is the performance penalty of decorators. The worse case is shown by) Tj T* 0 Tw (the following example:) Tj T* ET Q Q q @@ -8582,8 +8589,6 @@ n -6 -6 468.6898 72 re B* Q q .960784 .960784 .862745 rg -n 0 48 6 12 re f* -.960784 .960784 .862745 rg n 126 36 6 12 re f* .960784 .960784 .862745 rg n 0 24 186 12 re f* @@ -8591,7 +8596,7 @@ n 0 24 186 12 re f* n 0 12 0 12 re f* .960784 .960784 .862745 rg n 0 0 60 12 re f* -BT 1 0 0 1 0 50 Tm 12 TL /F3 10 Tf .098039 .090196 .486275 rg ($ ) Tj 0 0 0 rg (cat performance.sh) Tj T* (python3 -m timeit -s ) Tj .729412 .129412 .129412 rg (") Tj T* (from decorator import decorator) Tj T* T* (@decorator) Tj T* ET +BT 1 0 0 1 0 50 Tm 12 TL /F2 10 Tf 0 0 0 rg ($ cat performance.sh) Tj T* (python3 -m timeit -s ) Tj .729412 .129412 .129412 rg (") Tj T* (from decorator import decorator) Tj T* T* (@decorator) Tj T* ET Q Q Q @@ -8600,8 +8605,8 @@ Q endstream endobj -125 0 obj -<< /Length 10936 >> +126 0 obj +<< /Length 10945 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q @@ -8644,7 +8649,7 @@ n 0 12 48 12 re f* n 0 0 6 12 re f* .960784 .960784 .862745 rg n 12 0 30 12 re f* -BT 1 0 0 1 0 134 Tm 12 TL /F3 10 Tf .729412 .129412 .129412 rg (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* (") Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("f\(\)") Tj 0 0 0 rg T* T* (python3 -m timeit -s ) Tj .729412 .129412 .129412 rg (") Tj T* (def f\(\):) Tj T* ( pass) Tj T* (") Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("f\(\)") Tj T* ET +BT 1 0 0 1 0 134 Tm 12 TL /F2 10 Tf .729412 .129412 .129412 rg (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* (") Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("f\(\)") Tj 0 0 0 rg T* T* (python3 -m timeit -s ) Tj .729412 .129412 .129412 rg (") Tj T* (def f\(\):) Tj T* ( pass) Tj T* (") Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("f\(\)") Tj T* ET Q Q Q @@ -8653,7 +8658,7 @@ Q q 1 0 0 1 62.69291 587.8236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (On my laptop, using the ) Tj /F3 10 Tf 0 0 0 rg (do_nothing ) Tj /F1 10 Tf 0 0 0 rg (decorator instead of the plain function is five times slower:) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (On my laptop, using the ) Tj /F2 10 Tf 0 0 0 rg (do_nothing ) Tj /F1 10 Tf 0 0 0 rg (decorator instead of the plain function is five times slower:) Tj T* ET Q Q q @@ -8671,7 +8676,7 @@ n -6 -6 468.6898 48 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 26 Tm /F3 10 Tf 12 TL ($ bash performance.sh) Tj T* (1000000 loops, best of 3: 1.39 usec per loop) Tj T* (1000000 loops, best of 3: 0.278 usec per loop) Tj T* ET +BT 1 0 0 1 0 26 Tm /F2 10 Tf 12 TL ($ bash performance.sh) Tj T* (1000000 loops, best of 3: 1.39 usec per loop) Tj T* (1000000 loops, best of 3: 0.278 usec per loop) Tj T* ET Q Q Q @@ -8680,7 +8685,7 @@ Q q 1 0 0 1 62.69291 486.6236 cm q -BT 1 0 0 1 0 26 Tm 2.838221 Tw 12 TL /F1 10 Tf 0 0 0 rg (Of course, a real life function probably does something more useful than ) Tj /F3 10 Tf 0 0 0 rg (f ) Tj /F1 10 Tf 0 0 0 rg (here, so the real life) Tj T* 0 Tw 1.371654 Tw (performance penalty ) Tj /F4 10 Tf (could ) Tj /F1 10 Tf (be negligible. As always, the only way to know if there is a penalty in your) Tj T* 0 Tw (specific use case is to measure it.) Tj T* ET +BT 1 0 0 1 0 26 Tm .51832 Tw 12 TL /F1 10 Tf 0 0 0 rg (Of course, a real life function probably does something more useful than the function ) Tj /F2 10 Tf 0 0 0 rg (f ) Tj /F1 10 Tf 0 0 0 rg (here, so the real) Tj T* 0 Tw .480514 Tw (life performance penalty ) Tj /F4 10 Tf (could ) Tj /F1 10 Tf (be negligible. As always, the only way to know if there is a penalty in your) Tj T* 0 Tw (specific use case is to measure it.) Tj T* ET Q Q q @@ -8735,7 +8740,7 @@ n 48 0 6 12 re f* n 54 0 6 12 re f* .960784 .960784 .862745 rg n 60 0 6 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@trace) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj .4 .4 .4 rg (/) Tj .4 .4 .4 rg (0) Tj T* ET +BT 1 0 0 1 0 26 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@trace) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj .4 .4 .4 rg (/) Tj .4 .4 .4 rg (0) Tj T* ET Q Q Q @@ -8744,7 +8749,7 @@ Q q 1 0 0 1 62.69291 349.4236 cm q -BT 1 0 0 1 0 14 Tm 1.655697 Tw 12 TL /F1 10 Tf 0 0 0 rg (Calling ) Tj /F3 10 Tf 0 0 0 rg (f\(\) ) Tj /F1 10 Tf 0 0 0 rg (gives you a ) Tj /F3 10 Tf 0 0 0 rg (ZeroDivisionError) Tj /F1 10 Tf 0 0 0 rg (. But since the function is decorated, the traceback is) Tj T* 0 Tw (longer:) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.655697 Tw 12 TL /F1 10 Tf 0 0 0 rg (Calling ) Tj /F2 10 Tf 0 0 0 rg (f\(\) ) Tj /F1 10 Tf 0 0 0 rg (gives you a ) Tj /F2 10 Tf 0 0 0 rg (ZeroDivisionError) Tj /F1 10 Tf 0 0 0 rg (. But since the function is decorated, the traceback is) Tj T* 0 Tw (longer:) Tj T* ET Q Q q @@ -8889,7 +8894,7 @@ n 0 0 102 12 re f* n 102 0 6 12 re f* .960784 .960784 .862745 rg n 114 0 18 12 re f* -BT 1 0 0 1 0 98 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* 0 0 0 rg (Traceback) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (most) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (recent) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (call) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (last) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (File) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (") Tj (<) Tj (string) Tj (>) Tj (") Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (line) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (File) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (") Tj (<) Tj (doctest __main__[22]) Tj (>) Tj (") Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (line) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (4) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (trace) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (File) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (") Tj (<) Tj (doctest __main__[51]) Tj (>) Tj (") Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (line) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (3) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg T* ( ) Tj .4 .4 .4 rg (1) Tj .4 .4 .4 rg (/) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg T* /F6 10 Tf .823529 .254902 .227451 rg (ZeroDivisionError) Tj /F3 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (...) Tj T* ET +BT 1 0 0 1 0 98 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* 0 0 0 rg (Traceback) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (most) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (recent) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (call) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (last) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (File) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (") Tj (<) Tj (string) Tj (>) Tj (") Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (line) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (2) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (File) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (") Tj (<) Tj (doctest __main__[22]) Tj (>) Tj (") Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (line) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (4) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (trace) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (File) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg (") Tj (<) Tj (doctest __main__[51]) Tj (>) Tj (") Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (line) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (3) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj 0 0 0 rg T* ( ) Tj .4 .4 .4 rg (1) Tj .4 .4 .4 rg (/) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg T* /F6 10 Tf .823529 .254902 .227451 rg (ZeroDivisionError) Tj /F2 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (...) Tj T* ET Q Q Q @@ -8898,62 +8903,61 @@ Q q 1 0 0 1 62.69291 188.2236 cm q -BT 1 0 0 1 0 14 Tm 1.05528 Tw 12 TL /F1 10 Tf 0 0 0 rg (You see here the inner call to the decorator ) Tj /F3 10 Tf 0 0 0 rg (trace) Tj /F1 10 Tf 0 0 0 rg (, which calls ) Tj /F3 10 Tf 0 0 0 rg (f\(*args,) Tj ( ) Tj (**kw\)) Tj /F1 10 Tf 0 0 0 rg (, and a reference to) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (File) Tj ( ) Tj (") Tj (<) Tj (string) Tj (>) Tj (",) Tj ( ) Tj (line) Tj ( ) Tj (2,) Tj ( ) Tj (in) Tj ( ) Tj (f) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.05528 Tw 12 TL /F1 10 Tf 0 0 0 rg (You see here the inner call to the decorator ) Tj /F2 10 Tf 0 0 0 rg (trace) Tj /F1 10 Tf 0 0 0 rg (, which calls ) Tj /F2 10 Tf 0 0 0 rg (f\(*args,) Tj ( ) Tj (**kw\)) Tj /F1 10 Tf 0 0 0 rg (, and a reference to) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (File) Tj ( ) Tj (") Tj (<) Tj (string) Tj (>) Tj (",) Tj ( ) Tj (line) Tj ( ) Tj (2,) Tj ( ) Tj (in) Tj ( ) Tj (f) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET Q Q q 1 0 0 1 62.69291 146.2236 cm q -BT 1 0 0 1 0 26 Tm 1.091751 Tw 12 TL /F1 10 Tf 0 0 0 rg (This latter reference is due to the fact that internally, the decorator module uses ) Tj /F3 10 Tf 0 0 0 rg (exec ) Tj /F1 10 Tf 0 0 0 rg (to generate the) Tj T* 0 Tw .793984 Tw (decorated function. Notice that ) Tj /F3 10 Tf 0 0 0 rg (exec ) Tj /F1 10 Tf 0 0 0 rg (is ) Tj /F4 10 Tf (not ) Tj /F1 10 Tf (responsibile for the performance penalty, since is the called) Tj T* 0 Tw /F4 10 Tf (only once ) Tj /F1 10 Tf (\(at function decoration time\); it is ) Tj /F4 10 Tf (not ) Tj /F1 10 Tf (called each time the decorated function is called.) Tj T* ET +BT 1 0 0 1 0 26 Tm .928221 Tw 12 TL /F1 10 Tf 0 0 0 rg (This latter reference is due to the fact that, internally, the decorator module uses ) Tj /F2 10 Tf 0 0 0 rg (exec ) Tj /F1 10 Tf 0 0 0 rg (to generate the) Tj T* 0 Tw .941984 Tw (decorated function. Notice that ) Tj /F2 10 Tf 0 0 0 rg (exec ) Tj /F1 10 Tf 0 0 0 rg (is ) Tj /F4 10 Tf (not ) Tj /F1 10 Tf (responsible for the performance penalty, since is the called) Tj T* 0 Tw /F4 10 Tf (only once ) Tj /F1 10 Tf (\(at function decoration time\); it is ) Tj /F4 10 Tf (not ) Tj /F1 10 Tf (called each time the decorated function is called.) Tj T* ET Q Q q 1 0 0 1 62.69291 116.2236 cm q -BT 1 0 0 1 0 14 Tm 1.501235 Tw 12 TL /F1 10 Tf 0 0 0 rg (Presently, there is no clean way to avoid ) Tj /F3 10 Tf 0 0 0 rg (exec) Tj /F1 10 Tf 0 0 0 rg (. A clean solution would require changing the CPython) Tj T* 0 Tw (implementation, by adding a hook to functions \(to allow changing their signature directly\).) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.501235 Tw 12 TL /F1 10 Tf 0 0 0 rg (Presently, there is no clean way to avoid ) Tj /F2 10 Tf 0 0 0 rg (exec) Tj /F1 10 Tf 0 0 0 rg (. A clean solution would require changing the CPython) Tj T* 0 Tw (implementation, by adding a hook to functions \(to allow changing their signature directly\).) Tj T* ET Q Q endstream endobj -126 0 obj -<< /Length 15466 >> +127 0 obj +<< /Length 14045 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 62.69291 729.0236 cm q -BT 1 0 0 1 0 26 Tm 1.905984 Tw 12 TL /F1 10 Tf 0 0 0 rg (Even in Python 3.5, it is impossible to change the function signature directly. Thus, the ) Tj /F3 10 Tf 0 0 0 rg (decorator) Tj T* 0 Tw 1.624488 Tw /F1 10 Tf 0 0 0 rg (module is still useful! As a matter of fact, this is the main reason why I still maintain the module and) Tj T* 0 Tw (release new versions.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.905984 Tw 12 TL /F1 10 Tf 0 0 0 rg (Even in Python 3.5, it is impossible to change the function signature directly. Thus, the ) Tj /F2 10 Tf 0 0 0 rg (decorator) Tj T* 0 Tw 1.624488 Tw /F1 10 Tf 0 0 0 rg (module is still useful! As a matter of fact, this is the main reason why I still maintain the module and) Tj T* 0 Tw (release new versions.) Tj T* ET Q Q q 1 0 0 1 62.69291 663.0236 cm q -BT 1 0 0 1 0 50 Tm .155251 Tw 12 TL /F1 10 Tf 0 0 0 rg (It should be noted that in Python 3.5, a ) Tj /F4 10 Tf (lot ) Tj /F1 10 Tf (of improvements have been made: you can decorate a function) Tj T* 0 Tw 2.710976 Tw (with ) Tj /F3 10 Tf 0 0 0 rg (func_tools.update_wrapper) Tj /F1 10 Tf 0 0 0 rg (, and ) Tj /F3 10 Tf 0 0 0 rg (pydoc ) Tj /F1 10 Tf 0 0 0 rg (will see the correct signature. Unfortunately, the) Tj T* 0 Tw 9.38229 Tw (function will still have an incorrect signature internally, as you can see by using) Tj T* 0 Tw 2.521797 Tw /F3 10 Tf 0 0 0 rg (inspect.getfullargspec) Tj /F1 10 Tf 0 0 0 rg (; so, all documentation tools using the function \(which has rightly been) Tj T* 0 Tw (deprecated\) will see the wrong signature.) Tj T* ET +BT 1 0 0 1 0 50 Tm .155251 Tw 12 TL /F1 10 Tf 0 0 0 rg (It should be noted that in Python 3.5, a ) Tj /F4 10 Tf (lot ) Tj /F1 10 Tf (of improvements have been made: you can decorate a function) Tj T* 0 Tw 2.710976 Tw (with ) Tj /F2 10 Tf 0 0 0 rg (func_tools.update_wrapper) Tj /F1 10 Tf 0 0 0 rg (, and ) Tj /F2 10 Tf 0 0 0 rg (pydoc ) Tj /F1 10 Tf 0 0 0 rg (will see the correct signature. Unfortunately, the) Tj T* 0 Tw 9.38229 Tw (function will still have an incorrect signature internally, as you can see by using) Tj T* 0 Tw .243307 Tw /F2 10 Tf 0 0 0 rg (inspect.getfullargspec) Tj /F1 10 Tf 0 0 0 rg (; so, all documentation tools using ) Tj 1 0 0 rg (``) Tj 0 0 0 rg (inspect.getfullargspec`- which has been) Tj T* 0 Tw (rightly deprecated - will see the wrong signature.) Tj T* ET Q Q q -1 0 0 1 62.69291 609.0236 cm +1 0 0 1 62.69291 585.0236 cm q -BT 1 0 0 1 0 38 Tm 1.043828 Tw 12 TL /F1 10 Tf 0 0 0 rg (In the present implementation, decorators generated by ) Tj /F3 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (can only be used on user-defined) Tj T* 0 Tw .221235 Tw (Python functions or methods. They cannot be used on generic callable objects or built-in functions, due to) Tj T* 0 Tw .505318 Tw (limitations of the standard library's ) Tj /F3 10 Tf 0 0 0 rg (inspect ) Tj /F1 10 Tf 0 0 0 rg (module, especially for Python 2. \(In Python 3.5, many such) Tj T* 0 Tw (limitations have been removed.\)) Tj T* ET +BT 1 0 0 1 0 62 Tm 1.043828 Tw 12 TL /F1 10 Tf 0 0 0 rg (In the present implementation, decorators generated by ) Tj /F2 10 Tf 0 0 0 rg (decorator ) Tj /F1 10 Tf 0 0 0 rg (can only be used on user-defined) Tj T* 0 Tw .221235 Tw (Python functions or methods. They cannot be used on generic callable objects or built-in functions, due to) Tj T* 0 Tw .727318 Tw (limitations of the standard library's ) Tj /F2 10 Tf 0 0 0 rg (inspect ) Tj /F1 10 Tf 0 0 0 rg (module, especially for Python 2. In Python 3.5, many such) Tj T* 0 Tw .216303 Tw (limitations have been removed, but I still think that it is cleaner and safer to decorate only functions. If you) Tj T* 0 Tw .177126 Tw (want to decorate things like classmethods/staticmethods and general callables - which I will never support) Tj T* 0 Tw (in the decorator module - I suggest you to look at the ) Tj 0 0 .501961 rg (wrapt ) Tj 0 0 0 rg (project by Graeme Dumpleton.) Tj T* ET Q Q q -1 0 0 1 62.69291 567.0236 cm +1 0 0 1 62.69291 543.0236 cm q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL .53561 Tw (There is a strange quirk when decorating functions with keyword arguments, if one of the arguments has) Tj T* 0 Tw 2.368221 Tw (the same name used in the caller function for the first argument. The quirk was reported by David) Tj T* 0 Tw (Goldstein.) Tj T* ET +BT 1 0 0 1 0 26 Tm .53561 Tw 12 TL /F1 10 Tf 0 0 0 rg (There is a strange quirk when decorating functions with keyword arguments, if one of the arguments has) Tj T* 0 Tw 2.368221 Tw (the same name used in the caller function for the first argument. The quirk was reported by David) Tj T* 0 Tw (Goldstein.) Tj T* ET Q Q q -1 0 0 1 62.69291 549.0236 cm +1 0 0 1 62.69291 525.0236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is an example where it is manifest:) Tj T* ET Q Q q -1 0 0 1 62.69291 443.8236 cm +1 0 0 1 62.69291 419.8236 cm q q 1 0 0 1 0 0 cm @@ -9054,26 +9058,26 @@ n 252 0 18 12 re f* n 276 0 18 12 re f* .960784 .960784 .862745 rg n 300 0 36 12 re f* -BT 1 0 0 1 0 74 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@memoize) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (getkeys) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (kw) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (keys) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (getkeys) Tj 0 0 0 rg (\() Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (=) Tj .729412 .129412 .129412 rg ('a') Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg (Traceback) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (most) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (recent) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (call) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (last) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg T* /F6 10 Tf .823529 .254902 .227451 rg (TypeError) Tj /F3 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (_memoize) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (got) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (multiple) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (values) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (for) Tj /F3 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('func') Tj T* ET +BT 1 0 0 1 0 74 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@memoize) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (getkeys) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (kw) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (keys) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (getkeys) Tj 0 0 0 rg (\() Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (=) Tj .729412 .129412 .129412 rg ('a') Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* 0 0 0 rg (Traceback) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (most) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (recent) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (call) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (last) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg T* /F6 10 Tf .823529 .254902 .227451 rg (TypeError) Tj /F2 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (_memoize) Tj 0 0 0 rg (\(\)) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (got) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (multiple) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (values) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (for) Tj /F2 10 Tf 0 0 0 rg ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ('func') Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 411.8236 cm +1 0 0 1 62.69291 387.8236 cm q BT 1 0 0 1 0 14 Tm .467485 Tw 12 TL /F1 10 Tf 0 0 0 rg (The error message looks really strange... until you realize that the caller function ) Tj /F4 10 Tf 0 0 0 rg (_memoize ) Tj /F1 10 Tf 0 0 0 rg (uses ) Tj /F4 10 Tf 0 0 0 rg (func ) Tj /F1 10 Tf 0 0 0 rg (as) Tj T* 0 Tw (first argument, so there is a confusion between the positional argument and the keywork arguments.) Tj T* ET Q Q q -1 0 0 1 62.69291 381.8236 cm +1 0 0 1 62.69291 357.8236 cm q BT 1 0 0 1 0 14 Tm .862927 Tw 12 TL /F1 10 Tf 0 0 0 rg (The solution is to change the name of the first argument in ) Tj /F4 10 Tf 0 0 0 rg (_memoize) Tj /F1 10 Tf 0 0 0 rg (, or to change the implementation) Tj T* 0 Tw (like so:) Tj T* ET Q Q q -1 0 0 1 62.69291 228.6236 cm +1 0 0 1 62.69291 204.6236 cm q q 1 0 0 1 0 0 cm @@ -9226,27 +9230,34 @@ n 96 0 6 12 re f* n 102 0 18 12 re f* .960784 .960784 .862745 rg n 120 0 6 12 re f* -BT 1 0 0 1 0 122 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 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 (all_args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (all_args) Tj 0 0 0 rg ([) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (]) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (all_args) Tj 0 0 0 rg ([) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (:]) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# frozenset is used to ensure hashability) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (frozenset) Tj 0 0 0 rg (\() Tj 0 0 0 rg (kw) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (items) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (else) Tj /F3 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# attribute added by memoize) Tj /F3 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (not) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ([) Tj 0 0 0 rg (key) Tj 0 0 0 rg (]) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ([) Tj 0 0 0 rg (key) Tj 0 0 0 rg (]) Tj T* ET +BT 1 0 0 1 0 122 Tm 12 TL /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 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 (all_args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (all_args) Tj 0 0 0 rg ([) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (]) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (all_args) Tj 0 0 0 rg ([) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg (:]) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# frozenset is used to ensure hashability) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 .501961 0 rg (frozenset) Tj 0 0 0 rg (\() Tj 0 0 0 rg (kw) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (items) Tj 0 0 0 rg (\(\)\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (else) Tj /F2 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (args) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# attribute added by memoize) Tj /F2 10 Tf 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (if) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (key) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (not) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg (:) Tj 0 0 0 rg T* ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ([) Tj 0 0 0 rg (key) Tj 0 0 0 rg (]) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (func) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (args) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (**) Tj 0 0 0 rg (kw) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (cache) Tj 0 0 0 rg ([) Tj 0 0 0 rg (key) Tj 0 0 0 rg (]) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 196.6236 cm +1 0 0 1 62.69291 148.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .864104 Tw (This avoids the need to name the first argument, so the problem simply disappears. This is a technique) Tj T* 0 Tw (that you should keep in mind when writing decorators for functions with keyword arguments.) Tj T* ET +BT 1 0 0 1 0 38 Tm /F1 10 Tf 12 TL .864104 Tw (This avoids the need to name the first argument, so the problem simply disappears. This is a technique) Tj T* 0 Tw .609318 Tw (that you should keep in mind when writing decorators for functions with keyword arguments. Also, notice) Tj T* 0 Tw 1.05881 Tw (that lately I have come to believe that decorating functions with keyword arguments is not such a good) Tj T* 0 Tw (idea, and you may want not to do that.) Tj T* ET Q Q q -1 0 0 1 62.69291 166.6236 cm +1 0 0 1 62.69291 118.6236 cm q -BT 1 0 0 1 0 14 Tm .584692 Tw 12 TL /F1 10 Tf 0 0 0 rg (On a similar note, there is a restriction on argument names. For instance, if name an argument ) Tj /F3 10 Tf 0 0 0 rg (_call_) Tj T* 0 Tw /F1 10 Tf 0 0 0 rg (or ) Tj /F3 10 Tf 0 0 0 rg (_func_) Tj /F1 10 Tf 0 0 0 rg (, you will get a ) Tj /F3 10 Tf 0 0 0 rg (NameError) Tj /F1 10 Tf 0 0 0 rg (:) Tj T* ET +BT 1 0 0 1 0 14 Tm 1.943516 Tw 12 TL /F1 10 Tf 0 0 0 rg (On a similar note, there is a restriction on argument names. For instance, if you name an argument) Tj T* 0 Tw /F2 10 Tf 0 0 0 rg (_call_ ) Tj /F1 10 Tf 0 0 0 rg (or ) Tj /F2 10 Tf 0 0 0 rg (_func_) Tj /F1 10 Tf 0 0 0 rg (, you will get a ) Tj /F2 10 Tf 0 0 0 rg (NameError) Tj /F1 10 Tf 0 0 0 rg (:) Tj T* ET Q Q + +endstream +endobj +128 0 obj +<< /Length 11616 >> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 85.42362 cm +1 0 0 1 62.69291 655.8236 cm q q 1 0 0 1 0 0 cm @@ -9256,82 +9267,55 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 72 re B* +n -6 -6 468.6898 108 re B* Q q .960784 .960784 .862745 rg -n 0 48 6 12 re f* -.960784 .960784 .862745 rg -n 6 48 6 12 re f* +n 0 84 6 12 re f* .960784 .960784 .862745 rg -n 12 48 6 12 re f* +n 6 84 6 12 re f* .960784 .960784 .862745 rg -n 24 48 36 12 re f* +n 12 84 6 12 re f* .960784 .960784 .862745 rg -n 0 36 18 12 re f* +n 24 84 36 12 re f* .960784 .960784 .862745 rg -n 24 36 18 12 re f* +n 0 72 18 12 re f* .960784 .960784 .862745 rg -n 48 36 6 12 re f* +n 24 72 18 12 re f* .960784 .960784 .862745 rg -n 54 36 6 12 re f* +n 48 72 6 12 re f* .960784 .960784 .862745 rg -n 60 36 36 12 re f* +n 54 72 6 12 re f* .960784 .960784 .862745 rg -n 96 36 12 12 re f* +n 60 72 36 12 re f* .960784 .960784 .862745 rg -n 114 36 30 12 re f* +n 96 72 12 12 re f* .960784 .960784 .862745 rg -n 144 36 6 12 re f* +n 114 72 30 12 re f* .960784 .960784 .862745 rg -n 150 36 6 12 re f* +n 144 72 6 12 re f* .960784 .960784 .862745 rg -n 156 36 6 12 re f* +n 150 72 6 12 re f* .960784 .960784 .862745 rg -n 0 24 18 12 re f* +n 156 72 6 12 re f* .960784 .960784 .862745 rg -n 0 12 54 12 re f* +n 0 60 18 12 re f* .960784 .960784 .862745 rg -n 60 12 6 12 re f* +n 0 48 54 12 re f* .960784 .960784 .862745 rg -n 66 12 24 12 re f* +n 60 48 6 12 re f* .960784 .960784 .862745 rg -n 96 12 36 12 re f* +n 66 48 24 12 re f* .960784 .960784 .862745 rg -n 138 12 24 12 re f* +n 96 48 36 12 re f* .960784 .960784 .862745 rg -n 168 12 24 12 re f* +n 138 48 24 12 re f* .960784 .960784 .862745 rg -n 192 12 12 12 re f* +n 168 48 24 12 re f* .960784 .960784 .862745 rg -n 12 0 18 12 re f* -BT 1 0 0 1 0 50 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@trace) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f) Tj 0 0 0 rg (\() Tj 0 0 0 rg (_func_) Tj 0 0 0 rg (\):) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F3 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg T* 0 0 0 rg (Traceback) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (most) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (recent) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (call) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (last) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg T* ET -Q -Q -Q -Q -Q - -endstream -endobj -127 0 obj -<< /Length 9789 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 715.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 +n 192 48 12 12 re f* .960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* -Q -q +n 12 36 18 12 re f* .960784 .960784 .862745 rg n 0 24 54 12 re f* .960784 .960784 .862745 rg @@ -9368,21 +9352,21 @@ n 144 0 6 12 re f* n 156 0 36 12 re f* .960784 .960784 .862745 rg n 192 0 6 12 re f* -BT 1 0 0 1 0 26 Tm 12 TL /F6 10 Tf .823529 .254902 .227451 rg (NameError) Tj /F3 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (_func_) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (is) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (overridden) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F3 10 Tf 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f) Tj 0 0 0 rg (\() Tj 0 0 0 rg (_func_) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (_call_) Tj 0 0 0 rg (\() Tj 0 0 0 rg (_func_) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (_func_) Tj 0 0 0 rg (\)) Tj T* ET +BT 1 0 0 1 0 86 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj .666667 .133333 1 rg (@trace) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f) Tj 0 0 0 rg (\() Tj 0 0 0 rg (_func_) Tj 0 0 0 rg (\):) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (print) Tj /F2 10 Tf 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (\)) Tj 0 0 0 rg T* .4 .4 .4 rg (...) Tj 0 0 0 rg T* 0 0 0 rg (Traceback) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (\() Tj 0 0 0 rg (most) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (recent) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (call) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (last) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj .4 .4 .4 rg (...) Tj 0 0 0 rg T* /F6 10 Tf .823529 .254902 .227451 rg (NameError) Tj /F2 10 Tf 0 0 0 rg (:) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (_func_) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (is) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (overridden) Tj 0 0 0 rg ( ) Tj /F6 10 Tf .666667 .133333 1 rg (in) Tj /F2 10 Tf 0 0 0 rg T* /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f) Tj 0 0 0 rg (\() Tj 0 0 0 rg (_func_) Tj 0 0 0 rg (\):) Tj 0 0 0 rg T* ( ) Tj /F6 10 Tf 0 .501961 0 rg (return) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (_call_) Tj 0 0 0 rg (\() Tj 0 0 0 rg (_func_) Tj 0 0 0 rg (,) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (_func_) Tj 0 0 0 rg (\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 683.8236 cm +1 0 0 1 62.69291 623.8236 cm q 0 0 0 rg BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.720651 Tw (Finally, the implementation is such that the decorated function makes a \(shallow\) copy of the original) Tj T* 0 Tw (function dictionary:) Tj T* ET Q Q q -1 0 0 1 62.69291 530.6236 cm +1 0 0 1 62.69291 470.6236 cm q q 1 0 0 1 0 0 cm @@ -9515,37 +9499,37 @@ n 36 12 30 12 re f* n 72 12 234 12 re f* .960784 .960784 .862745 rg n 0 0 96 12 re f* -BT 1 0 0 1 0 122 Tm 12 TL /F3 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F3 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (pass) Tj /F3 10 Tf 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# the original function) Tj /F3 10 Tf 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (attr1) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("something") Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# setting an attribute) Tj /F3 10 Tf 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (attr2) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("something else") Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# setting another attribute) Tj /F3 10 Tf 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (traced_f) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (trace) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# the decorated function) Tj /F3 10 Tf 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (traced_f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (attr1) Tj 0 0 0 rg T* .729412 .129412 .129412 rg ('something') Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (traced_f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (attr2) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("something different") Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# setting attr) Tj /F3 10 Tf 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (attr2) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# the original attribute did not change) Tj /F3 10 Tf 0 0 0 rg T* .729412 .129412 .129412 rg ('something else') Tj T* ET +BT 1 0 0 1 0 122 Tm 12 TL /F2 10 Tf .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (def) Tj /F2 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (f) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg ( ) Tj /F6 10 Tf 0 .501961 0 rg (pass) Tj /F2 10 Tf 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# the original function) Tj /F2 10 Tf 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (attr1) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("something") Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# setting an attribute) Tj /F2 10 Tf 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (attr2) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("something else") Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# setting another attribute) Tj /F2 10 Tf 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (traced_f) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (trace) Tj 0 0 0 rg (\() Tj 0 0 0 rg (f) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# the decorated function) Tj /F2 10 Tf 0 0 0 rg T* T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (traced_f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (attr1) Tj 0 0 0 rg T* .729412 .129412 .129412 rg ('something') Tj 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (traced_f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (attr2) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (=) Tj 0 0 0 rg ( ) Tj .729412 .129412 .129412 rg ("something different") Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# setting attr) Tj /F2 10 Tf 0 0 0 rg T* .4 .4 .4 rg (>) Tj (>) Tj (>) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (f) Tj .4 .4 .4 rg (.) Tj 0 0 0 rg (attr2) Tj 0 0 0 rg ( ) Tj /F7 10 Tf .25098 .501961 .501961 rg (# the original attribute did not change) Tj /F2 10 Tf 0 0 0 rg T* .729412 .129412 .129412 rg ('something else') Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 497.6236 cm +1 0 0 1 62.69291 437.6236 cm q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (LICENSE) Tj T* ET +BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (LICENSE \(2-clause BSD\)) Tj T* ET Q Q q -1 0 0 1 62.69291 479.6236 cm +1 0 0 1 62.69291 419.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Copyright \(c\) 2005-2016, Michele Simionato All rights reserved.) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Copyright \(c\) 2005-2017, Michele Simionato All rights reserved.) Tj T* ET Q Q q -1 0 0 1 62.69291 449.6236 cm +1 0 0 1 62.69291 389.6236 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 443.6236 cm +1 0 0 1 62.69291 383.6236 cm Q q -1 0 0 1 62.69291 395.6236 cm +1 0 0 1 62.69291 335.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET BT 1 0 0 1 0 2 Tm T* ET @@ -9560,17 +9544,17 @@ q Q Q q -1 0 0 1 62.69291 395.6236 cm +1 0 0 1 62.69291 335.6236 cm Q q -1 0 0 1 62.69291 269.6236 cm +1 0 0 1 62.69291 209.6236 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 q -1 0 0 1 62.69291 239.6236 cm +1 0 0 1 62.69291 179.6236 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 @@ -9579,86 +9563,86 @@ Q endstream endobj -128 0 obj -<< /Nums [ 0 129 0 R 1 130 0 R 2 131 0 R 3 132 0 R 4 133 0 R - 5 134 0 R 6 135 0 R 7 136 0 R 8 137 0 R 9 138 0 R - 10 139 0 R 11 140 0 R 12 141 0 R 13 142 0 R 14 143 0 R - 15 144 0 R 16 145 0 R 17 146 0 R 18 147 0 R 19 148 0 R - 20 149 0 R 21 150 0 R ] >> -endobj 129 0 obj -<< /S /D /St 1 >> +<< /Nums [ 0 130 0 R 1 131 0 R 2 132 0 R 3 133 0 R 4 134 0 R + 5 135 0 R 6 136 0 R 7 137 0 R 8 138 0 R 9 139 0 R + 10 140 0 R 11 141 0 R 12 142 0 R 13 143 0 R 14 144 0 R + 15 145 0 R 16 146 0 R 17 147 0 R 18 148 0 R 19 149 0 R + 20 150 0 R 21 151 0 R ] >> endobj 130 0 obj -<< /S /D /St 2 >> +<< /S /D /St 1 >> endobj 131 0 obj -<< /S /D /St 3 >> +<< /S /D /St 2 >> endobj 132 0 obj -<< /S /D /St 4 >> +<< /S /D /St 3 >> endobj 133 0 obj -<< /S /D /St 5 >> +<< /S /D /St 4 >> endobj 134 0 obj -<< /S /D /St 6 >> +<< /S /D /St 5 >> endobj 135 0 obj -<< /S /D /St 7 >> +<< /S /D /St 6 >> endobj 136 0 obj -<< /S /D /St 8 >> +<< /S /D /St 7 >> endobj 137 0 obj -<< /S /D /St 9 >> +<< /S /D /St 8 >> endobj 138 0 obj -<< /S /D /St 10 >> +<< /S /D /St 9 >> endobj 139 0 obj -<< /S /D /St 11 >> +<< /S /D /St 10 >> endobj 140 0 obj -<< /S /D /St 12 >> +<< /S /D /St 11 >> endobj 141 0 obj -<< /S /D /St 13 >> +<< /S /D /St 12 >> endobj 142 0 obj -<< /S /D /St 14 >> +<< /S /D /St 13 >> endobj 143 0 obj -<< /S /D /St 15 >> +<< /S /D /St 14 >> endobj 144 0 obj -<< /S /D /St 16 >> +<< /S /D /St 15 >> endobj 145 0 obj -<< /S /D /St 17 >> +<< /S /D /St 16 >> endobj 146 0 obj -<< /S /D /St 18 >> +<< /S /D /St 17 >> endobj 147 0 obj -<< /S /D /St 19 >> +<< /S /D /St 18 >> endobj 148 0 obj -<< /S /D /St 20 >> +<< /S /D /St 19 >> endobj 149 0 obj -<< /S /D /St 21 >> +<< /S /D /St 20 >> endobj 150 0 obj +<< /S /D /St 21 >> +endobj +151 0 obj << /S /D /St 22 >> endobj xref -0 151 +0 152 0000000000 65535 f 0000000075 00000 n 0000000177 00000 n 0000000287 00000 n -0000000402 00000 n +0000000395 00000 n 0000000510 00000 n 0000000699 00000 n 0000000898 00000 n @@ -9736,80 +9720,81 @@ xref 0000014476 00000 n 0000014688 00000 n 0000014900 00000 n -0000015112 00000 n -0000015324 00000 n -0000015435 00000 n -0000015683 00000 n -0000015762 00000 n -0000015879 00000 n -0000016007 00000 n -0000016149 00000 n -0000016278 00000 n -0000016420 00000 n -0000016550 00000 n -0000016685 00000 n -0000016823 00000 n -0000016960 00000 n -0000017086 00000 n -0000017220 00000 n -0000017352 00000 n -0000017493 00000 n -0000017635 00000 n -0000017790 00000 n -0000017928 00000 n -0000018088 00000 n -0000018232 00000 n -0000018346 00000 n -0000018567 00000 n -0000026190 00000 n -0000034449 00000 n -0000046365 00000 n -0000059816 00000 n -0000079241 00000 n -0000099270 00000 n -0000116415 00000 n -0000134095 00000 n -0000152393 00000 n -0000163332 00000 n -0000180836 00000 n -0000197228 00000 n -0000213619 00000 n -0000225808 00000 n -0000241080 00000 n -0000255118 00000 n -0000268389 00000 n -0000280580 00000 n -0000294390 00000 n -0000305385 00000 n -0000320910 00000 n -0000330757 00000 n -0000331041 00000 n -0000331079 00000 n -0000331117 00000 n -0000331155 00000 n -0000331193 00000 n -0000331231 00000 n -0000331269 00000 n -0000331307 00000 n -0000331345 00000 n -0000331383 00000 n -0000331422 00000 n -0000331461 00000 n -0000331500 00000 n -0000331539 00000 n -0000331578 00000 n -0000331617 00000 n -0000331656 00000 n -0000331695 00000 n -0000331734 00000 n -0000331773 00000 n -0000331812 00000 n -0000331851 00000 n +0000015095 00000 n +0000015326 00000 n +0000015538 00000 n +0000015649 00000 n +0000015911 00000 n +0000015990 00000 n +0000016107 00000 n +0000016248 00000 n +0000016390 00000 n +0000016519 00000 n +0000016661 00000 n +0000016791 00000 n +0000016926 00000 n +0000017064 00000 n +0000017201 00000 n +0000017327 00000 n +0000017461 00000 n +0000017593 00000 n +0000017735 00000 n +0000017878 00000 n +0000018034 00000 n +0000018172 00000 n +0000018332 00000 n +0000018476 00000 n +0000018607 00000 n +0000018828 00000 n +0000026593 00000 n +0000034865 00000 n +0000046781 00000 n +0000060232 00000 n +0000079657 00000 n +0000099686 00000 n +0000116831 00000 n +0000134511 00000 n +0000152809 00000 n +0000163752 00000 n +0000181251 00000 n +0000197643 00000 n +0000214034 00000 n +0000226462 00000 n +0000241734 00000 n +0000255772 00000 n +0000269043 00000 n +0000281234 00000 n +0000294965 00000 n +0000305969 00000 n +0000320073 00000 n +0000331748 00000 n +0000332032 00000 n +0000332070 00000 n +0000332108 00000 n +0000332146 00000 n +0000332184 00000 n +0000332222 00000 n +0000332260 00000 n +0000332298 00000 n +0000332336 00000 n +0000332374 00000 n +0000332413 00000 n +0000332452 00000 n +0000332491 00000 n +0000332530 00000 n +0000332569 00000 n +0000332608 00000 n +0000332647 00000 n +0000332686 00000 n +0000332725 00000 n +0000332764 00000 n +0000332803 00000 n +0000332842 00000 n trailer << /ID % ReportLab generated PDF document -- digest (http://www.reportlab.com) - [(\335u\305\027\323\236f+p\321\341\351\)#\340;) (\335u\305\027\323\236f+p\321\341\351\)#\340;)] - /Info 84 0 R /Root 83 0 R /Size 151 >> + [(d\361p`_\330\303@\326\177hR\227\011V\331) (d\361p`_\330\303@\326\177hR\227\011V\331)] + /Info 85 0 R /Root 84 0 R /Size 152 >> startxref -331890 +332881 %%EOF diff --git a/src/decorator.py b/src/decorator.py index 09a466e..6362c02 100644 --- a/src/decorator.py +++ b/src/decorator.py @@ -1,6 +1,6 @@ # ######################### LICENSE ############################ # -# Copyright (c) 2005-2016, Michele Simionato +# Copyright (c) 2005-2017, Michele Simionato # All rights reserved. # Redistribution and use in source and binary forms, with or without @@ -40,7 +40,7 @@ import operator import itertools import collections -__version__ = '4.0.10' +__version__ = '4.0.11' if sys.version >= '3': from inspect import getfullargspec @@ -48,21 +48,13 @@ if sys.version >= '3': def get_init(cls): return cls.__init__ else: - class getfullargspec(object): - "A quick and dirty replacement for getfullargspec for Python 2.X" - def __init__(self, f): - self.args, self.varargs, self.varkw, self.defaults = \ - inspect.getargspec(f) - self.kwonlyargs = [] - self.kwonlydefaults = None - - def __iter__(self): - yield self.args - yield self.varargs - yield self.varkw - yield self.defaults + FullArgSpec = collections.namedtuple( + 'FullArgSpec', 'args varargs varkw defaults ' + 'kwonlyargs kwonlydefaults') - getargspec = inspect.getargspec + def getfullargspec(f): + "A quick and dirty replacement for getfullargspec for Python 2.X" + return FullArgSpec._make(inspect.getargspec(f) + ([], None)) def get_init(cls): return cls.__init__.__func__ @@ -78,7 +70,7 @@ def getargspec(f): return ArgSpec(spec.args, spec.varargs, spec.varkw, spec.defaults) -DEF = re.compile('\s*def\s*([_\w][_\w\d]*)\s*\(') +DEF = re.compile(r'\s*def\s*([_\w][_\w\d]*)\s*\(') # basic functionality @@ -92,6 +84,9 @@ class FunctionMaker(object): # Atomic get-and-increment provided by the GIL _compile_count = itertools.count() + # make pylint happy + args = varargs = varkw = defaults = kwonlyargs = kwonlydefaults = () + def __init__(self, func=None, name=None, signature=None, defaults=None, doc=None, module=None, funcdict=None): self.shortsignature = signature @@ -154,8 +149,8 @@ class FunctionMaker(object): func.__name__ = self.name func.__doc__ = getattr(self, 'doc', None) func.__dict__ = getattr(self, 'dict', {}) - func.__defaults__ = getattr(self, 'defaults', ()) - func.__kwdefaults__ = getattr(self, 'kwonlydefaults', None) + func.__defaults__ = self.defaults + func.__kwdefaults__ = self.kwonlydefaults or None func.__annotations__ = getattr(self, 'annotations', None) try: frame = sys._getframe(3) @@ -346,7 +341,7 @@ def dispatch_on(*dispatch_args): ras = [[] for _ in range(len(dispatch_args))] for types_ in typemap: for t, type_, ra in zip(types, types_, ras): - if issubclass(t, type_) and type_ not in t.__mro__: + if issubclass(t, type_) and type_ not in t.mro(): append(type_, ra) return [set(ra) for ra in ras] @@ -363,9 +358,9 @@ def dispatch_on(*dispatch_args): 'Ambiguous dispatch for %s: %s' % (t, vas)) elif n_vas == 1: va, = vas - mro = type('t', (t, va), {}).__mro__[1:] + mro = type('t', (t, va), {}).mro()[1:] else: - mro = t.__mro__ + mro = t.mro() lists.append(mro[:-1]) # discard t and object return lists diff --git a/src/tests/documentation.py b/src/tests/documentation.py index e651281..6b5d90c 100644 --- a/src/tests/documentation.py +++ b/src/tests/documentation.py @@ -1,6 +1,6 @@ from __future__ import print_function -doc = r""" +doc = r"""\ The ``decorator`` module ============================================================= @@ -33,12 +33,12 @@ trivial to distribute the module as an universal wheel_ since 2to3 is no more required. Since Python 2.5 has been released 9 years ago, I felt that it was reasonable to drop the support for it. If you need to support ancient versions of Python, stick with the decorator module version -3.4.2. The current version supports all Python releases from 2.6 up to 3.5. +3.4.2. The current version supports all Python releases from 2.6 up to 3.6. .. _wheel: http://pythonwheels.com/ -What's New ---------------------- +What's New in version 4 +----------------------- - **New documentation** There is now a single manual for all Python versions, so I took the @@ -596,7 +596,7 @@ decorated functions. In IPython, this means that the usual ``??`` trick will give you the (right on the spot) message ``Dynamically generated function. No source code available``. -In the past, I have considered this acceptable, since ``inspect.getsource`` +In the past, I considered this acceptable, since ``inspect.getsource`` does not really work with "regular" decorators. In those cases, ``inspect.getsource`` gives you the wrapper source code, which is probably not what you want: @@ -725,10 +725,12 @@ $$XMLWriter Here, you want to dispatch on the *second* argument; the first is already taken by ``self``. The ``dispatch_on`` decorator factory allows you to specify -the dispatch argument simplpy by passing its name as a string. (Note +the dispatch argument simply by passing its name as a string. (Note that if you misspell the name you will get an error.) -The decorated function decorated is turned into a generic function, +The decorated function `write` is turned into a generic function ( +`write` is a function at the idea it is decorated; it will be turned +into a method later, at class instantiation time), and it is called if there are no more specialized implementations. Usually, default functions should raise a ``NotImplementedError``, thus @@ -972,7 +974,7 @@ not use any cache, whereas the ``singledispatch`` implementation does. Caveats and limitations ------------------------------------------- -One thing you should be aware of is the performance penalty of decorators. +One thing you should be aware of, is the performance penalty of decorators. The worse case is shown by the following example: .. code-block:: bash @@ -1003,9 +1005,9 @@ plain function is five times slower:: 1000000 loops, best of 3: 0.278 usec per loop Of course, a real life function probably does something more useful -than ``f`` here, so the real life performance penalty *could* be negligible. -As always, the only way to know if there is a penalty in your specific use case -is to measure it. +than the function ``f`` here, so the real life performance penalty +*could* be negligible. As always, the only way to know if there is a +penalty in your specific use case is to measure it. More importantly, you should be aware that decorators will make your tracebacks longer and more difficult to understand. @@ -1036,7 +1038,7 @@ But since the function is decorated, the traceback is longer: You see here the inner call to the decorator ``trace``, which calls ``f(*args, **kw)``, and a reference to ``File "", line 2, in f``. -This latter reference is due to the fact that internally, the decorator +This latter reference is due to the fact that, internally, the decorator module uses ``exec`` to generate the decorated function. Notice that ``exec`` is *not* responsible for the performance penalty, since is the called *only once* (at function decoration time); it is *not* called @@ -1056,9 +1058,9 @@ been made: you can decorate a function with ``func_tools.update_wrapper``, and ``pydoc`` will see the correct signature. Unfortunately, the function will still have an incorrect signature internally, as you can see by using -``inspect.getfullargspec``; so, all documentation tools using the -function (which has rightly been deprecated) will see the wrong -signature. +``inspect.getfullargspec``; so, all documentation tools using +``inspect.getfullargspec`` - which has been rightly deprecated - +will see the wrong signature. .. _362: http://www.python.org/dev/peps/pep-0362 @@ -1066,7 +1068,13 @@ In the present implementation, decorators generated by ``decorator`` can only be used on user-defined Python functions or methods. They cannot be used on generic callable objects or built-in functions, due to limitations of the standard library's ``inspect`` module, especially -for Python 2. (In Python 3.5, many such limitations have been removed.) +for Python 2. In Python 3.5, many such limitations have been removed, but +I still think that it is cleaner and safer to decorate only +functions. If you want to decorate things like classmethods/staticmethods +and general callables - which I will never support in the decorator module - +I suggest you to look at the wrapt_ project by Graeme Dumpleton. + +.. _wrapt: https://wrapt.readthedocs.io/en/latest/ There is a strange quirk when decorating functions with keyword arguments, if one of the arguments has the same name used in the @@ -1109,7 +1117,10 @@ or to change the implementation like so: This avoids the need to name the first argument, so the problem simply disappears. This is a technique that you should keep in mind -when writing decorators for functions with keyword arguments. +when writing decorators for functions with keyword arguments. Also, +notice that lately I have come to believe that decorating functions with +keyword arguments is not such a good idea, and you may want not to do +that. On a similar note, there is a restriction on argument names. For instance, if you name an argument ``_call_`` or ``_func_``, you will get a ``NameError``: @@ -1146,10 +1157,10 @@ a (shallow) copy of the original function dictionary: .. _docutils: http://docutils.sourceforge.net/ .. _pygments: http://pygments.org/ -LICENSE +LICENSE (2-clause BSD) --------------------------------------------- -Copyright (c) 2005-2016, Michele Simionato +Copyright (c) 2005-2017, Michele Simionato All rights reserved. Redistribution and use in source and binary forms, with or without -- cgit v1.2.1