summaryrefslogtreecommitdiffstats
path: root/doc/src/snippets/qsql-namespace
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2010-05-06 05:05:37 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2010-05-06 05:05:37 (GMT)
commit378335c8efc2df04692d0d51618b1e305a24ace7 (patch)
tree61c6de74083c66c024596183f23d3c55fbbb6b3d /doc/src/snippets/qsql-namespace
parentb017f89f844c09354b50a45fd49fcdcee4f72e43 (diff)
parentd6cb7c903069e1dfde3ffc69649354c97d160b68 (diff)
downloadQt-378335c8efc2df04692d0d51618b1e305a24ace7.zip
Qt-378335c8efc2df04692d0d51618b1e305a24ace7.tar.gz
Qt-378335c8efc2df04692d0d51618b1e305a24ace7.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt into 4.7
Diffstat (limited to 'doc/src/snippets/qsql-namespace')
0 files changed, 0 insertions, 0 deletions
style='width: 0.0%;'/> -rwxr-xr-xDemo/cgi/cgi1.py14
-rwxr-xr-xDemo/cgi/cgi2.py22
-rwxr-xr-xDemo/cgi/cgi3.py10
-rw-r--r--Demo/cgi/wiki.py123
-rw-r--r--Demo/classes/Complex.py320
-rw-r--r--Demo/classes/Dates.py227
-rw-r--r--Demo/classes/Dbm.py66
-rw-r--r--Demo/classes/README12
-rw-r--r--Demo/classes/Range.py93
-rw-r--r--Demo/classes/Rev.py95
-rw-r--r--Demo/classes/Vec.py68
-rw-r--r--Demo/classes/bitvec.py333
-rw-r--r--Demo/comparisons/README60
-rwxr-xr-xDemo/comparisons/patterns4
-rwxr-xr-xDemo/comparisons/regextest.py47
-rwxr-xr-xDemo/comparisons/sortingtest.py45
-rwxr-xr-xDemo/comparisons/systemtest.py74
-rw-r--r--Demo/curses/README25
-rwxr-xr-xDemo/curses/life.py216
-rw-r--r--Demo/curses/ncurses.py273
-rw-r--r--Demo/curses/rain.py94
-rwxr-xr-xDemo/curses/repeat.py58
-rw-r--r--Demo/curses/tclock.py147
-rw-r--r--Demo/curses/xmas.py906
-rw-r--r--Demo/embed/Makefile57
-rw-r--r--Demo/embed/README19
-rw-r--r--Demo/embed/demo.c74
-rw-r--r--Demo/embed/importexc.c17
-rw-r--r--Demo/embed/loop.c33
-rw-r--r--Demo/md5test/README10
-rwxr-xr-xDemo/md5test/foo1
-rw-r--r--Demo/md5test/md5driver.py123
-rw-r--r--Demo/metaclasses/Eiffel.py113
-rw-r--r--Demo/metaclasses/Enum.py169
-rw-r--r--Demo/metaclasses/Meta.py118
-rw-r--r--Demo/metaclasses/Simple.py45
-rw-r--r--Demo/metaclasses/Synch.py256
-rw-r--r--Demo/metaclasses/Trace.py144
-rw-r--r--Demo/metaclasses/index.html605
-rw-r--r--Demo/metaclasses/meta-vladimir.txt256
-rw-r--r--Demo/newmetaclasses/Eiffel.py141
-rw-r--r--Demo/newmetaclasses/Enum.py177
-rw-r--r--Demo/parser/FILES6
-rw-r--r--Demo/parser/README32
-rw-r--r--Demo/parser/docstring.py2
-rw-r--r--Demo/parser/example.py190
-rw-r--r--Demo/parser/simple.py1
-rw-r--r--Demo/parser/source.py27
-rwxr-xr-xDemo/parser/test_parser.py48
-rw-r--r--Demo/parser/test_unparse.py213
-rw-r--r--Demo/parser/unparse.py606
-rw-r--r--Demo/pdist/FSProxy.py301
-rwxr-xr-xDemo/pdist/RCSProxy.py198
-rw-r--r--Demo/pdist/README121
-rw-r--r--Demo/pdist/client.py157
-rw-r--r--Demo/pdist/cmdfw.py144
-rw-r--r--Demo/pdist/cmptree.py208
-rw-r--r--Demo/pdist/cvslib.py364
-rw-r--r--Demo/pdist/cvslock.py280
-rw-r--r--Demo/pdist/mac.py19
-rwxr-xr-xDemo/pdist/makechangelog.py109
-rwxr-xr-xDemo/pdist/rcsbump33
-rw-r--r--Demo/pdist/rcsclient.py71
-rw-r--r--Demo/pdist/rcslib.py334
-rwxr-xr-xDemo/pdist/rcvs8
-rwxr-xr-xDemo/pdist/rcvs.py477
-rwxr-xr-xDemo/pdist/rrcs8
-rwxr-xr-xDemo/pdist/rrcs.py160
-rw-r--r--Demo/pdist/security.py33
-rw-r--r--Demo/pdist/server.py145
-rw-r--r--Demo/pdist/sumtree.py24
-rw-r--r--Demo/pysvr/Makefile57
-rw-r--r--Demo/pysvr/README9
-rw-r--r--Demo/pysvr/pysvr.c370
-rwxr-xr-xDemo/pysvr/pysvr.py124
-rw-r--r--Demo/rpc/MANIFEST10
-rw-r--r--Demo/rpc/README31
-rw-r--r--Demo/rpc/T.py22
-rw-r--r--Demo/rpc/mountclient.py202
-rw-r--r--Demo/rpc/nfsclient.py201
-rw-r--r--Demo/rpc/rnusersclient.py98
-rw-r--r--Demo/rpc/rpc.py893
-rwxr-xr-xDemo/rpc/test24
-rw-r--r--Demo/rpc/xdr.py200
-rw-r--r--Demo/scripts/README22
-rwxr-xr-xDemo/scripts/beer.py20
-rwxr-xr-xDemo/scripts/eqfix.py198
-rwxr-xr-xDemo/scripts/fact.py49
-rwxr-xr-xDemo/scripts/find-uname.py40
-rwxr-xr-xDemo/scripts/from.py35
-rwxr-xr-xDemo/scripts/lpwatch.py102
-rwxr-xr-xDemo/scripts/makedir.py21
-rwxr-xr-xDemo/scripts/markov.py121
-rwxr-xr-xDemo/scripts/mboxconvert.py124
-rwxr-xr-xDemo/scripts/morse.py138
-rwxr-xr-xDemo/scripts/newslist.doc59
-rwxr-xr-xDemo/scripts/newslist.py362
-rwxr-xr-xDemo/scripts/pi.py33
-rwxr-xr-xDemo/scripts/pp.py129
-rwxr-xr-xDemo/scripts/primes.py30
-rwxr-xr-xDemo/scripts/queens.py85
-rwxr-xr-xDemo/scripts/script.py42
-rwxr-xr-xDemo/scripts/unbirthday.py104
-rwxr-xr-xDemo/scripts/update.py92
-rw-r--r--Demo/sockets/README14
-rw-r--r--Demo/sockets/broadcast.py15
-rwxr-xr-xDemo/sockets/echosvr.py31
-rwxr-xr-xDemo/sockets/finger.py58
-rw-r--r--Demo/sockets/ftp.py146
-rwxr-xr-xDemo/sockets/gopher.py347
-rwxr-xr-xDemo/sockets/mcast.py80
-rw-r--r--Demo/sockets/radio.py14
-rwxr-xr-xDemo/sockets/rpython.py35
-rwxr-xr-xDemo/sockets/rpythond.py52
-rwxr-xr-xDemo/sockets/telnet.py109
-rwxr-xr-xDemo/sockets/throughput.py93
-rwxr-xr-xDemo/sockets/udpecho.py63
-rw-r--r--Demo/sockets/unicast.py14
-rw-r--r--Demo/sockets/unixclient.py12
-rw-r--r--Demo/sockets/unixserver.py24
-rw-r--r--Demo/threads/Coroutine.py159
-rw-r--r--Demo/threads/Generator.py92
-rw-r--r--Demo/threads/README11
-rw-r--r--Demo/threads/fcmp.py64
-rw-r--r--Demo/threads/find.py155
-rw-r--r--Demo/threads/squasher.py105
-rw-r--r--Demo/threads/sync.py603
-rw-r--r--Demo/threads/telnet.py114
-rw-r--r--Demo/tix/INSTALL.txt89
-rw-r--r--Demo/tix/README.txt19
-rwxr-xr-xDemo/tix/bitmaps/about.xpm50
-rwxr-xr-xDemo/tix/bitmaps/bold.xbm6
-rwxr-xr-xDemo/tix/bitmaps/capital.xbm6
-rwxr-xr-xDemo/tix/bitmaps/centerj.xbm6
-rwxr-xr-xDemo/tix/bitmaps/combobox.xbm14
-rwxr-xr-xDemo/tix/bitmaps/combobox.xpm49
-rwxr-xr-xDemo/tix/bitmaps/combobox.xpm.147
-rwxr-xr-xDemo/tix/bitmaps/drivea.xbm14
-rwxr-xr-xDemo/tix/bitmaps/drivea.xpm43
-rwxr-xr-xDemo/tix/bitmaps/exit.xpm48
-rwxr-xr-xDemo/tix/bitmaps/filebox.xbm14
-rwxr-xr-xDemo/tix/bitmaps/filebox.xpm49
-rwxr-xr-xDemo/tix/bitmaps/italic.xbm6
-rwxr-xr-xDemo/tix/bitmaps/justify.xbm6
-rwxr-xr-xDemo/tix/bitmaps/leftj.xbm6
-rwxr-xr-xDemo/tix/bitmaps/netw.xbm14
-rwxr-xr-xDemo/tix/bitmaps/netw.xpm45
-rwxr-xr-xDemo/tix/bitmaps/optmenu.xpm48
-rwxr-xr-xDemo/tix/bitmaps/rightj.xbm6
-rwxr-xr-xDemo/tix/bitmaps/select.xpm52
-rwxr-xr-xDemo/tix/bitmaps/tix.gifbin11042 -> 0 bytes-rwxr-xr-xDemo/tix/bitmaps/underline.xbm6
-rw-r--r--Demo/tix/grid.py28
-rw-r--r--Demo/tix/samples/Balloon.py68
-rw-r--r--Demo/tix/samples/BtnBox.py44
-rw-r--r--Demo/tix/samples/CmpImg.py196
-rw-r--r--Demo/tix/samples/ComboBox.py102
-rw-r--r--Demo/tix/samples/Control.py122
-rw-r--r--Demo/tix/samples/DirList.py131
-rw-r--r--Demo/tix/samples/DirTree.py117
-rw-r--r--Demo/tix/samples/NoteBook.py119
-rw-r--r--Demo/tix/samples/OptMenu.py68
-rw-r--r--Demo/tix/samples/PanedWin.py98
-rw-r--r--Demo/tix/samples/PopMenu.py57
-rw-r--r--Demo/tix/samples/SHList1.py131
-rw-r--r--Demo/tix/samples/SHList2.py168
-rw-r--r--Demo/tix/samples/Tree.py80
-rw-r--r--Demo/tix/tixwidgets.py1003
-rw-r--r--Demo/tkinter/README11
-rw-r--r--Demo/tkinter/guido/AttrDialog.py452
-rw-r--r--Demo/tkinter/guido/ManPage.py220
-rwxr-xr-xDemo/tkinter/guido/MimeViewer.py143
-rw-r--r--Demo/tkinter/guido/ShellWindow.py147
-rw-r--r--Demo/tkinter/guido/brownian.py50
-rw-r--r--Demo/tkinter/guido/brownian2.py55
-rw-r--r--Demo/tkinter/guido/canvasevents.py244
-rwxr-xr-xDemo/tkinter/guido/dialog.py109
-rwxr-xr-xDemo/tkinter/guido/electrons.py91
-rw-r--r--Demo/tkinter/guido/hanoi.py154
-rw-r--r--Demo/tkinter/guido/hello.py17
-rw-r--r--Demo/tkinter/guido/imagedraw.py23
-rw-r--r--Demo/tkinter/guido/imageview.py12
-rwxr-xr-xDemo/tkinter/guido/kill.py98
-rw-r--r--Demo/tkinter/guido/listtree.py37
-rwxr-xr-xDemo/tkinter/guido/mbox.py285
-rw-r--r--Demo/tkinter/guido/newmenubardemo.py47
-rw-r--r--Demo/tkinter/guido/optionmenu.py27
-rw-r--r--Demo/tkinter/guido/paint.py60
-rwxr-xr-xDemo/tkinter/guido/rmt.py159
-rwxr-xr-xDemo/tkinter/guido/solitaire.py637
-rw-r--r--Demo/tkinter/guido/sortvisu.py634
-rw-r--r--Demo/tkinter/guido/ss1.py845
-rwxr-xr-xDemo/tkinter/guido/svkill.py128
-rw-r--r--Demo/tkinter/guido/switch.py55
-rwxr-xr-xDemo/tkinter/guido/tkman.py267
-rw-r--r--Demo/tkinter/guido/wish.py27
-rw-r--r--Demo/tkinter/matt/00-HELLO-WORLD.py27
-rw-r--r--Demo/tkinter/matt/README30
-rw-r--r--Demo/tkinter/matt/animation-simple.py35
-rw-r--r--Demo/tkinter/matt/animation-w-velocity-ctrl.py44
-rw-r--r--Demo/tkinter/matt/bind-w-mult-calls-p-type.py44
-rw-r--r--Demo/tkinter/matt/canvas-demo-simple.py28
-rw-r--r--Demo/tkinter/matt/canvas-gridding.py61
-rw-r--r--Demo/tkinter/matt/canvas-moving-or-creating.py62
-rw-r--r--Demo/tkinter/matt/canvas-moving-w-mouse.py55
-rw-r--r--Demo/tkinter/matt/canvas-mult-item-sel.py78
-rw-r--r--Demo/tkinter/matt/canvas-reading-tag-info.py49
-rw-r--r--Demo/tkinter/matt/canvas-w-widget-draw-el.py36
-rw-r--r--Demo/tkinter/matt/canvas-with-scrollbars.py60
-rw-r--r--Demo/tkinter/matt/dialog-box.py64
-rw-r--r--Demo/tkinter/matt/entry-simple.py24
-rw-r--r--Demo/tkinter/matt/entry-with-shared-variable.py46
-rw-r--r--Demo/tkinter/matt/killing-window-w-wm.py42
-rw-r--r--Demo/tkinter/matt/menu-all-types-of-entries.py244
-rw-r--r--Demo/tkinter/matt/menu-simple.py112
-rw-r--r--Demo/tkinter/matt/not-what-you-might-think-1.py28
-rw-r--r--Demo/tkinter/matt/not-what-you-might-think-2.py30
-rw-r--r--Demo/tkinter/matt/packer-and-placer-together.py41
-rw-r--r--Demo/tkinter/matt/packer-simple.py32
-rw-r--r--Demo/tkinter/matt/placer-simple.py39
-rw-r--r--Demo/tkinter/matt/pong-demo-1.py54
-rw-r--r--Demo/tkinter/matt/printing-coords-of-items.py61
-rw-r--r--Demo/tkinter/matt/radiobutton-simple.py62
-rw-r--r--Demo/tkinter/matt/rubber-band-box-demo-1.py58
-rw-r--r--Demo/tkinter/matt/rubber-line-demo-1.py51
-rw-r--r--Demo/tkinter/matt/slider-demo-1.py36
-rw-r--r--Demo/tkinter/matt/subclass-existing-widgets.py28
-rw-r--r--Demo/tkinter/matt/two-radio-groups.py110
-rw-r--r--Demo/tkinter/matt/window-creation-more.py35
-rw-r--r--Demo/tkinter/matt/window-creation-simple.py31
-rw-r--r--Demo/tkinter/matt/window-creation-w-location.py45
-rw-r--r--Demo/tkinter/ttk/combo_themes.py46
-rw-r--r--Demo/tkinter/ttk/dirbrowser.py93
-rw-r--r--Demo/tkinter/ttk/img/close.gifbin101 -> 0 bytes-rw-r--r--Demo/tkinter/ttk/img/close_active.gifbin80 -> 0 bytes-rw-r--r--Demo/tkinter/ttk/img/close_pressed.gifbin101 -> 0 bytes-rw-r--r--Demo/tkinter/ttk/listbox_scrollcmd.py37
-rw-r--r--Demo/tkinter/ttk/mac_searchentry.py78
-rw-r--r--Demo/tkinter/ttk/notebook_closebtn.py78
-rw-r--r--Demo/tkinter/ttk/plastik_theme.py269
-rw-r--r--Demo/tkinter/ttk/roundframe.py111
-rw-r--r--Demo/tkinter/ttk/theme_selector.py61
-rw-r--r--Demo/tkinter/ttk/treeview_multicolumn.py107
-rw-r--r--Demo/tkinter/ttk/ttkcalendar.py231
-rw-r--r--Demo/tkinter/ttk/widget_state.py83
-rw-r--r--Demo/turtle/about_turtle.txt77
-rw-r--r--Demo/turtle/about_turtledemo.txt14
-rw-r--r--Demo/turtle/demohelp.txt75
-rw-r--r--Demo/turtle/tdemo_I_dontlike_tiltdemo.py58
-rw-r--r--Demo/turtle/tdemo_bytedesign.py162
-rw-r--r--Demo/turtle/tdemo_clock.py132
-rw-r--r--Demo/turtle/tdemo_colormixer.py58
-rw-r--r--Demo/turtle/tdemo_fractalcurves.py137
-rw-r--r--Demo/turtle/tdemo_lindenmayer_indian.py119
-rw-r--r--Demo/turtle/tdemo_minimal_hanoi.py76
-rw-r--r--Demo/turtle/tdemo_nim.py227
-rw-r--r--Demo/turtle/tdemo_paint.py50
-rw-r--r--Demo/turtle/tdemo_peace.py65
-rw-r--r--Demo/turtle/tdemo_penrose.py181
-rw-r--r--Demo/turtle/tdemo_planet_and_moon.py113
-rw-r--r--Demo/turtle/tdemo_tree.py63
-rw-r--r--Demo/turtle/tdemo_wikipedia.py65
-rw-r--r--Demo/turtle/tdemo_yinyang.py49
-rw-r--r--Demo/turtle/turtleDemo.py280
-rw-r--r--Demo/turtle/turtledemo_two_canvases.py49
-rw-r--r--Demo/xml/elem_count.py42
-rw-r--r--Demo/xml/roundtrip.py46
-rw-r--r--Demo/xml/rss2html.py97
-rwxr-xr-xDemo/zlib/minigzip.py133
-rwxr-xr-xDemo/zlib/zlibdemo.py48
-rw-r--r--Doc/Makefile23
-rw-r--r--Doc/README.txt10
-rw-r--r--Doc/c-api/abstract.rst2
-rw-r--r--Doc/c-api/allocation.rst65
-rw-r--r--Doc/c-api/arg.rst791
-rw-r--r--Doc/c-api/bool.rst8
-rw-r--r--Doc/c-api/buffer.rst444
-rw-r--r--Doc/c-api/bytearray.rst5
-rw-r--r--Doc/c-api/bytes.rst192
-rw-r--r--Doc/c-api/class.rst65
-rw-r--r--Doc/c-api/cobject.rst59
-rw-r--r--Doc/c-api/code.rst4
-rw-r--r--Doc/c-api/complex.rst15
-rw-r--r--Doc/c-api/concrete.rst13
-rw-r--r--Doc/c-api/conversion.rst56
-rw-r--r--Doc/c-api/datetime.rst55
-rw-r--r--Doc/c-api/descriptor.rst17
-rw-r--r--Doc/c-api/dict.rst68
-rw-r--r--Doc/c-api/exceptions.rst210
-rw-r--r--Doc/c-api/file.rst158
-rw-r--r--Doc/c-api/float.rst47
-rw-r--r--Doc/c-api/function.rst14
-rw-r--r--Doc/c-api/gcsupport.rst13
-rw-r--r--Doc/c-api/import.rst90
-rw-r--r--Doc/c-api/init.rst131
-rw-r--r--Doc/c-api/int.rst139
-rw-r--r--Doc/c-api/intro.rst74
-rw-r--r--Doc/c-api/iter.rst3
-rw-r--r--Doc/c-api/iterator.rst12
-rw-r--r--Doc/c-api/list.rst51
-rw-r--r--Doc/c-api/long.rst234
-rw-r--r--Doc/c-api/mapping.rst20
-rw-r--r--Doc/c-api/marshal.rst23
-rw-r--r--Doc/c-api/memoryview.rst52
-rw-r--r--Doc/c-api/method.rst70
-rw-r--r--Doc/c-api/module.rst126
-rw-r--r--Doc/c-api/none.rst6
-rw-r--r--Doc/c-api/number.rst79
-rw-r--r--Doc/c-api/objbuffer.rst43
-rw-r--r--Doc/c-api/object.rst114
-rw-r--r--Doc/c-api/objimpl.rst1
-rw-r--r--Doc/c-api/refcounting.rst1
-rw-r--r--Doc/c-api/reflection.rst6
-rw-r--r--Doc/c-api/sequence.rst56
-rw-r--r--Doc/c-api/set.rst28
-rw-r--r--Doc/c-api/slice.rst32
-rw-r--r--Doc/c-api/string.rst333
-rw-r--r--Doc/c-api/structures.rst40
-rw-r--r--Doc/c-api/sys.rst47
-rw-r--r--Doc/c-api/tuple.rst58
-rw-r--r--Doc/c-api/type.rst32
-rw-r--r--Doc/c-api/typeobj.rst379
-rw-r--r--Doc/c-api/unicode.rst443
-rw-r--r--Doc/c-api/utilities.rst1
-rw-r--r--Doc/c-api/veryhigh.rst62
-rw-r--r--Doc/c-api/weakref.rst16
-rw-r--r--Doc/conf.py11
-rw-r--r--Doc/data/refcounts.dat62
-rw-r--r--Doc/distutils/apiref.rst52
-rw-r--r--Doc/distutils/builtdist.rst11
-rw-r--r--Doc/distutils/commandref.rst44
-rw-r--r--Doc/distutils/examples.rst52
-rw-r--r--Doc/distutils/introduction.rst4
-rw-r--r--Doc/distutils/setupscript.rst27
-rw-r--r--Doc/distutils/sourcedist.rst156
-rw-r--r--Doc/distutils/uploading.rst6
-rw-r--r--Doc/extending/embedding.rst109
-rw-r--r--Doc/extending/extending.rst149
-rw-r--r--Doc/extending/newtypes.rst264
-rw-r--r--Doc/extending/windows.rst8
-rw-r--r--Doc/faq/design.rst236
-rw-r--r--Doc/faq/extending.rst61
-rw-r--r--Doc/faq/general.rst37
-rw-r--r--Doc/faq/gui.rst47
-rw-r--r--Doc/faq/installed.rst10
-rw-r--r--Doc/faq/library.rst446
-rw-r--r--Doc/faq/programming.rst565
-rw-r--r--Doc/faq/windows.rst20
-rw-r--r--Doc/glossary.rst165
-rw-r--r--Doc/howto/argparse.rst182
-rw-r--r--Doc/howto/curses.rst2
-rw-r--r--Doc/howto/descriptor.rst14
-rw-r--r--Doc/howto/doanddont.rst327
-rw-r--r--Doc/howto/functional.rst691
-rw-r--r--Doc/howto/index.rst1
-rw-r--r--Doc/howto/logging-cookbook.rst828
-rw-r--r--Doc/howto/logging.rst63
-rw-r--r--Doc/howto/pyporting.rst12
-rw-r--r--Doc/howto/regex.rst90
-rw-r--r--Doc/howto/sockets.rst71
-rw-r--r--Doc/howto/sorting.rst58
-rw-r--r--Doc/howto/unicode.rst446
-rw-r--r--Doc/howto/urllib2.rst192
-rw-r--r--Doc/howto/webservers.rst24
-rw-r--r--Doc/includes/dbpickle.py87
-rw-r--r--Doc/includes/email-alternative.py2
-rw-r--r--Doc/includes/email-dir.py2
-rw-r--r--Doc/includes/email-headers.py6
-rw-r--r--Doc/includes/email-mime.py2
-rw-r--r--Doc/includes/email-simple.py5
-rw-r--r--Doc/includes/email-unpack.py2
-rw-r--r--Doc/includes/minidom-example.py16
-rw-r--r--Doc/includes/mp_benchmarks.py95
-rw-r--r--Doc/includes/mp_newtype.py34
-rw-r--r--Doc/includes/mp_pool.py142
-rw-r--r--Doc/includes/mp_synchronize.py86
-rw-r--r--Doc/includes/mp_webserver.py14
-rw-r--r--Doc/includes/mp_workers.py6
-rw-r--r--Doc/includes/noddy.c62
-rw-r--r--Doc/includes/noddy2.c74
-rw-r--r--Doc/includes/noddy3.c78
-rw-r--r--Doc/includes/noddy4.c75
-rw-r--r--Doc/includes/run-func.c6
-rw-r--r--Doc/includes/shoddy.c24
-rw-r--r--Doc/includes/sqlite3/adapter_datetime.py5
-rw-r--r--Doc/includes/sqlite3/adapter_point_1.py4
-rw-r--r--Doc/includes/sqlite3/adapter_point_2.py4
-rw-r--r--Doc/includes/sqlite3/collation_reverse.py9
-rw-r--r--Doc/includes/sqlite3/complete_statement.py10
-rw-r--r--Doc/includes/sqlite3/converter_point.py10
-rw-r--r--Doc/includes/sqlite3/countcursors.py2
-rw-r--r--Doc/includes/sqlite3/ctx_manager.py2
-rw-r--r--Doc/includes/sqlite3/execsql_fetchonerow.py4
-rw-r--r--Doc/includes/sqlite3/execsql_printall_1.py2
-rw-r--r--Doc/includes/sqlite3/execute_1.py2
-rw-r--r--Doc/includes/sqlite3/execute_3.py2
-rw-r--r--Doc/includes/sqlite3/executemany_1.py4
-rw-r--r--Doc/includes/sqlite3/executemany_2.py4
-rw-r--r--Doc/includes/sqlite3/load_extension.py2
-rw-r--r--Doc/includes/sqlite3/md5func.py8
-rw-r--r--Doc/includes/sqlite3/mysumaggr.py2
-rw-r--r--Doc/includes/sqlite3/parse_colnames.py2
-rw-r--r--Doc/includes/sqlite3/pysqlite_datetime.py8
-rw-r--r--Doc/includes/sqlite3/row_factory.py2
-rw-r--r--Doc/includes/sqlite3/shortcut_methods.py4
-rw-r--r--Doc/includes/sqlite3/simple_tableprinter.py10
-rw-r--r--Doc/includes/sqlite3/text_factory.py27
-rw-r--r--Doc/includes/turtle-star.py10
-rw-r--r--Doc/includes/typestruct.h5
-rw-r--r--Doc/includes/tzinfo-examples.py2
-rw-r--r--Doc/install/index.rst17
-rw-r--r--Doc/library/2to3.rst33
-rw-r--r--Doc/library/__builtin__.rst44
-rw-r--r--Doc/library/__future__.rst3
-rw-r--r--Doc/library/_dummy_thread.rst25
-rw-r--r--Doc/library/_thread.rst191
-rw-r--r--Doc/library/_winreg.rst716
-rw-r--r--Doc/library/abc.rst54
-rw-r--r--Doc/library/aepack.rst92
-rw-r--r--Doc/library/aetools.rst90
-rw-r--r--Doc/library/aetypes.rst155
-rw-r--r--Doc/library/aifc.rst31
-rw-r--r--Doc/library/al.rst214
-rw-r--r--Doc/library/allos.rst1
-rw-r--r--Doc/library/anydbm.rst114
-rw-r--r--Doc/library/archiving.rst1
-rw-r--r--Doc/library/argparse.rst66
-rw-r--r--Doc/library/array.rst95
-rw-r--r--Doc/library/ast.rst20
-rw-r--r--Doc/library/asynchat.rst10
-rw-r--r--Doc/library/asyncore.rst45
-rw-r--r--Doc/library/atexit.rst43
-rw-r--r--Doc/library/audioop.rst12
-rw-r--r--Doc/library/autogil.rst35
-rw-r--r--Doc/library/base64.rst128
-rw-r--r--Doc/library/basehttpserver.rst302
-rw-r--r--Doc/library/bastion.rst64
-rw-r--r--Doc/library/bdb.rst35
-rw-r--r--Doc/library/binascii.rst38
-rw-r--r--Doc/library/binhex.rst13
-rw-r--r--Doc/library/bisect.rst8
-rw-r--r--Doc/library/bsddb.rst206
-rw-r--r--Doc/library/builtins.rst41
-rw-r--r--Doc/library/bz2.rst58
-rw-r--r--Doc/library/calendar.rst75
-rw-r--r--Doc/library/carbon.rst573
-rw-r--r--Doc/library/cd.rst340
-rw-r--r--Doc/library/cgi.rst112
-rw-r--r--Doc/library/cgihttpserver.rst76
-rw-r--r--Doc/library/cgitb.rst7
-rw-r--r--Doc/library/chunk.rst7
-rw-r--r--Doc/library/cmath.rst41
-rw-r--r--Doc/library/cmd.rst170
-rw-r--r--Doc/library/code.rst22
-rw-r--r--Doc/library/codecs.rst337
-rw-r--r--Doc/library/codeop.rst28
-rw-r--r--Doc/library/collections.rst303
-rw-r--r--Doc/library/colorpicker.rst28
-rw-r--r--Doc/library/commands.rst80
-rw-r--r--Doc/library/compileall.rst47
-rw-r--r--Doc/library/compiler.rst644
-rw-r--r--Doc/library/concurrent.futures.rst373
-rw-r--r--Doc/library/configparser.rst1416
-rw-r--r--Doc/library/constants.rst34
-rw-r--r--Doc/library/contextlib.rst147
-rw-r--r--Doc/library/cookie.rst311
-rw-r--r--Doc/library/cookielib.rst771
-rw-r--r--Doc/library/copy.rst7
-rw-r--r--Doc/library/copy_reg.rst66
-rw-r--r--Doc/library/copyreg.rst60
-rw-r--r--Doc/library/crypt.rst6
-rw-r--r--Doc/library/crypto.rst4
-rw-r--r--Doc/library/csv.rst210
-rw-r--r--Doc/library/ctypes.rst448
-rw-r--r--Doc/library/curses.ascii.rst3
-rw-r--r--Doc/library/curses.rst16
-rw-r--r--Doc/library/custominterp.rst1
-rw-r--r--Doc/library/datatypes.rst14
-rw-r--r--Doc/library/datetime.rst233
-rw-r--r--Doc/library/dbhash.rst115
-rw-r--r--Doc/library/dbm.rst308
-rw-r--r--Doc/library/debug.rst1
-rw-r--r--Doc/library/decimal.rst279
-rw-r--r--Doc/library/development.rst1
-rw-r--r--Doc/library/difflib.rst109
-rw-r--r--Doc/library/dircache.rst62
-rw-r--r--Doc/library/dis.rst394
-rw-r--r--Doc/library/distutils.rst17
-rw-r--r--Doc/library/dl.rst114
-rw-r--r--Doc/library/doctest.rst308
-rw-r--r--Doc/library/docxmlrpcserver.rst101
-rw-r--r--Doc/library/dumbdbm.rst84
-rw-r--r--Doc/library/dummy_thread.rst31
-rw-r--r--Doc/library/dummy_threading.rst12
-rw-r--r--Doc/library/easydialogs.rst215
-rw-r--r--Doc/library/email.charset.rst63
-rw-r--r--Doc/library/email.errors.rst3
-rw-r--r--Doc/library/email.generator.rst118
-rw-r--r--Doc/library/email.header.rst95
-rw-r--r--Doc/library/email.iterators.rst12
-rw-r--r--Doc/library/email.message.rst150
-rw-r--r--Doc/library/email.mime.rst26
-rw-r--r--Doc/library/email.parser.rst101
-rw-r--r--Doc/library/email.rst61
-rw-r--r--Doc/library/email.util.rst37
-rw-r--r--Doc/library/errno.rst1
-rw-r--r--Doc/library/exceptions.rst197
-rw-r--r--Doc/library/fcntl.rst24
-rw-r--r--Doc/library/filecmp.rst13
-rw-r--r--Doc/library/fileformats.rst4
-rw-r--r--Doc/library/fileinput.rst55
-rw-r--r--Doc/library/filesys.rst16
-rw-r--r--Doc/library/fl.rst523
-rw-r--r--Doc/library/fm.rst101
-rw-r--r--Doc/library/fnmatch.rst4
-rw-r--r--Doc/library/formatter.rst22
-rw-r--r--Doc/library/fpectl.rst7
-rw-r--r--Doc/library/fpformat.rst61
-rw-r--r--Doc/library/fractions.rst35
-rw-r--r--Doc/library/framework.rst340
-rw-r--r--Doc/library/frameworks.rst2
-rw-r--r--Doc/library/ftplib.rst115
-rw-r--r--Doc/library/functional.rst15
-rw-r--r--Doc/library/functions.rst1390
-rw-r--r--Doc/library/functools.rst143
-rw-r--r--Doc/library/future_builtins.rst61
-rw-r--r--Doc/library/gc.rst65
-rw-r--r--Doc/library/gdbm.rst126
-rw-r--r--Doc/library/gensuitemodule.rst61
-rw-r--r--Doc/library/getopt.rst39
-rw-r--r--Doc/library/getpass.rst18
-rw-r--r--Doc/library/gettext.rst258
-rw-r--r--Doc/library/gl.rst193
-rw-r--r--Doc/library/glob.rst1
-rw-r--r--Doc/library/grp.rst1
-rw-r--r--Doc/library/gzip.rst93
-rw-r--r--Doc/library/hashlib.rst102
-rw-r--r--Doc/library/heapq.rst26
-rw-r--r--Doc/library/hmac.rst35
-rw-r--r--Doc/library/hotshot.rst152
-rw-r--r--Doc/library/html.entities.rst32
-rw-r--r--Doc/library/html.parser.rst343
-rw-r--r--Doc/library/html.rst21
-rw-r--r--Doc/library/htmllib.rst198
-rw-r--r--Doc/library/htmlparser.rst345
-rw-r--r--Doc/library/http.client.rst624
-rw-r--r--Doc/library/http.cookiejar.rst742
-rw-r--r--Doc/library/http.cookies.rst247
-rw-r--r--Doc/library/http.server.rst380
-rw-r--r--Doc/library/httplib.rst614
-rw-r--r--Doc/library/i18n.rst1
-rw-r--r--Doc/library/ic.rst124
-rw-r--r--Doc/library/imageop.rst107
-rw-r--r--Doc/library/imaplib.rst57
-rw-r--r--Doc/library/imgfile.rst73
-rw-r--r--Doc/library/imghdr.rst5
-rw-r--r--Doc/library/imp.rst189
-rw-r--r--Doc/library/importlib.rst519
-rw-r--r--Doc/library/imputil.rst238
-rw-r--r--Doc/library/index.rst7
-rw-r--r--Doc/library/inspect.rst509
-rw-r--r--Doc/library/internet.rst23
-rw-r--r--Doc/library/intro.rst1
-rw-r--r--Doc/library/io.rst503
-rw-r--r--Doc/library/ipc.rst2
-rw-r--r--Doc/library/itertools.rst315
-rw-r--r--Doc/library/jpeg.rst95
-rw-r--r--Doc/library/json.rst208
-rw-r--r--Doc/library/language.rst1
-rw-r--r--Doc/library/linecache.rst9
-rw-r--r--Doc/library/locale.rst73
-rw-r--r--Doc/library/logging.config.rst9
-rw-r--r--Doc/library/logging.handlers.rst191
-rw-r--r--Doc/library/logging.rst267
-rw-r--r--Doc/library/mac.rst27
-rw-r--r--Doc/library/macos.rst123
-rw-r--r--Doc/library/macosa.rst93
-rw-r--r--Doc/library/macostools.rst135
-rw-r--r--Doc/library/macpath.rst1
-rw-r--r--Doc/library/mailbox.rst208
-rw-r--r--Doc/library/mailcap.rst2
-rw-r--r--Doc/library/markup.rst14
-rw-r--r--Doc/library/marshal.rst47
-rw-r--r--Doc/library/math.rst104
-rw-r--r--Doc/library/md5.rst96
-rw-r--r--Doc/library/mhlib.rst207
-rw-r--r--Doc/library/mimetools.rst132
-rw-r--r--Doc/library/mimetypes.rst4
-rw-r--r--Doc/library/mimewriter.rst85
-rw-r--r--Doc/library/mimify.rst96
-rw-r--r--Doc/library/miniaeframe.rst68
-rw-r--r--Doc/library/misc.rst1
-rw-r--r--Doc/library/mm.rst2
-rw-r--r--Doc/library/mmap.rst92
-rw-r--r--Doc/library/modulefinder.rst28
-rw-r--r--Doc/library/modules.rst4
-rw-r--r--Doc/library/msilib.rst16
-rw-r--r--Doc/library/msvcrt.rst27
-rw-r--r--Doc/library/multifile.rst191
-rw-r--r--Doc/library/multiprocessing.rst292
-rw-r--r--Doc/library/mutex.rst68
-rw-r--r--Doc/library/netdata.rst6
-rw-r--r--Doc/library/netrc.rst8
-rw-r--r--Doc/library/new.rst66
-rw-r--r--Doc/library/nis.rst23
-rw-r--r--Doc/library/nntplib.rst565
-rw-r--r--Doc/library/numbers.rst4
-rw-r--r--Doc/library/numeric.rst3
-rw-r--r--Doc/library/operator.rst415
-rw-r--r--Doc/library/optparse.rst35
-rw-r--r--Doc/library/os.path.rst110
-rw-r--r--Doc/library/os.rst688
-rw-r--r--Doc/library/ossaudiodev.rst12
-rw-r--r--Doc/library/othergui.rst21
-rw-r--r--Doc/library/parser.rst49
-rw-r--r--Doc/library/pdb.rst404
-rw-r--r--Doc/library/persistence.rst13
-rw-r--r--Doc/library/pickle.rst985
-rw-r--r--Doc/library/pickletools.rst98
-rw-r--r--Doc/library/pipes.rst39
-rw-r--r--Doc/library/pkgutil.rst12
-rw-r--r--Doc/library/platform.rst25
-rw-r--r--Doc/library/plistlib.rst72
-rw-r--r--Doc/library/popen2.rst199
-rw-r--r--Doc/library/poplib.rst19
-rw-r--r--Doc/library/posix.rst20
-rw-r--r--Doc/library/posixfile.rst189
-rw-r--r--Doc/library/pprint.rst154
-rw-r--r--Doc/library/profile.rst131
-rw-r--r--Doc/library/pty.rst48
-rw-r--r--Doc/library/pwd.rst1
-rw-r--r--Doc/library/py_compile.rst40
-rw-r--r--Doc/library/pydoc.rst33
-rw-r--r--Doc/library/pyexpat.rst144
-rw-r--r--Doc/library/python.rst5
-rw-r--r--Doc/library/queue.rst48
-rw-r--r--Doc/library/quopri.rst41
-rw-r--r--Doc/library/random.rst208
-rw-r--r--Doc/library/re.rst704
-rw-r--r--Doc/library/readline.rst21
-rw-r--r--Doc/library/repr.rst143
-rw-r--r--Doc/library/reprlib.rst159
-rw-r--r--Doc/library/resource.rst19
-rw-r--r--Doc/library/restricted.rst68
-rw-r--r--Doc/library/rexec.rst289
-rw-r--r--Doc/library/rfc822.rst355
-rw-r--r--Doc/library/rlcompleter.rst4
-rw-r--r--Doc/library/robotparser.rst79
-rw-r--r--Doc/library/runpy.rst29
-rw-r--r--Doc/library/sched.rst14
-rw-r--r--Doc/library/scrolledtext.rst38
-rw-r--r--Doc/library/select.rst36
-rw-r--r--Doc/library/sets.rst286
-rw-r--r--Doc/library/sgi.rst20
-rw-r--r--Doc/library/sgmllib.rst272
-rw-r--r--Doc/library/sha.rst87
-rw-r--r--Doc/library/shelve.rst104
-rw-r--r--Doc/library/shlex.rst55
-rw-r--r--Doc/library/shutil.rst142
-rw-r--r--Doc/library/signal.rst96
-rw-r--r--Doc/library/simplehttpserver.rst119
-rw-r--r--Doc/library/simplexmlrpcserver.rst259
-rw-r--r--Doc/library/site.rst17
-rw-r--r--Doc/library/smtpd.rst101
-rw-r--r--Doc/library/smtplib.rst90
-rw-r--r--Doc/library/socket.rst541
-rw-r--r--Doc/library/socketserver.rst111
-rw-r--r--Doc/library/someos.rst10
-rw-r--r--Doc/library/spwd.rst5
-rw-r--r--Doc/library/sqlite3.rst214
-rw-r--r--Doc/library/ssl.rst744
-rw-r--r--Doc/library/stat.rst7
-rw-r--r--Doc/library/statvfs.rst70
-rw-r--r--Doc/library/stdtypes.rst1959
-rw-r--r--Doc/library/string.rst409
-rw-r--r--Doc/library/stringio.rst127
-rw-r--r--Doc/library/stringprep.rst3
-rw-r--r--Doc/library/strings.rst14
-rw-r--r--Doc/library/struct.rst147
-rw-r--r--Doc/library/subprocess.rst279
-rw-r--r--Doc/library/sun.rst14
-rw-r--r--Doc/library/sunaudio.rst166
-rw-r--r--Doc/library/symbol.rst1
-rw-r--r--Doc/library/sys.rst455
-rw-r--r--Doc/library/sysconfig.rst43
-rw-r--r--Doc/library/syslog.rst5
-rw-r--r--Doc/library/tabnanny.rst10
-rw-r--r--Doc/library/tarfile.rst207
-rw-r--r--Doc/library/telnetlib.rst94
-rw-r--r--Doc/library/tempfile.rst120
-rw-r--r--Doc/library/termios.rst9
-rw-r--r--Doc/library/test.rst120
-rw-r--r--Doc/library/textwrap.rst30
-rw-r--r--Doc/library/thread.rst179
-rw-r--r--Doc/library/threading.rst584
-rw-r--r--Doc/library/time.rst285
-rw-r--r--Doc/library/timeit.rst45
-rw-r--r--Doc/library/tix.rst596
-rw-r--r--Doc/library/tk.rst21
-rw-r--r--Doc/library/tkinter.rst199
-rw-r--r--Doc/library/tkinter.scrolledtext.rst32
-rw-r--r--Doc/library/tkinter.tix.rst586
-rw-r--r--Doc/library/tkinter.ttk.rst1404
-rw-r--r--Doc/library/token.rst3
-rw-r--r--Doc/library/tokenize.rst198
-rw-r--r--Doc/library/trace.rst5
-rw-r--r--Doc/library/traceback.rst125
-rw-r--r--Doc/library/ttk.rst1407
-rw-r--r--Doc/library/tty.rst5
-rw-r--r--Doc/library/turtle-star.pdfbin0 -> 4418 bytes-rw-r--r--Doc/library/turtle-star.pngbin0 -> 39585 bytes-rw-r--r--Doc/library/turtle-star.ps447
-rw-r--r--Doc/library/turtle.rst386
-rw-r--r--Doc/library/types.rst189
-rw-r--r--Doc/library/undoc.rst222
-rw-r--r--Doc/library/unicodedata.rst84
-rw-r--r--Doc/library/unittest.rst491
-rw-r--r--Doc/library/unix.rst4
-rw-r--r--Doc/library/urllib.error.rst52
-rw-r--r--Doc/library/urllib.parse.rst566
-rw-r--r--Doc/library/urllib.request.rst1363
-rw-r--r--Doc/library/urllib.robotparser.rst67
-rw-r--r--Doc/library/urllib.rst503
-rw-r--r--Doc/library/urllib2.rst1006
-rw-r--r--Doc/library/urlparse.rst357
-rw-r--r--Doc/library/user.rst72
-rw-r--r--Doc/library/userdict.rst217
-rw-r--r--Doc/library/uu.rst12
-rw-r--r--Doc/library/uuid.rst17
-rw-r--r--Doc/library/warnings.rst65
-rw-r--r--Doc/library/wave.rst6
-rw-r--r--Doc/library/weakref.rst89
-rw-r--r--Doc/library/webbrowser.rst17
-rw-r--r--Doc/library/whichdb.rst24
-rw-r--r--Doc/library/windows.rst2
-rw-r--r--Doc/library/winreg.rst703
-rw-r--r--Doc/library/winsound.rst9
-rw-r--r--Doc/library/wsgiref.rst126
-rw-r--r--Doc/library/xdrlib.rst3
-rw-r--r--Doc/library/xml.dom.minidom.rst97
-rw-r--r--Doc/library/xml.dom.pulldom.rst99
-rw-r--r--Doc/library/xml.dom.rst46
-rw-r--r--Doc/library/xml.etree.elementtree.rst394
-rw-r--r--Doc/library/xml.sax.handler.rst7
-rw-r--r--Doc/library/xml.sax.reader.rst12
-rw-r--r--Doc/library/xml.sax.rst15
-rw-r--r--Doc/library/xml.sax.utils.rst25
-rw-r--r--Doc/library/xmllib.rst309
-rw-r--r--Doc/library/xmlrpc.client.rst543
-rw-r--r--Doc/library/xmlrpc.server.rst311
-rw-r--r--Doc/library/xmlrpclib.rst590
-rw-r--r--Doc/library/zipfile.rst148
-rw-r--r--Doc/library/zipimport.rst9
-rw-r--r--Doc/library/zlib.rst82
-rw-r--r--Doc/license.rst218
-rw-r--r--Doc/make.bat3
-rw-r--r--Doc/reference/compound_stmts.rst303
-rw-r--r--Doc/reference/datamodel.rst1428
-rw-r--r--Doc/reference/executionmodel.rst94
-rw-r--r--Doc/reference/expressions.rst636
-rw-r--r--Doc/reference/introduction.rst21
-rw-r--r--Doc/reference/lexical_analysis.rst462
-rw-r--r--Doc/reference/simple_stmts.rst406
-rw-r--r--Doc/reference/toplevel_components.rst25
-rwxr-xr-xDoc/tools/dailybuild.py89
-rwxr-xr-xDoc/tools/rstlint.py29
-rw-r--r--Doc/tools/sphinx-build.py6
-rw-r--r--Doc/tools/sphinxext/download.html4
-rw-r--r--Doc/tools/sphinxext/indexsidebar.html4
-rw-r--r--Doc/tools/sphinxext/patchlevel.py2
-rw-r--r--Doc/tools/sphinxext/pydoctheme/static/pydoctheme.css170
-rw-r--r--Doc/tools/sphinxext/pydoctheme/theme.conf23
-rw-r--r--Doc/tools/sphinxext/pyspecific.py6
-rw-r--r--Doc/tools/sphinxext/static/basic.css2
-rw-r--r--Doc/tools/sphinxext/static/copybutton.js3
-rw-r--r--Doc/tools/sphinxext/static/sidebar.js155
-rw-r--r--Doc/tools/sphinxext/susp-ignored.csv93
-rw-r--r--Doc/tools/sphinxext/suspicious.py52
-rw-r--r--Doc/tutorial/classes.rst222
-rw-r--r--Doc/tutorial/controlflow.rst189
-rw-r--r--Doc/tutorial/datastructures.rst176
-rw-r--r--Doc/tutorial/errors.rst120
-rw-r--r--Doc/tutorial/floatingpoint.rst266
-rw-r--r--Doc/tutorial/inputoutput.rst134
-rw-r--r--Doc/tutorial/interpreter.rst94
-rw-r--r--Doc/tutorial/introduction.rst162
-rw-r--r--Doc/tutorial/modules.rst108
-rw-r--r--Doc/tutorial/stdlib.rst31
-rw-r--r--Doc/tutorial/stdlib2.rst37
-rw-r--r--Doc/tutorial/whatnow.rst15
-rw-r--r--Doc/using/cmdline.rst152
-rw-r--r--Doc/using/mac.rst10
-rw-r--r--Doc/using/unix.rst12
-rw-r--r--Doc/using/windows.rst2
-rw-r--r--Doc/whatsnew/2.0.rst10
-rw-r--r--Doc/whatsnew/2.1.rst10
-rw-r--r--Doc/whatsnew/2.2.rst10
-rw-r--r--Doc/whatsnew/2.3.rst4
-rw-r--r--Doc/whatsnew/2.4.rst4
-rw-r--r--Doc/whatsnew/2.6.rst22
-rw-r--r--Doc/whatsnew/2.7.rst146
-rw-r--r--Doc/whatsnew/3.0.rst927
-rw-r--r--Doc/whatsnew/3.1.rst552
-rw-r--r--Doc/whatsnew/3.2.rst2702
-rw-r--r--Doc/whatsnew/index.rst3
-rw-r--r--Grammar/Grammar78
-rw-r--r--Include/Python-ast.h122
-rw-r--r--Include/Python.h51
-rw-r--r--Include/abstract.h263
-rw-r--r--Include/accu.h37
-rw-r--r--Include/asdl.h4
-rw-r--r--Include/ast.h7
-rw-r--r--Include/bltinmodule.h14
-rw-r--r--Include/boolobject.h6
-rw-r--r--Include/bufferobject.h33
-rw-r--r--Include/bytearrayobject.h4
-rw-r--r--Include/bytes_methods.h43
-rw-r--r--Include/bytesobject.h157
-rw-r--r--Include/cStringIO.h73
-rw-r--r--Include/cellobject.h3
-rw-r--r--Include/ceval.h76
-rw-r--r--Include/classobject.h71
-rw-r--r--Include/cobject.h89
-rw-r--r--Include/code.h26
-rw-r--r--Include/codecs.h15
-rw-r--r--Include/compile.h14
-rw-r--r--Include/complexobject.h16
-rw-r--r--Include/datetime.h10
-rw-r--r--Include/descrobject.h26
-rw-r--r--Include/dictobject.h22
-rw-r--r--Include/dtoa.h2
-rw-r--r--Include/dynamic_annotations.h499
-rw-r--r--Include/errcode.h1
-rw-r--r--Include/eval.h8
-rw-r--r--Include/fileobject.h70
-rw-r--r--Include/fileutils.h58
-rw-r--r--Include/floatobject.h45
-rw-r--r--Include/frameobject.h20
-rw-r--r--Include/funcobject.h17
-rw-r--r--Include/genobject.h2
-rw-r--r--Include/graminit.h130
-rw-r--r--Include/import.h75
-rw-r--r--Include/intobject.h80
-rw-r--r--Include/iterobject.h4
-rw-r--r--Include/listobject.h9
-rw-r--r--Include/longintrepr.h10
-rw-r--r--Include/longobject.h65
-rw-r--r--Include/marshal.h2
-rw-r--r--Include/memoryobject.h8
-rw-r--r--Include/methodobject.h18
-rw-r--r--Include/modsupport.h52
-rw-r--r--Include/moduleobject.h40
-rw-r--r--Include/object.h258
-rw-r--r--Include/objimpl.h22
-rw-r--r--Include/opcode.h55
-rw-r--r--Include/osdefs.h29
-rw-r--r--Include/parsetok.h40
-rw-r--r--Include/patchlevel.h12
-rw-r--r--Include/py_curses.h4
-rw-r--r--Include/pyarena.h2
-rw-r--r--Include/pyatomic.h184
-rw-r--r--Include/pycapsule.h5
-rw-r--r--Include/pyctype.h2
-rw-r--r--Include/pydebug.h13
-rw-r--r--Include/pyerrors.h169
-rw-r--r--Include/pygetopt.h7
-rw-r--r--Include/pymactoolbox.h217
-rw-r--r--Include/pymath.h4
-rw-r--r--Include/pyport.h181
-rw-r--r--Include/pystate.h39
-rw-r--r--Include/pystrcmp.h2
-rw-r--r--Include/pystrtod.h8
-rw-r--r--Include/pythonrun.h147
-rw-r--r--Include/pythread.h50
-rw-r--r--Include/pytime.h48
-rw-r--r--Include/rangeobject.h5
-rw-r--r--Include/setobject.h20
-rw-r--r--Include/sliceobject.h9
-rw-r--r--Include/stringobject.h210
-rw-r--r--Include/structmember.h80
-rw-r--r--Include/structseq.h34
-rw-r--r--Include/symtable.h61
-rw-r--r--Include/sysmodule.h26
-rw-r--r--Include/timefuncs.h2
-rw-r--r--Include/token.h62
-rw-r--r--Include/traceback.h17
-rw-r--r--Include/tupleobject.h9
-rw-r--r--Include/typeslots.h76
-rw-r--r--Include/ucnhash.h3
-rw-r--r--Include/unicodeobject.h561
-rw-r--r--Include/warnings.h28
-rw-r--r--Include/weakrefobject.h6
-rw-r--r--LICENSE12
-rw-r--r--Lib/BaseHTTPServer.py603
-rw-r--r--Lib/Bastion.py180
-rw-r--r--Lib/CGIHTTPServer.py378
-rw-r--r--Lib/ConfigParser.py753
-rw-r--r--Lib/Cookie.py761
-rw-r--r--Lib/DocXMLRPCServer.py279
-rw-r--r--Lib/HTMLParser.py472
-rw-r--r--Lib/MimeWriter.py186
-rw-r--r--Lib/Queue.py244
-rw-r--r--Lib/SimpleHTTPServer.py220
-rw-r--r--Lib/SimpleXMLRPCServer.py707
-rw-r--r--Lib/SocketServer.py731
-rw-r--r--Lib/StringIO.py324
-rw-r--r--Lib/UserDict.py180
-rw-r--r--Lib/UserList.py88
-rwxr-xr-xLib/UserString.py228
-rw-r--r--Lib/_LWPCookieJar.py170
-rw-r--r--Lib/_MozillaCookieJar.py149
-rw-r--r--Lib/__future__.py6
-rw-r--r--Lib/_abcoll.py146
-rw-r--r--Lib/_compat_pickle.py81
-rw-r--r--Lib/_dummy_thread.py155
-rw-r--r--Lib/_markupbase.py395
-rw-r--r--Lib/_pyio.py258
-rw-r--r--Lib/_strptime.py70
-rw-r--r--Lib/_threading_local.py159
-rw-r--r--Lib/_weakrefset.py6
-rw-r--r--Lib/abc.py88
-rw-r--r--Lib/aifc.py338
-rw-r--r--Lib/antigravity.py13
-rw-r--r--Lib/anydbm.py85
-rw-r--r--Lib/argparse.py77
-rw-r--r--Lib/ast.py31
-rw-r--r--Lib/asynchat.py56
-rw-r--r--Lib/asyncore.py42
-rw-r--r--Lib/atexit.py65
-rw-r--r--Lib/audiodev.py260
-rwxr-xr-xLib/base64.py328
-rw-r--r--Lib/bdb.py204
-rw-r--r--Lib/binhex.py248
-rw-r--r--Lib/bsddb/__init__.py455
-rw-r--r--Lib/bsddb/db.py60
-rw-r--r--Lib/bsddb/dbobj.py269
-rw-r--r--Lib/bsddb/dbrecio.py190
-rw-r--r--Lib/bsddb/dbshelve.py402
-rw-r--r--Lib/bsddb/dbtables.py843
-rw-r--r--Lib/bsddb/dbutils.py83
-rw-r--r--Lib/bsddb/test/test_all.py622
-rw-r--r--Lib/bsddb/test/test_associate.py465
-rw-r--r--Lib/bsddb/test/test_basics.py1192
-rw-r--r--Lib/bsddb/test/test_compare.py273
-rw-r--r--Lib/bsddb/test/test_compat.py184
-rw-r--r--Lib/bsddb/test/test_cursor_pget_bug.py54
-rw-r--r--Lib/bsddb/test/test_db.py142
-rw-r--r--Lib/bsddb/test/test_dbenv.py513
-rw-r--r--Lib/bsddb/test/test_dbobj.py70
-rw-r--r--Lib/bsddb/test/test_dbshelve.py405
-rw-r--r--Lib/bsddb/test/test_dbtables.py409
-rw-r--r--Lib/bsddb/test/test_distributed_transactions.py163
-rw-r--r--Lib/bsddb/test/test_early_close.py216
-rw-r--r--Lib/bsddb/test/test_fileid.py61
-rw-r--r--Lib/bsddb/test/test_get_none.py92
-rw-r--r--Lib/bsddb/test/test_join.py99
-rw-r--r--Lib/bsddb/test/test_lock.py191
-rw-r--r--Lib/bsddb/test/test_misc.py149
-rw-r--r--Lib/bsddb/test/test_pickle.py68
-rw-r--r--Lib/bsddb/test/test_queue.py168
-rw-r--r--Lib/bsddb/test/test_recno.py310
-rw-r--r--Lib/bsddb/test/test_replication.py495
-rw-r--r--Lib/bsddb/test/test_sequence.py142
-rw-r--r--Lib/bsddb/test/test_thread.py521
-rwxr-xr-xLib/cProfile.py12
-rw-r--r--Lib/calendar.py41
-rwxr-xr-xLib/cgi.py524
-rw-r--r--Lib/cgitb.py20
-rw-r--r--Lib/chunk.py14
-rw-r--r--Lib/cmd.py15
-rw-r--r--Lib/code.py47
-rw-r--r--Lib/codecs.py105
-rw-r--r--Lib/codeop.py12
-rw-r--r--Lib/collections.py666
-rw-r--r--Lib/commands.py90
-rw-r--r--Lib/compileall.py245
-rw-r--r--Lib/compiler/__init__.py31
-rw-r--r--Lib/compiler/ast.py1419
-rw-r--r--Lib/compiler/consts.py23
-rw-r--r--Lib/compiler/future.py74
-rw-r--r--Lib/compiler/misc.py73
-rw-r--r--Lib/compiler/pyassem.py763
-rw-r--r--Lib/compiler/pycodegen.py1555
-rw-r--r--Lib/compiler/symbols.py462
-rw-r--r--Lib/compiler/syntax.py46
-rw-r--r--Lib/compiler/transformer.py1535
-rw-r--r--Lib/compiler/visitor.py113
-rw-r--r--Lib/concurrent/__init__.py1
-rw-r--r--Lib/concurrent/futures/__init__.py18
-rw-r--r--Lib/concurrent/futures/_base.py569
-rw-r--r--Lib/concurrent/futures/process.py356
-rw-r--r--Lib/concurrent/futures/thread.py130
-rw-r--r--Lib/configparser.py1247
-rw-r--r--Lib/contextlib.py91
-rw-r--r--Lib/cookielib.py1794
-rw-r--r--Lib/copy.py113
-rw-r--r--Lib/copy_reg.py201
-rw-r--r--Lib/copyreg.py196
-rw-r--r--Lib/csv.py67
-rw-r--r--Lib/ctypes/__init__.py72
-rw-r--r--Lib/ctypes/_endian.py11
-rw-r--r--Lib/ctypes/macholib/__init__.py3
-rw-r--r--Lib/ctypes/macholib/dyld.py17
-rw-r--r--Lib/ctypes/macholib/dylib.py3
-rw-r--r--Lib/ctypes/macholib/framework.py3
-rw-r--r--Lib/ctypes/test/__init__.py18
-rw-r--r--Lib/ctypes/test/test_array_in_pointer.py2
-rw-r--r--Lib/ctypes/test/test_arrays.py89
-rw-r--r--Lib/ctypes/test/test_as_parameter.py4
-rw-r--r--Lib/ctypes/test/test_bitfields.py6
-rw-r--r--Lib/ctypes/test/test_buffers.py42
-rw-r--r--Lib/ctypes/test/test_bytes.py50
-rw-r--r--Lib/ctypes/test/test_byteswap.py10
-rw-r--r--Lib/ctypes/test/test_callbacks.py22
-rw-r--r--Lib/ctypes/test/test_cast.py18
-rw-r--r--Lib/ctypes/test/test_cfuncs.py2
-rw-r--r--Lib/ctypes/test/test_errno.py5
-rw-r--r--Lib/ctypes/test/test_find.py4
-rw-r--r--Lib/ctypes/test/test_frombuffer.py10
-rw-r--r--Lib/ctypes/test/test_funcptr.py14
-rw-r--r--Lib/ctypes/test/test_functions.py10
-rw-r--r--Lib/ctypes/test/test_incomplete.py6
-rw-r--r--Lib/ctypes/test/test_init.py2
-rw-r--r--Lib/ctypes/test/test_internals.py6
-rw-r--r--Lib/ctypes/test/test_keeprefs.py28
-rw-r--r--Lib/ctypes/test/test_libc.py10
-rw-r--r--Lib/ctypes/test/test_loading.py8
-rw-r--r--Lib/ctypes/test/test_memfunctions.py28
-rw-r--r--Lib/ctypes/test/test_numbers.py21
-rw-r--r--Lib/ctypes/test/test_objects.py18
-rw-r--r--Lib/ctypes/test/test_parameters.py18
-rw-r--r--Lib/ctypes/test/test_pep3118.py2
-rw-r--r--Lib/ctypes/test/test_pickling.py4
-rw-r--r--Lib/ctypes/test/test_pointers.py22
-rw-r--r--Lib/ctypes/test/test_prototypes.py56
-rw-r--r--Lib/ctypes/test/test_python_api.py38
-rw-r--r--Lib/ctypes/test/test_random_things.py14
-rw-r--r--Lib/ctypes/test/test_repr.py4
-rw-r--r--Lib/ctypes/test/test_returnfuncptrs.py18
-rw-r--r--Lib/ctypes/test/test_simplesubclasses.py8
-rw-r--r--Lib/ctypes/test/test_slicing.py50
-rw-r--r--Lib/ctypes/test/test_stringptr.py26
-rw-r--r--Lib/ctypes/test/test_strings.py110
-rw-r--r--Lib/ctypes/test/test_structures.py56
-rw-r--r--Lib/ctypes/test/test_unicode.py112
-rw-r--r--Lib/ctypes/test/test_values.py6
-rw-r--r--Lib/ctypes/util.py60
-rw-r--r--Lib/ctypes/wintypes.py173
-rw-r--r--Lib/curses/__init__.py4
-rw-r--r--Lib/curses/has_key.py4
-rw-r--r--Lib/curses/panel.py2
-rw-r--r--Lib/curses/textpad.py2
-rw-r--r--Lib/datetime.py2114
-rw-r--r--Lib/dbhash.py18
-rw-r--r--Lib/dbm/__init__.py185
-rw-r--r--Lib/dbm/dumb.py265
-rw-r--r--Lib/dbm/gnu.py3
-rw-r--r--Lib/dbm/ndbm.py3
-rw-r--r--Lib/decimal.py563
-rw-r--r--Lib/difflib.py127
-rw-r--r--Lib/dircache.py41
-rw-r--r--Lib/dis.py229
-rw-r--r--Lib/distutils/__init__.py4
-rw-r--r--Lib/distutils/archive_util.py105
-rw-r--r--Lib/distutils/bcppcompiler.py37
-rw-r--r--Lib/distutils/ccompiler.py281
-rw-r--r--Lib/distutils/cmd.py112
-rw-r--r--Lib/distutils/command/__init__.py4
-rw-r--r--Lib/distutils/command/bdist.py28
-rw-r--r--Lib/distutils/command/bdist_dumb.py38
-rw-r--r--Lib/distutils/command/bdist_msi.py37
-rw-r--r--Lib/distutils/command/bdist_rpm.py103
-rw-r--r--Lib/distutils/command/bdist_wininst.py83
-rw-r--r--Lib/distutils/command/build.py17
-rw-r--r--Lib/distutils/command/build_clib.py48
-rw-r--r--Lib/distutils/command/build_ext.py129
-rw-r--r--Lib/distutils/command/build_py.py44
-rw-r--r--Lib/distutils/command/build_scripts.py88
-rw-r--r--Lib/distutils/command/check.py12
-rw-r--r--Lib/distutils/command/clean.py4
-rw-r--r--Lib/distutils/command/command_template20
-rw-r--r--Lib/distutils/command/config.py40
-rw-r--r--Lib/distutils/command/install.py272
-rw-r--r--Lib/distutils/command/install_data.py2
-rw-r--r--Lib/distutils/command/install_egg_info.py5
-rw-r--r--Lib/distutils/command/install_headers.py4
-rw-r--r--Lib/distutils/command/install_lib.py20
-rw-r--r--Lib/distutils/command/install_scripts.py18
-rw-r--r--Lib/distutils/command/register.py77
-rw-r--r--Lib/distutils/command/sdist.py51
-rw-r--r--Lib/distutils/command/upload.py120
-rw-r--r--Lib/distutils/command/wininst-9.0-amd64.exebin223744 -> 224256 bytes-rw-r--r--Lib/distutils/command/wininst-9.0.exebin196096 -> 196096 bytes-rw-r--r--Lib/distutils/config.py9
-rw-r--r--Lib/distutils/core.py71
-rw-r--r--Lib/distutils/cygwinccompiler.py235
-rw-r--r--Lib/distutils/debug.py2
-rw-r--r--Lib/distutils/dep_util.py67
-rw-r--r--Lib/distutils/dir_util.py37
-rw-r--r--Lib/distutils/dist.py242
-rw-r--r--Lib/distutils/emxccompiler.py24
-rw-r--r--Lib/distutils/errors.py49
-rw-r--r--Lib/distutils/extension.py82
-rw-r--r--Lib/distutils/fancy_getopt.py167
-rw-r--r--Lib/distutils/file_util.py95
-rw-r--r--Lib/distutils/filelist.py93
-rw-r--r--Lib/distutils/log.py4
-rw-r--r--Lib/distutils/msvc9compiler.py59
-rw-r--r--Lib/distutils/msvccompiler.py267
-rw-r--r--Lib/distutils/spawn.py67
-rw-r--r--Lib/distutils/sysconfig.py152
-rw-r--r--Lib/distutils/tests/__init__.py2
-rw-r--r--Lib/distutils/tests/setuptools_build_ext.py287
-rw-r--r--Lib/distutils/tests/setuptools_extension.py51
-rw-r--r--Lib/distutils/tests/support.py28
-rw-r--r--Lib/distutils/tests/test_archive_util.py154
-rw-r--r--Lib/distutils/tests/test_bdist.py6
-rw-r--r--Lib/distutils/tests/test_bdist_dumb.py37
-rw-r--r--Lib/distutils/tests/test_bdist_msi.py2
-rw-r--r--Lib/distutils/tests/test_bdist_rpm.py3
-rw-r--r--Lib/distutils/tests/test_bdist_wininst.py3
-rw-r--r--Lib/distutils/tests/test_build.py2
-rw-r--r--Lib/distutils/tests/test_build_clib.py2
-rw-r--r--Lib/distutils/tests/test_build_ext.py185
-rw-r--r--Lib/distutils/tests/test_build_py.py81
-rw-r--r--Lib/distutils/tests/test_build_scripts.py8
-rw-r--r--Lib/distutils/tests/test_ccompiler.py82
-rw-r--r--Lib/distutils/tests/test_check.py17
-rw-r--r--Lib/distutils/tests/test_clean.py2
-rw-r--r--Lib/distutils/tests/test_cmd.py2
-rw-r--r--Lib/distutils/tests/test_config.py9
-rw-r--r--Lib/distutils/tests/test_config_cmd.py2
-rw-r--r--Lib/distutils/tests/test_core.py18
-rw-r--r--Lib/distutils/tests/test_cygwinccompiler.py155
-rw-r--r--Lib/distutils/tests/test_dep_util.py2
-rw-r--r--Lib/distutils/tests/test_dir_util.py13
-rw-r--r--Lib/distutils/tests/test_dist.py183
-rw-r--r--Lib/distutils/tests/test_extension.py69
-rw-r--r--Lib/distutils/tests/test_file_util.py19
-rw-r--r--Lib/distutils/tests/test_filelist.py2
-rw-r--r--Lib/distutils/tests/test_install.py13
-rw-r--r--Lib/distutils/tests/test_install_data.py2
-rw-r--r--Lib/distutils/tests/test_install_headers.py2
-rw-r--r--Lib/distutils/tests/test_install_lib.py70
-rw-r--r--Lib/distutils/tests/test_install_scripts.py2
-rw-r--r--Lib/distutils/tests/test_log.py37
-rw-r--r--Lib/distutils/tests/test_msvc9compiler.py10
-rw-r--r--Lib/distutils/tests/test_register.py82
-rw-r--r--Lib/distutils/tests/test_sdist.py102
-rw-r--r--Lib/distutils/tests/test_spawn.py8
-rw-r--r--Lib/distutils/tests/test_sysconfig.py61
-rw-r--r--Lib/distutils/tests/test_text_file.py2
-rw-r--r--Lib/distutils/tests/test_unixccompiler.py14
-rw-r--r--Lib/distutils/tests/test_upload.py69
-rw-r--r--Lib/distutils/tests/test_util.py264
-rw-r--r--Lib/distutils/tests/test_version.py6
-rw-r--r--Lib/distutils/tests/test_versionpredicate.py2
-rw-r--r--Lib/distutils/text_file.py91
-rw-r--r--Lib/distutils/unixccompiler.py68
-rw-r--r--Lib/distutils/util.py163
-rw-r--r--Lib/distutils/version.py124
-rw-r--r--Lib/distutils/versionpredicate.py8
-rw-r--r--Lib/doctest.py353
-rw-r--r--Lib/dumbdbm.py250
-rw-r--r--Lib/dummy_thread.py145
-rw-r--r--Lib/dummy_threading.py20
-rw-r--r--Lib/email/__init__.py99
-rw-r--r--Lib/email/_parseaddr.py22
-rw-r--r--Lib/email/base64mime.py116
-rw-r--r--Lib/email/charset.py238
-rw-r--r--Lib/email/encoders.py34
-rw-r--r--Lib/email/feedparser.py19
-rw-r--r--Lib/email/generator.py263
-rw-r--r--Lib/email/header.py662
-rw-r--r--Lib/email/iterators.py10
-rw-r--r--Lib/email/message.py210
-rw-r--r--Lib/email/mime/audio.py6
-rw-r--r--Lib/email/parser.py51
-rw-r--r--Lib/email/quoprimime.py322
-rw-r--r--Lib/email/test/data/msg_15.txt2
-rw-r--r--Lib/email/test/data/msg_26.txt5
-rw-r--r--Lib/email/test/test_email.py2314
-rw-r--r--Lib/email/test/test_email_codecs.py48
-rw-r--r--Lib/email/test/test_email_codecs_renamed.py77
-rw-r--r--Lib/email/test/test_email_renamed.py3297
-rw-r--r--Lib/email/test/test_email_torture.py4
-rw-r--r--Lib/email/utils.py88
-rw-r--r--Lib/encodings/__init__.py53
-rw-r--r--Lib/encodings/aliases.py42
-rw-r--r--Lib/encodings/base64_codec.py66
-rw-r--r--Lib/encodings/bz2_codec.py53
-rw-r--r--Lib/encodings/cp037.py512
-rw-r--r--Lib/encodings/cp1006.py512
-rw-r--r--Lib/encodings/cp1026.py512
-rw-r--r--Lib/encodings/cp1140.py512
-rw-r--r--Lib/encodings/cp1250.py512
-rw-r--r--Lib/encodings/cp1251.py512
-rw-r--r--Lib/encodings/cp1252.py512
-rw-r--r--Lib/encodings/cp1253.py512
-rw-r--r--Lib/encodings/cp1254.py512
-rw-r--r--Lib/encodings/cp1255.py512
-rw-r--r--Lib/encodings/cp1256.py512
-rw-r--r--Lib/encodings/cp1257.py512
-rw-r--r--Lib/encodings/cp1258.py512
-rw-r--r--Lib/encodings/cp424.py512
-rw-r--r--Lib/encodings/cp437.py512
-rw-r--r--Lib/encodings/cp500.py512
-rw-r--r--Lib/encodings/cp720.py512
-rw-r--r--Lib/encodings/cp737.py512
-rw-r--r--Lib/encodings/cp775.py512
-rw-r--r--Lib/encodings/cp850.py512
-rw-r--r--Lib/encodings/cp852.py512
-rw-r--r--Lib/encodings/cp855.py512
-rw-r--r--Lib/encodings/cp856.py512
-rw-r--r--Lib/encodings/cp857.py512
-rw-r--r--Lib/encodings/cp858.py512
-rw-r--r--Lib/encodings/cp860.py512
-rw-r--r--Lib/encodings/cp861.py512
-rw-r--r--Lib/encodings/cp862.py512
-rw-r--r--Lib/encodings/cp863.py512
-rw-r--r--Lib/encodings/cp864.py512
-rw-r--r--Lib/encodings/cp865.py512
-rw-r--r--Lib/encodings/cp866.py512
-rw-r--r--Lib/encodings/cp869.py512
-rw-r--r--Lib/encodings/cp874.py512
-rw-r--r--Lib/encodings/cp875.py512
-rw-r--r--Lib/encodings/hex_codec.py62
-rw-r--r--Lib/encodings/idna.py95
-rw-r--r--Lib/encodings/iso8859_1.py512
-rw-r--r--Lib/encodings/iso8859_10.py512
-rw-r--r--Lib/encodings/iso8859_11.py512
-rw-r--r--Lib/encodings/iso8859_13.py512
-rw-r--r--Lib/encodings/iso8859_14.py512
-rw-r--r--Lib/encodings/iso8859_15.py512
-rw-r--r--Lib/encodings/iso8859_16.py512
-rw-r--r--Lib/encodings/iso8859_2.py512
-rw-r--r--Lib/encodings/iso8859_3.py512
-rw-r--r--Lib/encodings/iso8859_4.py512
-rw-r--r--Lib/encodings/iso8859_5.py512
-rw-r--r--Lib/encodings/iso8859_6.py512
-rw-r--r--Lib/encodings/iso8859_7.py512
-rw-r--r--Lib/encodings/iso8859_8.py512
-rw-r--r--Lib/encodings/iso8859_9.py512
-rw-r--r--Lib/encodings/koi8_r.py512
-rw-r--r--Lib/encodings/koi8_u.py512
-rw-r--r--Lib/encodings/mac_arabic.py512
-rw-r--r--Lib/encodings/mac_centeuro.py512
-rw-r--r--Lib/encodings/mac_croatian.py512
-rw-r--r--Lib/encodings/mac_cyrillic.py512
-rw-r--r--Lib/encodings/mac_farsi.py512
-rw-r--r--Lib/encodings/mac_greek.py512
-rw-r--r--Lib/encodings/mac_iceland.py512
-rw-r--r--Lib/encodings/mac_roman.py512
-rw-r--r--Lib/encodings/mac_romanian.py512
-rw-r--r--Lib/encodings/mac_turkish.py512
-rw-r--r--Lib/encodings/punycode.py57
-rw-r--r--Lib/encodings/quopri_codec.py55
-rwxr-xr-x[-rw-r--r--]Lib/encodings/rot_13.py31
-rw-r--r--Lib/encodings/string_escape.py38
-rw-r--r--Lib/encodings/tis_620.py512
-rw-r--r--Lib/encodings/utf_16.py31
-rw-r--r--Lib/encodings/utf_32.py2
-rw-r--r--Lib/encodings/utf_8_sig.py31
-rw-r--r--Lib/encodings/uu_codec.py100
-rw-r--r--Lib/encodings/zlib_codec.py51
-rw-r--r--Lib/filecmp.py62
-rw-r--r--Lib/fileinput.py74
-rw-r--r--Lib/fnmatch.py45
-rw-r--r--Lib/formatter.py26
-rw-r--r--Lib/fpformat.py145
-rw-r--r--Lib/fractions.py129
-rw-r--r--Lib/ftplib.py256
-rw-r--r--Lib/functools.py122
-rw-r--r--Lib/genericpath.py5
-rw-r--r--Lib/getopt.py4
-rw-r--r--Lib/getpass.py24
-rw-r--r--Lib/gettext.py170
-rw-r--r--Lib/glob.py35
-rw-r--r--Lib/gzip.py285
-rw-r--r--Lib/hashlib.py70
-rw-r--r--Lib/heapq.py46
-rw-r--r--Lib/hmac.py30
-rw-r--r--Lib/hotshot/__init__.py78
-rw-r--r--Lib/hotshot/log.py194
-rw-r--r--Lib/hotshot/stats.py93
-rw-r--r--Lib/hotshot/stones.py30
-rw-r--r--Lib/html/__init__.py21
-rw-r--r--Lib/html/entities.py270
-rw-r--r--Lib/html/parser.py530
-rw-r--r--Lib/htmlentitydefs.py273
-rw-r--r--Lib/htmllib.py491
-rw-r--r--Lib/http/__init__.py1
-rw-r--r--Lib/http/client.py1187
-rw-r--r--Lib/http/cookiejar.py2091
-rw-r--r--Lib/http/cookies.py571
-rw-r--r--Lib/http/server.py1192
-rw-r--r--Lib/httplib.py1337
-rw-r--r--Lib/idlelib/AutoComplete.py13
-rw-r--r--Lib/idlelib/AutoCompleteWindow.py11
-rw-r--r--Lib/idlelib/CallTipWindow.py2
-rw-r--r--Lib/idlelib/CallTips.py297
-rw-r--r--Lib/idlelib/ClassBrowser.py2
-rw-r--r--Lib/idlelib/CodeContext.py10
-rw-r--r--Lib/idlelib/ColorDelegator.py55
-rw-r--r--Lib/idlelib/Debugger.py33
-rw-r--r--Lib/idlelib/Delegator.py6
-rw-r--r--Lib/idlelib/EditorWindow.py147
-rw-r--r--Lib/idlelib/FileList.py17
-rw-r--r--Lib/idlelib/FormatParagraph.py5
-rw-r--r--Lib/idlelib/GrepDialog.py20
-rw-r--r--Lib/idlelib/IOBinding.py308
-rw-r--r--Lib/idlelib/MultiCall.py26
-rw-r--r--Lib/idlelib/MultiStatusBar.py2
-rw-r--r--Lib/idlelib/NEWS.txt125
-rw-r--r--Lib/idlelib/ObjectBrowser.py33
-rw-r--r--Lib/idlelib/OutputWindow.py15
-rw-r--r--Lib/idlelib/Percolator.py13
-rw-r--r--Lib/idlelib/PyParse.py28
-rw-r--r--Lib/idlelib/PyShell.py229
-rw-r--r--Lib/idlelib/README.txt9
-rw-r--r--Lib/idlelib/RemoteDebugger.py33
-rw-r--r--Lib/idlelib/RemoteObjectBrowser.py8
-rw-r--r--Lib/idlelib/ReplaceDialog.py3
-rw-r--r--Lib/idlelib/ScriptBinding.py117
-rw-r--r--Lib/idlelib/ScrolledList.py6
-rw-r--r--Lib/idlelib/SearchDialog.py2
-rw-r--r--Lib/idlelib/SearchDialogBase.py2
-rw-r--r--Lib/idlelib/SearchEngine.py6
-rw-r--r--Lib/idlelib/StackViewer.py19
-rw-r--r--Lib/idlelib/ToolTip.py2
-rw-r--r--Lib/idlelib/TreeWidget.py4
-rw-r--r--Lib/idlelib/UndoDelegator.py10
-rw-r--r--Lib/idlelib/WidgetRedirector.py4
-rw-r--r--Lib/idlelib/WindowList.py12
-rw-r--r--Lib/idlelib/aboutDialog.py2
-rw-r--r--Lib/idlelib/config-main.def4
-rw-r--r--Lib/idlelib/configDialog.py105
-rw-r--r--Lib/idlelib/configHandler.py48
-rw-r--r--Lib/idlelib/configHelpSourceEdit.py8
-rw-r--r--Lib/idlelib/configSectionNameDialog.py6
-rw-r--r--Lib/idlelib/dynOptionMenuWidget.py6
-rw-r--r--Lib/idlelib/help.txt4
-rw-r--r--Lib/idlelib/idle.pyw2
-rw-r--r--Lib/idlelib/idlever.py2
-rw-r--r--Lib/idlelib/keybindingDialog.py13
-rw-r--r--Lib/idlelib/macosxSupport.py12
-rw-r--r--Lib/idlelib/rpc.py108
-rw-r--r--Lib/idlelib/run.py79
-rw-r--r--Lib/idlelib/tabbedpages.py12
-rw-r--r--Lib/idlelib/textView.py15
-rw-r--r--Lib/ihooks.py554
-rw-r--r--Lib/imaplib.py277
-rw-r--r--Lib/imghdr.py49
-rw-r--r--Lib/importlib/__init__.py126
-rw-r--r--Lib/importlib/_bootstrap.py890
-rw-r--r--Lib/importlib/abc.py304
-rw-r--r--Lib/importlib/machinery.py5
-rw-r--r--Lib/importlib/test/__init__.py (renamed from Lib/lib-tk/test/test_ttk/__init__.py)0
-rw-r--r--Lib/importlib/test/__main__.py29
-rw-r--r--Lib/importlib/test/abc.py99
-rw-r--r--Lib/importlib/test/benchmark.py172
-rw-r--r--Lib/importlib/test/builtin/__init__.py12
-rw-r--r--Lib/importlib/test/builtin/test_finder.py55
-rw-r--r--Lib/importlib/test/builtin/test_loader.py102
-rw-r--r--Lib/importlib/test/builtin/util.py7
-rw-r--r--Lib/importlib/test/extension/__init__.py13
-rw-r--r--Lib/importlib/test/extension/test_case_sensitivity.py42
-rw-r--r--Lib/importlib/test/extension/test_finder.py47
-rw-r--r--Lib/importlib/test/extension/test_loader.py59
-rw-r--r--Lib/importlib/test/extension/test_path_hook.py31
-rw-r--r--Lib/importlib/test/extension/util.py21
-rw-r--r--Lib/importlib/test/frozen/__init__.py13
-rw-r--r--Lib/importlib/test/frozen/test_finder.py47
-rw-r--r--Lib/importlib/test/frozen/test_loader.py105
-rw-r--r--Lib/importlib/test/import_/__init__.py13
-rw-r--r--Lib/importlib/test/import_/test___package__.py119
-rw-r--r--Lib/importlib/test/import_/test_api.py22
-rw-r--r--Lib/importlib/test/import_/test_caching.py86
-rw-r--r--Lib/importlib/test/import_/test_fromlist.py123
-rw-r--r--Lib/importlib/test/import_/test_meta_path.py97
-rw-r--r--Lib/importlib/test/import_/test_packages.py37
-rw-r--r--Lib/importlib/test/import_/test_path.py131
-rw-r--r--Lib/importlib/test/import_/test_relative_imports.py203
-rw-r--r--Lib/importlib/test/import_/util.py29
-rw-r--r--Lib/importlib/test/regrtest.py35
-rw-r--r--Lib/importlib/test/source/__init__.py13
-rw-r--r--Lib/importlib/test/source/test_abc_loader.py876
-rw-r--r--Lib/importlib/test/source/test_case_sensitivity.py60
-rw-r--r--Lib/importlib/test/source/test_file_loader.py419
-rw-r--r--Lib/importlib/test/source/test_finder.py153
-rw-r--r--Lib/importlib/test/source/test_path_hook.py26
-rw-r--r--Lib/importlib/test/source/test_source_encoding.py123
-rw-r--r--Lib/importlib/test/source/util.py97
-rw-r--r--Lib/importlib/test/test_abc.py89
-rw-r--r--Lib/importlib/test/test_api.py93
-rw-r--r--Lib/importlib/test/test_util.py118
-rw-r--r--Lib/importlib/test/util.py136
-rw-r--r--Lib/importlib/util.py5
-rw-r--r--Lib/imputil.py725
-rw-r--r--Lib/inspect.py534
-rw-r--r--Lib/io.py4
-rw-r--r--Lib/json/__init__.py99
-rw-r--r--Lib/json/decoder.py90
-rw-r--r--Lib/json/encoder.py75
-rw-r--r--Lib/json/scanner.py14
-rw-r--r--Lib/json/tests/__init__.py73
-rw-r--r--Lib/json/tests/test_check_circular.py34
-rw-r--r--Lib/json/tests/test_decode.py59
-rw-r--r--Lib/json/tests/test_default.py12
-rw-r--r--Lib/json/tests/test_dump.py32
-rw-r--r--Lib/json/tests/test_encode_basestring_ascii.py41
-rw-r--r--Lib/json/tests/test_fail.py105
-rw-r--r--Lib/json/tests/test_float.py37
-rw-r--r--Lib/json/tests/test_indent.py60
-rw-r--r--Lib/json/tests/test_pass1.py75
-rw-r--r--Lib/json/tests/test_pass2.py18
-rw-r--r--Lib/json/tests/test_pass3.py24
-rw-r--r--Lib/json/tests/test_recursion.py108
-rw-r--r--Lib/json/tests/test_scanstring.py109
-rw-r--r--Lib/json/tests/test_separators.py44
-rw-r--r--Lib/json/tests/test_speedups.py23
-rw-r--r--Lib/json/tests/test_tool.py69
-rw-r--r--Lib/json/tests/test_unicode.py89
-rw-r--r--Lib/json/tool.py8
-rwxr-xr-xLib/keyword.py30
-rw-r--r--Lib/lib-tk/Canvas.py194
-rw-r--r--Lib/lib-tk/Dialog.py49
-rw-r--r--Lib/lib-tk/FileDialog.py274
-rw-r--r--Lib/lib-tk/FixTk.py78
-rw-r--r--Lib/lib-tk/ScrolledText.py55
-rw-r--r--Lib/lib-tk/SimpleDialog.py112
-rw-r--r--Lib/lib-tk/Tix.py1965
-rw-r--r--Lib/lib-tk/Tkdnd.py321
-rw-r--r--Lib/lib-tk/Tkinter.py3763
-rw-r--r--Lib/lib-tk/test/runtktests.py114
-rw-r--r--Lib/lib-tk/test/test_tkinter/test_loadtk.py45
-rw-r--r--Lib/lib-tk/test/test_tkinter/test_text.py39
-rw-r--r--Lib/lib-tk/test/test_ttk/support.py33
-rw-r--r--Lib/lib-tk/test/test_ttk/test_extensions.py274
-rw-r--r--Lib/lib-tk/test/test_ttk/test_functions.py428
-rw-r--r--Lib/lib-tk/test/test_ttk/test_style.py91
-rw-r--r--Lib/lib-tk/test/test_ttk/test_widgets.py1150
-rw-r--r--Lib/lib-tk/tkColorChooser.py72
-rw-r--r--Lib/lib-tk/tkCommonDialog.py60
-rw-r--r--Lib/lib-tk/tkFileDialog.py215
-rw-r--r--Lib/lib-tk/tkFont.py216
-rw-r--r--Lib/lib-tk/tkMessageBox.py134
-rw-r--r--Lib/lib-tk/tkSimpleDialog.py323
-rw-r--r--Lib/lib-tk/ttk.py1635
-rw-r--r--Lib/lib-tk/turtle.py4035
-rw-r--r--Lib/lib2to3/__main__.py4
-rw-r--r--Lib/lib2to3/btm_matcher.py2
-rw-r--r--Lib/lib2to3/fixer_base.py6
-rw-r--r--Lib/lib2to3/fixer_util.py74
-rw-r--r--Lib/lib2to3/fixes/fix_apply.py6
-rw-r--r--Lib/lib2to3/fixes/fix_basestring.py2
-rw-r--r--Lib/lib2to3/fixes/fix_buffer.py2
-rw-r--r--Lib/lib2to3/fixes/fix_callable.py8
-rw-r--r--Lib/lib2to3/fixes/fix_dict.py10
-rw-r--r--Lib/lib2to3/fixes/fix_except.py14
-rw-r--r--Lib/lib2to3/fixes/fix_exec.py2
-rw-r--r--Lib/lib2to3/fixes/fix_execfile.py12
-rw-r--r--Lib/lib2to3/fixes/fix_exitfunc.py8
-rw-r--r--Lib/lib2to3/fixes/fix_filter.py10
-rw-r--r--Lib/lib2to3/fixes/fix_funcattrs.py2
-rw-r--r--Lib/lib2to3/fixes/fix_getcwdu.py2
-rw-r--r--Lib/lib2to3/fixes/fix_has_key.py6
-rw-r--r--Lib/lib2to3/fixes/fix_idioms.py26
-rw-r--r--Lib/lib2to3/fixes/fix_import.py8
-rw-r--r--Lib/lib2to3/fixes/fix_imports.py2
-rw-r--r--Lib/lib2to3/fixes/fix_input.py4
-rw-r--r--Lib/lib2to3/fixes/fix_intern.py4
-rw-r--r--Lib/lib2to3/fixes/fix_isinstance.py2
-rw-r--r--Lib/lib2to3/fixes/fix_itertools.py2
-rw-r--r--Lib/lib2to3/fixes/fix_itertools_imports.py8
-rw-r--r--Lib/lib2to3/fixes/fix_long.py2
-rw-r--r--Lib/lib2to3/fixes/fix_map.py8
-rw-r--r--Lib/lib2to3/fixes/fix_metaclass.py26
-rw-r--r--Lib/lib2to3/fixes/fix_methodattrs.py2
-rw-r--r--Lib/lib2to3/fixes/fix_ne.py4
-rw-r--r--Lib/lib2to3/fixes/fix_next.py14
-rw-r--r--Lib/lib2to3/fixes/fix_nonzero.py2
-rw-r--r--Lib/lib2to3/fixes/fix_numliterals.py8
-rw-r--r--Lib/lib2to3/fixes/fix_operator.py32
-rw-r--r--Lib/lib2to3/fixes/fix_paren.py2
-rw-r--r--Lib/lib2to3/fixes/fix_print.py22
-rw-r--r--Lib/lib2to3/fixes/fix_raise.py16
-rw-r--r--Lib/lib2to3/fixes/fix_raw_input.py2
-rw-r--r--Lib/lib2to3/fixes/fix_reduce.py2
-rw-r--r--Lib/lib2to3/fixes/fix_renames.py6
-rw-r--r--Lib/lib2to3/fixes/fix_repr.py2
-rw-r--r--Lib/lib2to3/fixes/fix_set_literal.py4
-rw-r--r--Lib/lib2to3/fixes/fix_standarderror.py2
-rw-r--r--Lib/lib2to3/fixes/fix_sys_exc.py6
-rw-r--r--Lib/lib2to3/fixes/fix_throw.py8
-rw-r--r--Lib/lib2to3/fixes/fix_tuple_params.py18
-rw-r--r--Lib/lib2to3/fixes/fix_types.py2
-rw-r--r--Lib/lib2to3/fixes/fix_unicode.py4
-rw-r--r--Lib/lib2to3/fixes/fix_urllib.py2
-rw-r--r--Lib/lib2to3/fixes/fix_ws_comma.py10
-rw-r--r--Lib/lib2to3/fixes/fix_xrange.py10
-rw-r--r--Lib/lib2to3/fixes/fix_xreadlines.py2
-rw-r--r--Lib/lib2to3/fixes/fix_zip.py4
-rw-r--r--Lib/lib2to3/main.py25
-rw-r--r--Lib/lib2to3/patcomp.py6
-rw-r--r--Lib/lib2to3/pgen2/conv.py66
-rw-r--r--Lib/lib2to3/pgen2/driver.py8
-rw-r--r--Lib/lib2to3/pgen2/grammar.py12
-rw-r--r--Lib/lib2to3/pgen2/literals.py2
-rw-r--r--Lib/lib2to3/pgen2/pgen.py40
-rwxr-xr-xLib/lib2to3/pgen2/token.py4
-rw-r--r--Lib/lib2to3/pgen2/tokenize.py18
-rw-r--r--Lib/lib2to3/pygram.py2
-rw-r--r--Lib/lib2to3/pytree.py20
-rw-r--r--Lib/lib2to3/refactor.py52
-rwxr-xr-xLib/lib2to3/tests/pytree_idempotency.py20
-rw-r--r--Lib/lib2to3/tests/support.py2
-rw-r--r--Lib/lib2to3/tests/test_fixers.py12
-rw-r--r--Lib/lib2to3/tests/test_main.py36
-rw-r--r--Lib/lib2to3/tests/test_parser.py41
-rw-r--r--Lib/lib2to3/tests/test_refactor.py8
-rw-r--r--Lib/lib2to3/tests/test_util.py10
-rw-r--r--Lib/linecache.py7
-rw-r--r--Lib/locale.py169
-rw-r--r--Lib/logging/__init__.py446
-rw-r--r--Lib/logging/config.py200
-rw-r--r--Lib/logging/handlers.py254
-rw-r--r--Lib/macpath.py102
-rw-r--r--Lib/macurl2path.py20
-rw-r--r--Lib/mailbox.py642
-rw-r--r--Lib/mailcap.py34
-rw-r--r--Lib/markupbase.py396
-rw-r--r--Lib/md5.py14
-rw-r--r--Lib/mhlib.py1005
-rw-r--r--Lib/mimetools.py250
-rw-r--r--Lib/mimetypes.py38
-rwxr-xr-xLib/mimify.py468
-rw-r--r--Lib/modulefinder.py128
-rw-r--r--Lib/msilib/__init__.py17
-rw-r--r--Lib/msilib/schema.py848
-rw-r--r--Lib/msilib/sequence.py220
-rw-r--r--Lib/msilib/text.py240
-rw-r--r--Lib/multifile.py162
-rw-r--r--Lib/multiprocessing/__init__.py1
-rw-r--r--Lib/multiprocessing/connection.py60
-rw-r--r--Lib/multiprocessing/dummy/__init__.py10
-rw-r--r--Lib/multiprocessing/dummy/connection.py2
-rw-r--r--Lib/multiprocessing/forking.py51
-rw-r--r--Lib/multiprocessing/heap.py6
-rw-r--r--Lib/multiprocessing/managers.py53
-rw-r--r--Lib/multiprocessing/pool.py63
-rw-r--r--Lib/multiprocessing/process.py41
-rw-r--r--Lib/multiprocessing/queues.py12
-rw-r--r--Lib/multiprocessing/sharedctypes.py11
-rw-r--r--Lib/multiprocessing/synchronize.py11
-rw-r--r--Lib/multiprocessing/util.py64
-rw-r--r--Lib/mutex.py55
-rw-r--r--Lib/netrc.py12
-rw-r--r--Lib/new.py17
-rw-r--r--Lib/nntplib.py1196
-rw-r--r--Lib/ntpath.py532
-rw-r--r--Lib/nturl2path.py22
-rw-r--r--Lib/numbers.py59
-rw-r--r--Lib/opcode.py46
-rw-r--r--Lib/optparse.py85
-rw-r--r--Lib/os.py535
-rw-r--r--Lib/os2emxpath.py13
-rw-r--r--Lib/pdb.doc202
-rwxr-xr-xLib/pdb.py1375
-rw-r--r--Lib/pickle.py971
-rw-r--r--Lib/pickletools.py565
-rw-r--r--Lib/pipes.py48
-rw-r--r--Lib/pkgutil.py19
-rw-r--r--Lib/plat-aix3/IN.py126
-rwxr-xr-xLib/plat-aix3/regen8
-rw-r--r--Lib/plat-aix4/IN.py12
-rw-r--r--Lib/plat-atheos/IN.py944
-rw-r--r--Lib/plat-atheos/TYPES.py142
-rwxr-xr-xLib/plat-atheos/regen3
-rw-r--r--Lib/plat-beos5/IN.py327
-rwxr-xr-xLib/plat-beos5/regen7
-rw-r--r--Lib/plat-darwin/IN.py405
-rw-r--r--Lib/plat-irix5/AL.py65
-rw-r--r--Lib/plat-irix5/CD.py38
-rw-r--r--Lib/plat-irix5/CL.py28
-rw-r--r--Lib/plat-irix5/CL_old.py240
-rw-r--r--Lib/plat-irix5/DEVICE.py404
-rw-r--r--Lib/plat-irix5/ERRNO.py150
-rw-r--r--Lib/plat-irix5/FILE.py242
-rw-r--r--Lib/plat-irix5/FL.py292
-rw-r--r--Lib/plat-irix5/GET.py62
-rw-r--r--Lib/plat-irix5/GL.py397
-rw-r--r--Lib/plat-irix5/GLWS.py16
-rw-r--r--Lib/plat-irix5/IN.py144
-rw-r--r--Lib/plat-irix5/IOCTL.py236
-rw-r--r--Lib/plat-irix5/SV.py124
-rw-r--r--Lib/plat-irix5/WAIT.py18
-rw-r--r--Lib/plat-irix5/cddb.py207
-rw-r--r--Lib/plat-irix5/cdplayer.py91
-rw-r--r--Lib/plat-irix5/flp.doc117
-rw-r--r--Lib/plat-irix5/flp.py455
-rw-r--r--Lib/plat-irix5/jpeg.py114
-rw-r--r--Lib/plat-irix5/panel.py284
-rw-r--r--Lib/plat-irix5/panelparser.py131
-rw-r--r--Lib/plat-irix5/readcd.doc104
-rw-r--r--Lib/plat-irix5/readcd.py247
-rwxr-xr-xLib/plat-irix5/regen10
-rw-r--r--Lib/plat-irix5/torgb.py102
-rw-r--r--Lib/plat-irix6/AL.py65
-rw-r--r--Lib/plat-irix6/CD.py38
-rw-r--r--Lib/plat-irix6/CL.py28
-rw-r--r--Lib/plat-irix6/DEVICE.py404
-rw-r--r--Lib/plat-irix6/ERRNO.py183
-rw-r--r--Lib/plat-irix6/FILE.py677
-rw-r--r--Lib/plat-irix6/FL.py292
-rw-r--r--Lib/plat-irix6/GET.py62
-rw-r--r--Lib/plat-irix6/GL.py397
-rw-r--r--Lib/plat-irix6/GLWS.py16
-rw-r--r--Lib/plat-irix6/IN.py388
-rw-r--r--Lib/plat-irix6/IOCTL.py236
-rw-r--r--Lib/plat-irix6/SV.py124
-rw-r--r--Lib/plat-irix6/WAIT.py338
-rw-r--r--Lib/plat-irix6/cddb.py207
-rw-r--r--Lib/plat-irix6/cdplayer.py91
-rw-r--r--Lib/plat-irix6/flp.doc117
-rw-r--r--Lib/plat-irix6/flp.py454
-rw-r--r--Lib/plat-irix6/jpeg.py114
-rw-r--r--Lib/plat-irix6/panel.py284
-rw-r--r--Lib/plat-irix6/panelparser.py131
-rw-r--r--Lib/plat-irix6/readcd.doc104
-rw-r--r--Lib/plat-irix6/readcd.py247
-rwxr-xr-xLib/plat-irix6/regen11
-rw-r--r--Lib/plat-irix6/torgb.py102
-rw-r--r--Lib/plat-linux2/DLFCN.py6
-rw-r--r--Lib/plat-linux2/IN.py32
-rw-r--r--Lib/plat-linux2/TYPES.py8
-rw-r--r--Lib/plat-mac/Audio_mac.py124
-rw-r--r--Lib/plat-mac/Carbon/AE.py1
-rw-r--r--Lib/plat-mac/Carbon/AH.py1
-rw-r--r--Lib/plat-mac/Carbon/Alias.py1
-rw-r--r--Lib/plat-mac/Carbon/Aliases.py18
-rw-r--r--Lib/plat-mac/Carbon/App.py1
-rw-r--r--Lib/plat-mac/Carbon/Appearance.py648
-rw-r--r--Lib/plat-mac/Carbon/AppleEvents.py961
-rw-r--r--Lib/plat-mac/Carbon/AppleHelp.py6
-rw-r--r--Lib/plat-mac/Carbon/CF.py1
-rw-r--r--Lib/plat-mac/Carbon/CG.py1
-rw-r--r--Lib/plat-mac/Carbon/CarbonEvents.py451
-rw-r--r--Lib/plat-mac/Carbon/CarbonEvt.py1
-rw-r--r--Lib/plat-mac/Carbon/Cm.py1
-rw-r--r--Lib/plat-mac/Carbon/Components.py62
-rw-r--r--Lib/plat-mac/Carbon/ControlAccessor.py56
-rw-r--r--Lib/plat-mac/Carbon/Controls.py668
-rw-r--r--Lib/plat-mac/Carbon/CoreFoundation.py28
-rw-r--r--Lib/plat-mac/Carbon/CoreGraphics.py28
-rw-r--r--Lib/plat-mac/Carbon/Ctl.py1
-rw-r--r--Lib/plat-mac/Carbon/Dialogs.py79
-rw-r--r--Lib/plat-mac/Carbon/Dlg.py1
-rw-r--r--Lib/plat-mac/Carbon/Drag.py1
-rw-r--r--Lib/plat-mac/Carbon/Dragconst.py86
-rw-r--r--Lib/plat-mac/Carbon/Events.py102
-rw-r--r--Lib/plat-mac/Carbon/Evt.py1
-rw-r--r--Lib/plat-mac/Carbon/File.py1
-rw-r--r--Lib/plat-mac/Carbon/Files.py426
-rw-r--r--Lib/plat-mac/Carbon/Fm.py1
-rw-r--r--Lib/plat-mac/Carbon/Folder.py1
-rw-r--r--Lib/plat-mac/Carbon/Folders.py190
-rw-r--r--Lib/plat-mac/Carbon/Fonts.py59
-rw-r--r--Lib/plat-mac/Carbon/Help.py1
-rw-r--r--Lib/plat-mac/Carbon/IBCarbon.py1
-rw-r--r--Lib/plat-mac/Carbon/IBCarbonRuntime.py5
-rw-r--r--Lib/plat-mac/Carbon/Icn.py1
-rw-r--r--Lib/plat-mac/Carbon/Icons.py381
-rw-r--r--Lib/plat-mac/Carbon/Launch.py1
-rw-r--r--Lib/plat-mac/Carbon/LaunchServices.py74
-rw-r--r--Lib/plat-mac/Carbon/List.py1
-rw-r--r--Lib/plat-mac/Carbon/Lists.py35
-rw-r--r--Lib/plat-mac/Carbon/MacHelp.py58
-rw-r--r--Lib/plat-mac/Carbon/MacTextEditor.py226
-rw-r--r--Lib/plat-mac/Carbon/MediaDescr.py97
-rw-r--r--Lib/plat-mac/Carbon/Menu.py1
-rw-r--r--Lib/plat-mac/Carbon/Menus.py169
-rw-r--r--Lib/plat-mac/Carbon/Mlte.py1
-rw-r--r--Lib/plat-mac/Carbon/OSA.py1
-rw-r--r--Lib/plat-mac/Carbon/OSAconst.py133
-rw-r--r--Lib/plat-mac/Carbon/QDOffscreen.py47
-rw-r--r--Lib/plat-mac/Carbon/Qd.py1
-rw-r--r--Lib/plat-mac/Carbon/Qdoffs.py1
-rw-r--r--Lib/plat-mac/Carbon/Qt.py5
-rw-r--r--Lib/plat-mac/Carbon/QuickDraw.py218
-rw-r--r--Lib/plat-mac/Carbon/QuickTime.py3468
-rw-r--r--Lib/plat-mac/Carbon/Res.py4
-rw-r--r--Lib/plat-mac/Carbon/Resources.py27
-rw-r--r--Lib/plat-mac/Carbon/Scrap.py1
-rw-r--r--Lib/plat-mac/Carbon/Snd.py1
-rw-r--r--Lib/plat-mac/Carbon/Sndihooks.py1
-rw-r--r--Lib/plat-mac/Carbon/Sound.py400
-rw-r--r--Lib/plat-mac/Carbon/TE.py1
-rw-r--r--Lib/plat-mac/Carbon/TextEdit.py57
-rw-r--r--Lib/plat-mac/Carbon/Win.py1
-rw-r--r--Lib/plat-mac/Carbon/Windows.py279
-rw-r--r--Lib/plat-mac/Carbon/__init__.py7
-rw-r--r--Lib/plat-mac/EasyDialogs.py841
-rw-r--r--Lib/plat-mac/FrameWork.py1126
-rw-r--r--Lib/plat-mac/MiniAEFrame.py200
-rw-r--r--Lib/plat-mac/PixMapWrapper.py218
-rw-r--r--Lib/plat-mac/aepack.py369
-rw-r--r--Lib/plat-mac/aetools.py363
-rw-r--r--Lib/plat-mac/aetypes.py571
-rw-r--r--Lib/plat-mac/applesingle.py146
-rw-r--r--Lib/plat-mac/appletrawmain.py67
-rwxr-xr-xLib/plat-mac/appletrunner.py20
-rw-r--r--Lib/plat-mac/argvemulator.py92
-rw-r--r--Lib/plat-mac/bgenlocations.py58
-rw-r--r--Lib/plat-mac/buildtools.py435
-rwxr-xr-xLib/plat-mac/bundlebuilder.py949
-rw-r--r--Lib/plat-mac/cfmfile.py187
-rw-r--r--Lib/plat-mac/dialogs.rsrcbin18133 -> 0 bytes-rw-r--r--Lib/plat-mac/errors.rsrcbin86868 -> 0 bytes-rw-r--r--Lib/plat-mac/findertools.py835
-rw-r--r--Lib/plat-mac/gensuitemodule.py1216
-rw-r--r--Lib/plat-mac/ic.py271
-rw-r--r--Lib/plat-mac/icopen.py69
-rw-r--r--Lib/plat-mac/lib-scriptpackages/CodeWarrior/CodeWarrior_suite.py682
-rw-r--r--Lib/plat-mac/lib-scriptpackages/CodeWarrior/Metrowerks_Shell_Suite.py2373
-rw-r--r--Lib/plat-mac/lib-scriptpackages/CodeWarrior/Required.py62
-rw-r--r--Lib/plat-mac/lib-scriptpackages/CodeWarrior/Standard_Suite.py408
-rw-r--r--Lib/plat-mac/lib-scriptpackages/CodeWarrior/__init__.py193
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Explorer/Microsoft_Internet_Explorer.py96
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Explorer/Netscape_Suite.py49
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Explorer/Required_Suite.py108
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Explorer/Standard_Suite.py72
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Explorer/URL_Suite.py54
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Explorer/Web_Browser_Suite.py226
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Explorer/__init__.py84
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Finder/Containers_and_folders.py279
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Finder/Enumerations.py145
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Finder/Files.py212
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Finder/Finder_Basics.py207
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Finder/Finder_items.py355
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Finder/Legacy_suite.py224
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Finder/Standard_Suite.py335
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Finder/Type_Definitions.py346
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Finder/Window_classes.py229
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Finder/__init__.py237
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Netscape/Mozilla_suite.py269
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Netscape/PowerPlant.py86
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Netscape/Required_suite.py108
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Netscape/Standard_Suite.py243
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Netscape/Standard_URL_suite.py60
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Netscape/Text.py122
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Netscape/WorldWideWeb_suite.py426
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Netscape/__init__.py109
-rw-r--r--Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py2215
-rw-r--r--Lib/plat-mac/lib-scriptpackages/StdSuites/Macintosh_Connectivity_Clas.py373
-rw-r--r--Lib/plat-mac/lib-scriptpackages/StdSuites/QuickDraw_Graphics_Suite.py417
-rw-r--r--Lib/plat-mac/lib-scriptpackages/StdSuites/QuickDraw_Graphics_Suppleme.py73
-rw-r--r--Lib/plat-mac/lib-scriptpackages/StdSuites/Required_Suite.py32
-rw-r--r--Lib/plat-mac/lib-scriptpackages/StdSuites/Standard_Suite.py738
-rw-r--r--Lib/plat-mac/lib-scriptpackages/StdSuites/Table_Suite.py104
-rw-r--r--Lib/plat-mac/lib-scriptpackages/StdSuites/Text_Suite.py224
-rw-r--r--Lib/plat-mac/lib-scriptpackages/StdSuites/Type_Names_Suite.py435
-rw-r--r--Lib/plat-mac/lib-scriptpackages/StdSuites/__init__.py475
-rw-r--r--Lib/plat-mac/lib-scriptpackages/SystemEvents/Disk_Folder_File_Suite.py381
-rw-r--r--Lib/plat-mac/lib-scriptpackages/SystemEvents/Folder_Actions_Suite.py287
-rw-r--r--Lib/plat-mac/lib-scriptpackages/SystemEvents/Hidden_Suite.py50
-rw-r--r--Lib/plat-mac/lib-scriptpackages/SystemEvents/Login_Items_Suite.py74
-rw-r--r--Lib/plat-mac/lib-scriptpackages/SystemEvents/Power_Suite.py149
-rw-r--r--Lib/plat-mac/lib-scriptpackages/SystemEvents/Processes_Suite.py214
-rw-r--r--Lib/plat-mac/lib-scriptpackages/SystemEvents/Standard_Suite.py582
-rw-r--r--Lib/plat-mac/lib-scriptpackages/SystemEvents/System_Events_Suite.py109
-rw-r--r--Lib/plat-mac/lib-scriptpackages/SystemEvents/Text_Suite.py195
-rw-r--r--Lib/plat-mac/lib-scriptpackages/SystemEvents/__init__.py144
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Terminal/Standard_Suite.py582
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Terminal/Terminal_Suite.py254
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Terminal/Text_Suite.py195
-rw-r--r--Lib/plat-mac/lib-scriptpackages/Terminal/__init__.py93
-rw-r--r--Lib/plat-mac/lib-scriptpackages/_builtinSuites/__init__.py31
-rw-r--r--Lib/plat-mac/lib-scriptpackages/_builtinSuites/builtin_Suite.py140
-rw-r--r--Lib/plat-mac/macerrors.py1857
-rw-r--r--Lib/plat-mac/macostools.py138
-rw-r--r--Lib/plat-mac/macresource.py135
-rw-r--r--Lib/plat-mac/pimp.py1182
-rw-r--r--Lib/plat-mac/terminalcommand.py50
-rw-r--r--Lib/plat-mac/videoreader.py294
-rw-r--r--Lib/plat-os2emx/IN.py12
-rw-r--r--Lib/plat-os2emx/_emx_link.py6
-rw-r--r--Lib/plat-os2emx/grp.py14
-rw-r--r--Lib/plat-os2emx/pwd.py16
-rw-r--r--Lib/plat-riscos/riscosenviron.py45
-rw-r--r--Lib/plat-riscos/riscospath.py378
-rw-r--r--Lib/plat-riscos/rourl2path.py70
-rw-r--r--Lib/plat-sunos5/IN.py58
-rw-r--r--Lib/plat-sunos5/STROPTS.py56
-rw-r--r--Lib/plat-sunos5/SUNAUDIODEV.py43
-rw-r--r--Lib/plat-sunos5/TYPES.py12
-rw-r--r--Lib/plat-unixware7/IN.py20
-rw-r--r--Lib/plat-unixware7/STROPTS.py132
-rwxr-xr-xLib/platform.py198
-rw-r--r--Lib/plistlib.py234
-rw-r--r--Lib/popen2.py201
-rw-r--r--Lib/poplib.py140
-rw-r--r--Lib/posixfile.py237
-rw-r--r--Lib/posixpath.py240
-rw-r--r--Lib/pprint.py198
-rwxr-xr-xLib/profile.py28
-rw-r--r--Lib/pstats.py259
-rw-r--r--Lib/pty.py10
-rw-r--r--Lib/py_compile.py83
-rw-r--r--Lib/pyclbr.py29
-rwxr-xr-xLib/pydoc.py1147
-rw-r--r--Lib/pydoc_data/_pydoc.css6
-rw-r--r--Lib/pydoc_data/topics.py121
-rw-r--r--Lib/queue.py261
-rwxr-xr-xLib/quopri.py141
-rw-r--r--Lib/random.py396
-rw-r--r--Lib/re.py145
-rw-r--r--Lib/repr.py132
-rw-r--r--Lib/reprlib.py157
-rw-r--r--Lib/rexec.py588
-rw-r--r--Lib/rfc822.py1011
-rw-r--r--Lib/rlcompleter.py14
-rw-r--r--Lib/robotparser.py222
-rw-r--r--Lib/runpy.py60
-rw-r--r--Lib/sched.py8
-rw-r--r--Lib/sets.py557
-rw-r--r--Lib/sgmllib.py553
-rw-r--r--Lib/sha.py15
-rw-r--r--Lib/shelve.py87
-rw-r--r--Lib/shlex.py62
-rw-r--r--Lib/shutil.py263
-rw-r--r--Lib/site.py142
-rwxr-xr-xLib/smtpd.py324
-rw-r--r--[-rwxr-xr-x]Lib/smtplib.py221
-rw-r--r--Lib/sndhdr.py119
-rw-r--r--Lib/socket.py681
-rw-r--r--Lib/socketserver.py727
-rw-r--r--Lib/sqlite3/__init__.py5
-rw-r--r--Lib/sqlite3/dbapi2.py15
-rw-r--r--Lib/sqlite3/test/dbapi.py58
-rw-r--r--Lib/sqlite3/test/dump.py2
-rw-r--r--Lib/sqlite3/test/factory.py60
-rw-r--r--Lib/sqlite3/test/hooks.py27
-rw-r--r--Lib/sqlite3/test/py25tests.py80
-rw-r--r--Lib/sqlite3/test/regression.py51
-rw-r--r--Lib/sqlite3/test/transactions.py3
-rw-r--r--Lib/sqlite3/test/types.py71
-rw-r--r--Lib/sqlite3/test/userfunctions.py55
-rw-r--r--Lib/sre.py13
-rw-r--r--Lib/sre_compile.py37
-rw-r--r--Lib/sre_constants.py5
-rw-r--r--Lib/sre_parse.py160
-rw-r--r--Lib/ssl.py411
-rw-r--r--Lib/stat.py54
-rw-r--r--Lib/statvfs.py18
-rw-r--r--Lib/string.py423
-rw-r--r--Lib/stringold.py432
-rw-r--r--Lib/stringprep.py340
-rw-r--r--Lib/struct.py11
-rw-r--r--Lib/subprocess.py851
-rw-r--r--Lib/sunau.py84
-rw-r--r--Lib/sunaudio.py49
-rwxr-xr-xLib/symbol.py134
-rw-r--r--Lib/symtable.py14
-rw-r--r--Lib/sysconfig.py142
-rwxr-xr-xLib/tabnanny.py51
-rw-r--r--Lib/tarfile.py1044
-rw-r--r--Lib/telnetlib.py228
-rw-r--r--Lib/tempfile.py231
-rw-r--r--Lib/test/__main__.py13
-rw-r--r--Lib/test/bad_coding2.py2
-rw-r--r--Lib/test/badsyntax_3131.py2
-rw-r--r--Lib/test/badsyntax_future8.py2
-rw-r--r--Lib/test/badsyntax_future9.py2
-rw-r--r--Lib/test/badsyntax_nocaret.py2
-rw-r--r--Lib/test/badsyntax_pep3120.py1
-rw-r--r--Lib/test/buffer_tests.py10
-rw-r--r--Lib/test/capath/4e1295a3.014
-rw-r--r--Lib/test/capath/5ed36f99.041
-rw-r--r--Lib/test/capath/6e88d7b8.014
-rw-r--r--Lib/test/capath/99d0fa06.041
-rw-r--r--Lib/test/cfgparser.2537
-rw-r--r--Lib/test/cfgparser.369
-rw-r--r--Lib/test/cmath_testcases.txt31
-rw-r--r--Lib/test/crashers/bogus_code_obj.py6
-rw-r--r--Lib/test/crashers/borrowed_ref_1.py2
-rw-r--r--Lib/test/crashers/borrowed_ref_2.py4
-rw-r--r--Lib/test/crashers/buffer_mutate.py30
-rw-r--r--Lib/test/crashers/decref_before_assignment.py44
-rw-r--r--Lib/test/crashers/gc_has_finalizer.py36
-rw-r--r--Lib/test/crashers/gc_inspection.py4
-rw-r--r--Lib/test/crashers/loosing_mro_ref.py6
-rw-r--r--Lib/test/crashers/nasty_eq_vs_dict.py2
-rw-r--r--Lib/test/crashers/recursive_call.py2
-rw-r--r--Lib/test/crashers/trace_at_recursion_limit.py27
-rw-r--r--Lib/test/crashers/underlying_dict.py20
-rw-r--r--Lib/test/curses_tests.py2
-rw-r--r--Lib/test/data/README2
-rw-r--r--Lib/test/datetimetester.py3685
-rw-r--r--Lib/test/decimaltestdata/and.decTest676
-rw-r--r--Lib/test/decimaltestdata/class.decTest262
-rw-r--r--Lib/test/decimaltestdata/comparetotal.decTest1596
-rw-r--r--Lib/test/decimaltestdata/comparetotmag.decTest1580
-rw-r--r--Lib/test/decimaltestdata/copy.decTest172
-rw-r--r--Lib/test/decimaltestdata/copyabs.decTest172
-rw-r--r--Lib/test/decimaltestdata/copynegate.decTest172
-rw-r--r--Lib/test/decimaltestdata/copysign.decTest354
-rw-r--r--Lib/test/decimaltestdata/ddAbs.decTest252
-rw-r--r--Lib/test/decimaltestdata/ddAdd.decTest2656
-rw-r--r--Lib/test/decimaltestdata/ddAnd.decTest694
-rw-r--r--Lib/test/decimaltestdata/ddBase.decTest2208
-rw-r--r--Lib/test/decimaltestdata/ddCanonical.decTest714
-rw-r--r--Lib/test/decimaltestdata/ddClass.decTest152
-rw-r--r--Lib/test/decimaltestdata/ddCompare.decTest1488
-rw-r--r--Lib/test/decimaltestdata/ddCompareSig.decTest1294
-rw-r--r--Lib/test/decimaltestdata/ddCompareTotal.decTest1412
-rw-r--r--Lib/test/decimaltestdata/ddCompareTotalMag.decTest1412
-rw-r--r--Lib/test/decimaltestdata/ddCopy.decTest176
-rw-r--r--Lib/test/decimaltestdata/ddCopyAbs.decTest176
-rw-r--r--Lib/test/decimaltestdata/ddCopyNegate.decTest176
-rw-r--r--Lib/test/decimaltestdata/ddCopySign.decTest350
-rw-r--r--Lib/test/decimaltestdata/ddDivide.decTest1726
-rw-r--r--Lib/test/decimaltestdata/ddDivideInt.decTest898
-rw-r--r--Lib/test/decimaltestdata/ddEncode.decTest990
-rw-r--r--Lib/test/decimaltestdata/ddFMA.decTest3396
-rw-r--r--Lib/test/decimaltestdata/ddInvert.decTest404
-rw-r--r--Lib/test/decimaltestdata/ddLogB.decTest318
-rw-r--r--Lib/test/decimaltestdata/ddMax.decTest644
-rw-r--r--Lib/test/decimaltestdata/ddMaxMag.decTest608
-rw-r--r--Lib/test/decimaltestdata/ddMin.decTest618
-rw-r--r--Lib/test/decimaltestdata/ddMinMag.decTest586
-rw-r--r--Lib/test/decimaltestdata/ddMinus.decTest176
-rw-r--r--Lib/test/decimaltestdata/ddMultiply.decTest1106
-rw-r--r--Lib/test/decimaltestdata/ddNextMinus.decTest252
-rw-r--r--Lib/test/decimaltestdata/ddNextPlus.decTest248
-rw-r--r--Lib/test/decimaltestdata/ddNextToward.decTest748
-rw-r--r--Lib/test/decimaltestdata/ddOr.decTest584
-rw-r--r--Lib/test/decimaltestdata/ddPlus.decTest176
-rw-r--r--Lib/test/decimaltestdata/ddQuantize.decTest1666
-rw-r--r--Lib/test/decimaltestdata/ddReduce.decTest364
-rw-r--r--Lib/test/decimaltestdata/ddRemainder.decTest1200
-rw-r--r--Lib/test/decimaltestdata/ddRemainderNear.decTest1258
-rw-r--r--Lib/test/decimaltestdata/ddRotate.decTest524
-rw-r--r--Lib/test/decimaltestdata/ddSameQuantum.decTest778
-rw-r--r--Lib/test/decimaltestdata/ddScaleB.decTest486
-rw-r--r--Lib/test/decimaltestdata/ddShift.decTest524
-rw-r--r--Lib/test/decimaltestdata/ddSubtract.decTest1258
-rw-r--r--Lib/test/decimaltestdata/ddToIntegral.decTest514
-rw-r--r--Lib/test/decimaltestdata/ddXor.decTest674
-rw-r--r--Lib/test/decimaltestdata/dqAbs.decTest252
-rw-r--r--Lib/test/decimaltestdata/dqAdd.decTest2430
-rw-r--r--Lib/test/decimaltestdata/dqAnd.decTest840
-rw-r--r--Lib/test/decimaltestdata/dqBase.decTest2162
-rw-r--r--Lib/test/decimaltestdata/dqCanonical.decTest744
-rw-r--r--Lib/test/decimaltestdata/dqClass.decTest154
-rw-r--r--Lib/test/decimaltestdata/dqCompare.decTest1506
-rw-r--r--Lib/test/decimaltestdata/dqCompareSig.decTest1294
-rw-r--r--Lib/test/decimaltestdata/dqCompareTotal.decTest1412
-rw-r--r--Lib/test/decimaltestdata/dqCompareTotalMag.decTest1412
-rw-r--r--Lib/test/decimaltestdata/dqCopy.decTest176
-rw-r--r--Lib/test/decimaltestdata/dqCopyAbs.decTest176
-rw-r--r--Lib/test/decimaltestdata/dqCopyNegate.decTest176
-rw-r--r--Lib/test/decimaltestdata/dqCopySign.decTest350
-rw-r--r--Lib/test/decimaltestdata/dqDivide.decTest1616
-rw-r--r--Lib/test/decimaltestdata/dqDivideInt.decTest906
-rw-r--r--Lib/test/decimaltestdata/dqEncode.decTest954
-rw-r--r--Lib/test/decimaltestdata/dqFMA.decTest3572
-rw-r--r--Lib/test/decimaltestdata/dqInvert.decTest490
-rw-r--r--Lib/test/decimaltestdata/dqLogB.decTest320
-rw-r--r--Lib/test/decimaltestdata/dqMax.decTest644
-rw-r--r--Lib/test/decimaltestdata/dqMaxMag.decTest608
-rw-r--r--Lib/test/decimaltestdata/dqMin.decTest618
-rw-r--r--Lib/test/decimaltestdata/dqMinMag.decTest586
-rw-r--r--Lib/test/decimaltestdata/dqMinus.decTest176
-rw-r--r--Lib/test/decimaltestdata/dqMultiply.decTest1178
-rw-r--r--Lib/test/decimaltestdata/dqNextMinus.decTest252
-rw-r--r--Lib/test/decimaltestdata/dqNextPlus.decTest248
-rw-r--r--Lib/test/decimaltestdata/dqNextToward.decTest750
-rw-r--r--Lib/test/decimaltestdata/dqOr.decTest802
-rw-r--r--Lib/test/decimaltestdata/dqPlus.decTest176
-rw-r--r--Lib/test/decimaltestdata/dqQuantize.decTest1672
-rw-r--r--Lib/test/decimaltestdata/dqReduce.decTest366
-rw-r--r--Lib/test/decimaltestdata/dqRemainder.decTest1194
-rw-r--r--Lib/test/decimaltestdata/dqRemainderNear.decTest1262
-rw-r--r--Lib/test/decimaltestdata/dqRotate.decTest596
-rw-r--r--Lib/test/decimaltestdata/dqSameQuantum.decTest778
-rw-r--r--Lib/test/decimaltestdata/dqScaleB.decTest520
-rw-r--r--Lib/test/decimaltestdata/dqShift.decTest596
-rw-r--r--Lib/test/decimaltestdata/dqSubtract.decTest1270
-rw-r--r--Lib/test/decimaltestdata/dqToIntegral.decTest514
-rw-r--r--Lib/test/decimaltestdata/dqXor.decTest820
-rw-r--r--Lib/test/decimaltestdata/dsBase.decTest2124
-rw-r--r--Lib/test/decimaltestdata/dsEncode.decTest744
-rw-r--r--Lib/test/decimaltestdata/exp.decTest1348
-rw-r--r--Lib/test/decimaltestdata/extra.decTest13
-rw-r--r--Lib/test/decimaltestdata/fma.decTest6852
-rw-r--r--Lib/test/decimaltestdata/invert.decTest352
-rw-r--r--Lib/test/decimaltestdata/ln.decTest1222
-rw-r--r--Lib/test/decimaltestdata/log10.decTest1102
-rw-r--r--Lib/test/decimaltestdata/logb.decTest376
-rw-r--r--Lib/test/decimaltestdata/maxmag.decTest808
-rw-r--r--Lib/test/decimaltestdata/minmag.decTest780
-rw-r--r--Lib/test/decimaltestdata/nextminus.decTest296
-rw-r--r--Lib/test/decimaltestdata/nextplus.decTest300
-rw-r--r--Lib/test/decimaltestdata/nexttoward.decTest852
-rw-r--r--Lib/test/decimaltestdata/or.decTest668
-rw-r--r--Lib/test/decimaltestdata/powersqrt.decTest5940
-rw-r--r--Lib/test/decimaltestdata/rotate.decTest494
-rw-r--r--Lib/test/decimaltestdata/scaleb.decTest418
-rw-r--r--Lib/test/decimaltestdata/shift.decTest500
-rw-r--r--Lib/test/decimaltestdata/tointegralx.decTest510
-rw-r--r--Lib/test/decimaltestdata/xor.decTest670
-rw-r--r--Lib/test/dis_module.py5
-rw-r--r--Lib/test/doctest_aliases.py2
-rw-r--r--Lib/test/double_const.py2
-rw-r--r--Lib/test/encoded_modules/__init__.py23
-rw-r--r--Lib/test/encoded_modules/module_iso_8859_1.py5
-rw-r--r--Lib/test/encoded_modules/module_koi8_r.py3
-rw-r--r--Lib/test/exception_hierarchy.txt74
-rw-r--r--Lib/test/fork_wait.py14
-rw-r--r--Lib/test/formatfloat_testcases.txt97
-rw-r--r--Lib/test/gdb_sample.py2
-rw-r--r--Lib/test/greyrgb.uue1547
-rw-r--r--Lib/test/infinite_reload.py8
-rw-r--r--Lib/test/inspect_fodder.py4
-rw-r--r--Lib/test/inspect_fodder2.py20
-rw-r--r--Lib/test/json_tests/__init__.py73
-rw-r--r--Lib/test/json_tests/test_decode.py68
-rw-r--r--Lib/test/json_tests/test_default.py12
-rw-r--r--Lib/test/json_tests/test_dump.py32
-rw-r--r--Lib/test/json_tests/test_encode_basestring_ascii.py44
-rw-r--r--Lib/test/json_tests/test_fail.py105
-rw-r--r--Lib/test/json_tests/test_float.py33
-rw-r--r--Lib/test/json_tests/test_indent.py63
-rw-r--r--Lib/test/json_tests/test_pass1.py75
-rw-r--r--Lib/test/json_tests/test_pass2.py18
-rw-r--r--Lib/test/json_tests/test_pass3.py24
-rw-r--r--Lib/test/json_tests/test_recursion.py100
-rw-r--r--Lib/test/json_tests/test_scanstring.py103
-rw-r--r--Lib/test/json_tests/test_separators.py44
-rw-r--r--Lib/test/json_tests/test_speedups.py24
-rw-r--r--Lib/test/json_tests/test_tool.py69
-rw-r--r--Lib/test/json_tests/test_unicode.py75
-rw-r--r--Lib/test/keycert.pem59
-rw-r--r--Lib/test/keycert2.pem31
-rw-r--r--Lib/test/leakers/test_dictself.py12
-rw-r--r--Lib/test/leakers/test_gestalt.py2
-rw-r--r--Lib/test/leakers/test_selftype.py4
-rw-r--r--Lib/test/list_tests.py88
-rw-r--r--Lib/test/lock_tests.py358
-rw-r--r--Lib/test/make_ssl_certs.py64
-rw-r--r--Lib/test/mapping_tests.py157
-rw-r--r--Lib/test/math_testcases.txt72
-rw-r--r--Lib/test/mime.types1445
-rw-r--r--Lib/test/mock_socket.py154
-rw-r--r--Lib/test/mp_fork_bomb.py13
-rw-r--r--Lib/test/outstanding_bugs.py74
-rw-r--r--Lib/test/pickletester.py1111
-rw-r--r--Lib/test/pstats.pckbin0 -> 66607 bytes-rw-r--r--Lib/test/pydoc_mod.py2
-rw-r--r--Lib/test/pydocfodder.py6
-rwxr-xr-xLib/test/pystone.py14
-rwxr-xr-xLib/test/re_tests.py12
-rwxr-xr-xLib/test/regrtest.py888
-rw-r--r--Lib/test/reperf.py4
-rw-r--r--Lib/test/sample_doctest.py6
-rw-r--r--Lib/test/script_helper.py69
-rw-r--r--Lib/test/seq_tests.py64
-rw-r--r--Lib/test/sha256.pem222
-rw-r--r--Lib/test/sndhdrdata/README12
-rw-r--r--Lib/test/sndhdrdata/sndhdr.8svxbin0 -> 110 bytes-rw-r--r--Lib/test/sndhdrdata/sndhdr.aifcbin0 -> 106 bytes-rw-r--r--Lib/test/sndhdrdata/sndhdr.aiffbin0 -> 108 bytes-rw-r--r--Lib/test/sndhdrdata/sndhdr.aubin0 -> 64 bytes-rw-r--r--Lib/test/sndhdrdata/sndhdr.hcombin0 -> 256 bytes-rw-r--r--Lib/test/sndhdrdata/sndhdr.sndtbin0 -> 129 bytes-rw-r--r--Lib/test/sndhdrdata/sndhdr.vocbin0 -> 63 bytes-rw-r--r--Lib/test/sndhdrdata/sndhdr.wavbin0 -> 64 bytes-rw-r--r--Lib/test/sortperf.py24
-rw-r--r--Lib/test/ssl_cert.pem25
-rw-r--r--Lib/test/ssl_key.pem25
-rw-r--r--Lib/test/ssl_servers.py189
-rw-r--r--Lib/test/string_tests.py631
-rw-r--r--Lib/test/subprocessdata/fd_status.py24
-rw-r--r--Lib/test/subprocessdata/input_reader.py7
-rw-r--r--Lib/test/subprocessdata/qcat.py7
-rw-r--r--Lib/test/subprocessdata/qgrep.py10
-rw-r--r--Lib/test/support.py1721
-rw-r--r--Lib/test/symlink_support.py100
-rw-r--r--Lib/test/test_MimeWriter.py292
-rw-r--r--Lib/test/test_SimpleHTTPServer.py41
-rw-r--r--Lib/test/test_StringIO.py179
-rw-r--r--Lib/test/test___all__.py22
-rw-r--r--Lib/test/test___future__.py8
-rw-r--r--Lib/test/test__locale.py15
-rw-r--r--Lib/test/test_abc.py153
-rw-r--r--Lib/test/test_abstract_numbers.py20
-rw-r--r--Lib/test/test_aepack.py90
-rw-r--r--Lib/test/test_aifc.py217
-rwxr-xr-xLib/test/test_al.py25
-rw-r--r--Lib/test/test_anydbm.py97
-rw-r--r--Lib/test/test_applesingle.py71
-rw-r--r--Lib/test/test_argparse.py88
-rwxr-xr-xLib/test/test_array.py453
-rw-r--r--Lib/test/test_ascii_formatd.py58
-rw-r--r--Lib/test/test_ast.py112
-rw-r--r--Lib/test/test_asynchat.py97
-rw-r--r--Lib/test/test_asyncore.py95
-rw-r--r--Lib/test/test_atexit.py139
-rw-r--r--Lib/test/test_audioop.py56
-rw-r--r--Lib/test/test_augassign.py44
-rw-r--r--Lib/test/test_base64.py342
-rw-r--r--Lib/test/test_bastion.py3
-rw-r--r--Lib/test/test_bigaddrspace.py103
-rw-r--r--Lib/test/test_bigmem.py917
-rw-r--r--Lib/test/test_binascii.py130
-rwxr-xr-xLib/test/test_binhex.py34
-rw-r--r--Lib/test/test_binop.py135
-rw-r--r--Lib/test/test_bisect.py44
-rw-r--r--Lib/test/test_bool.py145
-rwxr-xr-xLib/test/test_bsddb.py357
-rw-r--r--Lib/test/test_bsddb185.py43
-rw-r--r--Lib/test/test_bsddb3.py81
-rw-r--r--Lib/test/test_buffer.py31
-rw-r--r--Lib/test/test_bufio.py7
-rw-r--r--Lib/test/test_builtin.py1114
-rw-r--r--Lib/test/test_bytes.py303
-rw-r--r--Lib/test/test_bz2.py139
-rw-r--r--Lib/test/test_calendar.py31
-rw-r--r--Lib/test/test_call.py25
-rw-r--r--Lib/test/test_capi.py172
-rwxr-xr-xLib/test/test_cd.py30
-rw-r--r--Lib/test/test_cfgparser.py1561
-rw-r--r--Lib/test/test_cgi.py194
-rw-r--r--Lib/test/test_charmapcodec.py34
-rwxr-xr-xLib/test/test_cl.py82
-rw-r--r--Lib/test/test_class.py276
-rw-r--r--Lib/test/test_cmath.py84
-rw-r--r--Lib/test/test_cmd.py52
-rw-r--r--Lib/test/test_cmd_line.py364
-rw-r--r--Lib/test/test_cmd_line_script.py193
-rw-r--r--Lib/test/test_code.py54
-rw-r--r--Lib/test/test_codeccallbacks.py445
-rw-r--r--Lib/test/test_codecencodings_cn.py68
-rw-r--r--Lib/test/test_codecencodings_hk.py16
-rw-r--r--Lib/test/test_codecencodings_iso2022.py16
-rw-r--r--Lib/test/test_codecencodings_jp.py92
-rw-r--r--Lib/test/test_codecencodings_kr.py68
-rw-r--r--Lib/test/test_codecencodings_tw.py16
-rw-r--r--Lib/test/test_codecmaps_cn.py6
-rw-r--r--Lib/test/test_codecmaps_hk.py8
-rw-r--r--Lib/test/test_codecmaps_jp.py26
-rw-r--r--Lib/test/test_codecmaps_kr.py14
-rw-r--r--Lib/test/test_codecmaps_tw.py10
-rw-r--r--Lib/test/test_codecs.py1475
-rw-r--r--Lib/test/test_codeop.py14
-rw-r--r--Lib/test/test_coding.py42
-rw-r--r--Lib/test/test_coercion.py348
-rw-r--r--Lib/test/test_collections.py347
-rw-r--r--Lib/test/test_colorsys.py4
-rw-r--r--Lib/test/test_commands.py74
-rw-r--r--Lib/test/test_compare.py47
-rw-r--r--Lib/test/test_compile.py207
-rw-r--r--Lib/test/test_compileall.py304
-rw-r--r--Lib/test/test_compiler.py317
-rw-r--r--Lib/test/test_complex.py327
-rw-r--r--Lib/test/test_complex_args.py118
-rw-r--r--Lib/test/test_concurrent_futures.py639
-rw-r--r--Lib/test/test_contains.py68
-rw-r--r--Lib/test/test_contextlib.py298
-rw-r--r--Lib/test/test_cookie.py99
-rw-r--r--Lib/test/test_cookielib.py1762
-rw-r--r--Lib/test/test_copy.py138
-rw-r--r--Lib/test/test_copy_reg.py121
-rw-r--r--Lib/test/test_copyreg.py121
-rw-r--r--Lib/test/test_cpickle.py139
-rw-r--r--Lib/test/test_cprofile.py85
-rw-r--r--Lib/test/test_crypt.py10
-rw-r--r--Lib/test/test_csv.py369
-rw-r--r--Lib/test/test_ctypes.py7
-rw-r--r--Lib/test/test_curses.py39
-rw-r--r--Lib/test/test_datetime.py3403
-rw-r--r--Lib/test/test_dbm.py178
-rw-r--r--Lib/test/test_dbm_dumb.py205
-rwxr-xr-xLib/test/test_dbm_gnu.py88
-rwxr-xr-xLib/test/test_dbm_ndbm.py43
-rw-r--r--Lib/test/test_decimal.py250
-rw-r--r--Lib/test/test_decorators.py16
-rw-r--r--Lib/test/test_defaultdict.py25
-rw-r--r--Lib/test/test_deque.py193
-rw-r--r--Lib/test/test_descr.py1478
-rw-r--r--Lib/test/test_descrtut.py121
-rw-r--r--Lib/test/test_dict.py223
-rw-r--r--Lib/test/test_dictcomps.py6
-rw-r--r--Lib/test/test_dictviews.py161
-rw-r--r--Lib/test/test_difflib.py23
-rw-r--r--Lib/test/test_dircache.py77
-rw-r--r--Lib/test/test_dis.py304
-rw-r--r--Lib/test/test_distutils.py6
-rwxr-xr-xLib/test/test_dl.py39
-rw-r--r--Lib/test/test_doctest.py692
-rw-r--r--Lib/test/test_doctest.txt6
-rw-r--r--Lib/test/test_doctest2.py37
-rw-r--r--Lib/test/test_doctest3.txt2
-rw-r--r--Lib/test/test_doctest4.txt10
-rw-r--r--Lib/test/test_docxmlrpc.py87
-rw-r--r--Lib/test/test_dumbdbm.py179
-rw-r--r--Lib/test/test_dummy_thread.py48
-rw-r--r--Lib/test/test_dummy_threading.py29
-rw-r--r--Lib/test/test_dynamic.py143
-rw-r--r--Lib/test/test_email.py8
-rw-r--r--Lib/test/test_email_codecs.py15
-rw-r--r--Lib/test/test_email_renamed.py12
-rw-r--r--Lib/test/test_enumerate.py52
-rw-r--r--Lib/test/test_eof.py14
-rw-r--r--Lib/test/test_epoll.py16
-rwxr-xr-xLib/test/test_errno.py13
-rw-r--r--Lib/test/test_exception_variations.py14
-rw-r--r--Lib/test/test_exceptions.py787
-rw-r--r--Lib/test/test_extcall.py65
-rw-r--r--Lib/test/test_fcntl.py27
-rw-r--r--Lib/test/test_file.py22
-rw-r--r--Lib/test/test_file2k.py832
-rw-r--r--Lib/test/test_file_eintr.py11
-rw-r--r--Lib/test/test_filecmp.py42
-rw-r--r--Lib/test/test_fileinput.py97
-rw-r--r--Lib/test/test_fileio.py58
-rw-r--r--Lib/test/test_float.py380
-rw-r--r--Lib/test/test_flufl.py27
-rw-r--r--Lib/test/test_fnmatch.py47
-rw-r--r--Lib/test/test_fork1.py48
-rw-r--r--Lib/test/test_format.py374
-rw-r--r--Lib/test/test_fpformat.py76
-rw-r--r--Lib/test/test_fractions.py75
-rw-r--r--Lib/test/test_frozen.py40
-rw-r--r--Lib/test/test_ftplib.py255
-rw-r--r--Lib/test/test_funcattrs.py236
-rw-r--r--Lib/test/test_functools.py301
-rw-r--r--Lib/test/test_future.py34
-rw-r--r--Lib/test/test_future2.py2
-rw-r--r--Lib/test/test_future3.py4
-rw-r--r--Lib/test/test_future4.py41
-rw-r--r--Lib/test/test_future5.py8
-rw-r--r--Lib/test/test_future_builtins.py38
-rw-r--r--Lib/test/test_gc.py118
-rw-r--r--Lib/test/test_gdb.py305
-rw-r--r--Lib/test/test_gdbm.py82
-rw-r--r--Lib/test/test_generators.py369
-rw-r--r--Lib/test/test_genericpath.py168
-rw-r--r--Lib/test/test_genexps.py76
-rw-r--r--Lib/test/test_getargs.py31
-rw-r--r--Lib/test/test_getargs2.py214
-rw-r--r--Lib/test/test_getopt.py2
-rw-r--r--Lib/test/test_gettext.py74
-rwxr-xr-xLib/test/test_gl.py155
-rw-r--r--Lib/test/test_glob.py61
-rw-r--r--Lib/test/test_global.py15
-rw-r--r--Lib/test/test_grammar.py338
-rw-r--r--Lib/test/test_grp.py14
-rw-r--r--Lib/test/test_gzip.py146
-rw-r--r--Lib/test/test_hash.py106
-rw-r--r--Lib/test/test_hashlib.py201
-rw-r--r--Lib/test/test_heapq.py70
-rw-r--r--Lib/test/test_hmac.py134
-rw-r--r--Lib/test/test_hotshot.py158
-rw-r--r--Lib/test/test_html.py24
-rw-r--r--Lib/test/test_htmllib.py69
-rw-r--r--Lib/test/test_htmlparser.py520
-rw-r--r--Lib/test/test_http_cookiejar.py1661
-rw-r--r--Lib/test/test_http_cookies.py187
-rw-r--r--Lib/test/test_httplib.py510
-rw-r--r--Lib/test/test_httpservers.py404
-rwxr-xr-xLib/test/test_imageop.py211
-rw-r--r--Lib/test/test_imaplib.py139
-rwxr-xr-xLib/test/test_imgfile.py119
-rw-r--r--Lib/test/test_imp.py292
-rw-r--r--Lib/test/test_import.py519
-rw-r--r--Lib/test/test_importhooks.py42
-rw-r--r--Lib/test/test_importlib.py173
-rw-r--r--Lib/test/test_index.py119
-rw-r--r--Lib/test/test_inspect.py712
-rw-r--r--Lib/test/test_int.py370
-rw-r--r--Lib/test/test_int_literal.py117
-rw-r--r--Lib/test/test_io.py349
-rw-r--r--Lib/test/test_ioctl.py16
-rw-r--r--Lib/test/test_isinstance.py28
-rw-r--r--Lib/test/test_iter.py212
-rw-r--r--Lib/test/test_iterlen.py66
-rw-r--r--Lib/test/test_itertools.py691
-rw-r--r--Lib/test/test_json.py6
-rw-r--r--Lib/test/test_keywordonlyarg.py183
-rw-r--r--Lib/test/test_kqueue.py29
-rw-r--r--Lib/test/test_largefile.py16
-rw-r--r--Lib/test/test_lib2to3.py9
-rw-r--r--Lib/test/test_linecache.py12
-rw-r--r--Lib/test/test_linuxaudiodev.py99
-rw-r--r--Lib/test/test_list.py37
-rw-r--r--Lib/test/test_listcomps.py148
-rw-r--r--Lib/test/test_locale.py93
-rw-r--r--Lib/test/test_logging.py682
-rw-r--r--Lib/test/test_long.py1278
-rw-r--r--Lib/test/test_long_future.py221
-rw-r--r--Lib/test/test_longexp.py4
-rw-r--r--Lib/test/test_macos.py98
-rw-r--r--Lib/test/test_macostools.py88
-rw-r--r--Lib/test/test_macpath.py82
-rw-r--r--Lib/test/test_mailbox.py590
-rw-r--r--Lib/test/test_marshal.py240
-rw-r--r--Lib/test/test_math.py183
-rw-r--r--Lib/test/test_md5.py61
-rw-r--r--Lib/test/test_memoryio.py84
-rw-r--r--Lib/test/test_memoryview.py161
-rw-r--r--Lib/test/test_metaclass.py257
-rw-r--r--Lib/test/test_mhlib.py348
-rw-r--r--Lib/test/test_mimetools.py53
-rw-r--r--Lib/test/test_mimetypes.py24
-rw-r--r--Lib/test/test_minidom.py75
-rw-r--r--Lib/test/test_mmap.py523
-rw-r--r--Lib/test/test_module.py10
-rw-r--r--Lib/test/test_modulefinder.py29
-rw-r--r--Lib/test/test_msilib.py2
-rw-r--r--Lib/test/test_multibytecodec.py235
-rw-r--r--Lib/test/test_multibytecodec_support.py161
-rw-r--r--Lib/test/test_multifile.py67
-rw-r--r--Lib/test/test_multiprocessing.py327
-rw-r--r--Lib/test/test_mutants.py39
-rw-r--r--Lib/test/test_mutex.py35
-rw-r--r--Lib/test/test_netrc.py6
-rw-r--r--Lib/test/test_new.py163
-rw-r--r--Lib/test/test_nis.py15
-rw-r--r--Lib/test/test_nntplib.py1389
-rw-r--r--Lib/test/test_normalization.py14
-rw-r--r--Lib/test/test_ntpath.py98
-rw-r--r--Lib/test/test_numeric_tower.py206
-rw-r--r--Lib/test/test_old_mailbox.py160
-rw-r--r--Lib/test/test_opcodes.py35
-rw-r--r--Lib/test/test_openpty.py8
-rw-r--r--Lib/test/test_operator.py156
-rw-r--r--Lib/test/test_optparse.py89
-rw-r--r--Lib/test/test_os.py906
-rw-r--r--Lib/test/test_ossaudiodev.py34
-rw-r--r--Lib/test/test_osx_env.py36
-rw-r--r--Lib/test/test_parser.py243
-rw-r--r--Lib/test/test_pdb.py550
-rw-r--r--Lib/test/test_peepholer.py143
-rw-r--r--Lib/test/test_pep247.py62
-rw-r--r--Lib/test/test_pep263.py38
-rw-r--r--Lib/test/test_pep277.py88
-rw-r--r--Lib/test/test_pep292.py55
-rw-r--r--Lib/test/test_pep3120.py47
-rw-r--r--Lib/test/test_pep3131.py40
-rw-r--r--Lib/test/test_pep352.py136
-rw-r--r--Lib/test/test_pickle.py121
-rw-r--r--Lib/test/test_pickletools.py17
-rw-r--r--Lib/test/test_pipes.py15
-rw-r--r--Lib/test/test_pkg.py76
-rw-r--r--Lib/test/test_pkgimport.py41
-rw-r--r--Lib/test/test_pkgutil.py105
-rw-r--r--Lib/test/test_platform.py57
-rw-r--r--Lib/test/test_plistlib.py90
-rw-r--r--Lib/test/test_poll.py12
-rw-r--r--Lib/test/test_popen.py27
-rw-r--r--Lib/test/test_popen2.py130
-rw-r--r--Lib/test/test_poplib.py96
-rw-r--r--Lib/test/test_posix.py207
-rw-r--r--Lib/test/test_posixpath.py592
-rw-r--r--Lib/test/test_pow.py32
-rw-r--r--Lib/test/test_pprint.py423
-rw-r--r--Lib/test/test_print.py49
-rw-r--r--Lib/test/test_profile.py148
-rw-r--r--Lib/test/test_property.py2
-rw-r--r--Lib/test/test_pstats.py23
-rw-r--r--Lib/test/test_pty.py42
-rw-r--r--Lib/test/test_pwd.py22
-rw-r--r--Lib/test/test_py3kwarn.py426
-rw-r--r--Lib/test/test_py_compile.py13
-rw-r--r--Lib/test/test_pyclbr.py71
-rw-r--r--Lib/test/test_pydoc.py290
-rw-r--r--Lib/test/test_pyexpat.py252
-rw-r--r--Lib/test/test_queue.py122
-rw-r--r--Lib/test/test_quopri.py91
-rw-r--r--Lib/test/test_raise.py383
-rw-r--r--Lib/test/test_random.py227
-rw-r--r--Lib/test/test_range.py524
-rw-r--r--Lib/test/test_re.py300
-rw-r--r--Lib/test/test_readline.py2
-rw-r--r--Lib/test/test_repr.py327
-rw-r--r--Lib/test/test_reprlib.py340
-rw-r--r--Lib/test/test_resource.py20
-rw-r--r--Lib/test/test_rfc822.py257
-rw-r--r--Lib/test/test_richcmp.py50
-rw-r--r--Lib/test/test_rlcompleter.py6
-rw-r--r--Lib/test/test_robotparser.py34
-rw-r--r--Lib/test/test_runpy.py474
-rw-r--r--Lib/test/test_sax.py197
-rw-r--r--Lib/test/test_sched.py81
-rw-r--r--Lib/test/test_scope.py507
-rw-r--r--Lib/test/test_scriptpackages.py51
-rw-r--r--Lib/test/test_select.py18
-rw-r--r--Lib/test/test_set.py231
-rw-r--r--Lib/test/test_setcomps.py22
-rw-r--r--Lib/test/test_sets.py862
-rw-r--r--Lib/test/test_sgmllib.py439
-rw-r--r--Lib/test/test_sha.py56
-rw-r--r--Lib/test/test_shelve.py118
-rw-r--r--Lib/test/test_shlex.py17
-rw-r--r--Lib/test/test_shutil.py443
-rw-r--r--Lib/test/test_signal.py333
-rw-r--r--Lib/test/test_site.py129
-rw-r--r--Lib/test/test_slice.py31
-rw-r--r--Lib/test/test_smtpd.py291
-rw-r--r--Lib/test/test_smtplib.py375
-rw-r--r--Lib/test/test_smtpnet.py16
-rw-r--r--Lib/test/test_sndhdr.py23
-rw-r--r--Lib/test/test_socket.py1085
-rw-r--r--Lib/test/test_socketserver.py102
-rw-r--r--Lib/test/test_softspace.py23
-rw-r--r--Lib/test/test_sort.py153
-rw-r--r--Lib/test/test_sqlite.py21
-rw-r--r--Lib/test/test_ssl.py1393
-rw-r--r--Lib/test/test_startfile.py30
-rw-r--r--Lib/test/test_str.py461
-rw-r--r--Lib/test/test_strftime.py48
-rw-r--r--Lib/test/test_string.py136
-rw-r--r--Lib/test/test_stringprep.py80
-rw-r--r--Lib/test/test_strlit.py150
-rw-r--r--Lib/test/test_strop.py153
-rw-r--r--Lib/test/test_strptime.py10
-rw-r--r--Lib/test/test_strtod.py34
-rw-r--r--Lib/test/test_struct.py350
-rw-r--r--Lib/test/test_structmembers.py61
-rw-r--r--Lib/test/test_structseq.py27
-rw-r--r--Lib/test/test_subprocess.py1222
-rw-r--r--Lib/test/test_sunau.py70
-rw-r--r--Lib/test/test_sunaudiodev.py33
-rw-r--r--Lib/test/test_sundry.py40
-rw-r--r--Lib/test/test_super.py90
-rw-r--r--Lib/test/test_support.py1333
-rw-r--r--Lib/test/test_symtable.py16
-rw-r--r--Lib/test/test_syntax.py201
-rw-r--r--Lib/test/test_sys.py515
-rw-r--r--Lib/test/test_sys_setprofile.py34
-rw-r--r--Lib/test/test_sys_settrace.py61
-rw-r--r--Lib/test/test_sysconfig.py96
-rw-r--r--Lib/test/test_syslog.py39
-rw-r--r--Lib/test/test_tarfile.py1224
-rw-r--r--Lib/test/test_tcl.py28
-rw-r--r--Lib/test/test_telnetlib.py566
-rw-r--r--Lib/test/test_tempfile.py325
-rw-r--r--Lib/test/test_textwrap.py40
-rw-r--r--Lib/test/test_thread.py31
-rw-r--r--Lib/test/test_threaded_import.py256
-rw-r--r--Lib/test/test_threadedtempfile.py8
-rw-r--r--Lib/test/test_threading.py319
-rw-r--r--Lib/test/test_threading_local.py67
-rw-r--r--Lib/test/test_threadsignals.py156
-rw-r--r--Lib/test/test_time.py242
-rw-r--r--Lib/test/test_timeit.py306
-rw-r--r--Lib/test/test_timeout.py244
-rw-r--r--Lib/test/test_tk.py29
-rw-r--r--Lib/test/test_tokenize.py589
-rw-r--r--Lib/test/test_tools.py75
-rw-r--r--Lib/test/test_trace.py23
-rw-r--r--Lib/test/test_traceback.py352
-rw-r--r--Lib/test/test_transformer.py38
-rw-r--r--Lib/test/test_ttk_guionly.py38
-rw-r--r--Lib/test/test_ttk_textonly.py13
-rw-r--r--Lib/test/test_tuple.py46
-rw-r--r--Lib/test/test_typechecks.py29
-rw-r--r--Lib/test/test_types.py312
-rw-r--r--Lib/test/test_ucn.py82
-rw-r--r--Lib/test/test_unary.py35
-rw-r--r--Lib/test/test_undocumented_details.py39
-rw-r--r--Lib/test/test_unicode.py2355
-rw-r--r--Lib/test/test_unicode_file.py95
-rw-r--r--Lib/test/test_unicodedata.py246
-rw-r--r--Lib/test/test_unittest.py10
-rw-r--r--Lib/test/test_univnewlines.py19
-rw-r--r--Lib/test/test_univnewlines2k.py130
-rw-r--r--Lib/test/test_unpack.py14
-rw-r--r--Lib/test/test_unpack_ex.py174
-rw-r--r--Lib/test/test_urllib.py833
-rw-r--r--Lib/test/test_urllib2.py434
-rw-r--r--Lib/test/test_urllib2_localnet.py361
-rw-r--r--Lib/test/test_urllib2net.py179
-rw-r--r--Lib/test/test_urllib_response.py42
-rw-r--r--Lib/test/test_urllibnet.py192
-rwxr-xr-x[-rw-r--r--]Lib/test/test_urlparse.py528
-rw-r--r--Lib/test/test_userdict.py242
-rw-r--r--Lib/test/test_userlist.py16
-rwxr-xr-xLib/test/test_userstring.py108
-rw-r--r--Lib/test/test_uu.py154
-rw-r--r--Lib/test/test_uuid.py173
-rw-r--r--Lib/test/test_wait3.py6
-rw-r--r--Lib/test/test_wait4.py2
-rw-r--r--Lib/test/test_warnings.py112
-rw-r--r--Lib/test/test_wave.py29
-rw-r--r--Lib/test/test_weakref.py299
-rw-r--r--Lib/test/test_weakset.py52
-rw-r--r--Lib/test/test_whichdb.py68
-rw-r--r--Lib/test/test_winreg.py111
-rw-r--r--Lib/test/test_winsound.py30
-rw-r--r--Lib/test/test_with.py48
-rw-r--r--Lib/test/test_wsgiref.py149
-rw-r--r--Lib/test/test_xdrlib.py14
-rw-r--r--Lib/test/test_xml_etree.py304
-rw-r--r--Lib/test/test_xml_etree_c.py32
-rw-r--r--Lib/test/test_xmllib.py48
-rw-r--r--Lib/test/test_xmlrpc.py478
-rw-r--r--Lib/test/test_xmlrpc_net.py61
-rw-r--r--Lib/test/test_xpickle.py264
-rw-r--r--Lib/test/test_xrange.py218
-rw-r--r--Lib/test/test_zipfile.py548
-rw-r--r--Lib/test/test_zipfile64.py36
-rw-r--r--Lib/test/test_zipimport.py100
-rw-r--r--Lib/test/test_zipimport_support.py209
-rw-r--r--Lib/test/test_zlib.py298
-rw-r--r--Lib/test/testall.py10
-rw-r--r--Lib/test/testcodec.py6
-rw-r--r--Lib/test/testimg.uue1170
-rw-r--r--Lib/test/testimgr.uue1170
-rw-r--r--Lib/test/testrgb.uue971
-rw-r--r--Lib/test/testtar.tarbin281600 -> 435200 bytes-rw-r--r--Lib/test/tf_inherit_check.py4
-rw-r--r--Lib/test/threaded_import_hangers.py2
-rw-r--r--Lib/test/time_hashlib.py52
-rw-r--r--Lib/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt13
-rw-r--r--Lib/test/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt11
-rw-r--r--Lib/test/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt13
-rw-r--r--Lib/test/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt12
-rw-r--r--Lib/test/tokenize_tests.txt57
-rw-r--r--Lib/test/win_console_handler.py4
-rw-r--r--Lib/test/wrongcert.pem32
-rw-r--r--Lib/test/xmltests.py5
-rw-r--r--Lib/test/zip_cp437_header.zipbin0 -> 270 bytes-rw-r--r--Lib/textwrap.py60
-rw-r--r--Lib/this.py2
-rw-r--r--Lib/threading.py776
-rw-r--r--Lib/timeit.py48
-rw-r--r--Lib/tkinter/__init__.py3743
-rw-r--r--Lib/tkinter/__main__.py7
-rw-r--r--Lib/tkinter/_fix.py78
-rw-r--r--Lib/tkinter/colorchooser.py72
-rw-r--r--Lib/tkinter/commondialog.py60
-rw-r--r--Lib/tkinter/constants.py (renamed from Lib/lib-tk/Tkconstants.py)0
-rw-r--r--Lib/tkinter/dialog.py49
-rw-r--r--Lib/tkinter/dnd.py321
-rw-r--r--Lib/tkinter/filedialog.py481
-rw-r--r--Lib/tkinter/font.py217
-rw-r--r--Lib/tkinter/messagebox.py134
-rw-r--r--Lib/tkinter/scrolledtext.py54
-rw-r--r--Lib/tkinter/simpledialog.py423
-rw-r--r--Lib/tkinter/test/README (renamed from Lib/lib-tk/test/README)0
-rw-r--r--Lib/tkinter/test/__init__.py (renamed from Lib/lib-tk/test/test_tkinter/__init__.py)0
-rw-r--r--Lib/tkinter/test/runtktests.py72
-rw-r--r--Lib/tkinter/test/support.py79
-rw-r--r--Lib/tkinter/test/test_tkinter/__init__.py (renamed from Lib/bsddb/test/__init__.py)0
-rw-r--r--Lib/tkinter/test/test_tkinter/test_font.py33
-rw-r--r--Lib/tkinter/test/test_tkinter/test_loadtk.py46
-rw-r--r--Lib/tkinter/test/test_tkinter/test_text.py39
-rw-r--r--Lib/tkinter/test/test_ttk/__init__.py0
-rw-r--r--Lib/tkinter/test/test_ttk/test_extensions.py274
-rw-r--r--Lib/tkinter/test/test_ttk/test_functions.py423
-rw-r--r--Lib/tkinter/test/test_ttk/test_style.py91
-rw-r--r--Lib/tkinter/test/test_ttk/test_widgets.py1151
-rw-r--r--Lib/tkinter/tix.py1964
-rw-r--r--Lib/tkinter/ttk.py1635
-rw-r--r--Lib/toaiff.py110
-rwxr-xr-xLib/token.py86
-rw-r--r--Lib/tokenize.py383
-rw-r--r--Lib/trace.py276
-rw-r--r--Lib/traceback.py165
-rw-r--r--Lib/turtle.py4133
-rw-r--r--Lib/turtledemo/__init__.py0
-rwxr-xr-xLib/turtledemo/__main__.py266
-rw-r--r--Lib/turtledemo/about_turtle.txt76
-rw-r--r--Lib/turtledemo/about_turtledemo.txt13
-rw-r--r--Lib/turtledemo/bytedesign.py162
-rw-r--r--Lib/turtledemo/chaos.py (renamed from Demo/turtle/tdemo_chaos.py)0
-rw-r--r--Lib/turtledemo/clock.py132
-rw-r--r--Lib/turtledemo/colormixer.py60
-rw-r--r--Lib/turtledemo/demohelp.txt70
-rw-r--r--Lib/turtledemo/forest.py109
-rw-r--r--Lib/turtledemo/fractalcurves.py138
-rw-r--r--Lib/turtledemo/lindenmayer.py119
-rw-r--r--Lib/turtledemo/minimal_hanoi.py76
-rw-r--r--Lib/turtledemo/nim.py226
-rw-r--r--Lib/turtledemo/paint.py50
-rw-r--r--Lib/turtledemo/peace.py65
-rw-r--r--Lib/turtledemo/penrose.py181
-rw-r--r--Lib/turtledemo/planet_and_moon.py113
-rw-r--r--Lib/turtledemo/round_dance.py86
-rw-r--r--Lib/turtledemo/tree.py63
-rw-r--r--Lib/turtledemo/turtle.cfg (renamed from Demo/turtle/turtle.cfg)0
-rw-r--r--Lib/turtledemo/two_canvases.py52
-rw-r--r--Lib/turtledemo/wikipedia.py65
-rw-r--r--Lib/turtledemo/yinyang.py49
-rw-r--r--Lib/types.py61
-rw-r--r--Lib/unittest/case.py531
-rw-r--r--Lib/unittest/loader.py57
-rw-r--r--Lib/unittest/main.py119
-rw-r--r--Lib/unittest/result.py7
-rw-r--r--Lib/unittest/runner.py45
-rw-r--r--Lib/unittest/suite.py12
-rw-r--r--Lib/unittest/test/_test_warnings.py74
-rw-r--r--Lib/unittest/test/support.py45
-rw-r--r--Lib/unittest/test/test_assertions.py46
-rw-r--r--Lib/unittest/test/test_break.py12
-rw-r--r--Lib/unittest/test/test_case.py522
-rw-r--r--Lib/unittest/test/test_discovery.py69
-rw-r--r--Lib/unittest/test/test_functiontestcase.py14
-rw-r--r--Lib/unittest/test/test_loader.py58
-rw-r--r--Lib/unittest/test/test_program.py115
-rw-r--r--Lib/unittest/test/test_result.py45
-rw-r--r--Lib/unittest/test/test_runner.py123
-rw-r--r--Lib/unittest/test/test_setups.py7
-rw-r--r--Lib/unittest/test/test_skipping.py21
-rw-r--r--Lib/unittest/test/test_suite.py15
-rw-r--r--Lib/unittest/util.py30
-rw-r--r--Lib/urllib.py1602
-rw-r--r--Lib/urllib/__init__.py0
-rw-r--r--Lib/urllib/error.py69
-rw-r--r--Lib/urllib/parse.py983
-rw-r--r--Lib/urllib/request.py2484
-rw-r--r--Lib/urllib/response.py96
-rw-r--r--Lib/urllib/robotparser.py204
-rw-r--r--Lib/urllib2.py1470
-rw-r--r--Lib/urlparse.py403
-rw-r--r--Lib/user.py48
-rwxr-xr-xLib/uu.py61
-rw-r--r--Lib/uuid.py225
-rw-r--r--Lib/warnings.py53
-rw-r--r--Lib/wave.py94
-rw-r--r--Lib/weakref.py218
-rw-r--r--Lib/webbrowser.py38
-rw-r--r--Lib/whichdb.py117
-rw-r--r--Lib/wsgiref/handlers.py181
-rw-r--r--Lib/wsgiref/headers.py39
-rw-r--r--Lib/wsgiref/simple_server.py39
-rw-r--r--Lib/wsgiref/util.py12
-rw-r--r--Lib/wsgiref/validate.py59
-rw-r--r--Lib/xdrlib.py41
-rw-r--r--Lib/xml/__init__.py21
-rw-r--r--Lib/xml/dom/NodeFilter.py2
-rw-r--r--Lib/xml/dom/__init__.py2
-rw-r--r--Lib/xml/dom/domreg.py10
-rw-r--r--Lib/xml/dom/expatbuilder.py12
-rw-r--r--Lib/xml/dom/minicompat.py9
-rw-r--r--Lib/xml/dom/minidom.py91
-rw-r--r--Lib/xml/dom/pulldom.py17
-rw-r--r--Lib/xml/dom/xmlbuilder.py14
-rw-r--r--Lib/xml/etree/ElementInclude.py9
-rw-r--r--Lib/xml/etree/ElementPath.py6
-rw-r--r--Lib/xml/etree/ElementTree.py233
-rw-r--r--Lib/xml/parsers/expat.py8
-rw-r--r--Lib/xml/sax/__init__.py15
-rw-r--r--Lib/xml/sax/expatreader.py5
-rw-r--r--Lib/xml/sax/handler.py2
-rw-r--r--Lib/xml/sax/saxutils.py61
-rw-r--r--Lib/xml/sax/xmlreader.py35
-rw-r--r--Lib/xmllib.py930
-rw-r--r--Lib/xmlrpc/__init__.py1
-rw-r--r--Lib/xmlrpc/client.py1463
-rw-r--r--Lib/xmlrpc/server.py966
-rw-r--r--Lib/xmlrpclib.py1639
-rw-r--r--Lib/zipfile.py395
-rw-r--r--Mac/BuildScript/resources/ReadMe.txt2
-rw-r--r--Mac/BuildScript/resources/Welcome.rtf6
-rwxr-xr-xMac/BuildScript/scripts/postflight.framework4
-rwxr-xr-xMac/BuildScript/scripts/postflight.patch-profile2
-rw-r--r--Mac/Demo/PICTbrowse/ICONbrowse.py161
-rw-r--r--Mac/Demo/PICTbrowse/PICTbrowse.py140
-rw-r--r--Mac/Demo/PICTbrowse/PICTbrowse.rsrcbin785 -> 0 bytes-rw-r--r--Mac/Demo/PICTbrowse/PICTbrowse2.py162
-rw-r--r--Mac/Demo/PICTbrowse/cicnbrowse.py161
-rw-r--r--Mac/Demo/PICTbrowse/oldPICTbrowse.py158
-rw-r--r--Mac/Demo/PICTbrowse/oldPICTbrowse.rsrcbin502 -> 0 bytes-rw-r--r--Mac/Demo/applescript.html362
-rw-r--r--Mac/Demo/applescript/Disk_Copy/Special_Events.py424
-rw-r--r--Mac/Demo/applescript/Disk_Copy/Standard_Suite.py477
-rw-r--r--Mac/Demo/applescript/Disk_Copy/Utility_Events.py213
-rw-r--r--Mac/Demo/applescript/Disk_Copy/__init__.py35
-rw-r--r--Mac/Demo/applescript/makedisk.py15
-rw-r--r--Mac/Demo/example0.html75
-rw-r--r--Mac/Demo/example0/checktext.py35
-rw-r--r--Mac/Demo/example1.html193
-rw-r--r--Mac/Demo/example1/dnslookup-1.gifbin2570 -> 0 bytes-rw-r--r--Mac/Demo/example1/dnslookup-1.py55
-rw-r--r--Mac/Demo/example1/dnslookup-1.rsrcbin604 -> 0 bytes-rw-r--r--Mac/Demo/example2.html162
-rw-r--r--Mac/Demo/example2/dnslookup-2.gifbin2984 -> 0 bytes-rw-r--r--Mac/Demo/example2/dnslookup-2.py85
-rw-r--r--Mac/Demo/example2/dnslookup-2.rsrcbin707 -> 0 bytes-rw-r--r--Mac/Demo/html.icons/createmake.pngbin14212 -> 0 bytes-rw-r--r--Mac/Demo/html.icons/mkapplet.gifbin1010 -> 0 bytes-rw-r--r--Mac/Demo/html.icons/options.gifbin4231 -> 0 bytes-rw-r--r--Mac/Demo/html.icons/preferences.gifbin5344 -> 0 bytes-rw-r--r--Mac/Demo/html.icons/python.gifbin1004 -> 0 bytes-rw-r--r--Mac/Demo/imgbrowse/imgbrowse.py115
-rw-r--r--Mac/Demo/imgbrowse/mac_image.py55
-rw-r--r--Mac/Demo/index.html156
-rw-r--r--Mac/Demo/mlte/mlted.py374
-rw-r--r--Mac/Demo/quicktime/MovieInWindow.py70
-rw-r--r--Mac/Demo/quicktime/VerySimplePlayer.py92
-rw-r--r--Mac/Demo/resources/copyres.py57
-rw-r--r--Mac/Demo/resources/listres.py60
-rw-r--r--Mac/Demo/sound/morse.py180
-rw-r--r--Mac/Demo/sound/morselib.py188
-rw-r--r--Mac/Demo/sound/playaiff.py45
-rw-r--r--Mac/Demo/textedit.html150
-rw-r--r--Mac/Demo/textedit/ped.py359
-rw-r--r--Mac/Extras.ReadMe.txt5
-rw-r--r--Mac/Extras.install.py8
-rw-r--r--Mac/IDLE/IDLE.app/Contents/Info.plist57
-rwxr-xr-xMac/IDLE/IDLE.app/Contents/MacOS/IDLE23
-rw-r--r--Mac/IDLE/IDLE.app/Contents/PkgInfo1
-rw-r--r--Mac/IDLE/IDLE.app/Contents/Resources/IDLE.icnsbin0 -> 53456 bytes-rw-r--r--Mac/IDLE/IDLE.app/Contents/Resources/PythonCompiled.icnsbin0 -> 60777 bytes-rw-r--r--Mac/IDLE/IDLE.app/Contents/Resources/PythonSource.icnsbin0 -> 54522 bytes-rw-r--r--Mac/IDLE/IDLE.app/Contents/Resources/idlemain.py73
-rw-r--r--Mac/IDLE/Info.plist.in64
-rw-r--r--Mac/IDLE/Makefile.in65
-rw-r--r--Mac/IDLE/config-extensions.def93
-rw-r--r--Mac/IDLE/config-main.def79
-rw-r--r--Mac/IDLE/idlemain.py75
-rw-r--r--Mac/Makefile.in169
-rw-r--r--Mac/Modules/ColorPickermodule.c90
-rw-r--r--Mac/Modules/MacOS.c739
-rw-r--r--Mac/Modules/Nav.c967
-rw-r--r--Mac/Modules/OSATerminology.c102
-rw-r--r--Mac/Modules/_scproxy.c231
-rw-r--r--Mac/Modules/ae/README24
-rw-r--r--Mac/Modules/ae/_AEmodule.c1459
-rw-r--r--Mac/Modules/ae/aescan.py97
-rw-r--r--Mac/Modules/ae/aesupport.py237
-rw-r--r--Mac/Modules/ah/_AHmodule.c144
-rw-r--r--Mac/Modules/ah/ahscan.py51
-rw-r--r--Mac/Modules/ah/ahsupport.py45
-rw-r--r--Mac/Modules/app/_Appmodule.c1832
-rw-r--r--Mac/Modules/app/appscan.py80
-rw-r--r--Mac/Modules/app/appsupport.py133
-rw-r--r--Mac/Modules/autoGIL.c152
-rw-r--r--Mac/Modules/carbonevt/CarbonEvtscan.py115
-rw-r--r--Mac/Modules/carbonevt/CarbonEvtsupport.py314
-rwxr-xr-xMac/Modules/carbonevt/_CarbonEvtmodule.c2219
-rw-r--r--Mac/Modules/cf/_CFmodule.c4996
-rw-r--r--Mac/Modules/cf/cfscan.py141
-rw-r--r--Mac/Modules/cf/cfsupport.py666
-rw-r--r--Mac/Modules/cf/pycfbridge.c303
-rw-r--r--Mac/Modules/cf/pycfbridge.h11
-rwxr-xr-xMac/Modules/cg/CFMLateImport.c1360
-rwxr-xr-xMac/Modules/cg/CFMLateImport.h272
-rwxr-xr-xMac/Modules/cg/CGStubLibbin2776 -> 0 bytes-rwxr-xr-xMac/Modules/cg/CGStubLib.exp60
-rwxr-xr-xMac/Modules/cg/CGStubLib.readme3
-rwxr-xr-xMac/Modules/cg/_CGmodule.c1316
-rw-r--r--Mac/Modules/cg/cgscan.py83
-rw-r--r--Mac/Modules/cg/cgsupport.py192
-rw-r--r--Mac/Modules/cm/_Cmmodule.c955
-rw-r--r--Mac/Modules/cm/cmscan.py88
-rw-r--r--Mac/Modules/cm/cmsupport.py125
-rw-r--r--Mac/Modules/ctl/_Ctlmodule.c5815
-rw-r--r--Mac/Modules/ctl/ctledit.py45
-rw-r--r--Mac/Modules/ctl/ctlscan.py171
-rw-r--r--Mac/Modules/ctl/ctlsupport.py826
-rw-r--r--Mac/Modules/dlg/_Dlgmodule.c1609
-rw-r--r--Mac/Modules/dlg/dlgscan.py115
-rw-r--r--Mac/Modules/dlg/dlgsupport.py278
-rw-r--r--Mac/Modules/drag/_Dragmodule.c1158
-rw-r--r--Mac/Modules/drag/dragscan.py79
-rw-r--r--Mac/Modules/drag/dragsupport.py293
-rw-r--r--Mac/Modules/evt/_Evtmodule.c559
-rw-r--r--Mac/Modules/evt/evtedit.py9
-rw-r--r--Mac/Modules/evt/evtscan.py80
-rw-r--r--Mac/Modules/evt/evtsupport.py92
-rw-r--r--Mac/Modules/file/_Filemodule.c3410
-rw-r--r--Mac/Modules/file/filescan.py198
-rw-r--r--Mac/Modules/file/filesupport.py918
-rw-r--r--Mac/Modules/fm/_Fmmodule.c368
-rw-r--r--Mac/Modules/fm/fmscan.py71
-rw-r--r--Mac/Modules/fm/fmsupport.py81
-rw-r--r--Mac/Modules/folder/_Foldermodule.c342
-rw-r--r--Mac/Modules/folder/folderscan.py67
-rw-r--r--Mac/Modules/folder/foldersupport.py56
-rw-r--r--Mac/Modules/gestaltmodule.c55
-rw-r--r--Mac/Modules/help/_Helpmodule.c196
-rw-r--r--Mac/Modules/help/helpscan.py66
-rw-r--r--Mac/Modules/help/helpsupport.py78
-rw-r--r--Mac/Modules/ibcarbon/IBCarbonscan.py47
-rw-r--r--Mac/Modules/ibcarbon/IBCarbonsupport.py51
-rw-r--r--Mac/Modules/ibcarbon/_IBCarbon.c270
-rw-r--r--Mac/Modules/icgluemodule.c478
-rw-r--r--Mac/Modules/icn/_Icnmodule.c1607
-rw-r--r--Mac/Modules/icn/icnscan.py71
-rw-r--r--Mac/Modules/icn/icnsupport.py90
-rw-r--r--Mac/Modules/launch/_Launchmodule.c481
-rw-r--r--Mac/Modules/launch/launchscan.py85
-rw-r--r--Mac/Modules/launch/launchsupport.py101
-rw-r--r--Mac/Modules/launch/setup.py13
-rw-r--r--Mac/Modules/list/_Listmodule.c1140
-rw-r--r--Mac/Modules/list/listscan.py87
-rw-r--r--Mac/Modules/list/listsupport.py255
-rw-r--r--Mac/Modules/menu/_Menumodule.c3477
-rw-r--r--Mac/Modules/menu/menuedit.py123
-rw-r--r--Mac/Modules/menu/menuscan.py96
-rw-r--r--Mac/Modules/menu/menusupport.py108
-rw-r--r--Mac/Modules/mlte/_Mltemodule.c1690
-rw-r--r--Mac/Modules/mlte/mltescan.py142
-rw-r--r--Mac/Modules/mlte/mltesupport.py202
-rw-r--r--Mac/Modules/osa/_OSAmodule.c899
-rw-r--r--Mac/Modules/osa/osascan.py61
-rw-r--r--Mac/Modules/osa/osasupport.py105
-rw-r--r--Mac/Modules/osa/setup.py13
-rw-r--r--Mac/Modules/qd/_Qdmodule.c7154
-rw-r--r--Mac/Modules/qd/qdedit.py158
-rw-r--r--Mac/Modules/qd/qdscan.py234
-rw-r--r--Mac/Modules/qd/qdsupport.py377
-rw-r--r--Mac/Modules/qdoffs/_Qdoffsmodule.c722
-rw-r--r--Mac/Modules/qdoffs/qdoffsscan.py65
-rw-r--r--Mac/Modules/qdoffs/qdoffssupport.py139
-rw-r--r--Mac/Modules/qt/_Qtmodule.c28091
-rw-r--r--Mac/Modules/qt/qtscan.py318
-rw-r--r--Mac/Modules/qt/qtsupport.py382
-rw-r--r--Mac/Modules/qt/setup.py13
-rw-r--r--Mac/Modules/res/_Resmodule.c1760
-rw-r--r--Mac/Modules/res/resedit.py102
-rw-r--r--Mac/Modules/res/resscan.py83
-rw-r--r--Mac/Modules/res/ressupport.py221
-rw-r--r--Mac/Modules/scrap/_Scrapmodule.c365
-rw-r--r--Mac/Modules/scrap/scrapscan.py60
-rw-r--r--Mac/Modules/scrap/scrapsupport.py75
-rw-r--r--Mac/Modules/snd/_Sndihooks.c512
-rw-r--r--Mac/Modules/snd/_Sndmodule.c1163
-rw-r--r--Mac/Modules/snd/sndscan.py127
-rw-r--r--Mac/Modules/snd/sndsupport.py319
-rw-r--r--Mac/Modules/te/_TEmodule.c1339
-rw-r--r--Mac/Modules/te/tescan.py66
-rw-r--r--Mac/Modules/te/tesupport.py216
-rw-r--r--Mac/Modules/win/_Winmodule.c3265
-rw-r--r--Mac/Modules/win/winedit.py69
-rw-r--r--Mac/Modules/win/winscan.py129
-rw-r--r--Mac/Modules/win/winsupport.py226
-rw-r--r--Mac/PythonLauncher/Makefile.in7
-rw-r--r--Mac/README55
-rw-r--r--Mac/Resources/iconsrc/IDE.psdbin0 -> 83876 bytes-rw-r--r--Mac/Resources/iconsrc/PackageManager.psdbin0 -> 71056 bytes-rw-r--r--Mac/Resources/iconsrc/PythonApplet.psdbin0 -> 41543 bytes-rwxr-xr-xMac/Resources/iconsrc/PythonCompiled.psdbin0 -> 76118 bytes-rwxr-xr-xMac/Resources/iconsrc/PythonIcon.psdbin0 -> 67236 bytes-rwxr-xr-xMac/Resources/iconsrc/PythonSource.psdbin0 -> 62075 bytes-rw-r--r--Mac/Resources/iconsrc/PythonWSource.psdbin0 -> 64185 bytes-rw-r--r--Mac/Tools/Doc/HelpIndexingTool/Help_Indexing_Tool_Suite.py110
-rw-r--r--Mac/Tools/Doc/HelpIndexingTool/Miscellaneous_Standards.py49
-rw-r--r--Mac/Tools/Doc/HelpIndexingTool/Required_Suite.py32
-rw-r--r--Mac/Tools/Doc/HelpIndexingTool/Standard_Suite.py343
-rw-r--r--Mac/Tools/Doc/HelpIndexingTool/__init__.py78
-rw-r--r--Mac/Tools/Doc/HelpIndexingTool/odds_and_ends.py49
-rw-r--r--Mac/Tools/Doc/README35
-rw-r--r--Mac/Tools/Doc/setup.py213
-rw-r--r--Mac/Tools/bundlebuilder.py934
-rw-r--r--Mac/Tools/fixapplepython23.py35
-rw-r--r--Mac/Tools/pythonw.c4
-rw-r--r--Mac/scripts/BuildApplet.icnsbin120107 -> 0 bytes-rw-r--r--Mac/scripts/BuildApplet.plist55
-rw-r--r--Mac/scripts/BuildApplet.py156
-rw-r--r--Mac/scripts/BuildApplet.rsrcbin3169 -> 0 bytes-rw-r--r--Mac/scripts/bgenall.py56
-rw-r--r--Mac/scripts/buildpkg.py484
-rw-r--r--Mac/scripts/cachersrc.py44
-rw-r--r--Mac/scripts/errors.txt1852
-rw-r--r--Mac/scripts/genallsuites.py52
-rw-r--r--Mac/scripts/mkestrres-errno.h7
-rwxr-xr-xMac/scripts/mkestrres-macerrors.h13
-rw-r--r--Mac/scripts/mkestrres.py157
-rw-r--r--Mac/scripts/zappycfiles.py29
-rw-r--r--Makefile.pre.in381
-rw-r--r--Misc/ACKS127
-rw-r--r--Misc/BeOS-NOTES43
-rw-r--r--Misc/BeOS-setup.py574
-rw-r--r--Misc/HISTORY1403
-rw-r--r--Misc/NEWS10439
-rw-r--r--Misc/README17
-rw-r--r--Misc/README.Emacs32
-rw-r--r--Misc/README.OpenBSD38
-rw-r--r--Misc/README.klocwork30
-rw-r--r--Misc/RFD114
-rw-r--r--Misc/RPM/README27
-rw-r--r--Misc/RPM/python-2.7.spec390
-rw-r--r--Misc/RPM/python-3.2.spec390
-rw-r--r--Misc/Vim/python.vim43
-rw-r--r--Misc/Vim/vim_syntax.py10
-rw-r--r--Misc/Vim/vimrc2
-rw-r--r--Misc/cheatsheet2273
-rw-r--r--Misc/developers.txt346
-rw-r--r--Misc/gdbinit10
-rw-r--r--Misc/maintainers.rst319
-rw-r--r--Misc/pymemcompat.h85
-rw-r--r--Misc/python-config.in35
-rw-r--r--Misc/python-wing3.wpr2
-rw-r--r--Misc/python-wing4.wpr6
-rw-r--r--Misc/python.man38
-rw-r--r--Misc/python.pc.in6
-rw-r--r--Misc/setuid-prog.c176
-rw-r--r--Misc/valgrind-python.supp2
-rw-r--r--Misc/vgrindefs2
-rw-r--r--Modules/Setup.config.in2
-rw-r--r--Modules/Setup.dist154
-rw-r--r--Modules/_bisectmodule.c41
-rw-r--r--Modules/_bsddb.c10026
-rw-r--r--Modules/_codecsmodule.c161
-rw-r--r--Modules/_collectionsmodule.c273
-rw-r--r--Modules/_csv.c301
-rw-r--r--Modules/_ctypes/_ctypes.c905
-rw-r--r--Modules/_ctypes/_ctypes_test.c36
-rw-r--r--Modules/_ctypes/callbacks.c75
-rw-r--r--Modules/_ctypes/callproc.c233
-rw-r--r--Modules/_ctypes/cfield.c241
-rw-r--r--Modules/_ctypes/ctypes.h119
-rw-r--r--Modules/_ctypes/libffi_msvc/ffi.c2
-rw-r--r--Modules/_ctypes/malloc_closure.c4
-rw-r--r--Modules/_ctypes/stgdict.c18
-rw-r--r--Modules/_curses_panel.c51
-rw-r--r--Modules/_cursesmodule.c245
-rw-r--r--Modules/_datetimemodule.c5472
-rw-r--r--Modules/_dbmmodule.c437
-rw-r--r--Modules/_elementtree.c373
-rw-r--r--Modules/_functoolsmodule.c234
-rw-r--r--Modules/_gdbmmodule.c593
-rw-r--r--Modules/_gestalt.c84
-rw-r--r--Modules/_hashopenssl.c202
-rw-r--r--Modules/_heapqmodule.c71
-rw-r--r--Modules/_hotshot.c1643
-rw-r--r--Modules/_io/_iomodule.c189
-rw-r--r--Modules/_io/_iomodule.h26
-rw-r--r--Modules/_io/bufferedio.c94
-rw-r--r--Modules/_io/bytesio.c184
-rw-r--r--Modules/_io/fileio.c127
-rw-r--r--Modules/_io/iobase.c31
-rw-r--r--Modules/_io/stringio.c50
-rw-r--r--Modules/_io/textio.c252
-rw-r--r--Modules/_json.c1072
-rw-r--r--Modules/_localemodule.c356
-rw-r--r--Modules/_lsprof.c70
-rw-r--r--Modules/_multiprocessing/connection.h26
-rw-r--r--Modules/_multiprocessing/multiprocessing.c49
-rw-r--r--Modules/_multiprocessing/semaphore.c6
-rw-r--r--Modules/_multiprocessing/win32_functions.c2
-rw-r--r--Modules/_pickle.c6425
-rw-r--r--Modules/_posixsubprocess.c804
-rw-r--r--Modules/_randommodule.c114
-rw-r--r--Modules/_scproxy.c261
-rw-r--r--Modules/_sqlite/cache.c10
-rw-r--r--Modules/_sqlite/cache.h2
-rw-r--r--Modules/_sqlite/connection.c222
-rw-r--r--Modules/_sqlite/connection.h11
-rw-r--r--Modules/_sqlite/cursor.c129
-rw-r--r--Modules/_sqlite/cursor.h2
-rw-r--r--Modules/_sqlite/module.c53
-rw-r--r--Modules/_sqlite/module.h2
-rw-r--r--Modules/_sqlite/prepare_protocol.c4
-rw-r--r--Modules/_sqlite/prepare_protocol.h2
-rw-r--r--Modules/_sqlite/row.c21
-rw-r--r--Modules/_sqlite/row.h2
-rw-r--r--Modules/_sqlite/sqlitecompat.h2
-rw-r--r--Modules/_sqlite/statement.c90
-rw-r--r--Modules/_sqlite/statement.h2
-rw-r--r--Modules/_sqlite/util.c2
-rw-r--r--Modules/_sqlite/util.h2
-rw-r--r--Modules/_sre.c272
-rw-r--r--Modules/_ssl.c1269
-rw-r--r--Modules/_struct.c479
-rw-r--r--Modules/_testcapimodule.c861
-rw-r--r--Modules/_testembed.c58
-rw-r--r--Modules/_threadmodule.c1336
-rw-r--r--Modules/_time.c28
-rw-r--r--Modules/_time.h3
-rw-r--r--Modules/_tkinter.c583
-rw-r--r--Modules/_weakref.c23
-rw-r--r--Modules/addrinfo.h2
-rw-r--r--Modules/almodule.c3232
-rw-r--r--Modules/arraymodule.c1260
-rw-r--r--Modules/atexitmodule.c301
-rw-r--r--Modules/audioop.c267
-rw-r--r--Modules/binascii.c173
-rw-r--r--Modules/bsddb.h299
-rw-r--r--Modules/bsddbmodule.c864
-rw-r--r--Modules/bz2module.c522
-rw-r--r--Modules/cPickle.c6023
-rw-r--r--Modules/cStringIO.c760
-rw-r--r--Modules/cdmodule.c800
-rw-r--r--Modules/cgen.py523
-rw-r--r--Modules/cgensupport.c310
-rw-r--r--Modules/cgensupport.h64
-rw-r--r--Modules/cjkcodecs/cjkcodecs.h26
-rw-r--r--Modules/cjkcodecs/multibytecodec.c164
-rw-r--r--Modules/clmodule.c2563
-rw-r--r--Modules/cmathmodule.c34
-rw-r--r--Modules/config.c.in23
-rw-r--r--Modules/cryptmodule.c17
-rw-r--r--Modules/cstubs1364
-rw-r--r--Modules/datetimemodule.c5117
-rw-r--r--Modules/dbmmodule.c417
-rw-r--r--Modules/dlmodule.c284
-rw-r--r--Modules/errnomodule.c78
-rw-r--r--Modules/expat/expat_external.h2
-rw-r--r--Modules/fcntlmodule.c60
-rw-r--r--Modules/flmodule.c2144
-rw-r--r--Modules/fmmodule.c269
-rw-r--r--Modules/fpectlmodule.c22
-rw-r--r--Modules/fpetestmodule.c36
-rw-r--r--Modules/future_builtins.c105
-rw-r--r--Modules/gcmodule.c153
-rw-r--r--Modules/gdbmmodule.c548
-rw-r--r--Modules/getaddrinfo.c10
-rw-r--r--Modules/getnameinfo.c4
-rw-r--r--Modules/getpath.c447
-rw-r--r--Modules/glmodule.c7633
-rw-r--r--Modules/grpmodule.c83
-rw-r--r--Modules/hashlib.h28
-rw-r--r--Modules/imageop.c794
-rw-r--r--Modules/imgfile.c509
-rw-r--r--Modules/itertoolsmodule.c914
-rw-r--r--Modules/ld_so_aix.in4
-rw-r--r--Modules/linuxaudiodev.c505
-rw-r--r--Modules/main.c429
-rwxr-xr-xModules/makesetup10
-rw-r--r--Modules/mathmodule.c471
-rw-r--r--Modules/md5.c394
-rw-r--r--Modules/md5.h91
-rw-r--r--Modules/md5module.c681
-rw-r--r--Modules/mmapmodule.c325
-rw-r--r--Modules/nismodule.c51
-rw-r--r--Modules/operator.c275
-rw-r--r--Modules/ossaudiodev.c163
-rw-r--r--Modules/parsermodule.c1027
-rw-r--r--Modules/posixmodule.c4317
-rw-r--r--Modules/puremodule.c992
-rw-r--r--Modules/pwdmodule.c54
-rw-r--r--Modules/pyexpat.c557
-rw-r--r--Modules/python.c59
-rw-r--r--Modules/readline.c117
-rw-r--r--Modules/resource.c65
-rw-r--r--Modules/selectmodule.c101
-rw-r--r--Modules/sgimodule.c55
-rw-r--r--Modules/sha1module.c560
-rw-r--r--Modules/sha256module.c103
-rw-r--r--Modules/sha512module.c103
-rw-r--r--Modules/shamodule.c623
-rw-r--r--Modules/signalmodule.c126
-rw-r--r--Modules/socketmodule.c995
-rw-r--r--Modules/socketmodule.h67
-rw-r--r--Modules/spwdmodule.c47
-rw-r--r--Modules/sre.h3
-rw-r--r--Modules/stropmodule.c1270
-rw-r--r--Modules/sunaudiodev.c467
-rw-r--r--Modules/svmodule.c970
-rw-r--r--Modules/symtablemodule.c34
-rw-r--r--Modules/syslogmodule.c75
-rw-r--r--Modules/termios.c95
-rw-r--r--Modules/threadmodule.c934
-rw-r--r--Modules/timemodule.c538
-rw-r--r--Modules/timing.h64
-rw-r--r--Modules/timingmodule.c62
-rw-r--r--Modules/unicodedata.c102
-rw-r--r--Modules/unicodedata_db.h4929
-rw-r--r--Modules/unicodename_db.h34126
-rw-r--r--Modules/xxlimited.c287
-rw-r--r--Modules/xxmodule.c65
-rw-r--r--Modules/xxsubtype.c44
-rw-r--r--Modules/yuv.h99
-rw-r--r--Modules/yuvconvert.c118
-rw-r--r--Modules/zipimport.c488
-rw-r--r--Modules/zlib/ChangeLog355
-rw-r--r--Modules/zlib/FAQ261
-rw-r--r--Modules/zlib/INDEX30
-rw-r--r--Modules/zlib/Makefile157
-rw-r--r--Modules/zlib/Makefile.in223
-rw-r--r--Modules/zlib/README86
-rw-r--r--Modules/zlib/adler32.c38
-rw-r--r--Modules/zlib/compress.c5
-rwxr-xr-xModules/zlib/configure345
-rw-r--r--Modules/zlib/crc32.c35
-rw-r--r--Modules/zlib/deflate.c268
-rw-r--r--Modules/zlib/deflate.h35
-rw-r--r--Modules/zlib/example.c4
-rw-r--r--Modules/zlib/gzclose.c25
-rw-r--r--Modules/zlib/gzguts.h132
-rw-r--r--Modules/zlib/gzlib.c537
-rw-r--r--Modules/zlib/gzread.c653
-rw-r--r--Modules/zlib/gzwrite.c531
-rw-r--r--Modules/zlib/infback.c93
-rw-r--r--Modules/zlib/inffast.c80
-rw-r--r--Modules/zlib/inffast.h4
-rw-r--r--Modules/zlib/inflate.c282
-rw-r--r--Modules/zlib/inflate.h31
-rw-r--r--Modules/zlib/inftrees.c63
-rw-r--r--Modules/zlib/inftrees.h27
-rw-r--r--Modules/zlib/make_vms.com479
-rw-r--r--Modules/zlib/minigzip.c134
-rw-r--r--Modules/zlib/trees.c93
-rw-r--r--Modules/zlib/trees.h4
-rw-r--r--Modules/zlib/uncompr.c4
-rw-r--r--Modules/zlib/zconf.h190
-rw-r--r--Modules/zlib/zconf.h.cmakein430
-rw-r--r--Modules/zlib/zconf.h.in428
-rw-r--r--Modules/zlib/zlib.366
-rw-r--r--Modules/zlib/zlib.h1162
-rw-r--r--Modules/zlib/zlib.map68
-rw-r--r--Modules/zlib/zlib.pc.in13
-rw-r--r--Modules/zlib/zutil.c32
-rw-r--r--Modules/zlib/zutil.h63
-rw-r--r--Modules/zlibmodule.c464
-rw-r--r--Objects/abstract.c963
-rw-r--r--Objects/accu.c115
-rw-r--r--Objects/boolobject.c72
-rw-r--r--Objects/bufferobject.c867
-rw-r--r--Objects/bytearrayobject.c376
-rw-r--r--Objects/bytes_methods.c225
-rw-r--r--Objects/bytesobject.c3131
-rw-r--r--Objects/capsule.c38
-rw-r--r--Objects/cellobject.c68
-rw-r--r--Objects/classobject.c2761
-rw-r--r--Objects/cobject.c172
-rw-r--r--Objects/codeobject.c156
-rw-r--r--Objects/complexobject.c376
-rw-r--r--Objects/descrobject.c293
-rw-r--r--Objects/dictobject.c628
-rw-r--r--Objects/enumobject.c38
-rw-r--r--Objects/exceptions.c1135
-rw-r--r--Objects/fileobject.c2817
-rw-r--r--Objects/floatobject.c634
-rw-r--r--Objects/frameobject.c89
-rw-r--r--Objects/funcobject.c221
-rw-r--r--Objects/genobject.c43
-rw-r--r--Objects/intobject.c1567
-rw-r--r--Objects/iterobject.c16
-rw-r--r--Objects/listobject.c805
-rw-r--r--Objects/listsort.txt2
-rw-r--r--Objects/longobject.c1885
-rw-r--r--Objects/memoryobject.c220
-rw-r--r--Objects/methodobject.c145
-rw-r--r--Objects/moduleobject.c244
-rw-r--r--Objects/object.c1279
-rw-r--r--Objects/obmalloc.c2
-rw-r--r--Objects/rangeobject.c1319
-rw-r--r--Objects/setobject.c286
-rw-r--r--Objects/sliceobject.c137
-rw-r--r--Objects/stringlib/eq.h21
-rw-r--r--Objects/stringlib/formatter.h47
-rw-r--r--Objects/stringlib/string_format.h61
-rw-r--r--Objects/stringlib/stringdefs.h22
-rw-r--r--Objects/stringlib/unicodedefs.h3
-rw-r--r--Objects/stringobject.c4839
-rw-r--r--Objects/structseq.c260
-rw-r--r--Objects/tupleobject.c139
-rw-r--r--Objects/typeobject.c1380
-rw-r--r--Objects/typeslots.inc75
-rw-r--r--Objects/typeslots.py30
-rw-r--r--Objects/unicodectype.c129
-rw-r--r--Objects/unicodeobject.c3877
-rw-r--r--Objects/unicodetype_db.h3260
-rw-r--r--Objects/weakrefobject.c86
-rw-r--r--PC/VC6/_bsddb.dsp99
-rw-r--r--PC/VC6/build_ssl.py47
-rw-r--r--PC/VC6/pcbuild.dsw16
-rw-r--r--PC/VC6/pythoncore.dsp100
-rw-r--r--PC/VC6/readme.txt63
-rwxr-xr-xPC/VC6/rt.bat4
-rw-r--r--PC/VC6/select.dsp4
-rw-r--r--PC/VS7.1/_bsddb.vcproj258
-rw-r--r--PC/VS7.1/_elementtree.vcproj4
-rw-r--r--PC/VS7.1/_tkinter.vcproj8
-rw-r--r--PC/VS7.1/make_versioninfo.vcproj2
-rw-r--r--PC/VS7.1/pcbuild.sln13
-rw-r--r--PC/VS7.1/pyexpat.vcproj4
-rw-r--r--PC/VS7.1/python.build1
-rw-r--r--PC/VS7.1/python.iss17
-rw-r--r--PC/VS7.1/python.vcproj4
-rw-r--r--PC/VS7.1/python20.wse34
-rw-r--r--PC/VS7.1/pythoncore.vcproj164
-rw-r--r--PC/VS7.1/readme.txt95
-rwxr-xr-xPC/VS7.1/rt.bat4
-rw-r--r--PC/VS8.0/_bsddb.vcproj1463
-rw-r--r--PC/VS8.0/_bsddb44.vcproj1252
-rw-r--r--PC/VS8.0/_hashlib.vcproj8
-rw-r--r--PC/VS8.0/_ssl.vcproj8
-rw-r--r--PC/VS8.0/build_ssl.bat4
-rw-r--r--PC/VS8.0/build_ssl.py41
-rw-r--r--PC/VS8.0/bz2.vcproj16
-rw-r--r--PC/VS8.0/kill_python.c2
-rw-r--r--PC/VS8.0/make_buildinfo.c42
-rw-r--r--PC/VS8.0/make_buildinfo.vcproj61
-rw-r--r--PC/VS8.0/pcbuild.sln45
-rw-r--r--PC/VS8.0/pyproject.vsprops28
-rw-r--r--PC/VS8.0/pythoncore.vcproj296
-rw-r--r--PC/VS8.0/rt.bat4
-rw-r--r--PC/VS8.0/ssl.vcproj189
-rw-r--r--PC/WinMain.c6
-rw-r--r--PC/_msi.c92
-rw-r--r--PC/_subprocess.c132
-rw-r--r--PC/_winreg.c1866
-rw-r--r--PC/bdist_wininst/install.c49
-rw-r--r--PC/config.c235
-rw-r--r--PC/dllbase_nt.txt2
-rw-r--r--PC/errmap.h2
-rw-r--r--PC/example_nt/example.c26
-rw-r--r--PC/example_nt/example.vcproj4
-rw-r--r--PC/generrmap.c24
-rw-r--r--PC/getpathp.c354
-rwxr-xr-xPC/msvcrtmodule.c154
-rw-r--r--PC/os2emx/Makefile54
-rw-r--r--PC/os2emx/README.os2emx54
-rw-r--r--PC/os2emx/config.c27
-rw-r--r--PC/os2emx/getpathp.c2
-rw-r--r--PC/os2emx/pyconfig.h4
-rw-r--r--PC/os2emx/python27.def262
-rw-r--r--PC/os2vacpp/config.c12
-rw-r--r--PC/os2vacpp/makefile339
-rw-r--r--PC/os2vacpp/makefile.omk236
-rw-r--r--PC/os2vacpp/pyconfig.h3
-rw-r--r--PC/os2vacpp/python.def5
-rw-r--r--PC/pyconfig.h34
-rw-r--r--PC/python.mk10
-rw-r--r--PC/python3.def689
-rw-r--r--PC/python3.mak10
-rw-r--r--PC/python32gen.py25
-rw-r--r--PC/python32stub.def689
-rw-r--r--PC/python3dll.c9
-rw-r--r--PC/python_nt.rc2
-rw-r--r--PC/testpy.py8
-rw-r--r--PC/winreg.c1850
-rw-r--r--PC/winsound.c70
-rw-r--r--PCbuild/_bsddb.vcproj1463
-rw-r--r--PCbuild/_hashlib.vcproj8
-rw-r--r--PCbuild/_ssl.vcproj8
-rw-r--r--PCbuild/build_ssl.bat4
-rw-r--r--PCbuild/build_ssl.py51
-rw-r--r--PCbuild/build_tkinter.py14
-rw-r--r--PCbuild/bz2.vcproj16
-rw-r--r--PCbuild/kill_python.c2
-rw-r--r--PCbuild/make_buildinfo.c57
-rw-r--r--PCbuild/make_buildinfo.vcproj61
-rw-r--r--PCbuild/pcbuild.sln80
-rw-r--r--PCbuild/pyproject.vsprops30
-rw-r--r--PCbuild/python3dll.vcproj246
-rw-r--r--PCbuild/pythoncore.vcproj300
-rw-r--r--PCbuild/readme.txt15
-rw-r--r--PCbuild/rt.bat6
-rw-r--r--PCbuild/ssl.vcproj189
-rw-r--r--PCbuild/vs9to8.py4
-rw-r--r--PCbuild/xxlimited.vcproj417
-rw-r--r--Parser/Python.asdl40
-rw-r--r--Parser/asdl.py119
-rwxr-xr-xParser/asdl_c.py111
-rw-r--r--Parser/grammar.c4
-rw-r--r--Parser/intrcheck.c4
-rw-r--r--Parser/myreadline.c24
-rw-r--r--Parser/parser.c18
-rw-r--r--Parser/parsetok.c84
-rw-r--r--Parser/pgenmain.c2
-rw-r--r--Parser/printgrammar.c2
-rw-r--r--Parser/spark.py86
-rw-r--r--Parser/tokenizer.c719
-rw-r--r--Parser/tokenizer.h23
-rw-r--r--Python/Python-ast.c1264
-rw-r--r--Python/_warnings.c243
-rw-r--r--Python/ast.c1678
-rw-r--r--Python/atof.c50
-rw-r--r--Python/bltinmodule.c2573
-rw-r--r--Python/ceval.c2489
-rw-r--r--Python/ceval_gil.h433
-rw-r--r--Python/codecs.c280
-rw-r--r--Python/compile.c1065
-rw-r--r--Python/dynamic_annotations.c154
-rw-r--r--Python/dynload_atheos.c47
-rw-r--r--Python/dynload_beos.c254
-rw-r--r--Python/dynload_dl.c2
-rw-r--r--Python/dynload_hpux.c4
-rw-r--r--Python/dynload_next.c2
-rw-r--r--Python/dynload_os2.c2
-rw-r--r--Python/dynload_shlib.c23
-rw-r--r--Python/dynload_win.c50
-rw-r--r--Python/errors.c266
-rw-r--r--Python/fileutils.c481
-rw-r--r--Python/formatter_string.c17
-rw-r--r--Python/formatter_unicode.c18
-rw-r--r--Python/frozen.c20
-rw-r--r--Python/frozenmain.c48
-rw-r--r--Python/future.c26
-rw-r--r--Python/getargs.c746
-rw-r--r--Python/getcopyright.c2
-rw-r--r--Python/getcwd.c3
-rw-r--r--Python/getopt.c50
-rw-r--r--Python/graminit.c2157
-rw-r--r--Python/import.c1503
-rw-r--r--Python/importdl.c64
-rw-r--r--Python/mactoolboxglue.c474
-rwxr-xr-xPython/makeopcodetargets.py46
-rw-r--r--Python/marshal.c498
-rw-r--r--Python/modsupport.c179
-rw-r--r--Python/mysnprintf.c1
-rw-r--r--Python/mystrtoul.c42
-rw-r--r--Python/opcode_targets.h258
-rw-r--r--Python/peephole.c169
-rw-r--r--Python/pyarena.c1
-rw-r--r--Python/pystate.c107
-rw-r--r--Python/pystrtod.c75
-rw-r--r--Python/pythonrun.c1239
-rw-r--r--Python/pytime.c60
-rw-r--r--Python/strtod.c159
-rw-r--r--Python/structmember.c133
-rw-r--r--Python/symtable.c761
-rw-r--r--Python/sysmodule.c962
-rw-r--r--Python/thread.c18
-rw-r--r--Python/thread_atheos.h259
-rw-r--r--Python/thread_beos.h248
-rw-r--r--Python/thread_nt.h114
-rw-r--r--Python/thread_pthread.h217
-rw-r--r--Python/traceback.c331
-rw-r--r--README1274
-rw-r--r--RISCOS/Makefile448
-rw-r--r--RISCOS/Modules/config.c73
-rw-r--r--RISCOS/Modules/drawfmodule.c664
-rw-r--r--RISCOS/Modules/getpath_riscos.c60
-rw-r--r--RISCOS/Modules/riscosmodule.c603
-rw-r--r--RISCOS/Modules/swimodule.c575
-rw-r--r--RISCOS/Python/dynload_riscos.c63
-rw-r--r--RISCOS/Python/getcwd_riscos.c5
-rw-r--r--RISCOS/README36
-rw-r--r--RISCOS/pyconfig.h718
-rw-r--r--RISCOS/sleep.c41
-rw-r--r--RISCOS/support/!Boot22
-rw-r--r--RISCOS/support/!Run2
-rw-r--r--RISCOS/support/!Spritesbin1532 -> 0 bytes-rw-r--r--RISCOS/support/!Sprites22bin2876 -> 0 bytes-rw-r--r--RISCOS/support/AddToPathbin256 -> 0 bytes-rw-r--r--RISCOS/unixstuff.c74
-rw-r--r--RISCOS/unixstuff.h14
-rw-r--r--Tools/README53
-rw-r--r--Tools/audiopy/README112
-rwxr-xr-xTools/audiopy/audiopy507
-rw-r--r--Tools/bgen/README9
-rw-r--r--Tools/bgen/bgen/bgen.py12
-rw-r--r--Tools/bgen/bgen/bgenBuffer.py301
-rw-r--r--Tools/bgen/bgen/bgenGenerator.py302
-rw-r--r--Tools/bgen/bgen/bgenGeneratorGroup.py40
-rw-r--r--Tools/bgen/bgen/bgenHeapBuffer.py145
-rw-r--r--Tools/bgen/bgen/bgenModule.py94
-rw-r--r--Tools/bgen/bgen/bgenObjectDefinition.py512
-rw-r--r--Tools/bgen/bgen/bgenOutput.py219
-rw-r--r--Tools/bgen/bgen/bgenStackBuffer.py62
-rw-r--r--Tools/bgen/bgen/bgenStringBuffer.py67
-rw-r--r--Tools/bgen/bgen/bgenType.py328
-rw-r--r--Tools/bgen/bgen/bgenVariable.py112
-rw-r--r--Tools/bgen/bgen/macsupport.py197
-rw-r--r--Tools/bgen/bgen/scantools.py849
-rw-r--r--Tools/buildbot/buildmsi.bat1
-rw-r--r--Tools/buildbot/clean.bat2
-rw-r--r--Tools/buildbot/external-amd64.bat11
-rw-r--r--Tools/buildbot/external-common.bat23
-rw-r--r--Tools/buildbot/external.bat10
-rw-r--r--Tools/buildbot/test-amd64.bat2
-rw-r--r--Tools/buildbot/test.bat2
-rw-r--r--Tools/ccbench/ccbench.py27
-rw-r--r--Tools/compiler/ACKS8
-rw-r--r--Tools/compiler/README18
-rw-r--r--Tools/compiler/ast.txt104
-rw-r--r--Tools/compiler/astgen.py294
-rw-r--r--Tools/compiler/compile.py51
-rwxr-xr-xTools/compiler/demo.py38
-rwxr-xr-xTools/compiler/dumppyc.py46
-rw-r--r--Tools/compiler/regrtest.py78
-rw-r--r--Tools/compiler/stacktest.py43
-rw-r--r--Tools/demo/README16
-rwxr-xr-xTools/demo/beer.py25
-rwxr-xr-xTools/demo/eiffel.py146
-rwxr-xr-xTools/demo/hanoi.py154
-rwxr-xr-xTools/demo/life.py251
-rwxr-xr-xTools/demo/markov.py125
-rwxr-xr-xTools/demo/mcast.py82
-rwxr-xr-xTools/demo/queens.py85
-rwxr-xr-xTools/demo/redemo.py173
-rwxr-xr-xTools/demo/rpython.py38
-rwxr-xr-xTools/demo/rpythond.py58
-rwxr-xr-xTools/demo/sortvisu.py635
-rwxr-xr-xTools/demo/ss1.py846
-rwxr-xr-xTools/demo/vector.py74
-rw-r--r--Tools/faqwiz/README114
-rw-r--r--Tools/faqwiz/faqconf.py577
-rw-r--r--Tools/faqwiz/faqcust.py1
-rwxr-xr-xTools/faqwiz/faqw.py33
-rw-r--r--Tools/faqwiz/faqwiz.py841
-rwxr-xr-xTools/faqwiz/move-faqwiz.sh55
-rw-r--r--Tools/framer/README.txt8
-rw-r--r--Tools/framer/TODO.txt6
-rw-r--r--Tools/framer/example.py126
-rw-r--r--Tools/framer/framer/__init__.py6
-rw-r--r--Tools/framer/framer/bases.py220
-rw-r--r--Tools/framer/framer/function.py173
-rw-r--r--Tools/framer/framer/member.py73
-rw-r--r--Tools/framer/framer/slots.py64
-rw-r--r--Tools/framer/framer/struct.py52
-rw-r--r--Tools/framer/framer/structparse.py46
-rw-r--r--Tools/framer/framer/template.py102
-rw-r--r--Tools/framer/framer/util.py35
-rw-r--r--Tools/freeze/bkfile.py6
-rw-r--r--Tools/freeze/checkextensions.py6
-rw-r--r--Tools/freeze/checkextensions_win32.py2
-rw-r--r--Tools/freeze/extensions_win32.ini2
-rw-r--r--Tools/freeze/flag.py2
-rwxr-xr-xTools/freeze/freeze.py39
-rw-r--r--Tools/freeze/hello.py2
-rw-r--r--Tools/freeze/makeconfig.py17
-rw-r--r--Tools/freeze/makefreeze.py11
-rw-r--r--Tools/freeze/makemakefile.py3
-rw-r--r--Tools/freeze/parsesetup.py15
-rw-r--r--Tools/freeze/winmakemakefile.py129
-rw-r--r--Tools/gdb/libpython.py340
-rw-r--r--Tools/i18n/makelocalealias.py28
-rwxr-xr-xTools/i18n/msgfmt.py78
-rwxr-xr-xTools/i18n/pygettext.py67
-rw-r--r--Tools/iobench/iobench.py6
-rw-r--r--Tools/msi/msi.py98
-rw-r--r--Tools/msi/msilib.py65
-rw-r--r--Tools/msi/uuids.py56
-rw-r--r--Tools/parser/test_unparse.py247
-rw-r--r--Tools/parser/unparse.py604
-rw-r--r--Tools/pybench/Arithmetic.py50
-rw-r--r--Tools/pybench/Calls.py30
-rw-r--r--Tools/pybench/CommandLine.py136
-rw-r--r--Tools/pybench/Constructs.py12
-rw-r--r--Tools/pybench/Dict.py24
-rw-r--r--Tools/pybench/Exceptions.py14
-rw-r--r--Tools/pybench/Imports.py12
-rw-r--r--Tools/pybench/Instances.py4
-rw-r--r--Tools/pybench/Lists.py40
-rw-r--r--Tools/pybench/Lookups.py70
-rw-r--r--Tools/pybench/NewInstances.py4
-rw-r--r--Tools/pybench/Numbers.py376
-rw-r--r--Tools/pybench/README27
-rw-r--r--Tools/pybench/Setup.py2
-rw-r--r--Tools/pybench/Strings.py76
-rw-r--r--Tools/pybench/Tuples.py8
-rw-r--r--Tools/pybench/Unicode.py65
-rw-r--r--Tools/pybench/With.py18
-rw-r--r--Tools/pybench/clockres.py11
-rwxr-xr-xTools/pybench/pybench.py249
-rw-r--r--Tools/pybench/systimes.py33
-rw-r--r--Tools/pynche/ChipViewer.py2
-rw-r--r--Tools/pynche/ColorDB.py27
-rw-r--r--Tools/pynche/DetailsViewer.py2
-rw-r--r--Tools/pynche/ListViewer.py2
-rw-r--r--Tools/pynche/Main.py12
-rw-r--r--Tools/pynche/PyncheWidget.py22
-rw-r--r--Tools/pynche/StripViewer.py18
-rw-r--r--Tools/pynche/Switchboard.py15
-rw-r--r--Tools/pynche/TextViewer.py2
-rw-r--r--Tools/pynche/TypeinViewer.py2
-rw-r--r--Tools/pynche/pyColorChooser.py8
-rw-r--r--Tools/scripts/README128
-rwxr-xr-xTools/scripts/abitype.py202
-rw-r--r--[-rwxr-xr-x]Tools/scripts/analyze_dxp.py1
-rwxr-xr-xTools/scripts/byext.py38
-rwxr-xr-xTools/scripts/byteyears.py8
-rwxr-xr-xTools/scripts/checkappend.py167
-rwxr-xr-xTools/scripts/checkpyc.py67
-rwxr-xr-xTools/scripts/classfix.py190
-rwxr-xr-xTools/scripts/cleanfuture.py32
-rwxr-xr-xTools/scripts/combinerefs.py19
-rwxr-xr-xTools/scripts/copytime.py4
-rwxr-xr-xTools/scripts/crlf.py20
-rwxr-xr-xTools/scripts/cvsfiles.py72
-rwxr-xr-xTools/scripts/db2pickle.py18
-rwxr-xr-xTools/scripts/diff.py2
-rwxr-xr-xTools/scripts/dutree.py10
-rwxr-xr-xTools/scripts/eptags.py2
-rwxr-xr-xTools/scripts/find-uname.py40
-rwxr-xr-xTools/scripts/find_recursionlimit.py46
-rwxr-xr-xTools/scripts/finddiv.py16
-rwxr-xr-xTools/scripts/findlinksto.py14
-rwxr-xr-xTools/scripts/findnocoding.py66
-rwxr-xr-xTools/scripts/fixcid.py28
-rwxr-xr-xTools/scripts/fixdiv.py62
-rwxr-xr-xTools/scripts/fixheader.py30
-rwxr-xr-xTools/scripts/fixnotice.py12
-rwxr-xr-xTools/scripts/fixps.py10
-rwxr-xr-xTools/scripts/ftpmirror.py143
-rwxr-xr-xTools/scripts/get-remote-certificate.py84
-rwxr-xr-xTools/scripts/google.py4
-rwxr-xr-xTools/scripts/gprof2html.py14
-rwxr-xr-xTools/scripts/h2py.py26
-rwxr-xr-xTools/scripts/hotshotmain.py55
-rwxr-xr-xTools/scripts/idle5
-rwxr-xr-xTools/scripts/idle35
-rwxr-xr-xTools/scripts/ifdef.py2
-rwxr-xr-xTools/scripts/lfcr.py20
-rwxr-xr-xTools/scripts/linktree.py32
-rwxr-xr-xTools/scripts/lll.py8
-rwxr-xr-xTools/scripts/logmerge.py185
-rwxr-xr-xTools/scripts/mailerdaemon.py60
-rwxr-xr-xTools/scripts/make_ctype.py94
-rwxr-xr-xTools/scripts/md5sum.py10
-rwxr-xr-xTools/scripts/methfix.py171
-rwxr-xr-xTools/scripts/mkreal.py6
-rwxr-xr-xTools/scripts/ndiff.py12
-rwxr-xr-xTools/scripts/nm2def.py4
-rwxr-xr-xTools/scripts/objgraph.py73
-rwxr-xr-xTools/scripts/parseentities.py10
-rwxr-xr-xTools/scripts/patchcheck.py24
-rwxr-xr-xTools/scripts/pathfix.py56
-rwxr-xr-xTools/scripts/pdeps.py40
-rwxr-xr-xTools/scripts/pickle2db.py24
-rwxr-xr-xTools/scripts/pindent.py8
-rwxr-xr-xTools/scripts/ptags.py2
-rwxr-xr-xTools/scripts/pydoc5
-rwxr-xr-xTools/scripts/pydoc35
-rwxr-xr-xTools/scripts/pysource.py16
-rwxr-xr-xTools/scripts/redemo.py172
-rwxr-xr-xTools/scripts/reindent-rst.py2
-rwxr-xr-xTools/scripts/reindent.py92
-rwxr-xr-xTools/scripts/rgrep.py24
-rwxr-xr-xTools/scripts/serve.py8
-rw-r--r--Tools/scripts/setup.py20
-rwxr-xr-xTools/scripts/suff.py22
-rwxr-xr-x[-rw-r--r--]Tools/scripts/svneol.py51
-rw-r--r--Tools/scripts/texcheck.py233
-rwxr-xr-xTools/scripts/texi2html.py307
-rwxr-xr-xTools/scripts/treesync.py59
-rwxr-xr-xTools/scripts/untabify.py27
-rwxr-xr-xTools/scripts/which.py6
-rw-r--r--Tools/scripts/win_add2path.py24
-rwxr-xr-xTools/scripts/xxci.py116
-rw-r--r--Tools/ssl/get-remote-certificate.py79
-rw-r--r--Tools/test2to3/README3
-rw-r--r--Tools/test2to3/maintest.py10
-rw-r--r--Tools/test2to3/setup.py26
-rw-r--r--Tools/test2to3/test/runtests.py19
-rw-r--r--Tools/test2to3/test/test_foo.py8
-rw-r--r--Tools/test2to3/test2to3/__init__.py1
-rw-r--r--Tools/test2to3/test2to3/hello.py5
-rw-r--r--Tools/unicode/comparecodecs.py30
-rw-r--r--Tools/unicode/gencjkcodecs.py2
-rw-r--r--Tools/unicode/gencodec.py53
-rw-r--r--Tools/unicode/genwincodec.py6
-rw-r--r--Tools/unicode/genwincodecs.bat2
-rw-r--r--Tools/unicode/listcodecs.py12
-rw-r--r--Tools/unicode/makeunicodedata.py570
-rw-r--r--Tools/unicode/mkstringprep.py100
-rw-r--r--Tools/unittestgui/README.txt16
-rw-r--r--Tools/unittestgui/unittestgui.py479
-rw-r--r--Tools/versioncheck/README41
-rw-r--r--Tools/versioncheck/_checkversion.py16
-rw-r--r--Tools/versioncheck/checkversions.py52
-rw-r--r--Tools/versioncheck/pyversioncheck.py98
-rw-r--r--Tools/webchecker/README23
-rw-r--r--Tools/webchecker/tktools.py366
-rwxr-xr-xTools/webchecker/wcgui.py456
-rw-r--r--Tools/webchecker/wcmac.py7
-rwxr-xr-xTools/webchecker/webchecker.py892
-rwxr-xr-xTools/webchecker/websucker.py123
-rwxr-xr-xTools/webchecker/wsgui.py240
-rw-r--r--Tools/world/README85
-rwxr-xr-xTools/world/world551
-rwxr-xr-xconfigure1760
-rw-r--r--configure.ac879
-rw-r--r--pyconfig.h.in68
-rw-r--r--setup.py696
3575 files changed, 341283 insertions, 587958 deletions
diff --git a/.bzrignore b/.bzrignore
index 2527052..959a7df 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -11,6 +11,7 @@ python
build
Makefile.pre
platform
+pybuilddir.txt
pyconfig.h
libpython*.a
libpython*.so*
@@ -30,10 +31,13 @@ Modules/Setup
Modules/Setup.config
Modules/Setup.local
Modules/config.c
+Modules/ld_so_aix
Parser/pgen
+Parser/pgen.stamp
Lib/test/data/*
Lib/lib2to3/Grammar*.pickle
Lib/lib2to3/PatternGrammar*.pickle
+__pycache__
.coverage
coverage/*
htmlcov/*
diff --git a/.gitignore b/.gitignore
index 1ff7d5e..c1a8055 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,13 +5,17 @@
*.pyd
*.pyo
*.rej
+*.swp
*~
+.gdb_history
Doc/build/
Doc/tools/docutils/
+Doc/tools/jinja/
Doc/tools/jinja2/
Doc/tools/pygments/
Doc/tools/sphinx/
Lib/lib2to3/*.pickle
+Lib/plat-mac/errors.rsrc.df.rsrc
Makefile
Makefile.pre
Misc/python.pc
@@ -20,6 +24,7 @@ Modules/Setup.config
Modules/Setup.local
Modules/config.c
Modules/ld_so_aix
+Modules/_testembed
PCbuild/*.bsc
PCbuild/*.dll
PCbuild/*.exe
@@ -29,18 +34,35 @@ PCbuild/*.ncb
PCbuild/*.o
PCbuild/*.pdb
PCbuild/Win32-temp-*
+PCbuild/amd64/
+.purify
Parser/pgen
Parser/pgen.stamp
+__pycache__
autom4te.cache
build/
+buildno
+config.cache
+config.log
+config.status
+config.status.lineno
+core
+db_home
config.log
config.status
libpython*.a
libpython*.so*
+platform
+pybuilddir.txt
pyconfig.h
python
+python.exe
python-gdb.py
+python.exe-gdb.py
+reflog.txt
+.svn/
tags
+TAGS
.coverage
coverage/
htmlcov/
diff --git a/.hgeol b/.hgeol
index fe66605..ed13171 100644
--- a/.hgeol
+++ b/.hgeol
@@ -28,8 +28,8 @@
Lib/email/test/data/msg_26.txt = BIN
Lib/test/cjkencodings/* = BIN
-Lib/test/decimaltestdata/*.decTest = BIN
Lib/test/sndhdrdata/sndhdr.* = BIN
+Lib/test/decimaltestdata/*.decTest = BIN
# All other files (which presumably are human-editable) are "native".
# This must be the last rule!
diff --git a/.hgignore b/.hgignore
index 8c402ff..24df3b9 100644
--- a/.hgignore
+++ b/.hgignore
@@ -34,9 +34,10 @@ Parser/pgen$
Parser/pgen.stamp$
^core
^python-gdb.py
+^python.exe-gdb.py
+^pybuilddir.txt
syntax: glob
-python.exe-gdb.py
libpython*.a
libpython*.so*
*.swp
@@ -52,6 +53,7 @@ Misc/*.wpu
PC/python_nt*.h
PC/pythonnt_rc*.h
PC/*.obj
+PC/*.exe
PCbuild/*.exe
PCbuild/*.dll
PCbuild/*.pdb
@@ -61,6 +63,8 @@ PCbuild/*.o
PCbuild/*.ncb
PCbuild/*.bsc
PCbuild/Win32-temp-*
+__pycache__
+Modules/_testembed
.coverage
coverage/
htmlcov/
diff --git a/.hgtags b/.hgtags
index 5681a12..f061b90 100644
--- a/.hgtags
+++ b/.hgtags
@@ -35,8 +35,6 @@ f08c7a2a56f80741f5f192fd0ebe0b0967a203cf v1.5.2b1
55bba197d4870cdae62aeca00e20240a756b84f8 v2.0b2
e276329cce036a5f9e9d3451256dca5984e543dc v2.0c1
2fa4e35083e02342ca014bf5bfba46aecb816c31 v2.0
-83459cc191c1c9c8cc6b08ada99c02f0af6ad54f v2.0.1c1
-73de94a722d206a45c0b49d3011c629ead4d62b1 v2.0.1
b60831eeab5a06dd3c5e8297a99e39297aa8794b v2.1a1
b382f1f07ec6b2c95551658b30c6139eeb32077a v2.1a2
d0c830db5e68edd4aaa3401216e610c9ff145826 v2.1b1
@@ -44,35 +42,9 @@ b59a536ae1ef3774fd85c17f623e8926b7b6c095 v2.1b2
d611276e9ad53b5d32d1e8065e1d811c32f7d96f v2.1c1
ff065e674af6c9ab895bd9eff7d9e9039a376c7d v2.1c2
020e95d8180d7943fe54701e1db0a7d7d87e2b1e v2.1
-22bed2dd1b286564dea4d9a67d4ed80dc3225193 v2.1.1c1
-572533a3038d1832c8a200fb8718112dd83758e9 v2.1.1
-f76a425b14e4ee8ade5e9239598538534b3a90a4 v2.1.2c1
-cf31b10e45b48615094cae90e3c5bd072587d8e6 v2.1.2
-7d1504c80fa072b4ba86edda13a13b0a05ae8eab v2.1.3
08796a137f1ada2462f7a3177306df5f67a767e1 v2.2a3
-765434e7aa019c1bb82f9813b8025830867cbdc0 v2.2.1c1
-11c952c7d4be6638040764910be80bd9c3c17de6 v2.2.1c2
-4045e6e92fafabad42f6c9989b67076fbad452ca v2.2
-394790316aa380d22e4d670bc69a639e725f0300 v2.2.1
-0128313c2855d71753f00fccc60bb39ed92a0c54 v2.2.2b1
-61d531533a86224a1c26917c18013d91f592fbfb v2.2.2
-ac77b91342534d09b1e432e1dc3b70dbbec3a919 v2.2.3c1
-f4f134ad46abd0bc973d3f6094ea56e62ac5c492 v2.2.3
d054c29647f90bccb8345bd779bca1eecf2dd7f2 v2.3c1
fce5c9e9abc722394cb2e909b7e2a39080d4448e v2.3c2
-fa65f6527fe134aa97e03e1b2af365d443b67dc7 v2.3.1
-7d7362a71253bff4fc1b0c825c14569778db8c36 v2.3.2c1
-be2533fb10a587c8da89b18c5f381f478d720593 v2.3.2
-d21d4ba2f973467d30794a3d2ac493658180e503 v2.3.3c1
-a8f1286f217129cdb53e320ee125d2c2c80e1377 v2.3.3
-3639861d02646af1da3123c25560c4db3d7edbce v2.3.4c1
-a74f9081c6970878cabe151f969617587915400c v2.3.4
-2639b10daa985b20b3cabec45169d523cac29d68 v2.3.5c1
-d228509424172f977edad4f7860a9c747cd655c8 v2.3.5
-b21427ff26475f9c7f4a701da324e951c2b162fe v2.3.6c1
-3b6fb5439c1061a941401245076c315beafcc787 v2.3.6
-893c7bd4a92bd889a85e691f49188c37b0a72357 v2.3.7c1
-2022943ad450c41d64708fb5caca2d2672b5b8f8 v2.3.7
92ca658fd420095b6284c9ce6e9082a80285ec9c v2.4a1
055fc6955f3c6522bfeb7ed4c671c97d5baaaac2 v2.4a2
186b72550e53533ef6175f6411f932c1298193d7 v2.4a3
@@ -80,79 +52,50 @@ b21427ff26475f9c7f4a701da324e951c2b162fe v2.3.6c1
7e387a9dcc79954a77695adef8b593da35be1214 v2.4b2
ff80d8bbef6e13426c8a85d7f9d837b8f8f89834 v2.4c1
f31e18d313c7a4fc66914b2d27e130a0f72c0b69 v2.4
-1195f9ba3439097cc5b5a367e3ae1b43f157b264 v2.4.1c1
-333cf303543b680ec5e3fdf7e8c9661f9488a50e v2.4.1c2
-f9054d235870029afa33ef945bca7ece99616c10 v2.4.1
-d02d387554e200befceec999b788f4593b434b49 v2.4.2c1
-8d37276fdf077d6d23d963d3f7f95381d00f1926 v2.4.2
-7c5be7c0fdfdbbc0ac1d91c07038bc81412da412 v2.4.3c1
-8cca2492626ce408cd567110811c0692fd1d37dd v2.4.3
-baaeea722b1c97ca03179e5a02a4717e7017ba2a v2.4.4c1
-592ac93532efdfa9a40f47b96b1c1231d2eae0e5 v2.4.4
-1f7d628c70a9aefe762c2c32210876faf8d64c78 v2.4.5c1
-d8df4aa06261de5e4c0aa051e448697d4791e437 v2.4.5
-a6c3c715e2b70740c4b6b4f7dc6f47b16a7e5905 v2.4.6c1
-f3f1f1462c82536bb23796e70c85522144ee24db v2.4.6
-67192da3e69c985bb1272da932d7de6073033fad v2.5a0
-896f9fead17e720ec4a21de3ac214518da84845f v2.5a1
-26d0770f2b7ee289a39a3b55dcec1c1ee65849c5 v2.5a2
-d49b198f545cd82fbf735a22979c332b8a97eecb v2.5b1
-03b6fe57cd6df5bb34ca19f4b760b943186cc806 v2.5b2
-c0abb18299b442e1160d2f958bce18f66850caa9 v2.5b3
-2dc64d570e8d7a4498ab850108c85709c276df93 v2.5c1
-cc3cb3a8237ea545db917d84c49d8a0a5e175cc1 v2.5c2
-c10a71cf16e471425e6d7564e3f7a648f14b702e v2.5
-4777c4007b5b194423953d41b1e5e6adaaba6c5d v2.5.1c1
-490d8c09abcb814950be7bb7a25c3ff2047c7eb5 v2.5.1
-0a8aae575cdddbf3d133fcb4eed91080e3fe41f3 v2.5.2c1
-1d508bbbdb49a2b11629ee186a63928291b08694 v2.5.2
-9530d334d2624219e7ee1aecaf33532e910266bc v2.5.3c1
-3cc056d21c2f4435a534d23345bad9c0a9d9b3cb v2.5.3
-a0a6d9909312ad9c1d844af66e9c91931b93852a v2.5.4
-657f16582943739b906f66f7efad4014492c8b1c v2.5.5c1
-1dc91e9dd5c13a4bc2d3bb7d4b5896ab264f2325 v2.5.5c2
-7098a46f0b75e5aacfaf81d65d72e3613b023532 v2.5.5
-a87c7b96672b69dffef64c59b56fba5bb2059b99 v2.5.6c1
-de34c7b097e8d66b1140c211dbd61d48b31ba483 v2.5.6
-2d0bd095c420b0711000d9be66848f6cfd972b3b v2.6a1
-eec144917a189be11ed5efa35c6604d03bc62bcc v2.6a2
-48e9fb0a721799877f26edaef01ac6e6029b6812 v2.6a3
-2f2f32af8c4ee8f6598f632dc83701a20726d10a v2.6b1
-81ec8263bd6e25c9a8855cd0ce9ae881732972be v2.6b2
-c62862d73f9ec64d655494cf1f61443446f2dea2 v2.6b3
-1ebb2a8cc06c94471d72b5476c2050c4d115a1aa v2.6rc1
-525792097c6308a78a76b7b5f56bbd8a24c26acf v2.6rc2
-95fff5a6a276520b2e7e0f75fe303f49376567a5 v2.6
-cabf303e787aa5cd7209b40e3b2caba3ee75c5a5 v2.6.1
-01f1ae83631ae82bd8598a11c17e3f9b3f56c38a v2.6.2c1
-4feba09a826ba99e5b482707b3d9643eba34156f v2.6.2
-1873542c00000c4b7ce2c7992d1f2d87f866232a v2.6.3rc1
-00c3396d7a8c4ab4c2c841d61013a073ae921d0f v2.6.3
-25aa90a6865b63133962dd64626c53c7b6fd47d5 v2.6.4rc1
-ea1fdafbe4fe2458ac17287e0d6c709ed00fce5c v2.6.4rc2
-8803c3d61da275c71cabe9e9d0274dac9902e2c0 v2.6.4
-c9f68e42ab796a3bab4f8cf3cc69ce10503cb990 v2.6.5rc1
-fa4630916699046357a5ac16884f3fc47bd0eaa6 v2.6.5rc2
-99af4b44e7e490390817a597a542546d749e698e v2.6.5
-c1dc9e7986a2a8e1070ec7bee748520febef382e v2.6.6rc1
-e189dc8fd66154ef46d9cd22584d56669b544ca3 v2.6.6rc2
-9f8771e0905277f8b3c2799113a062fda4164995 v2.6.6
-caab08cd2b3eb5a6f78479b2513b65d36c754f41 v2.6.8rc1
-1d1b7b9fad48bd0dc60dc8a06cca4459ef273127 v2.6.8rc2
-c9910fd022fc842e5578e1bf5a30ba55a37239fc v2.6.8
-b4107eb00b4271fb73a9e1b736d4f23460950778 v2.7a1
-adc85ebc7271cc22e24e816782bb2b8d7fa3a6b3 v2.7a2
-4180557b7a9bb9dd5341a18af199f843f199e46e v2.7a3
-d2e1027edde84a02853fcf9790f311f10f46cf0a v2.7a4
-61550a1302b07a731436a84b2d86eb2bab3b2fb0 v2.7b1
-6bb9891d4275bd42a69b3d903d13b687543c915d v2.7b2
-381c5eeb511038d091d8e0808c4b85087ed2f684 v2.7rc1
-13e5b0b2071a2a42067fb03facc931409fa6ba50 v2.7rc2
-2145593d108de62ebf770987a4ac2a57d268c9d1 v2.7
-63d9f00fea0730c1c437a50f64a42b7792bdcbfb v2.7.1rc1
-5395f96588d4f0199d329cb79eb109648dc4ef5e v2.7.1
-f48756685406e8d0fa9d23d841fceb07e36a5656 v2.7.2rc1
-8527427914a29d895bcb30be76a465143993a793 v2.7.2
-b2c6aff96e1251a4f03cf866e7e75fb8232869f2 v2.7.3rc1
-d46c1973d3c407ecaa6a8ee16d3fad3ef506b51f v2.7.3rc2
-70274d53c1ddc60c5f9a2b8a422a49884021447c v2.7.3
+cd3f783cd08a16781e236c0b9cb5717d1d995fa9 v3.0a1
+65e82140e281bf26f2e22eda05a7f9956c420f8b v3.0a2
+df15827f34881b9af0936350813ced5c123c8230 v3.0a3
+15f773f7300e372c56a21d59fe49ca26955a6477 v3.0a4
+e35935475153377d6727d64e6c52f72c3b84015b v3.0a5
+a335c4d643b1cfe14197a9ef195c9b2804f608fc v3.0b1
+16ec4bb14a68ea428acf09ebf0c92981da2646f3 v3.0b2
+509e30a7968e01be329ec121540b3e755fc4e566 v3.0b3
+507ede9c7f7f475dfafbd4a52c22d767d10a2bc0 v3.0rc1
+8fae465a39627b590385462e6095eb63af45240a v3.0rc2
+e83a60c69d53f5551a306e77a6d38e9b11485496 v3.0rc3
+bc1ce368986e45b1faf96f93995df46bcd75e7b8 v3.1a1
+ee430e5075db2adf8124e6b94916a89ca41d3171 v3.1a2
+b63020797f9678adaf4d2c3e26574a9eef2ef028 v3.1b1
+4353fd0843cb31b356adc50f93d220e2e7255ef2 v3.1rc1
+0b87e438e1b53e3f812cad963a7fdb65d198ba2f v3.1rc2
+a69a031ac1402dede8b1ef80096436bca6d371f3 v3.1
+35efb1054ec6ceca72017a587263cb6a9257340b v3.1.1rc1
+8b9c0f573ab29c41c6c5fdcca82a1fe0ff5355af v3.1.1
+149b8b87514d10416b598884db5f74651f625b38 v3.1.2rc1
+960efa327c5d9c18df995437b0ac550cb89c9f85 v3.1.2
+d18e9d71f369d8211f6ac87252c6d3211f9bd09f v3.1.3rc1
+a4f75773c0060cee38b0bb651a7aba6f56b0e996 v3.1.3
+32fcb9e94985cb19ce37ba9543f091c0dbe9d7dd v3.1.4rc1
+c918ec9f3a76d6afedfbb5d455004de880443a3d v3.1.4
+ee26aca3219cf4bb0b93352e83edcc9cb28c7802 v3.1.5rc1
+75db2bc69fc9a3e4801e94e3e19801cb096208d8 v3.1.5rc2
+7395330e495ec3316862ca1f6ce0aaf7bdf6785b v3.1.5
+b37b7834757492d009b99cf0ca4d42d2153d7fac v3.2a1
+56d4373cecb73c8b45126ba7b045b3c7b3f94b0b v3.2a2
+da012d9a2c23d144e399d2e01a55b8a83ad94573 v3.2a3
+d92a5b850f5e56808bedc01723906ed64c5e6e2e v3.2a4
+b635cea94195780c8716e236479af319bcc26253 v3.2b1
+e3af5f3a7904c0d5343ec9633ea66e7acfd23a66 v3.2b2
+865d5b24bf28ca41b536befc326407c03e74a4d5 v3.2rc1
+acf3e24dd0d0dfd1e20c907d696d3da965a8f56f v3.2rc2
+18c1f52896501c7ee13b038454a39acb45a87979 v3.2rc3
+a222a015e28d8ae9af3899258dc6c15c3d40add0 v3.2
+8ffac2337a3323323d02153ac919fd1483176652 v3.2.1b1
+cfa9364997c7f2e67b9cbb45c3a5fa3bba4e4999 v3.2.1rc1
+5df549718fb4841ff521fe051f6b54f290fad5d8 v3.2.1rc2
+ac1f7e5c05104d557d5acd922e95625ba5d1fe10 v3.2.1
+c860feaa348d663e598986894ee4680480577e15 v3.2.2rc1
+137e45f15c0bd262c9ad4c032d97425bc0589456 v3.2.2
+7085403daf439adb3f9e70ef13f6bedb1c447376 v3.2.3rc1
+428f05cb7277e1d42bb9dd8d1af6b6270ebc6112 v3.2.3rc2
+3d0686d90f55a78f96d9403da2c52dc2411419d0 v3.2.3
diff --git a/Demo/README b/Demo/README
deleted file mode 100644
index 9d150d6..0000000
--- a/Demo/README
+++ /dev/null
@@ -1,61 +0,0 @@
-This directory contains various demonstrations of what you can do with
-Python. They were all written by me except where explicitly stated
-otherwise -- in general, demos contributed by others ends up in the
-../Contrib directory, unless I think they're of utmost general
-importance (like Matt Conway's Tk demos).
-
-A fair number of utilities that are useful when while developing
-Python code can be found in the ../Tools directory -- some of these
-can also be considered good examples of how to write Python code.
-
-Finally, in order to save disk space and net bandwidth, not all
-subdirectories listed here are distributed. They are listed just
-in case I change my mind about them.
-
-
-cgi CGI examples (see also ../Tools/faqwiz/.)
-
-classes Some examples of how to use classes.
-
-comparisons A set of responses to a really old language-comparison
- challenge.
-
-curses A set of curses demos.
-
-embed An example of embedding Python in another application
- (see also pysvr).
-
-imputil Demonstration subclasses of imputil.Importer.
-
-md5test Test program for the optional md5 module.
-
-metaclasses The code from the 1.5 metaclasses paper on the web.
-
-parser Example using the parser module.
-
-pdist Old, unfinished code messing with CVS, RCS and remote
- files.
-
-pysvr An example of embedding Python in a threaded
- application.
-
-rpc A set of classes for building clients and servers for
- Sun RPC.
-
-scripts Some useful Python scripts that I put in my bin
- directory. No optional built-in modules needed.
-
-sockets Examples for the new built-in module 'socket'.
-
-threads Demos that use the 'thread' module. (Currently these
- only run on SGIs, but this may change in the future.)
-
-tix Demos using the Tix widget set addition to Tkinter.
-
-tkinter Demos using the Tk interface (including Matt Conway's
- excellent set of demos).
-
-xml Some XML demos.
-
-zlib Some demos for the zlib module (see also the standard
- library module gzip.py).
diff --git a/Demo/cgi/README b/Demo/cgi/README
deleted file mode 100644
index e50d2d0..0000000
--- a/Demo/cgi/README
+++ /dev/null
@@ -1,11 +0,0 @@
-CGI Examples
-------------
-
-Here are some example CGI programs. For a larger example, see
-../../Tools/faqwiz/.
-
-cgi0.sh -- A shell script to test your server is configured for CGI
-cgi1.py -- A Python script to test your server is configured for CGI
-cgi2.py -- A Python script showing how to parse a form
-cgi3.py -- A Python script for driving an arbitrary CGI application
-wiki.py -- Sample CGI application: a minimal Wiki implementation
diff --git a/Demo/cgi/cgi0.sh b/Demo/cgi/cgi0.sh
deleted file mode 100755
index 5cefcd3..0000000
--- a/Demo/cgi/cgi0.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#! /bin/sh
-
-# If you can't get this to work, your web server isn't set up right
-
-echo Content-type: text/plain
-echo
-echo Hello world
-echo This is cgi0.sh
diff --git a/Demo/cgi/cgi1.py b/Demo/cgi/cgi1.py
deleted file mode 100755
index c6f3efa..0000000
--- a/Demo/cgi/cgi1.py
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env python
-
-"""CGI test 1 - check server setup."""
-
-# Until you get this to work, your web server isn't set up right or
-# your Python isn't set up right.
-
-# If cgi0.sh works but cgi1.py doesn't, check the #! line and the file
-# permissions. The docs for the cgi.py module have debugging tips.
-
-print "Content-type: text/html"
-print
-print "<h1>Hello world</h1>"
-print "<p>This is cgi1.py"
diff --git a/Demo/cgi/cgi2.py b/Demo/cgi/cgi2.py
deleted file mode 100755
index 8026c55..0000000
--- a/Demo/cgi/cgi2.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env python
-
-"""CGI test 2 - basic use of cgi module."""
-
-import cgitb; cgitb.enable()
-
-import cgi
-
-def main():
- form = cgi.FieldStorage()
- print "Content-type: text/html"
- print
- if not form:
- print "<h1>No Form Keys</h1>"
- else:
- print "<h1>Form Keys</h1>"
- for key in form.keys():
- value = form[key].value
- print "<p>", cgi.escape(key), ":", cgi.escape(value)
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/cgi/cgi3.py b/Demo/cgi/cgi3.py
deleted file mode 100755
index 6693a86..0000000
--- a/Demo/cgi/cgi3.py
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env python
-
-"""CGI test 3 (persistent data)."""
-
-import cgitb; cgitb.enable()
-
-from wiki import main
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/cgi/wiki.py b/Demo/cgi/wiki.py
deleted file mode 100644
index ee094a8..0000000
--- a/Demo/cgi/wiki.py
+++ /dev/null
@@ -1,123 +0,0 @@
-"""Wiki main program. Imported and run by cgi3.py."""
-
-import os, re, cgi, sys, tempfile
-escape = cgi.escape
-
-def main():
- form = cgi.FieldStorage()
- print "Content-type: text/html"
- print
- cmd = form.getvalue("cmd", "view")
- page = form.getvalue("page", "FrontPage")
- wiki = WikiPage(page)
- method = getattr(wiki, 'cmd_' + cmd, None) or wiki.cmd_view
- method(form)
-
-class WikiPage:
-
- homedir = tempfile.gettempdir()
- scripturl = os.path.basename(sys.argv[0])
-
- def __init__(self, name):
- if not self.iswikiword(name):
- raise ValueError, "page name is not a wiki word"
- self.name = name
- self.load()
-
- def cmd_view(self, form):
- print "<h1>", escape(self.splitwikiword(self.name)), "</h1>"
- print "<p>"
- for line in self.data.splitlines():
- line = line.rstrip()
- if not line:
- print "<p>"
- else:
- print self.formatline(line)
- print "<hr>"
- print "<p>", self.mklink("edit", self.name, "Edit this page") + ";"
- print self.mklink("view", "FrontPage", "go to front page") + "."
-
- def formatline(self, line):
- words = []
- for word in re.split('(\W+)', line):
- if self.iswikiword(word):
- if os.path.isfile(self.mkfile(word)):
- word = self.mklink("view", word, word)
- else:
- word = self.mklink("new", word, word + "*")
- else:
- word = escape(word)
- words.append(word)
- return "".join(words)
-
- def cmd_edit(self, form, label="Change"):
- print "<h1>", label, self.name, "</h1>"
- print '<form method="POST" action="%s">' % self.scripturl
- s = '<textarea cols="70" rows="20" name="text">%s</textarea>'
- print s % self.data
- print '<input type="hidden" name="cmd" value="create">'
- print '<input type="hidden" name="page" value="%s">' % self.name
- print '<br>'
- print '<input type="submit" value="%s Page">' % label
- print "</form>"
-
- def cmd_create(self, form):
- self.data = form.getvalue("text", "").strip()
- error = self.store()
- if error:
- print "<h1>I'm sorry. That didn't work</h1>"
- print "<p>An error occurred while attempting to write the file:"
- print "<p>", escape(error)
- else:
- # Use a redirect directive, to avoid "reload page" problems
- print "<head>"
- s = '<meta http-equiv="refresh" content="1; URL=%s">'
- print s % (self.scripturl + "?cmd=view&page=" + self.name)
- print "<head>"
- print "<h1>OK</h1>"
- print "<p>If nothing happens, please click here:",
- print self.mklink("view", self.name, self.name)
-
- def cmd_new(self, form):
- self.cmd_edit(form, label="Create")
-
- def iswikiword(self, word):
- return re.match("[A-Z][a-z]+([A-Z][a-z]*)+", word)
-
- def splitwikiword(self, word):
- chars = []
- for c in word:
- if chars and c.isupper():
- chars.append(' ')
- chars.append(c)
- return "".join(chars)
-
- def mkfile(self, name=None):
- if name is None:
- name = self.name
- return os.path.join(self.homedir, name + ".txt")
-
- def mklink(self, cmd, page, text):
- link = self.scripturl + "?cmd=" + cmd + "&page=" + page
- return '<a href="%s">%s</a>' % (link, text)
-
- def load(self):
- try:
- f = open(self.mkfile())
- data = f.read().strip()
- f.close()
- except IOError:
- data = ""
- self.data = data
-
- def store(self):
- data = self.data
- try:
- f = open(self.mkfile(), "w")
- f.write(data)
- if data and not data.endswith('\n'):
- f.write('\n')
- f.close()
- return ""
- except IOError, err:
- return "IOError: %s" % str(err)
diff --git a/Demo/classes/Complex.py b/Demo/classes/Complex.py
deleted file mode 100644
index 2b306ad..0000000
--- a/Demo/classes/Complex.py
+++ /dev/null
@@ -1,320 +0,0 @@
-# Complex numbers
-# ---------------
-
-# [Now that Python has a complex data type built-in, this is not very
-# useful, but it's still a nice example class]
-
-# This module represents complex numbers as instances of the class Complex.
-# A Complex instance z has two data attribues, z.re (the real part) and z.im
-# (the imaginary part). In fact, z.re and z.im can have any value -- all
-# arithmetic operators work regardless of the type of z.re and z.im (as long
-# as they support numerical operations).
-#
-# The following functions exist (Complex is actually a class):
-# Complex([re [,im]) -> creates a complex number from a real and an imaginary part
-# IsComplex(z) -> true iff z is a complex number (== has .re and .im attributes)
-# ToComplex(z) -> a complex number equal to z; z itself if IsComplex(z) is true
-# if z is a tuple(re, im) it will also be converted
-# PolarToComplex([r [,phi [,fullcircle]]]) ->
-# the complex number z for which r == z.radius() and phi == z.angle(fullcircle)
-# (r and phi default to 0)
-# exp(z) -> returns the complex exponential of z. Equivalent to pow(math.e,z).
-#
-# Complex numbers have the following methods:
-# z.abs() -> absolute value of z
-# z.radius() == z.abs()
-# z.angle([fullcircle]) -> angle from positive X axis; fullcircle gives units
-# z.phi([fullcircle]) == z.angle(fullcircle)
-#
-# These standard functions and unary operators accept complex arguments:
-# abs(z)
-# -z
-# +z
-# not z
-# repr(z) == `z`
-# str(z)
-# hash(z) -> a combination of hash(z.re) and hash(z.im) such that if z.im is zero
-# the result equals hash(z.re)
-# Note that hex(z) and oct(z) are not defined.
-#
-# These conversions accept complex arguments only if their imaginary part is zero:
-# int(z)
-# long(z)
-# float(z)
-#
-# The following operators accept two complex numbers, or one complex number
-# and one real number (int, long or float):
-# z1 + z2
-# z1 - z2
-# z1 * z2
-# z1 / z2
-# pow(z1, z2)
-# cmp(z1, z2)
-# Note that z1 % z2 and divmod(z1, z2) are not defined,
-# nor are shift and mask operations.
-#
-# The standard module math does not support complex numbers.
-# The cmath modules should be used instead.
-#
-# Idea:
-# add a class Polar(r, phi) and mixed-mode arithmetic which
-# chooses the most appropriate type for the result:
-# Complex for +,-,cmp
-# Polar for *,/,pow
-
-import math
-import sys
-
-twopi = math.pi*2.0
-halfpi = math.pi/2.0
-
-def IsComplex(obj):
- return hasattr(obj, 're') and hasattr(obj, 'im')
-
-def ToComplex(obj):
- if IsComplex(obj):
- return obj
- elif isinstance(obj, tuple):
- return Complex(*obj)
- else:
- return Complex(obj)
-
-def PolarToComplex(r = 0, phi = 0, fullcircle = twopi):
- phi = phi * (twopi / fullcircle)
- return Complex(math.cos(phi)*r, math.sin(phi)*r)
-
-def Re(obj):
- if IsComplex(obj):
- return obj.re
- return obj
-
-def Im(obj):
- if IsComplex(obj):
- return obj.im
- return 0
-
-class Complex:
-
- def __init__(self, re=0, im=0):
- _re = 0
- _im = 0
- if IsComplex(re):
- _re = re.re
- _im = re.im
- else:
- _re = re
- if IsComplex(im):
- _re = _re - im.im
- _im = _im + im.re
- else:
- _im = _im + im
- # this class is immutable, so setting self.re directly is
- # not possible.
- self.__dict__['re'] = _re
- self.__dict__['im'] = _im
-
- def __setattr__(self, name, value):
- raise TypeError, 'Complex numbers are immutable'
-
- def __hash__(self):
- if not self.im:
- return hash(self.re)
- return hash((self.re, self.im))
-
- def __repr__(self):
- if not self.im:
- return 'Complex(%r)' % (self.re,)
- else:
- return 'Complex(%r, %r)' % (self.re, self.im)
-
- def __str__(self):
- if not self.im:
- return repr(self.re)
- else:
- return 'Complex(%r, %r)' % (self.re, self.im)
-
- def __neg__(self):
- return Complex(-self.re, -self.im)
-
- def __pos__(self):
- return self
-
- def __abs__(self):
- return math.hypot(self.re, self.im)
-
- def __int__(self):
- if self.im:
- raise ValueError, "can't convert Complex with nonzero im to int"
- return int(self.re)
-
- def __long__(self):
- if self.im:
- raise ValueError, "can't convert Complex with nonzero im to long"
- return long(self.re)
-
- def __float__(self):
- if self.im:
- raise ValueError, "can't convert Complex with nonzero im to float"
- return float(self.re)
-
- def __cmp__(self, other):
- other = ToComplex(other)
- return cmp((self.re, self.im), (other.re, other.im))
-
- def __rcmp__(self, other):
- other = ToComplex(other)
- return cmp(other, self)
-
- def __nonzero__(self):
- return not (self.re == self.im == 0)
-
- abs = radius = __abs__
-
- def angle(self, fullcircle = twopi):
- return (fullcircle/twopi) * ((halfpi - math.atan2(self.re, self.im)) % twopi)
-
- phi = angle
-
- def __add__(self, other):
- other = ToComplex(other)
- return Complex(self.re + other.re, self.im + other.im)
-
- __radd__ = __add__
-
- def __sub__(self, other):
- other = ToComplex(other)
- return Complex(self.re - other.re, self.im - other.im)
-
- def __rsub__(self, other):
- other = ToComplex(other)
- return other - self
-
- def __mul__(self, other):
- other = ToComplex(other)
- return Complex(self.re*other.re - self.im*other.im,
- self.re*other.im + self.im*other.re)
-
- __rmul__ = __mul__
-
- def __div__(self, other):
- other = ToComplex(other)
- d = float(other.re*other.re + other.im*other.im)
- if not d: raise ZeroDivisionError, 'Complex division'
- return Complex((self.re*other.re + self.im*other.im) / d,
- (self.im*other.re - self.re*other.im) / d)
-
- def __rdiv__(self, other):
- other = ToComplex(other)
- return other / self
-
- def __pow__(self, n, z=None):
- if z is not None:
- raise TypeError, 'Complex does not support ternary pow()'
- if IsComplex(n):
- if n.im:
- if self.im: raise TypeError, 'Complex to the Complex power'
- else: return exp(math.log(self.re)*n)
- n = n.re
- r = pow(self.abs(), n)
- phi = n*self.angle()
- return Complex(math.cos(phi)*r, math.sin(phi)*r)
-
- def __rpow__(self, base):
- base = ToComplex(base)
- return pow(base, self)
-
-def exp(z):
- r = math.exp(z.re)
- return Complex(math.cos(z.im)*r,math.sin(z.im)*r)
-
-
-def checkop(expr, a, b, value, fuzz = 1e-6):
- print ' ', a, 'and', b,
- try:
- result = eval(expr)
- except:
- result = sys.exc_type
- print '->', result
- if isinstance(result, str) or isinstance(value, str):
- ok = (result == value)
- else:
- ok = abs(result - value) <= fuzz
- if not ok:
- print '!!\t!!\t!! should be', value, 'diff', abs(result - value)
-
-def test():
- print 'test constructors'
- constructor_test = (
- # "expect" is an array [re,im] "got" the Complex.
- ( (0,0), Complex() ),
- ( (0,0), Complex() ),
- ( (1,0), Complex(1) ),
- ( (0,1), Complex(0,1) ),
- ( (1,2), Complex(Complex(1,2)) ),
- ( (1,3), Complex(Complex(1,2),1) ),
- ( (0,0), Complex(0,Complex(0,0)) ),
- ( (3,4), Complex(3,Complex(4)) ),
- ( (-1,3), Complex(1,Complex(3,2)) ),
- ( (-7,6), Complex(Complex(1,2),Complex(4,8)) ) )
- cnt = [0,0]
- for t in constructor_test:
- cnt[0] += 1
- if ((t[0][0]!=t[1].re)or(t[0][1]!=t[1].im)):
- print " expected", t[0], "got", t[1]
- cnt[1] += 1
- print " ", cnt[1], "of", cnt[0], "tests failed"
- # test operators
- testsuite = {
- 'a+b': [
- (1, 10, 11),
- (1, Complex(0,10), Complex(1,10)),
- (Complex(0,10), 1, Complex(1,10)),
- (Complex(0,10), Complex(1), Complex(1,10)),
- (Complex(1), Complex(0,10), Complex(1,10)),
- ],
- 'a-b': [
- (1, 10, -9),
- (1, Complex(0,10), Complex(1,-10)),
- (Complex(0,10), 1, Complex(-1,10)),
- (Complex(0,10), Complex(1), Complex(-1,10)),
- (Complex(1), Complex(0,10), Complex(1,-10)),
- ],
- 'a*b': [
- (1, 10, 10),
- (1, Complex(0,10), Complex(0, 10)),
- (Complex(0,10), 1, Complex(0,10)),
- (Complex(0,10), Complex(1), Complex(0,10)),
- (Complex(1), Complex(0,10), Complex(0,10)),
- ],
- 'a/b': [
- (1., 10, 0.1),
- (1, Complex(0,10), Complex(0, -0.1)),
- (Complex(0, 10), 1, Complex(0, 10)),
- (Complex(0, 10), Complex(1), Complex(0, 10)),
- (Complex(1), Complex(0,10), Complex(0, -0.1)),
- ],
- 'pow(a,b)': [
- (1, 10, 1),
- (1, Complex(0,10), 1),
- (Complex(0,10), 1, Complex(0,10)),
- (Complex(0,10), Complex(1), Complex(0,10)),
- (Complex(1), Complex(0,10), 1),
- (2, Complex(4,0), 16),
- ],
- 'cmp(a,b)': [
- (1, 10, -1),
- (1, Complex(0,10), 1),
- (Complex(0,10), 1, -1),
- (Complex(0,10), Complex(1), -1),
- (Complex(1), Complex(0,10), 1),
- ],
- }
- for expr in sorted(testsuite):
- print expr + ':'
- t = (expr,)
- for item in testsuite[expr]:
- checkop(*(t+item))
-
-
-if __name__ == '__main__':
- test()
diff --git a/Demo/classes/Dates.py b/Demo/classes/Dates.py
deleted file mode 100644
index e860517..0000000
--- a/Demo/classes/Dates.py
+++ /dev/null
@@ -1,227 +0,0 @@
-# Class Date supplies date objects that support date arithmetic.
-#
-# Date(month,day,year) returns a Date object. An instance prints as,
-# e.g., 'Mon 16 Aug 1993'.
-#
-# Addition, subtraction, comparison operators, min, max, and sorting
-# all work as expected for date objects: int+date or date+int returns
-# the date `int' days from `date'; date+date raises an exception;
-# date-int returns the date `int' days before `date'; date2-date1 returns
-# an integer, the number of days from date1 to date2; int-date raises an
-# exception; date1 < date2 is true iff date1 occurs before date2 (&
-# similarly for other comparisons); min(date1,date2) is the earlier of
-# the two dates and max(date1,date2) the later; and date objects can be
-# used as dictionary keys.
-#
-# Date objects support one visible method, date.weekday(). This returns
-# the day of the week the date falls on, as a string.
-#
-# Date objects also have 4 read-only data attributes:
-# .month in 1..12
-# .day in 1..31
-# .year int or long int
-# .ord the ordinal of the date relative to an arbitrary staring point
-#
-# The Dates module also supplies function today(), which returns the
-# current date as a date object.
-#
-# Those entranced by calendar trivia will be disappointed, as no attempt
-# has been made to accommodate the Julian (etc) system. On the other
-# hand, at least this package knows that 2000 is a leap year but 2100
-# isn't, and works fine for years with a hundred decimal digits <wink>.
-
-# Tim Peters tim@ksr.com
-# not speaking for Kendall Square Research Corp
-
-# Adapted to Python 1.1 (where some hacks to overcome coercion are unnecessary)
-# by Guido van Rossum
-
-# Note that as of Python 2.3, a datetime module is included in the stardard
-# library.
-
-# vi:set tabsize=8:
-
-_MONTH_NAMES = [ 'January', 'February', 'March', 'April', 'May',
- 'June', 'July', 'August', 'September', 'October',
- 'November', 'December' ]
-
-_DAY_NAMES = [ 'Friday', 'Saturday', 'Sunday', 'Monday',
- 'Tuesday', 'Wednesday', 'Thursday' ]
-
-_DAYS_IN_MONTH = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
-
-_DAYS_BEFORE_MONTH = []
-dbm = 0
-for dim in _DAYS_IN_MONTH:
- _DAYS_BEFORE_MONTH.append(dbm)
- dbm = dbm + dim
-del dbm, dim
-
-_INT_TYPES = type(1), type(1L)
-
-def _is_leap(year): # 1 if leap year, else 0
- if year % 4 != 0: return 0
- if year % 400 == 0: return 1
- return year % 100 != 0
-
-def _days_in_year(year): # number of days in year
- return 365 + _is_leap(year)
-
-def _days_before_year(year): # number of days before year
- return year*365L + (year+3)//4 - (year+99)//100 + (year+399)//400
-
-def _days_in_month(month, year): # number of days in month of year
- if month == 2 and _is_leap(year): return 29
- return _DAYS_IN_MONTH[month-1]
-
-def _days_before_month(month, year): # number of days in year before month
- return _DAYS_BEFORE_MONTH[month-1] + (month > 2 and _is_leap(year))
-
-def _date2num(date): # compute ordinal of date.month,day,year
- return _days_before_year(date.year) + \
- _days_before_month(date.month, date.year) + \
- date.day
-
-_DI400Y = _days_before_year(400) # number of days in 400 years
-
-def _num2date(n): # return date with ordinal n
- if type(n) not in _INT_TYPES:
- raise TypeError, 'argument must be integer: %r' % type(n)
-
- ans = Date(1,1,1) # arguments irrelevant; just getting a Date obj
- del ans.ord, ans.month, ans.day, ans.year # un-initialize it
- ans.ord = n
-
- n400 = (n-1)//_DI400Y # # of 400-year blocks preceding
- year, n = 400 * n400, n - _DI400Y * n400
- more = n // 365
- dby = _days_before_year(more)
- if dby >= n:
- more = more - 1
- dby = dby - _days_in_year(more)
- year, n = year + more, int(n - dby)
-
- try: year = int(year) # chop to int, if it fits
- except (ValueError, OverflowError): pass
-
- month = min(n//29 + 1, 12)
- dbm = _days_before_month(month, year)
- if dbm >= n:
- month = month - 1
- dbm = dbm - _days_in_month(month, year)
-
- ans.month, ans.day, ans.year = month, n-dbm, year
- return ans
-
-def _num2day(n): # return weekday name of day with ordinal n
- return _DAY_NAMES[ int(n % 7) ]
-
-
-class Date:
- def __init__(self, month, day, year):
- if not 1 <= month <= 12:
- raise ValueError, 'month must be in 1..12: %r' % (month,)
- dim = _days_in_month(month, year)
- if not 1 <= day <= dim:
- raise ValueError, 'day must be in 1..%r: %r' % (dim, day)
- self.month, self.day, self.year = month, day, year
- self.ord = _date2num(self)
-
- # don't allow setting existing attributes
- def __setattr__(self, name, value):
- if self.__dict__.has_key(name):
- raise AttributeError, 'read-only attribute ' + name
- self.__dict__[name] = value
-
- def __cmp__(self, other):
- return cmp(self.ord, other.ord)
-
- # define a hash function so dates can be used as dictionary keys
- def __hash__(self):
- return hash(self.ord)
-
- # print as, e.g., Mon 16 Aug 1993
- def __repr__(self):
- return '%.3s %2d %.3s %r' % (
- self.weekday(),
- self.day,
- _MONTH_NAMES[self.month-1],
- self.year)
-
- # Python 1.1 coerces neither int+date nor date+int
- def __add__(self, n):
- if type(n) not in _INT_TYPES:
- raise TypeError, 'can\'t add %r to date' % type(n)
- return _num2date(self.ord + n)
- __radd__ = __add__ # handle int+date
-
- # Python 1.1 coerces neither date-int nor date-date
- def __sub__(self, other):
- if type(other) in _INT_TYPES: # date-int
- return _num2date(self.ord - other)
- else:
- return self.ord - other.ord # date-date
-
- # complain about int-date
- def __rsub__(self, other):
- raise TypeError, 'Can\'t subtract date from integer'
-
- def weekday(self):
- return _num2day(self.ord)
-
-def today():
- import time
- local = time.localtime(time.time())
- return Date(local[1], local[2], local[0])
-
-class DateTestError(Exception):
- pass
-
-def test(firstyear, lastyear):
- a = Date(9,30,1913)
- b = Date(9,30,1914)
- if repr(a) != 'Tue 30 Sep 1913':
- raise DateTestError, '__repr__ failure'
- if (not a < b) or a == b or a > b or b != b:
- raise DateTestError, '__cmp__ failure'
- if a+365 != b or 365+a != b:
- raise DateTestError, '__add__ failure'
- if b-a != 365 or b-365 != a:
- raise DateTestError, '__sub__ failure'
- try:
- x = 1 - a
- raise DateTestError, 'int-date should have failed'
- except TypeError:
- pass
- try:
- x = a + b
- raise DateTestError, 'date+date should have failed'
- except TypeError:
- pass
- if a.weekday() != 'Tuesday':
- raise DateTestError, 'weekday() failure'
- if max(a,b) is not b or min(a,b) is not a:
- raise DateTestError, 'min/max failure'
- d = {a-1:b, b:a+1}
- if d[b-366] != b or d[a+(b-a)] != Date(10,1,1913):
- raise DateTestError, 'dictionary failure'
-
- # verify date<->number conversions for first and last days for
- # all years in firstyear .. lastyear
-
- lord = _days_before_year(firstyear)
- y = firstyear
- while y <= lastyear:
- ford = lord + 1
- lord = ford + _days_in_year(y) - 1
- fd, ld = Date(1,1,y), Date(12,31,y)
- if (fd.ord,ld.ord) != (ford,lord):
- raise DateTestError, ('date->num failed', y)
- fd, ld = _num2date(ford), _num2date(lord)
- if (1,1,y,12,31,y) != \
- (fd.month,fd.day,fd.year,ld.month,ld.day,ld.year):
- raise DateTestError, ('num->date failed', y)
- y = y + 1
-
-if __name__ == '__main__':
- test(1850, 2150)
diff --git a/Demo/classes/Dbm.py b/Demo/classes/Dbm.py
deleted file mode 100644
index 892c103..0000000
--- a/Demo/classes/Dbm.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# A wrapper around the (optional) built-in class dbm, supporting keys
-# and values of almost any type instead of just string.
-# (Actually, this works only for keys and values that can be read back
-# correctly after being converted to a string.)
-
-
-class Dbm:
-
- def __init__(self, filename, mode, perm):
- import dbm
- self.db = dbm.open(filename, mode, perm)
-
- def __repr__(self):
- s = ''
- for key in self.keys():
- t = repr(key) + ': ' + repr(self[key])
- if s: t = ', ' + t
- s = s + t
- return '{' + s + '}'
-
- def __len__(self):
- return len(self.db)
-
- def __getitem__(self, key):
- return eval(self.db[repr(key)])
-
- def __setitem__(self, key, value):
- self.db[repr(key)] = repr(value)
-
- def __delitem__(self, key):
- del self.db[repr(key)]
-
- def keys(self):
- res = []
- for key in self.db.keys():
- res.append(eval(key))
- return res
-
- def has_key(self, key):
- return self.db.has_key(repr(key))
-
-
-def test():
- d = Dbm('@dbm', 'rw', 0600)
- print d
- while 1:
- try:
- key = input('key: ')
- if d.has_key(key):
- value = d[key]
- print 'currently:', value
- value = input('value: ')
- if value is None:
- del d[key]
- else:
- d[key] = value
- except KeyboardInterrupt:
- print ''
- print d
- except EOFError:
- print '[eof]'
- break
- print d
-
-
-test()
diff --git a/Demo/classes/README b/Demo/classes/README
deleted file mode 100644
index e5bc289..0000000
--- a/Demo/classes/README
+++ /dev/null
@@ -1,12 +0,0 @@
-Examples of classes that implement special operators (see reference manual):
-
-Complex.py Complex numbers
-Dates.py Date manipulation package by Tim Peters
-Dbm.py Wrapper around built-in dbm, supporting arbitrary values
-Range.py Example of a generator: re-implement built-in range()
-Rev.py Yield the reverse of a sequence
-Vec.py A simple vector class
-bitvec.py A bit-vector class by Jan-Hein B\"uhrman
-
-(For straightforward examples of basic class features, such as use of
-methods and inheritance, see the library code.)
diff --git a/Demo/classes/Range.py b/Demo/classes/Range.py
deleted file mode 100644
index 3f1daae..0000000
--- a/Demo/classes/Range.py
+++ /dev/null
@@ -1,93 +0,0 @@
-"""Example of a generator: re-implement the built-in range function
-without actually constructing the list of values.
-
-OldStyleRange is coded in the way required to work in a 'for' loop before
-iterators were introduced into the language; using __getitem__ and __len__ .
-
-"""
-def handleargs(arglist):
- """Take list of arguments and extract/create proper start, stop, and step
- values and return in a tuple"""
- try:
- if len(arglist) == 1:
- return 0, int(arglist[0]), 1
- elif len(arglist) == 2:
- return int(arglist[0]), int(arglist[1]), 1
- elif len(arglist) == 3:
- if arglist[2] == 0:
- raise ValueError("step argument must not be zero")
- return tuple(int(x) for x in arglist)
- else:
- raise TypeError("range() accepts 1-3 arguments, given", len(arglist))
- except TypeError:
- raise TypeError("range() arguments must be numbers or strings "
- "representing numbers")
-
-def genrange(*a):
- """Function to implement 'range' as a generator"""
- start, stop, step = handleargs(a)
- value = start
- while value < stop:
- yield value
- value += step
-
-class oldrange:
- """Class implementing a range object.
- To the user the instances feel like immutable sequences
- (and you can't concatenate or slice them)
-
- Done using the old way (pre-iterators; __len__ and __getitem__) to have an
- object be used by a 'for' loop.
-
- """
-
- def __init__(self, *a):
- """ Initialize start, stop, and step values along with calculating the
- nubmer of values (what __len__ will return) in the range"""
- self.start, self.stop, self.step = handleargs(a)
- self.len = max(0, (self.stop - self.start) // self.step)
-
- def __repr__(self):
- """implement repr(x) which is also used by print"""
- return 'range(%r, %r, %r)' % (self.start, self.stop, self.step)
-
- def __len__(self):
- """implement len(x)"""
- return self.len
-
- def __getitem__(self, i):
- """implement x[i]"""
- if 0 <= i <= self.len:
- return self.start + self.step * i
- else:
- raise IndexError, 'range[i] index out of range'
-
-
-def test():
- import time, __builtin__
- #Just a quick sanity check
- correct_result = __builtin__.range(5, 100, 3)
- oldrange_result = list(oldrange(5, 100, 3))
- genrange_result = list(genrange(5, 100, 3))
- if genrange_result != correct_result or oldrange_result != correct_result:
- raise Exception("error in implementation:\ncorrect = %s"
- "\nold-style = %s\ngenerator = %s" %
- (correct_result, oldrange_result, genrange_result))
- print "Timings for range(1000):"
- t1 = time.time()
- for i in oldrange(1000):
- pass
- t2 = time.time()
- for i in genrange(1000):
- pass
- t3 = time.time()
- for i in __builtin__.range(1000):
- pass
- t4 = time.time()
- print t2-t1, 'sec (old-style class)'
- print t3-t2, 'sec (generator)'
- print t4-t3, 'sec (built-in)'
-
-
-if __name__ == '__main__':
- test()
diff --git a/Demo/classes/Rev.py b/Demo/classes/Rev.py
deleted file mode 100644
index 7fd78e0..0000000
--- a/Demo/classes/Rev.py
+++ /dev/null
@@ -1,95 +0,0 @@
-'''
-A class which presents the reverse of a sequence without duplicating it.
-From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu>
-
-It works on mutable or inmutable sequences.
-
->>> chars = list(Rev('Hello World!'))
->>> print ''.join(chars)
-!dlroW olleH
-
-The .forw is so you can use anonymous sequences in __init__, and still
-keep a reference the forward sequence. )
-If you give it a non-anonymous mutable sequence, the reverse sequence
-will track the updated values. ( but not reassignment! - another
-good reason to use anonymous values in creating the sequence to avoid
-confusion. Maybe it should be change to copy input sequence to break
-the connection completely ? )
-
->>> nnn = range(3)
->>> rnn = Rev(nnn)
->>> for n in rnn: print n
-...
-2
-1
-0
->>> for n in range(4, 6): nnn.append(n) # update nnn
-...
->>> for n in rnn: print n # prints reversed updated values
-...
-5
-4
-2
-1
-0
->>> nnn = nnn[1:-1]
->>> nnn
-[1, 2, 4]
->>> for n in rnn: print n # prints reversed values of old nnn
-...
-5
-4
-2
-1
-0
-
-#
->>> WH = Rev('Hello World!')
->>> print WH.forw, WH.back
-Hello World! !dlroW olleH
->>> nnn = Rev(range(1, 10))
->>> print nnn.forw
-[1, 2, 3, 4, 5, 6, 7, 8, 9]
->>> print nnn.back
-[9, 8, 7, 6, 5, 4, 3, 2, 1]
-
->>> rrr = Rev(nnn)
->>> rrr
-<1, 2, 3, 4, 5, 6, 7, 8, 9>
-
-'''
-
-class Rev:
- def __init__(self, seq):
- self.forw = seq
- self.back = self
-
- def __len__(self):
- return len(self.forw)
-
- def __getitem__(self, j):
- return self.forw[-(j + 1)]
-
- def __repr__(self):
- seq = self.forw
- if isinstance(seq, list):
- wrap = '[]'
- sep = ', '
- elif isinstance(seq, tuple):
- wrap = '()'
- sep = ', '
- elif isinstance(seq, str):
- wrap = ''
- sep = ''
- else:
- wrap = '<>'
- sep = ', '
- outstrs = [str(item) for item in self.back]
- return wrap[:1] + sep.join(outstrs) + wrap[-1:]
-
-def _test():
- import doctest, Rev
- return doctest.testmod(Rev)
-
-if __name__ == "__main__":
- _test()
diff --git a/Demo/classes/Vec.py b/Demo/classes/Vec.py
deleted file mode 100644
index b8771ea..0000000
--- a/Demo/classes/Vec.py
+++ /dev/null
@@ -1,68 +0,0 @@
-class Vec:
- """ A simple vector class
-
- Instances of the Vec class can be constructed from numbers
-
- >>> a = Vec(1, 2, 3)
- >>> b = Vec(3, 2, 1)
-
- added
- >>> a + b
- Vec(4, 4, 4)
-
- subtracted
- >>> a - b
- Vec(-2, 0, 2)
-
- and multiplied by a scalar on the left
- >>> 3.0 * a
- Vec(3.0, 6.0, 9.0)
-
- or on the right
- >>> a * 3.0
- Vec(3.0, 6.0, 9.0)
- """
- def __init__(self, *v):
- self.v = list(v)
-
- @classmethod
- def fromlist(cls, v):
- if not isinstance(v, list):
- raise TypeError
- inst = cls()
- inst.v = v
- return inst
-
- def __repr__(self):
- args = ', '.join(repr(x) for x in self.v)
- return 'Vec({0})'.format(args)
-
- def __len__(self):
- return len(self.v)
-
- def __getitem__(self, i):
- return self.v[i]
-
- def __add__(self, other):
- # Element-wise addition
- v = [x + y for x, y in zip(self.v, other.v)]
- return Vec.fromlist(v)
-
- def __sub__(self, other):
- # Element-wise subtraction
- v = [x - y for x, y in zip(self.v, other.v)]
- return Vec.fromlist(v)
-
- def __mul__(self, scalar):
- # Multiply by scalar
- v = [x * scalar for x in self.v]
- return Vec.fromlist(v)
-
- __rmul__ = __mul__
-
-
-def test():
- import doctest
- doctest.testmod()
-
-test()
diff --git a/Demo/classes/bitvec.py b/Demo/classes/bitvec.py
deleted file mode 100644
index c0eafa0..0000000
--- a/Demo/classes/bitvec.py
+++ /dev/null
@@ -1,333 +0,0 @@
-#
-# this is a rather strict implementation of a bit vector class
-# it is accessed the same way as an array of python-ints, except
-# the value must be 0 or 1
-#
-
-import sys; rprt = sys.stderr.write #for debugging
-
-class error(Exception):
- pass
-
-
-def _check_value(value):
- if type(value) != type(0) or not 0 <= value < 2:
- raise error, 'bitvec() items must have int value 0 or 1'
-
-
-import math
-
-def _compute_len(param):
- mant, l = math.frexp(float(param))
- bitmask = 1L << l
- if bitmask <= param:
- raise RuntimeError('(param, l) = %r' % ((param, l),))
- while l:
- bitmask = bitmask >> 1
- if param & bitmask:
- break
- l = l - 1
- return l
-
-
-def _check_key(len, key):
- if type(key) != type(0):
- raise TypeError, 'sequence subscript not int'
- if key < 0:
- key = key + len
- if not 0 <= key < len:
- raise IndexError, 'list index out of range'
- return key
-
-def _check_slice(len, i, j):
- #the type is ok, Python already checked that
- i, j = max(i, 0), min(len, j)
- if i > j:
- i = j
- return i, j
-
-
-class BitVec:
-
- def __init__(self, *params):
- self._data = 0L
- self._len = 0
- if not len(params):
- pass
- elif len(params) == 1:
- param, = params
- if type(param) == type([]):
- value = 0L
- bit_mask = 1L
- for item in param:
- # strict check
- #_check_value(item)
- if item:
- value = value | bit_mask
- bit_mask = bit_mask << 1
- self._data = value
- self._len = len(param)
- elif type(param) == type(0L):
- if param < 0:
- raise error, 'bitvec() can\'t handle negative longs'
- self._data = param
- self._len = _compute_len(param)
- else:
- raise error, 'bitvec() requires array or long parameter'
- elif len(params) == 2:
- param, length = params
- if type(param) == type(0L):
- if param < 0:
- raise error, \
- 'can\'t handle negative longs'
- self._data = param
- if type(length) != type(0):
- raise error, 'bitvec()\'s 2nd parameter must be int'
- computed_length = _compute_len(param)
- if computed_length > length:
- print 'warning: bitvec() value is longer than the length indicates, truncating value'
- self._data = self._data & \
- ((1L << length) - 1)
- self._len = length
- else:
- raise error, 'bitvec() requires array or long parameter'
- else:
- raise error, 'bitvec() requires 0 -- 2 parameter(s)'
-
-
- def append(self, item):
- #_check_value(item)
- #self[self._len:self._len] = [item]
- self[self._len:self._len] = \
- BitVec(long(not not item), 1)
-
-
- def count(self, value):
- #_check_value(value)
- if value:
- data = self._data
- else:
- data = (~self)._data
- count = 0
- while data:
- data, count = data >> 1, count + (data & 1 != 0)
- return count
-
-
- def index(self, value):
- #_check_value(value):
- if value:
- data = self._data
- else:
- data = (~self)._data
- index = 0
- if not data:
- raise ValueError, 'list.index(x): x not in list'
- while not (data & 1):
- data, index = data >> 1, index + 1
- return index
-
-
- def insert(self, index, item):
- #_check_value(item)
- #self[index:index] = [item]
- self[index:index] = BitVec(long(not not item), 1)
-
-
- def remove(self, value):
- del self[self.index(value)]
-
-
- def reverse(self):
- #ouch, this one is expensive!
- #for i in self._len>>1: self[i], self[l-i] = self[l-i], self[i]
- data, result = self._data, 0L
- for i in range(self._len):
- if not data:
- result = result << (self._len - i)
- break
- result, data = (result << 1) | (data & 1), data >> 1
- self._data = result
-
-
- def sort(self):
- c = self.count(1)
- self._data = ((1L << c) - 1) << (self._len - c)
-
-
- def copy(self):
- return BitVec(self._data, self._len)
-
-
- def seq(self):
- result = []
- for i in self:
- result.append(i)
- return result
-
-
- def __repr__(self):
- ##rprt('<bitvec class instance object>.' + '__repr__()\n')
- return 'bitvec(%r, %r)' % (self._data, self._len)
-
- def __cmp__(self, other, *rest):
- #rprt('%r.__cmp__%r\n' % (self, (other,) + rest))
- if type(other) != type(self):
- other = apply(bitvec, (other, ) + rest)
- #expensive solution... recursive binary, with slicing
- length = self._len
- if length == 0 or other._len == 0:
- return cmp(length, other._len)
- if length != other._len:
- min_length = min(length, other._len)
- return cmp(self[:min_length], other[:min_length]) or \
- cmp(self[min_length:], other[min_length:])
- #the lengths are the same now...
- if self._data == other._data:
- return 0
- if length == 1:
- return cmp(self[0], other[0])
- else:
- length = length >> 1
- return cmp(self[:length], other[:length]) or \
- cmp(self[length:], other[length:])
-
-
- def __len__(self):
- #rprt('%r.__len__()\n' % (self,))
- return self._len
-
- def __getitem__(self, key):
- #rprt('%r.__getitem__(%r)\n' % (self, key))
- key = _check_key(self._len, key)
- return self._data & (1L << key) != 0
-
- def __setitem__(self, key, value):
- #rprt('%r.__setitem__(%r, %r)\n' % (self, key, value))
- key = _check_key(self._len, key)
- #_check_value(value)
- if value:
- self._data = self._data | (1L << key)
- else:
- self._data = self._data & ~(1L << key)
-
- def __delitem__(self, key):
- #rprt('%r.__delitem__(%r)\n' % (self, key))
- key = _check_key(self._len, key)
- #el cheapo solution...
- self._data = self[:key]._data | self[key+1:]._data >> key
- self._len = self._len - 1
-
- def __getslice__(self, i, j):
- #rprt('%r.__getslice__(%r, %r)\n' % (self, i, j))
- i, j = _check_slice(self._len, i, j)
- if i >= j:
- return BitVec(0L, 0)
- if i:
- ndata = self._data >> i
- else:
- ndata = self._data
- nlength = j - i
- if j != self._len:
- #we'll have to invent faster variants here
- #e.g. mod_2exp
- ndata = ndata & ((1L << nlength) - 1)
- return BitVec(ndata, nlength)
-
- def __setslice__(self, i, j, sequence, *rest):
- #rprt('%s.__setslice__%r\n' % (self, (i, j, sequence) + rest))
- i, j = _check_slice(self._len, i, j)
- if type(sequence) != type(self):
- sequence = apply(bitvec, (sequence, ) + rest)
- #sequence is now of our own type
- ls_part = self[:i]
- ms_part = self[j:]
- self._data = ls_part._data | \
- ((sequence._data | \
- (ms_part._data << sequence._len)) << ls_part._len)
- self._len = self._len - j + i + sequence._len
-
- def __delslice__(self, i, j):
- #rprt('%r.__delslice__(%r, %r)\n' % (self, i, j))
- i, j = _check_slice(self._len, i, j)
- if i == 0 and j == self._len:
- self._data, self._len = 0L, 0
- elif i < j:
- self._data = self[:i]._data | (self[j:]._data >> i)
- self._len = self._len - j + i
-
- def __add__(self, other):
- #rprt('%r.__add__(%r)\n' % (self, other))
- retval = self.copy()
- retval[self._len:self._len] = other
- return retval
-
- def __mul__(self, multiplier):
- #rprt('%r.__mul__(%r)\n' % (self, multiplier))
- if type(multiplier) != type(0):
- raise TypeError, 'sequence subscript not int'
- if multiplier <= 0:
- return BitVec(0L, 0)
- elif multiplier == 1:
- return self.copy()
- #handle special cases all 0 or all 1...
- if self._data == 0L:
- return BitVec(0L, self._len * multiplier)
- elif (~self)._data == 0L:
- return ~BitVec(0L, self._len * multiplier)
- #otherwise el cheapo again...
- retval = BitVec(0L, 0)
- while multiplier:
- retval, multiplier = retval + self, multiplier - 1
- return retval
-
- def __and__(self, otherseq, *rest):
- #rprt('%r.__and__%r\n' % (self, (otherseq,) + rest))
- if type(otherseq) != type(self):
- otherseq = apply(bitvec, (otherseq, ) + rest)
- #sequence is now of our own type
- return BitVec(self._data & otherseq._data, \
- min(self._len, otherseq._len))
-
-
- def __xor__(self, otherseq, *rest):
- #rprt('%r.__xor__%r\n' % (self, (otherseq,) + rest))
- if type(otherseq) != type(self):
- otherseq = apply(bitvec, (otherseq, ) + rest)
- #sequence is now of our own type
- return BitVec(self._data ^ otherseq._data, \
- max(self._len, otherseq._len))
-
-
- def __or__(self, otherseq, *rest):
- #rprt('%r.__or__%r\n' % (self, (otherseq,) + rest))
- if type(otherseq) != type(self):
- otherseq = apply(bitvec, (otherseq, ) + rest)
- #sequence is now of our own type
- return BitVec(self._data | otherseq._data, \
- max(self._len, otherseq._len))
-
-
- def __invert__(self):
- #rprt('%r.__invert__()\n' % (self,))
- return BitVec(~self._data & ((1L << self._len) - 1), \
- self._len)
-
- def __coerce__(self, otherseq, *rest):
- #needed for *some* of the arithmetic operations
- #rprt('%r.__coerce__%r\n' % (self, (otherseq,) + rest))
- if type(otherseq) != type(self):
- otherseq = apply(bitvec, (otherseq, ) + rest)
- return self, otherseq
-
- def __int__(self):
- return int(self._data)
-
- def __long__(self):
- return long(self._data)
-
- def __float__(self):
- return float(self._data)
-
-
-bitvec = BitVec
diff --git a/Demo/comparisons/README b/Demo/comparisons/README
deleted file mode 100644
index 111667c..0000000
--- a/Demo/comparisons/README
+++ /dev/null
@@ -1,60 +0,0 @@
-Subject: Re: What language would you use?
-From: Tom Christiansen <tchrist@mox.perl.com>
-Date: 6 Nov 1994 15:14:51 GMT
-Newsgroups: comp.lang.python,comp.lang.tcl,comp.lang.scheme,comp.lang.misc,comp.lang.perl
-Message-Id: <39irtb$3t4@csnews.cs.Colorado.EDU>
-References: <39b7ha$j9v@zeno.nscf.org> <39hhjp$lgn@csnews.cs.Colorado.EDU> <39hvsu$dus@mathserv.mps.ohio-state.edu>
-
-[...]
-If you're really into benchmarks, I'd love it if someone were to code up
-the following problems in tcl, python, and scheme (and whatever else you'd
-like). Separate versions (one optimized for speed, one for beauty :-) are
-ok. Post your code so we can time it on our own systems.
-
-0) Factorial Test (numerics and function calls)
-
- (we did this already)
-
-1) Regular Expressions Test
-
- Read a file of (extended per egrep) regular expressions (one per line),
- and apply those to all files whose names are listed on the command line.
- Basically, an 'egrep -f' simulator. Test it with 20 "vt100" patterns
- against a five /etc/termcap files. Tests using more elaborate patters
- would also be interesting. Your code should not break if given hundreds
- of regular expressions or binary files to scan.
-
-2) Sorting Test
-
- Sort an input file that consists of lines like this
-
- var1=23 other=14 ditto=23 fred=2
-
- such that each output line is sorted WRT to the number. Order
- of output lines does not change. Resolve collisions using the
- variable name. e.g.
-
- fred=2 other=14 ditto=23 var1=23
-
- Lines may be up to several kilobytes in length and contain
- zillions of variables.
-
-3) System Test
-
- Given a list of directories, report any bogus symbolic links contained
- anywhere in those subtrees. A bogus symbolic link is one that cannot
- be resolved because it points to a nonexistent or otherwise
- unresolvable file. Do *not* use an external find executable.
- Directories may be very very deep. Print a warning immediately if the
- system you're running on doesn't support symbolic links.
-
-
-I'll post perl solutions if people post the others.
-
-
---tom
---
-Tom Christiansen Perl Consultant, Gamer, Hiker tchrist@mox.perl.com
-
- "But Billy! A *small* allowance prepares you for a lifetime of small
- salaries and for your Social Security payments." --Family Circus
diff --git a/Demo/comparisons/patterns b/Demo/comparisons/patterns
deleted file mode 100755
index f4da846..0000000
--- a/Demo/comparisons/patterns
+++ /dev/null
@@ -1,4 +0,0 @@
-^def
-^class
-^import
-^from
diff --git a/Demo/comparisons/regextest.py b/Demo/comparisons/regextest.py
deleted file mode 100755
index b27d741..0000000
--- a/Demo/comparisons/regextest.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#! /usr/bin/env python
-
-# 1) Regular Expressions Test
-#
-# Read a file of (extended per egrep) regular expressions (one per line),
-# and apply those to all files whose names are listed on the command line.
-# Basically, an 'egrep -f' simulator. Test it with 20 "vt100" patterns
-# against a five /etc/termcap files. Tests using more elaborate patters
-# would also be interesting. Your code should not break if given hundreds
-# of regular expressions or binary files to scan.
-
-# This implementation:
-# - combines all patterns into a single one using ( ... | ... | ... )
-# - reads patterns from stdin, scans files given as command line arguments
-# - produces output in the format <file>:<lineno>:<line>
-# - is only about 2.5 times as slow as egrep (though I couldn't run
-# Tom's test -- this system, a vanilla SGI, only has /etc/terminfo)
-
-import string
-import sys
-import re
-
-def main():
- pats = map(chomp, sys.stdin.readlines())
- bigpat = '(' + '|'.join(pats) + ')'
- prog = re.compile(bigpat)
-
- for file in sys.argv[1:]:
- try:
- fp = open(file, 'r')
- except IOError, msg:
- print "%s: %s" % (file, msg)
- continue
- lineno = 0
- while 1:
- line = fp.readline()
- if not line:
- break
- lineno = lineno + 1
- if prog.search(line):
- print "%s:%s:%s" % (file, lineno, line),
-
-def chomp(s):
- return s.rstrip('\n')
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/comparisons/sortingtest.py b/Demo/comparisons/sortingtest.py
deleted file mode 100755
index 08a73e3..0000000
--- a/Demo/comparisons/sortingtest.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#! /usr/bin/env python
-
-# 2) Sorting Test
-#
-# Sort an input file that consists of lines like this
-#
-# var1=23 other=14 ditto=23 fred=2
-#
-# such that each output line is sorted WRT to the number. Order
-# of output lines does not change. Resolve collisions using the
-# variable name. e.g.
-#
-# fred=2 other=14 ditto=23 var1=23
-#
-# Lines may be up to several kilobytes in length and contain
-# zillions of variables.
-
-# This implementation:
-# - Reads stdin, writes stdout
-# - Uses any amount of whitespace to separate fields
-# - Allows signed numbers
-# - Treats illegally formatted fields as field=0
-# - Outputs the sorted fields with exactly one space between them
-# - Handles blank input lines correctly
-
-import re
-import sys
-
-def main():
- prog = re.compile('^(.*)=([-+]?[0-9]+)')
- def makekey(item, prog=prog):
- match = prog.match(item)
- if match:
- var, num = match.groups()
- return int(num), var
- else:
- # Bad input -- pretend it's a var with value 0
- return 0, item
- for line in sys.stdin:
- items = sorted(makekey(item) for item in line.split())
- for num, var in items:
- print "%s=%s" % (var, num),
- print
-
-main()
diff --git a/Demo/comparisons/systemtest.py b/Demo/comparisons/systemtest.py
deleted file mode 100755
index bbc313b..0000000
--- a/Demo/comparisons/systemtest.py
+++ /dev/null
@@ -1,74 +0,0 @@
-#! /usr/bin/env python
-
-# 3) System Test
-#
-# Given a list of directories, report any bogus symbolic links contained
-# anywhere in those subtrees. A bogus symbolic link is one that cannot
-# be resolved because it points to a nonexistent or otherwise
-# unresolvable file. Do *not* use an external find executable.
-# Directories may be very very deep. Print a warning immediately if the
-# system you're running on doesn't support symbolic links.
-
-# This implementation:
-# - takes one optional argument, using the current directory as default
-# - uses chdir to increase performance
-# - sorts the names per directory
-# - prints output lines of the form "path1 -> path2" as it goes
-# - prints error messages about directories it can't list or chdir into
-
-import os
-import sys
-from stat import *
-
-def main():
- try:
- # Note: can't test for presence of lstat -- it's always there
- dummy = os.readlink
- except AttributeError:
- print "This system doesn't have symbolic links"
- sys.exit(0)
- if sys.argv[1:]:
- prefix = sys.argv[1]
- else:
- prefix = ''
- if prefix:
- os.chdir(prefix)
- if prefix[-1:] != '/': prefix = prefix + '/'
- reportboguslinks(prefix)
- else:
- reportboguslinks('')
-
-def reportboguslinks(prefix):
- try:
- names = os.listdir('.')
- except os.error, msg:
- print "%s%s: can't list: %s" % (prefix, '.', msg)
- return
- names.sort()
- for name in names:
- if name == os.curdir or name == os.pardir:
- continue
- try:
- mode = os.lstat(name)[ST_MODE]
- except os.error:
- print "%s%s: can't stat: %s" % (prefix, name, msg)
- continue
- if S_ISLNK(mode):
- try:
- os.stat(name)
- except os.error:
- print "%s%s -> %s" % \
- (prefix, name, os.readlink(name))
- elif S_ISDIR(mode):
- try:
- os.chdir(name)
- except os.error, msg:
- print "%s%s: can't chdir: %s" % \
- (prefix, name, msg)
- continue
- try:
- reportboguslinks(prefix + name + '/')
- finally:
- os.chdir('..')
-
-main()
diff --git a/Demo/curses/README b/Demo/curses/README
deleted file mode 100644
index 2d1c4b1..0000000
--- a/Demo/curses/README
+++ /dev/null
@@ -1,25 +0,0 @@
-This is a collection of demos and tests for the curses module.
-
-ncurses demos
-=============
-
-These demos are converted from the C versions in the ncurses
-distribution, and were contributed by Thomas Gellekum <tg@FreeBSD.org>
-I didn't strive for a `pythonic' style, but bluntly copied the
-originals. I won't attempt to `beautify' the program anytime soon, but
-I wouldn't mind someone else making an effort in that direction, of
-course.
-
-ncurses.py -- currently only a panels demo
-rain.py -- raindrops keep falling on my desktop
-tclock.py -- ASCII clock, by Howard Jones
-xmas.py -- I'm dreaming of an ASCII christmas
-
-Please submit bugfixes and new contributions to the Python bug tracker.
-
-
-Other demos
-===========
-
-life.py -- Simple game of Life
-repeat.py -- Repeatedly execute a shell command (like watch(1))
diff --git a/Demo/curses/life.py b/Demo/curses/life.py
deleted file mode 100755
index 98fb62e..0000000
--- a/Demo/curses/life.py
+++ /dev/null
@@ -1,216 +0,0 @@
-#!/usr/bin/env python
-# life.py -- A curses-based version of Conway's Game of Life.
-# Contributed by AMK
-#
-# An empty board will be displayed, and the following commands are available:
-# E : Erase the board
-# R : Fill the board randomly
-# S : Step for a single generation
-# C : Update continuously until a key is struck
-# Q : Quit
-# Cursor keys : Move the cursor around the board
-# Space or Enter : Toggle the contents of the cursor's position
-#
-# TODO :
-# Support the mouse
-# Use colour if available
-# Make board updates faster
-#
-
-import random, string, traceback
-import curses
-
-class LifeBoard:
- """Encapsulates a Life board
-
- Attributes:
- X,Y : horizontal and vertical size of the board
- state : dictionary mapping (x,y) to 0 or 1
-
- Methods:
- display(update_board) -- If update_board is true, compute the
- next generation. Then display the state
- of the board and refresh the screen.
- erase() -- clear the entire board
- makeRandom() -- fill the board randomly
- set(y,x) -- set the given cell to Live; doesn't refresh the screen
- toggle(y,x) -- change the given cell from live to dead, or vice
- versa, and refresh the screen display
-
- """
- def __init__(self, scr, char=ord('*')):
- """Create a new LifeBoard instance.
-
- scr -- curses screen object to use for display
- char -- character used to render live cells (default: '*')
- """
- self.state = {}
- self.scr = scr
- Y, X = self.scr.getmaxyx()
- self.X, self.Y = X-2, Y-2-1
- self.char = char
- self.scr.clear()
-
- # Draw a border around the board
- border_line = '+'+(self.X*'-')+'+'
- self.scr.addstr(0, 0, border_line)
- self.scr.addstr(self.Y+1,0, border_line)
- for y in range(0, self.Y):
- self.scr.addstr(1+y, 0, '|')
- self.scr.addstr(1+y, self.X+1, '|')
- self.scr.refresh()
-
- def set(self, y, x):
- """Set a cell to the live state"""
- if x<0 or self.X<=x or y<0 or self.Y<=y:
- raise ValueError, "Coordinates out of range %i,%i"% (y,x)
- self.state[x,y] = 1
-
- def toggle(self, y, x):
- """Toggle a cell's state between live and dead"""
- if x<0 or self.X<=x or y<0 or self.Y<=y:
- raise ValueError, "Coordinates out of range %i,%i"% (y,x)
- if self.state.has_key( (x,y) ):
- del self.state[x,y]
- self.scr.addch(y+1, x+1, ' ')
- else:
- self.state[x,y] = 1
- self.scr.addch(y+1, x+1, self.char)
- self.scr.refresh()
-
- def erase(self):
- """Clear the entire board and update the board display"""
- self.state = {}
- self.display(update_board=False)
-
- def display(self, update_board=True):
- """Display the whole board, optionally computing one generation"""
- M,N = self.X, self.Y
- if not update_board:
- for i in range(0, M):
- for j in range(0, N):
- if self.state.has_key( (i,j) ):
- self.scr.addch(j+1, i+1, self.char)
- else:
- self.scr.addch(j+1, i+1, ' ')
- self.scr.refresh()
- return
-
- d = {}
- self.boring = 1
- for i in range(0, M):
- L = range( max(0, i-1), min(M, i+2) )
- for j in range(0, N):
- s = 0
- live = self.state.has_key( (i,j) )
- for k in range( max(0, j-1), min(N, j+2) ):
- for l in L:
- if self.state.has_key( (l,k) ):
- s += 1
- s -= live
- if s == 3:
- # Birth
- d[i,j] = 1
- self.scr.addch(j+1, i+1, self.char)
- if not live: self.boring = 0
- elif s == 2 and live: d[i,j] = 1 # Survival
- elif live:
- # Death
- self.scr.addch(j+1, i+1, ' ')
- self.boring = 0
- self.state = d
- self.scr.refresh()
-
- def makeRandom(self):
- "Fill the board with a random pattern"
- self.state = {}
- for i in range(0, self.X):
- for j in range(0, self.Y):
- if random.random() > 0.5:
- self.set(j,i)
-
-
-def erase_menu(stdscr, menu_y):
- "Clear the space where the menu resides"
- stdscr.move(menu_y, 0)
- stdscr.clrtoeol()
- stdscr.move(menu_y+1, 0)
- stdscr.clrtoeol()
-
-def display_menu(stdscr, menu_y):
- "Display the menu of possible keystroke commands"
- erase_menu(stdscr, menu_y)
- stdscr.addstr(menu_y, 4,
- 'Use the cursor keys to move, and space or Enter to toggle a cell.')
- stdscr.addstr(menu_y+1, 4,
- 'E)rase the board, R)andom fill, S)tep once or C)ontinuously, Q)uit')
-
-def keyloop(stdscr):
- # Clear the screen and display the menu of keys
- stdscr.clear()
- stdscr_y, stdscr_x = stdscr.getmaxyx()
- menu_y = (stdscr_y-3)-1
- display_menu(stdscr, menu_y)
-
- # Allocate a subwindow for the Life board and create the board object
- subwin = stdscr.subwin(stdscr_y-3, stdscr_x, 0, 0)
- board = LifeBoard(subwin, char=ord('*'))
- board.display(update_board=False)
-
- # xpos, ypos are the cursor's position
- xpos, ypos = board.X//2, board.Y//2
-
- # Main loop:
- while (1):
- stdscr.move(1+ypos, 1+xpos) # Move the cursor
- c = stdscr.getch() # Get a keystroke
- if 0<c<256:
- c = chr(c)
- if c in ' \n':
- board.toggle(ypos, xpos)
- elif c in 'Cc':
- erase_menu(stdscr, menu_y)
- stdscr.addstr(menu_y, 6, ' Hit any key to stop continuously '
- 'updating the screen.')
- stdscr.refresh()
- # Activate nodelay mode; getch() will return -1
- # if no keystroke is available, instead of waiting.
- stdscr.nodelay(1)
- while (1):
- c = stdscr.getch()
- if c != -1:
- break
- stdscr.addstr(0,0, '/')
- stdscr.refresh()
- board.display()
- stdscr.addstr(0,0, '+')
- stdscr.refresh()
-
- stdscr.nodelay(0) # Disable nodelay mode
- display_menu(stdscr, menu_y)
-
- elif c in 'Ee':
- board.erase()
- elif c in 'Qq':
- break
- elif c in 'Rr':
- board.makeRandom()
- board.display(update_board=False)
- elif c in 'Ss':
- board.display()
- else: pass # Ignore incorrect keys
- elif c == curses.KEY_UP and ypos>0: ypos -= 1
- elif c == curses.KEY_DOWN and ypos<board.Y-1: ypos += 1
- elif c == curses.KEY_LEFT and xpos>0: xpos -= 1
- elif c == curses.KEY_RIGHT and xpos<board.X-1: xpos += 1
- else:
- # Ignore incorrect keys
- pass
-
-
-def main(stdscr):
- keyloop(stdscr) # Enter the main loop
-
-
-if __name__ == '__main__':
- curses.wrapper(main)
diff --git a/Demo/curses/ncurses.py b/Demo/curses/ncurses.py
deleted file mode 100644
index 0bdc1a9..0000000
--- a/Demo/curses/ncurses.py
+++ /dev/null
@@ -1,273 +0,0 @@
-#!/usr/bin/env python
-#
-# $Id$
-#
-# (n)curses exerciser in Python, an interactive test for the curses
-# module. Currently, only the panel demos are ported.
-
-import curses
-from curses import panel
-
-def wGetchar(win = None):
- if win is None: win = stdscr
- return win.getch()
-
-def Getchar():
- wGetchar()
-
-#
-# Panels tester
-#
-def wait_a_while():
- if nap_msec == 1:
- Getchar()
- else:
- curses.napms(nap_msec)
-
-def saywhat(text):
- stdscr.move(curses.LINES - 1, 0)
- stdscr.clrtoeol()
- stdscr.addstr(text)
-
-def mkpanel(color, rows, cols, tly, tlx):
- win = curses.newwin(rows, cols, tly, tlx)
- pan = panel.new_panel(win)
- if curses.has_colors():
- if color == curses.COLOR_BLUE:
- fg = curses.COLOR_WHITE
- else:
- fg = curses.COLOR_BLACK
- bg = color
- curses.init_pair(color, fg, bg)
- win.bkgdset(ord(' '), curses.color_pair(color))
- else:
- win.bkgdset(ord(' '), curses.A_BOLD)
-
- return pan
-
-def pflush():
- panel.update_panels()
- curses.doupdate()
-
-def fill_panel(pan):
- win = pan.window()
- num = pan.userptr()[1]
-
- win.move(1, 1)
- win.addstr("-pan%c-" % num)
- win.clrtoeol()
- win.box()
-
- maxy, maxx = win.getmaxyx()
- for y in range(2, maxy - 1):
- for x in range(1, maxx - 1):
- win.move(y, x)
- win.addch(num)
-
-def demo_panels(win):
- global stdscr, nap_msec, mod
- stdscr = win
- nap_msec = 1
- mod = ["test", "TEST", "(**)", "*()*", "<-->", "LAST"]
-
- stdscr.refresh()
-
- for y in range(0, curses.LINES - 1):
- for x in range(0, curses.COLS):
- stdscr.addstr("%d" % ((y + x) % 10))
- for y in range(0, 1):
- p1 = mkpanel(curses.COLOR_RED,
- curses.LINES // 2 - 2,
- curses.COLS // 8 + 1,
- 0,
- 0)
- p1.set_userptr("p1")
-
- p2 = mkpanel(curses.COLOR_GREEN,
- curses.LINES // 2 + 1,
- curses.COLS // 7,
- curses.LINES // 4,
- curses.COLS // 10)
- p2.set_userptr("p2")
-
- p3 = mkpanel(curses.COLOR_YELLOW,
- curses.LINES // 4,
- curses.COLS // 10,
- curses.LINES // 2,
- curses.COLS // 9)
- p3.set_userptr("p3")
-
- p4 = mkpanel(curses.COLOR_BLUE,
- curses.LINES // 2 - 2,
- curses.COLS // 8,
- curses.LINES // 2 - 2,
- curses.COLS // 3)
- p4.set_userptr("p4")
-
- p5 = mkpanel(curses.COLOR_MAGENTA,
- curses.LINES // 2 - 2,
- curses.COLS // 8,
- curses.LINES // 2,
- curses.COLS // 2 - 2)
- p5.set_userptr("p5")
-
- fill_panel(p1)
- fill_panel(p2)
- fill_panel(p3)
- fill_panel(p4)
- fill_panel(p5)
- p4.hide()
- p5.hide()
- pflush()
- saywhat("press any key to continue")
- wait_a_while()
-
- saywhat("h3 s1 s2 s4 s5;press any key to continue")
- p1.move(0, 0)
- p3.hide()
- p1.show()
- p2.show()
- p4.show()
- p5.show()
- pflush()
- wait_a_while()
-
- saywhat("s1; press any key to continue")
- p1.show()
- pflush()
- wait_a_while()
-
- saywhat("s2; press any key to continue")
- p2.show()
- pflush()
- wait_a_while()
-
- saywhat("m2; press any key to continue")
- p2.move(curses.LINES // 3 + 1, curses.COLS // 8)
- pflush()
- wait_a_while()
-
- saywhat("s3; press any key to continue")
- p3.show()
- pflush()
- wait_a_while()
-
- saywhat("m3; press any key to continue")
- p3.move(curses.LINES // 4 + 1, curses.COLS // 15)
- pflush()
- wait_a_while()
-
- saywhat("b3; press any key to continue")
- p3.bottom()
- pflush()
- wait_a_while()
-
- saywhat("s4; press any key to continue")
- p4.show()
- pflush()
- wait_a_while()
-
- saywhat("s5; press any key to continue")
- p5.show()
- pflush()
- wait_a_while()
-
- saywhat("t3; press any key to continue")
- p3.top()
- pflush()
- wait_a_while()
-
- saywhat("t1; press any key to continue")
- p1.show()
- pflush()
- wait_a_while()
-
- saywhat("t2; press any key to continue")
- p2.show()
- pflush()
- wait_a_while()
-
- saywhat("t3; press any key to continue")
- p3.show()
- pflush()
- wait_a_while()
-
- saywhat("t4; press any key to continue")
- p4.show()
- pflush()
- wait_a_while()
-
- for itmp in range(0, 6):
- w4 = p4.window()
- w5 = p5.window()
-
- saywhat("m4; press any key to continue")
- w4.move(curses.LINES // 8, 1)
- w4.addstr(mod[itmp])
- p4.move(curses.LINES // 6, itmp * curses.COLS // 8)
- w5.move(curses.LINES // 6, 1)
- w5.addstr(mod[itmp])
- pflush()
- wait_a_while()
-
- saywhat("m5; press any key to continue")
- w4.move(curses.LINES // 6, 1)
- w4.addstr(mod[itmp])
- p5.move(curses.LINES // 3 - 1, itmp * 10 + 6)
- w5.move(curses.LINES // 8, 1)
- w5.addstr(mod[itmp])
- pflush()
- wait_a_while()
-
- saywhat("m4; press any key to continue")
- p4.move(curses.LINES // 6, (itmp + 1) * curses.COLS // 8)
- pflush()
- wait_a_while()
-
- saywhat("t5; press any key to continue")
- p5.top()
- pflush()
- wait_a_while()
-
- saywhat("t2; press any key to continue")
- p2.top()
- pflush()
- wait_a_while()
-
- saywhat("t1; press any key to continue")
- p1.top()
- pflush()
- wait_a_while()
-
- saywhat("d2; press any key to continue")
- del p2
- pflush()
- wait_a_while()
-
- saywhat("h3; press any key to continue")
- p3.hide()
- pflush()
- wait_a_while()
-
- saywhat("d1; press any key to continue")
- del p1
- pflush()
- wait_a_while()
-
- saywhat("d4; press any key to continue")
- del p4
- pflush()
- wait_a_while()
-
- saywhat("d5; press any key to continue")
- del p5
- pflush()
- wait_a_while()
- if nap_msec == 1:
- break
- nap_msec = 100
-
-#
-# one fine day there'll be the menu at this place
-#
-curses.wrapper(demo_panels)
diff --git a/Demo/curses/rain.py b/Demo/curses/rain.py
deleted file mode 100644
index 9d46e6e..0000000
--- a/Demo/curses/rain.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env python
-#
-# $Id$
-#
-# somebody should probably check the randrange()s...
-
-import curses
-from random import randrange
-
-def next_j(j):
- if j == 0:
- j = 4
- else:
- j -= 1
-
- if curses.has_colors():
- z = randrange(0, 3)
- color = curses.color_pair(z)
- if z:
- color = color | curses.A_BOLD
- stdscr.attrset(color)
-
- return j
-
-def main(win):
- # we know that the first argument from curses.wrapper() is stdscr.
- # Initialize it globally for convenience.
- global stdscr
- stdscr = win
-
- if curses.has_colors():
- bg = curses.COLOR_BLACK
- curses.init_pair(1, curses.COLOR_BLUE, bg)
- curses.init_pair(2, curses.COLOR_CYAN, bg)
-
- curses.nl()
- curses.noecho()
- # XXX curs_set() always returns ERR
- # curses.curs_set(0)
- stdscr.timeout(0)
-
- c = curses.COLS - 4
- r = curses.LINES - 4
- xpos = [0] * c
- ypos = [0] * r
- for j in range(4, -1, -1):
- xpos[j] = randrange(0, c) + 2
- ypos[j] = randrange(0, r) + 2
-
- j = 0
- while True:
- x = randrange(0, c) + 2
- y = randrange(0, r) + 2
-
- stdscr.addch(y, x, ord('.'))
-
- stdscr.addch(ypos[j], xpos[j], ord('o'))
-
- j = next_j(j)
- stdscr.addch(ypos[j], xpos[j], ord('O'))
-
- j = next_j(j)
- stdscr.addch( ypos[j] - 1, xpos[j], ord('-'))
- stdscr.addstr(ypos[j], xpos[j] - 1, "|.|")
- stdscr.addch( ypos[j] + 1, xpos[j], ord('-'))
-
- j = next_j(j)
- stdscr.addch( ypos[j] - 2, xpos[j], ord('-'))
- stdscr.addstr(ypos[j] - 1, xpos[j] - 1, "/ \\")
- stdscr.addstr(ypos[j], xpos[j] - 2, "| O |")
- stdscr.addstr(ypos[j] + 1, xpos[j] - 1, "\\ /")
- stdscr.addch( ypos[j] + 2, xpos[j], ord('-'))
-
- j = next_j(j)
- stdscr.addch( ypos[j] - 2, xpos[j], ord(' '))
- stdscr.addstr(ypos[j] - 1, xpos[j] - 1, " ")
- stdscr.addstr(ypos[j], xpos[j] - 2, " ")
- stdscr.addstr(ypos[j] + 1, xpos[j] - 1, " ")
- stdscr.addch( ypos[j] + 2, xpos[j], ord(' '))
-
- xpos[j] = x
- ypos[j] = y
-
- ch = stdscr.getch()
- if ch == ord('q') or ch == ord('Q'):
- return
- elif ch == ord('s'):
- stdscr.nodelay(0)
- elif ch == ord(' '):
- stdscr.nodelay(1)
-
- curses.napms(50)
-
-curses.wrapper(main)
diff --git a/Demo/curses/repeat.py b/Demo/curses/repeat.py
deleted file mode 100755
index fa7daac..0000000
--- a/Demo/curses/repeat.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#! /usr/bin/env python
-
-"""repeat <shell-command>
-
-This simple program repeatedly (at 1-second intervals) executes the
-shell command given on the command line and displays the output (or as
-much of it as fits on the screen). It uses curses to paint each new
-output on top of the old output, so that if nothing changes, the
-screen doesn't change. This is handy to watch for changes in e.g. a
-directory or process listing.
-
-To end, hit Control-C.
-"""
-
-# Author: Guido van Rossum
-
-# Disclaimer: there's a Linux program named 'watch' that does the same
-# thing. Honestly, I didn't know of its existence when I wrote this!
-
-# To do: add features until it has the same functionality as watch(1);
-# then compare code size and development time.
-
-import os
-import sys
-import time
-import curses
-
-def main():
- if not sys.argv[1:]:
- print __doc__
- sys.exit(0)
- cmd = " ".join(sys.argv[1:])
- p = os.popen(cmd, "r")
- text = p.read()
- sts = p.close()
- if sts:
- print >>sys.stderr, "Exit code:", sts
- sys.exit(sts)
- w = curses.initscr()
- try:
- while True:
- w.erase()
- try:
- w.addstr(text)
- except curses.error:
- pass
- w.refresh()
- time.sleep(1)
- p = os.popen(cmd, "r")
- text = p.read()
- sts = p.close()
- if sts:
- print >>sys.stderr, "Exit code:", sts
- sys.exit(sts)
- finally:
- curses.endwin()
-
-main()
diff --git a/Demo/curses/tclock.py b/Demo/curses/tclock.py
deleted file mode 100644
index 8058d9a..0000000
--- a/Demo/curses/tclock.py
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/usr/bin/env python
-#
-# $Id$
-#
-# From tclock.c, Copyright Howard Jones <ha.jones@ic.ac.uk>, September 1994.
-
-from math import *
-import curses, time
-
-ASPECT = 2.2
-
-def sign(_x):
- if _x < 0: return -1
- return 1
-
-def A2XY(angle, radius):
- return (int(round(ASPECT * radius * sin(angle))),
- int(round(radius * cos(angle))))
-
-def plot(x, y, col):
- stdscr.addch(y, x, col)
-
-# draw a diagonal line using Bresenham's algorithm
-def dline(pair, from_x, from_y, x2, y2, ch):
- if curses.has_colors():
- stdscr.attrset(curses.color_pair(pair))
-
- dx = x2 - from_x
- dy = y2 - from_y
-
- ax = abs(dx * 2)
- ay = abs(dy * 2)
-
- sx = sign(dx)
- sy = sign(dy)
-
- x = from_x
- y = from_y
-
- if ax > ay:
- d = ay - ax // 2
-
- while True:
- plot(x, y, ch)
- if x == x2:
- return
-
- if d >= 0:
- y += sy
- d -= ax
- x += sx
- d += ay
- else:
- d = ax - ay // 2
-
- while True:
- plot(x, y, ch)
- if y == y2:
- return
-
- if d >= 0:
- x += sx
- d -= ay
- y += sy
- d += ax
-
-def main(win):
- global stdscr
- stdscr = win
-
- lastbeep = -1
- my_bg = curses.COLOR_BLACK
-
- stdscr.nodelay(1)
- stdscr.timeout(0)
-# curses.curs_set(0)
- if curses.has_colors():
- curses.init_pair(1, curses.COLOR_RED, my_bg)
- curses.init_pair(2, curses.COLOR_MAGENTA, my_bg)
- curses.init_pair(3, curses.COLOR_GREEN, my_bg)
-
- cx = (curses.COLS - 1) // 2
- cy = curses.LINES // 2
- ch = min( cy-1, int(cx // ASPECT) - 1)
- mradius = (3 * ch) // 4
- hradius = ch // 2
- sradius = 5 * ch // 6
-
- for i in range(0, 12):
- sangle = (i + 1) * 2.0 * pi / 12.0
- sdx, sdy = A2XY(sangle, sradius)
-
- stdscr.addstr(cy - sdy, cx + sdx, "%d" % (i + 1))
-
- stdscr.addstr(0, 0,
- "ASCII Clock by Howard Jones <ha.jones@ic.ac.uk>, 1994")
-
- sradius = max(sradius-4, 8)
-
- while True:
- curses.napms(1000)
-
- tim = time.time()
- t = time.localtime(tim)
-
- hours = t[3] + t[4] / 60.0
- if hours > 12.0:
- hours -= 12.0
-
- mangle = t[4] * 2 * pi / 60.0
- mdx, mdy = A2XY(mangle, mradius)
-
- hangle = hours * 2 * pi / 12.0
- hdx, hdy = A2XY(hangle, hradius)
-
- sangle = t[5] * 2 * pi / 60.0
- sdx, sdy = A2XY(sangle, sradius)
-
- dline(3, cx, cy, cx + mdx, cy - mdy, ord('#'))
-
- stdscr.attrset(curses.A_REVERSE)
- dline(2, cx, cy, cx + hdx, cy - hdy, ord('.'))
- stdscr.attroff(curses.A_REVERSE)
-
- if curses.has_colors():
- stdscr.attrset(curses.color_pair(1))
-
- plot(cx + sdx, cy - sdy, ord('O'))
-
- if curses.has_colors():
- stdscr.attrset(curses.color_pair(0))
-
- stdscr.addstr(curses.LINES - 2, 0, time.ctime(tim))
- stdscr.refresh()
- if (t[5] % 5) == 0 and t[5] != lastbeep:
- lastbeep = t[5]
- curses.beep()
-
- ch = stdscr.getch()
- if ch == ord('q'):
- return 0
-
- plot(cx + sdx, cy - sdy, ord(' '))
- dline(0, cx, cy, cx + hdx, cy - hdy, ord(' '))
- dline(0, cx, cy, cx + mdx, cy - mdy, ord(' '))
-
-curses.wrapper(main)
diff --git a/Demo/curses/xmas.py b/Demo/curses/xmas.py
deleted file mode 100644
index 349b3a8..0000000
--- a/Demo/curses/xmas.py
+++ /dev/null
@@ -1,906 +0,0 @@
-# asciixmas
-# December 1989 Larry Bartz Indianapolis, IN
-#
-# $Id$
-#
-# I'm dreaming of an ascii character-based monochrome Christmas,
-# Just like the ones I used to know!
-# Via a full duplex communications channel,
-# At 9600 bits per second,
-# Even though it's kinda slow.
-#
-# I'm dreaming of an ascii character-based monochrome Christmas,
-# With ev'ry C program I write!
-# May your screen be merry and bright!
-# And may all your Christmases be amber or green,
-# (for reduced eyestrain and improved visibility)!
-#
-#
-# Notes on the Python version:
-# I used a couple of `try...except curses.error' to get around some functions
-# returning ERR. The errors come from using wrapping functions to fill
-# windows to the last character cell. The C version doesn't have this problem,
-# it simply ignores any return values.
-#
-
-import curses
-import sys
-
-FROMWHO = "Thomas Gellekum <tg@FreeBSD.org>"
-
-def set_color(win, color):
- if curses.has_colors():
- n = color + 1
- curses.init_pair(n, color, my_bg)
- win.attroff(curses.A_COLOR)
- win.attron(curses.color_pair(n))
-
-def unset_color(win):
- if curses.has_colors():
- win.attrset(curses.color_pair(0))
-
-def look_out(msecs):
- curses.napms(msecs)
- if stdscr.getch() != -1:
- curses.beep()
- sys.exit(0)
-
-def boxit():
- for y in range(0, 20):
- stdscr.addch(y, 7, ord('|'))
-
- for x in range(8, 80):
- stdscr.addch(19, x, ord('_'))
-
- for x in range(0, 80):
- stdscr.addch(22, x, ord('_'))
-
- return
-
-def seas():
- stdscr.addch(4, 1, ord('S'))
- stdscr.addch(6, 1, ord('E'))
- stdscr.addch(8, 1, ord('A'))
- stdscr.addch(10, 1, ord('S'))
- stdscr.addch(12, 1, ord('O'))
- stdscr.addch(14, 1, ord('N'))
- stdscr.addch(16, 1, ord("'"))
- stdscr.addch(18, 1, ord('S'))
-
- return
-
-def greet():
- stdscr.addch(3, 5, ord('G'))
- stdscr.addch(5, 5, ord('R'))
- stdscr.addch(7, 5, ord('E'))
- stdscr.addch(9, 5, ord('E'))
- stdscr.addch(11, 5, ord('T'))
- stdscr.addch(13, 5, ord('I'))
- stdscr.addch(15, 5, ord('N'))
- stdscr.addch(17, 5, ord('G'))
- stdscr.addch(19, 5, ord('S'))
-
- return
-
-def fromwho():
- stdscr.addstr(21, 13, FROMWHO)
- return
-
-def tree():
- set_color(treescrn, curses.COLOR_GREEN)
- treescrn.addch(1, 11, ord('/'))
- treescrn.addch(2, 11, ord('/'))
- treescrn.addch(3, 10, ord('/'))
- treescrn.addch(4, 9, ord('/'))
- treescrn.addch(5, 9, ord('/'))
- treescrn.addch(6, 8, ord('/'))
- treescrn.addch(7, 7, ord('/'))
- treescrn.addch(8, 6, ord('/'))
- treescrn.addch(9, 6, ord('/'))
- treescrn.addch(10, 5, ord('/'))
- treescrn.addch(11, 3, ord('/'))
- treescrn.addch(12, 2, ord('/'))
-
- treescrn.addch(1, 13, ord('\\'))
- treescrn.addch(2, 13, ord('\\'))
- treescrn.addch(3, 14, ord('\\'))
- treescrn.addch(4, 15, ord('\\'))
- treescrn.addch(5, 15, ord('\\'))
- treescrn.addch(6, 16, ord('\\'))
- treescrn.addch(7, 17, ord('\\'))
- treescrn.addch(8, 18, ord('\\'))
- treescrn.addch(9, 18, ord('\\'))
- treescrn.addch(10, 19, ord('\\'))
- treescrn.addch(11, 21, ord('\\'))
- treescrn.addch(12, 22, ord('\\'))
-
- treescrn.addch(4, 10, ord('_'))
- treescrn.addch(4, 14, ord('_'))
- treescrn.addch(8, 7, ord('_'))
- treescrn.addch(8, 17, ord('_'))
-
- treescrn.addstr(13, 0, "//////////// \\\\\\\\\\\\\\\\\\\\\\\\")
-
- treescrn.addstr(14, 11, "| |")
- treescrn.addstr(15, 11, "|_|")
-
- unset_color(treescrn)
- treescrn.refresh()
- w_del_msg.refresh()
-
- return
-
-def balls():
- treescrn.overlay(treescrn2)
-
- set_color(treescrn2, curses.COLOR_BLUE)
- treescrn2.addch(3, 9, ord('@'))
- treescrn2.addch(3, 15, ord('@'))
- treescrn2.addch(4, 8, ord('@'))
- treescrn2.addch(4, 16, ord('@'))
- treescrn2.addch(5, 7, ord('@'))
- treescrn2.addch(5, 17, ord('@'))
- treescrn2.addch(7, 6, ord('@'))
- treescrn2.addch(7, 18, ord('@'))
- treescrn2.addch(8, 5, ord('@'))
- treescrn2.addch(8, 19, ord('@'))
- treescrn2.addch(10, 4, ord('@'))
- treescrn2.addch(10, 20, ord('@'))
- treescrn2.addch(11, 2, ord('@'))
- treescrn2.addch(11, 22, ord('@'))
- treescrn2.addch(12, 1, ord('@'))
- treescrn2.addch(12, 23, ord('@'))
-
- unset_color(treescrn2)
- treescrn2.refresh()
- w_del_msg.refresh()
- return
-
-def star():
- treescrn2.attrset(curses.A_BOLD | curses.A_BLINK)
- set_color(treescrn2, curses.COLOR_YELLOW)
-
- treescrn2.addch(0, 12, ord('*'))
- treescrn2.standend()
-
- unset_color(treescrn2)
- treescrn2.refresh()
- w_del_msg.refresh()
- return
-
-def strng1():
- treescrn2.attrset(curses.A_BOLD | curses.A_BLINK)
- set_color(treescrn2, curses.COLOR_WHITE)
-
- treescrn2.addch(3, 13, ord('\''))
- treescrn2.addch(3, 12, ord(':'))
- treescrn2.addch(3, 11, ord('.'))
-
- treescrn2.attroff(curses.A_BOLD | curses.A_BLINK)
- unset_color(treescrn2)
-
- treescrn2.refresh()
- w_del_msg.refresh()
- return
-
-def strng2():
- treescrn2.attrset(curses.A_BOLD | curses.A_BLINK)
- set_color(treescrn2, curses.COLOR_WHITE)
-
- treescrn2.addch(5, 14, ord('\''))
- treescrn2.addch(5, 13, ord(':'))
- treescrn2.addch(5, 12, ord('.'))
- treescrn2.addch(5, 11, ord(','))
- treescrn2.addch(6, 10, ord('\''))
- treescrn2.addch(6, 9, ord(':'))
-
- treescrn2.attroff(curses.A_BOLD | curses.A_BLINK)
- unset_color(treescrn2)
-
- treescrn2.refresh()
- w_del_msg.refresh()
- return
-
-def strng3():
- treescrn2.attrset(curses.A_BOLD | curses.A_BLINK)
- set_color(treescrn2, curses.COLOR_WHITE)
-
- treescrn2.addch(7, 16, ord('\''))
- treescrn2.addch(7, 15, ord(':'))
- treescrn2.addch(7, 14, ord('.'))
- treescrn2.addch(7, 13, ord(','))
- treescrn2.addch(8, 12, ord('\''))
- treescrn2.addch(8, 11, ord(':'))
- treescrn2.addch(8, 10, ord('.'))
- treescrn2.addch(8, 9, ord(','))
-
- treescrn2.attroff(curses.A_BOLD | curses.A_BLINK)
- unset_color(treescrn2)
-
- treescrn2.refresh()
- w_del_msg.refresh()
- return
-
-def strng4():
- treescrn2.attrset(curses.A_BOLD | curses.A_BLINK)
- set_color(treescrn2, curses.COLOR_WHITE)
-
- treescrn2.addch(9, 17, ord('\''))
- treescrn2.addch(9, 16, ord(':'))
- treescrn2.addch(9, 15, ord('.'))
- treescrn2.addch(9, 14, ord(','))
- treescrn2.addch(10, 13, ord('\''))
- treescrn2.addch(10, 12, ord(':'))
- treescrn2.addch(10, 11, ord('.'))
- treescrn2.addch(10, 10, ord(','))
- treescrn2.addch(11, 9, ord('\''))
- treescrn2.addch(11, 8, ord(':'))
- treescrn2.addch(11, 7, ord('.'))
- treescrn2.addch(11, 6, ord(','))
- treescrn2.addch(12, 5, ord('\''))
-
- treescrn2.attroff(curses.A_BOLD | curses.A_BLINK)
- unset_color(treescrn2)
-
- treescrn2.refresh()
- w_del_msg.refresh()
- return
-
-def strng5():
- treescrn2.attrset(curses.A_BOLD | curses.A_BLINK)
- set_color(treescrn2, curses.COLOR_WHITE)
-
- treescrn2.addch(11, 19, ord('\''))
- treescrn2.addch(11, 18, ord(':'))
- treescrn2.addch(11, 17, ord('.'))
- treescrn2.addch(11, 16, ord(','))
- treescrn2.addch(12, 15, ord('\''))
- treescrn2.addch(12, 14, ord(':'))
- treescrn2.addch(12, 13, ord('.'))
- treescrn2.addch(12, 12, ord(','))
-
- treescrn2.attroff(curses.A_BOLD | curses.A_BLINK)
- unset_color(treescrn2)
-
- # save a fully lit tree
- treescrn2.overlay(treescrn)
-
- treescrn2.refresh()
- w_del_msg.refresh()
- return
-
-def blinkit():
- treescrn8.touchwin()
-
- for cycle in range(5):
- if cycle == 0:
- treescrn3.overlay(treescrn8)
- treescrn8.refresh()
- w_del_msg.refresh()
- break
- elif cycle == 1:
- treescrn4.overlay(treescrn8)
- treescrn8.refresh()
- w_del_msg.refresh()
- break
- elif cycle == 2:
- treescrn5.overlay(treescrn8)
- treescrn8.refresh()
- w_del_msg.refresh()
- break
- elif cycle == 3:
- treescrn6.overlay(treescrn8)
- treescrn8.refresh()
- w_del_msg.refresh()
- break
- elif cycle == 4:
- treescrn7.overlay(treescrn8)
- treescrn8.refresh()
- w_del_msg.refresh()
- break
-
- treescrn8.touchwin()
-
- # ALL ON
- treescrn.overlay(treescrn8)
- treescrn8.refresh()
- w_del_msg.refresh()
-
- return
-
-def deer_step(win, y, x):
- win.mvwin(y, x)
- win.refresh()
- w_del_msg.refresh()
- look_out(5)
-
-def reindeer():
- y_pos = 0
-
- for x_pos in range(70, 62, -1):
- if x_pos < 66: y_pos = 1
- for looper in range(0, 4):
- dotdeer0.addch(y_pos, x_pos, ord('.'))
- dotdeer0.refresh()
- w_del_msg.refresh()
- dotdeer0.erase()
- dotdeer0.refresh()
- w_del_msg.refresh()
- look_out(50)
-
- y_pos = 2
-
- for x_pos in range(x_pos - 1, 50, -1):
- for looper in range(0, 4):
- if x_pos < 56:
- y_pos = 3
-
- try:
- stardeer0.addch(y_pos, x_pos, ord('*'))
- except curses.error:
- pass
- stardeer0.refresh()
- w_del_msg.refresh()
- stardeer0.erase()
- stardeer0.refresh()
- w_del_msg.refresh()
- else:
- dotdeer0.addch(y_pos, x_pos, ord('*'))
- dotdeer0.refresh()
- w_del_msg.refresh()
- dotdeer0.erase()
- dotdeer0.refresh()
- w_del_msg.refresh()
-
- x_pos = 58
-
- for y_pos in range(2, 5):
- lildeer0.touchwin()
- lildeer0.refresh()
- w_del_msg.refresh()
-
- for looper in range(0, 4):
- deer_step(lildeer3, y_pos, x_pos)
- deer_step(lildeer2, y_pos, x_pos)
- deer_step(lildeer1, y_pos, x_pos)
- deer_step(lildeer2, y_pos, x_pos)
- deer_step(lildeer3, y_pos, x_pos)
-
- lildeer0.touchwin()
- lildeer0.refresh()
- w_del_msg.refresh()
-
- x_pos -= 2
-
- x_pos = 35
-
- for y_pos in range(5, 10):
-
- middeer0.touchwin()
- middeer0.refresh()
- w_del_msg.refresh()
-
- for looper in range(2):
- deer_step(middeer3, y_pos, x_pos)
- deer_step(middeer2, y_pos, x_pos)
- deer_step(middeer1, y_pos, x_pos)
- deer_step(middeer2, y_pos, x_pos)
- deer_step(middeer3, y_pos, x_pos)
-
- middeer0.touchwin()
- middeer0.refresh()
- w_del_msg.refresh()
-
- x_pos -= 3
-
- look_out(300)
-
- y_pos = 1
-
- for x_pos in range(8, 16):
- deer_step(bigdeer4, y_pos, x_pos)
- deer_step(bigdeer3, y_pos, x_pos)
- deer_step(bigdeer2, y_pos, x_pos)
- deer_step(bigdeer1, y_pos, x_pos)
- deer_step(bigdeer2, y_pos, x_pos)
- deer_step(bigdeer3, y_pos, x_pos)
- deer_step(bigdeer4, y_pos, x_pos)
- deer_step(bigdeer0, y_pos, x_pos)
-
- x_pos -= 1
-
- for looper in range(0, 6):
- deer_step(lookdeer4, y_pos, x_pos)
- deer_step(lookdeer3, y_pos, x_pos)
- deer_step(lookdeer2, y_pos, x_pos)
- deer_step(lookdeer1, y_pos, x_pos)
- deer_step(lookdeer2, y_pos, x_pos)
- deer_step(lookdeer3, y_pos, x_pos)
- deer_step(lookdeer4, y_pos, x_pos)
-
- deer_step(lookdeer0, y_pos, x_pos)
-
- for y_pos in range(y_pos, 10):
- for looper in range(0, 2):
- deer_step(bigdeer4, y_pos, x_pos)
- deer_step(bigdeer3, y_pos, x_pos)
- deer_step(bigdeer2, y_pos, x_pos)
- deer_step(bigdeer1, y_pos, x_pos)
- deer_step(bigdeer2, y_pos, x_pos)
- deer_step(bigdeer3, y_pos, x_pos)
- deer_step(bigdeer4, y_pos, x_pos)
- deer_step(bigdeer0, y_pos, x_pos)
-
- y_pos -= 1
-
- deer_step(lookdeer3, y_pos, x_pos)
- return
-
-def main(win):
- global stdscr
- stdscr = win
-
- global my_bg, y_pos, x_pos
- global treescrn, treescrn2, treescrn3, treescrn4
- global treescrn5, treescrn6, treescrn7, treescrn8
- global dotdeer0, stardeer0
- global lildeer0, lildeer1, lildeer2, lildeer3
- global middeer0, middeer1, middeer2, middeer3
- global bigdeer0, bigdeer1, bigdeer2, bigdeer3, bigdeer4
- global lookdeer0, lookdeer1, lookdeer2, lookdeer3, lookdeer4
- global w_holiday, w_del_msg
-
- my_bg = curses.COLOR_BLACK
- # curses.curs_set(0)
-
- treescrn = curses.newwin(16, 27, 3, 53)
- treescrn2 = curses.newwin(16, 27, 3, 53)
- treescrn3 = curses.newwin(16, 27, 3, 53)
- treescrn4 = curses.newwin(16, 27, 3, 53)
- treescrn5 = curses.newwin(16, 27, 3, 53)
- treescrn6 = curses.newwin(16, 27, 3, 53)
- treescrn7 = curses.newwin(16, 27, 3, 53)
- treescrn8 = curses.newwin(16, 27, 3, 53)
-
- dotdeer0 = curses.newwin(3, 71, 0, 8)
-
- stardeer0 = curses.newwin(4, 56, 0, 8)
-
- lildeer0 = curses.newwin(7, 53, 0, 8)
- lildeer1 = curses.newwin(2, 4, 0, 0)
- lildeer2 = curses.newwin(2, 4, 0, 0)
- lildeer3 = curses.newwin(2, 4, 0, 0)
-
- middeer0 = curses.newwin(15, 42, 0, 8)
- middeer1 = curses.newwin(3, 7, 0, 0)
- middeer2 = curses.newwin(3, 7, 0, 0)
- middeer3 = curses.newwin(3, 7, 0, 0)
-
- bigdeer0 = curses.newwin(10, 23, 0, 0)
- bigdeer1 = curses.newwin(10, 23, 0, 0)
- bigdeer2 = curses.newwin(10, 23, 0, 0)
- bigdeer3 = curses.newwin(10, 23, 0, 0)
- bigdeer4 = curses.newwin(10, 23, 0, 0)
-
- lookdeer0 = curses.newwin(10, 25, 0, 0)
- lookdeer1 = curses.newwin(10, 25, 0, 0)
- lookdeer2 = curses.newwin(10, 25, 0, 0)
- lookdeer3 = curses.newwin(10, 25, 0, 0)
- lookdeer4 = curses.newwin(10, 25, 0, 0)
-
- w_holiday = curses.newwin(1, 27, 3, 27)
-
- w_del_msg = curses.newwin(1, 20, 23, 60)
-
- try:
- w_del_msg.addstr(0, 0, "Hit any key to quit")
- except curses.error:
- pass
-
- try:
- w_holiday.addstr(0, 0, "H A P P Y H O L I D A Y S")
- except curses.error:
- pass
-
- # set up the windows for our various reindeer
- lildeer1.addch(0, 0, ord('V'))
- lildeer1.addch(1, 0, ord('@'))
- lildeer1.addch(1, 1, ord('<'))
- lildeer1.addch(1, 2, ord('>'))
- try:
- lildeer1.addch(1, 3, ord('~'))
- except curses.error:
- pass
-
- lildeer2.addch(0, 0, ord('V'))
- lildeer2.addch(1, 0, ord('@'))
- lildeer2.addch(1, 1, ord('|'))
- lildeer2.addch(1, 2, ord('|'))
- try:
- lildeer2.addch(1, 3, ord('~'))
- except curses.error:
- pass
-
- lildeer3.addch(0, 0, ord('V'))
- lildeer3.addch(1, 0, ord('@'))
- lildeer3.addch(1, 1, ord('>'))
- lildeer3.addch(1, 2, ord('<'))
- try:
- lildeer2.addch(1, 3, ord('~')) # XXX
- except curses.error:
- pass
-
- middeer1.addch(0, 2, ord('y'))
- middeer1.addch(0, 3, ord('y'))
- middeer1.addch(1, 2, ord('0'))
- middeer1.addch(1, 3, ord('('))
- middeer1.addch(1, 4, ord('='))
- middeer1.addch(1, 5, ord(')'))
- middeer1.addch(1, 6, ord('~'))
- middeer1.addch(2, 3, ord('\\'))
- middeer1.addch(2, 5, ord('/'))
-
- middeer2.addch(0, 2, ord('y'))
- middeer2.addch(0, 3, ord('y'))
- middeer2.addch(1, 2, ord('0'))
- middeer2.addch(1, 3, ord('('))
- middeer2.addch(1, 4, ord('='))
- middeer2.addch(1, 5, ord(')'))
- middeer2.addch(1, 6, ord('~'))
- middeer2.addch(2, 3, ord('|'))
- middeer2.addch(2, 5, ord('|'))
-
- middeer3.addch(0, 2, ord('y'))
- middeer3.addch(0, 3, ord('y'))
- middeer3.addch(1, 2, ord('0'))
- middeer3.addch(1, 3, ord('('))
- middeer3.addch(1, 4, ord('='))
- middeer3.addch(1, 5, ord(')'))
- middeer3.addch(1, 6, ord('~'))
- middeer3.addch(2, 3, ord('/'))
- middeer3.addch(2, 5, ord('\\'))
-
- bigdeer1.addch(0, 17, ord('\\'))
- bigdeer1.addch(0, 18, ord('/'))
- bigdeer1.addch(0, 19, ord('\\'))
- bigdeer1.addch(0, 20, ord('/'))
- bigdeer1.addch(1, 18, ord('\\'))
- bigdeer1.addch(1, 20, ord('/'))
- bigdeer1.addch(2, 19, ord('|'))
- bigdeer1.addch(2, 20, ord('_'))
- bigdeer1.addch(3, 18, ord('/'))
- bigdeer1.addch(3, 19, ord('^'))
- bigdeer1.addch(3, 20, ord('0'))
- bigdeer1.addch(3, 21, ord('\\'))
- bigdeer1.addch(4, 17, ord('/'))
- bigdeer1.addch(4, 18, ord('/'))
- bigdeer1.addch(4, 19, ord('\\'))
- bigdeer1.addch(4, 22, ord('\\'))
- bigdeer1.addstr(5, 7, "^~~~~~~~~// ~~U")
- bigdeer1.addstr(6, 7, "( \\_____( /") # ))
- bigdeer1.addstr(7, 8, "( ) /")
- bigdeer1.addstr(8, 9, "\\\\ /")
- bigdeer1.addstr(9, 11, "\\>/>")
-
- bigdeer2.addch(0, 17, ord('\\'))
- bigdeer2.addch(0, 18, ord('/'))
- bigdeer2.addch(0, 19, ord('\\'))
- bigdeer2.addch(0, 20, ord('/'))
- bigdeer2.addch(1, 18, ord('\\'))
- bigdeer2.addch(1, 20, ord('/'))
- bigdeer2.addch(2, 19, ord('|'))
- bigdeer2.addch(2, 20, ord('_'))
- bigdeer2.addch(3, 18, ord('/'))
- bigdeer2.addch(3, 19, ord('^'))
- bigdeer2.addch(3, 20, ord('0'))
- bigdeer2.addch(3, 21, ord('\\'))
- bigdeer2.addch(4, 17, ord('/'))
- bigdeer2.addch(4, 18, ord('/'))
- bigdeer2.addch(4, 19, ord('\\'))
- bigdeer2.addch(4, 22, ord('\\'))
- bigdeer2.addstr(5, 7, "^~~~~~~~~// ~~U")
- bigdeer2.addstr(6, 7, "(( )____( /") # ))
- bigdeer2.addstr(7, 7, "( / |")
- bigdeer2.addstr(8, 8, "\\/ |")
- bigdeer2.addstr(9, 9, "|> |>")
-
- bigdeer3.addch(0, 17, ord('\\'))
- bigdeer3.addch(0, 18, ord('/'))
- bigdeer3.addch(0, 19, ord('\\'))
- bigdeer3.addch(0, 20, ord('/'))
- bigdeer3.addch(1, 18, ord('\\'))
- bigdeer3.addch(1, 20, ord('/'))
- bigdeer3.addch(2, 19, ord('|'))
- bigdeer3.addch(2, 20, ord('_'))
- bigdeer3.addch(3, 18, ord('/'))
- bigdeer3.addch(3, 19, ord('^'))
- bigdeer3.addch(3, 20, ord('0'))
- bigdeer3.addch(3, 21, ord('\\'))
- bigdeer3.addch(4, 17, ord('/'))
- bigdeer3.addch(4, 18, ord('/'))
- bigdeer3.addch(4, 19, ord('\\'))
- bigdeer3.addch(4, 22, ord('\\'))
- bigdeer3.addstr(5, 7, "^~~~~~~~~// ~~U")
- bigdeer3.addstr(6, 6, "( ()_____( /") # ))
- bigdeer3.addstr(7, 6, "/ / /")
- bigdeer3.addstr(8, 5, "|/ \\")
- bigdeer3.addstr(9, 5, "/> \\>")
-
- bigdeer4.addch(0, 17, ord('\\'))
- bigdeer4.addch(0, 18, ord('/'))
- bigdeer4.addch(0, 19, ord('\\'))
- bigdeer4.addch(0, 20, ord('/'))
- bigdeer4.addch(1, 18, ord('\\'))
- bigdeer4.addch(1, 20, ord('/'))
- bigdeer4.addch(2, 19, ord('|'))
- bigdeer4.addch(2, 20, ord('_'))
- bigdeer4.addch(3, 18, ord('/'))
- bigdeer4.addch(3, 19, ord('^'))
- bigdeer4.addch(3, 20, ord('0'))
- bigdeer4.addch(3, 21, ord('\\'))
- bigdeer4.addch(4, 17, ord('/'))
- bigdeer4.addch(4, 18, ord('/'))
- bigdeer4.addch(4, 19, ord('\\'))
- bigdeer4.addch(4, 22, ord('\\'))
- bigdeer4.addstr(5, 7, "^~~~~~~~~// ~~U")
- bigdeer4.addstr(6, 6, "( )______( /") # )
- bigdeer4.addstr(7, 5, "(/ \\") # )
- bigdeer4.addstr(8, 0, "v___= ----^")
-
- lookdeer1.addstr(0, 16, "\\/ \\/")
- lookdeer1.addstr(1, 17, "\\Y/ \\Y/")
- lookdeer1.addstr(2, 19, "\\=/")
- lookdeer1.addstr(3, 17, "^\\o o/^")
- lookdeer1.addstr(4, 17, "//( )")
- lookdeer1.addstr(5, 7, "^~~~~~~~~// \\O/")
- lookdeer1.addstr(6, 7, "( \\_____( /") # ))
- lookdeer1.addstr(7, 8, "( ) /")
- lookdeer1.addstr(8, 9, "\\\\ /")
- lookdeer1.addstr(9, 11, "\\>/>")
-
- lookdeer2.addstr(0, 16, "\\/ \\/")
- lookdeer2.addstr(1, 17, "\\Y/ \\Y/")
- lookdeer2.addstr(2, 19, "\\=/")
- lookdeer2.addstr(3, 17, "^\\o o/^")
- lookdeer2.addstr(4, 17, "//( )")
- lookdeer2.addstr(5, 7, "^~~~~~~~~// \\O/")
- lookdeer2.addstr(6, 7, "(( )____( /") # ))
- lookdeer2.addstr(7, 7, "( / |")
- lookdeer2.addstr(8, 8, "\\/ |")
- lookdeer2.addstr(9, 9, "|> |>")
-
- lookdeer3.addstr(0, 16, "\\/ \\/")
- lookdeer3.addstr(1, 17, "\\Y/ \\Y/")
- lookdeer3.addstr(2, 19, "\\=/")
- lookdeer3.addstr(3, 17, "^\\o o/^")
- lookdeer3.addstr(4, 17, "//( )")
- lookdeer3.addstr(5, 7, "^~~~~~~~~// \\O/")
- lookdeer3.addstr(6, 6, "( ()_____( /") # ))
- lookdeer3.addstr(7, 6, "/ / /")
- lookdeer3.addstr(8, 5, "|/ \\")
- lookdeer3.addstr(9, 5, "/> \\>")
-
- lookdeer4.addstr(0, 16, "\\/ \\/")
- lookdeer4.addstr(1, 17, "\\Y/ \\Y/")
- lookdeer4.addstr(2, 19, "\\=/")
- lookdeer4.addstr(3, 17, "^\\o o/^")
- lookdeer4.addstr(4, 17, "//( )")
- lookdeer4.addstr(5, 7, "^~~~~~~~~// \\O/")
- lookdeer4.addstr(6, 6, "( )______( /") # )
- lookdeer4.addstr(7, 5, "(/ \\") # )
- lookdeer4.addstr(8, 0, "v___= ----^")
-
- ###############################################
- curses.cbreak()
- stdscr.nodelay(1)
-
- while 1:
- stdscr.clear()
- treescrn.erase()
- w_del_msg.touchwin()
- treescrn.touchwin()
- treescrn2.erase()
- treescrn2.touchwin()
- treescrn8.erase()
- treescrn8.touchwin()
- stdscr.refresh()
- look_out(150)
- boxit()
- stdscr.refresh()
- look_out(150)
- seas()
- stdscr.refresh()
- greet()
- stdscr.refresh()
- look_out(150)
- fromwho()
- stdscr.refresh()
- look_out(150)
- tree()
- look_out(150)
- balls()
- look_out(150)
- star()
- look_out(150)
- strng1()
- strng2()
- strng3()
- strng4()
- strng5()
-
- # set up the windows for our blinking trees
- #
- # treescrn3
- treescrn.overlay(treescrn3)
-
- # balls
- treescrn3.addch(4, 18, ord(' '))
- treescrn3.addch(7, 6, ord(' '))
- treescrn3.addch(8, 19, ord(' '))
- treescrn3.addch(11, 22, ord(' '))
-
- # star
- treescrn3.addch(0, 12, ord('*'))
-
- # strng1
- treescrn3.addch(3, 11, ord(' '))
-
- # strng2
- treescrn3.addch(5, 13, ord(' '))
- treescrn3.addch(6, 10, ord(' '))
-
- # strng3
- treescrn3.addch(7, 16, ord(' '))
- treescrn3.addch(7, 14, ord(' '))
-
- # strng4
- treescrn3.addch(10, 13, ord(' '))
- treescrn3.addch(10, 10, ord(' '))
- treescrn3.addch(11, 8, ord(' '))
-
- # strng5
- treescrn3.addch(11, 18, ord(' '))
- treescrn3.addch(12, 13, ord(' '))
-
- # treescrn4
- treescrn.overlay(treescrn4)
-
- # balls
- treescrn4.addch(3, 9, ord(' '))
- treescrn4.addch(4, 16, ord(' '))
- treescrn4.addch(7, 6, ord(' '))
- treescrn4.addch(8, 19, ord(' '))
- treescrn4.addch(11, 2, ord(' '))
- treescrn4.addch(12, 23, ord(' '))
-
- # star
- treescrn4.standout()
- treescrn4.addch(0, 12, ord('*'))
- treescrn4.standend()
-
- # strng1
- treescrn4.addch(3, 13, ord(' '))
-
- # strng2
-
- # strng3
- treescrn4.addch(7, 15, ord(' '))
- treescrn4.addch(8, 11, ord(' '))
-
- # strng4
- treescrn4.addch(9, 16, ord(' '))
- treescrn4.addch(10, 12, ord(' '))
- treescrn4.addch(11, 8, ord(' '))
-
- # strng5
- treescrn4.addch(11, 18, ord(' '))
- treescrn4.addch(12, 14, ord(' '))
-
- # treescrn5
- treescrn.overlay(treescrn5)
-
- # balls
- treescrn5.addch(3, 15, ord(' '))
- treescrn5.addch(10, 20, ord(' '))
- treescrn5.addch(12, 1, ord(' '))
-
- # star
- treescrn5.addch(0, 12, ord(' '))
-
- # strng1
- treescrn5.addch(3, 11, ord(' '))
-
- # strng2
- treescrn5.addch(5, 12, ord(' '))
-
- # strng3
- treescrn5.addch(7, 14, ord(' '))
- treescrn5.addch(8, 10, ord(' '))
-
- # strng4
- treescrn5.addch(9, 15, ord(' '))
- treescrn5.addch(10, 11, ord(' '))
- treescrn5.addch(11, 7, ord(' '))
-
- # strng5
- treescrn5.addch(11, 17, ord(' '))
- treescrn5.addch(12, 13, ord(' '))
-
- # treescrn6
- treescrn.overlay(treescrn6)
-
- # balls
- treescrn6.addch(6, 7, ord(' '))
- treescrn6.addch(7, 18, ord(' '))
- treescrn6.addch(10, 4, ord(' '))
- treescrn6.addch(11, 23, ord(' '))
-
- # star
- treescrn6.standout()
- treescrn6.addch(0, 12, ord('*'))
- treescrn6.standend()
-
- # strng1
-
- # strng2
- treescrn6.addch(5, 11, ord(' '))
-
- # strng3
- treescrn6.addch(7, 13, ord(' '))
- treescrn6.addch(8, 9, ord(' '))
-
- # strng4
- treescrn6.addch(9, 14, ord(' '))
- treescrn6.addch(10, 10, ord(' '))
- treescrn6.addch(11, 6, ord(' '))
-
- # strng5
- treescrn6.addch(11, 16, ord(' '))
- treescrn6.addch(12, 12, ord(' '))
-
- # treescrn7
-
- treescrn.overlay(treescrn7)
-
- # balls
- treescrn7.addch(3, 15, ord(' '))
- treescrn7.addch(6, 7, ord(' '))
- treescrn7.addch(7, 18, ord(' '))
- treescrn7.addch(10, 4, ord(' '))
- treescrn7.addch(11, 22, ord(' '))
-
- # star
- treescrn7.addch(0, 12, ord('*'))
-
- # strng1
- treescrn7.addch(3, 12, ord(' '))
-
- # strng2
- treescrn7.addch(5, 13, ord(' '))
- treescrn7.addch(6, 9, ord(' '))
-
- # strng3
- treescrn7.addch(7, 15, ord(' '))
- treescrn7.addch(8, 11, ord(' '))
-
- # strng4
- treescrn7.addch(9, 16, ord(' '))
- treescrn7.addch(10, 12, ord(' '))
- treescrn7.addch(11, 8, ord(' '))
-
- # strng5
- treescrn7.addch(11, 18, ord(' '))
- treescrn7.addch(12, 14, ord(' '))
-
- look_out(150)
- reindeer()
-
- w_holiday.touchwin()
- w_holiday.refresh()
- w_del_msg.refresh()
-
- look_out(500)
- for i in range(0, 20):
- blinkit()
-
-curses.wrapper(main)
diff --git a/Demo/embed/Makefile b/Demo/embed/Makefile
deleted file mode 100644
index 19ba344..0000000
--- a/Demo/embed/Makefile
+++ /dev/null
@@ -1,57 +0,0 @@
-# Makefile for embedded Python use demo.
-# (This version originally written on Red Hat Linux 6.1;
-# edit lines marked with XXX.)
-
-# XXX The compiler you are using
-CC= gcc
-
-# XXX Top of the build tree and source tree
-blddir= ../..
-srcdir= ../..
-
-# Python version
-VERSION= 2.7
-
-# Compiler flags
-OPT= -g
-INCLUDES= -I$(srcdir)/Include -I$(blddir)
-CFLAGS= $(OPT)
-CPPFLAGS= $(INCLUDES)
-
-# The Python library
-LIBPYTHON= $(blddir)/libpython$(VERSION).a
-
-# XXX edit LIBS (in particular) to match $(blddir)/Makefile
-LIBS= -lnsl -ldl -lreadline -ltermcap -lieee -lpthread -lutil
-LDFLAGS= -Xlinker -export-dynamic
-SYSLIBS= -lm
-MODLIBS=
-ALLLIBS= $(LIBPYTHON) $(MODLIBS) $(LIBS) $(SYSLIBS)
-
-# Build the demo applications
-all: demo loop importexc
-demo: demo.o
- $(CC) $(LDFLAGS) demo.o $(ALLLIBS) -o demo
-
-loop: loop.o
- $(CC) $(LDFLAGS) loop.o $(ALLLIBS) -o loop
-
-importexc: importexc.o
- $(CC) $(LDFLAGS) importexc.o $(ALLLIBS) -o importexc
-
-# Administrative targets
-
-test: demo
- ./demo
-
-COMMAND="print 'hello world'"
-looptest: loop
- ./loop $(COMMAND)
-
-clean:
- -rm -f *.o core
-
-clobber: clean
- -rm -f *~ @* '#'* demo loop importexc
-
-realclean: clobber
diff --git a/Demo/embed/README b/Demo/embed/README
deleted file mode 100644
index a0f7af8..0000000
--- a/Demo/embed/README
+++ /dev/null
@@ -1,19 +0,0 @@
-This directory show how to embed the Python interpreter in your own
-application. The file demo.c shows you all that is needed in your C
-code.
-
-To build it, you may have to edit the Makefile:
-
-1) set blddir to the directory where you built Python, if it isn't in
-the source directory (../..)
-
-2) change the variables that together define the list of libraries
-(MODLIBS, LIBS, SYSLIBS) to link with, to match their definitions in
-$(blddir)/Modules/Makefile
-
-An additional test program, loop.c, is used to experiment with memory
-leakage caused by repeated initialization and finalization of the
-interpreter. It can be build by saying "make loop" and tested with
-"make looptest". Command line usage is "./loop <python-command>",
-e.g. "./loop 'print 2+2'" should spit out an endless number of lines
-containing the number 4.
diff --git a/Demo/embed/demo.c b/Demo/embed/demo.c
deleted file mode 100644
index 00c5a0e..0000000
--- a/Demo/embed/demo.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Example of embedding Python in another program */
-
-#include "Python.h"
-
-void initxyzzy(void); /* Forward */
-
-main(int argc, char **argv)
-{
- /* Pass argv[0] to the Python interpreter */
- Py_SetProgramName(argv[0]);
-
- /* Initialize the Python interpreter. Required. */
- Py_Initialize();
-
- /* Add a static module */
- initxyzzy();
-
- /* Define sys.argv. It is up to the application if you
- want this; you can also leave it undefined (since the Python
- code is generally not a main program it has no business
- touching sys.argv...)
-
- If the third argument is true, sys.path is modified to include
- either the directory containing the script named by argv[0], or
- the current working directory. This can be risky; if you run
- an application embedding Python in a directory controlled by
- someone else, attackers could put a Trojan-horse module in the
- directory (say, a file named os.py) that your application would
- then import and run.
- */
- PySys_SetArgvEx(argc, argv, 0);
-
- /* Do some application specific code */
- printf("Hello, brave new world\n\n");
-
- /* Execute some Python statements (in module __main__) */
- PyRun_SimpleString("import sys\n");
- PyRun_SimpleString("print sys.builtin_module_names\n");
- PyRun_SimpleString("print sys.modules.keys()\n");
- PyRun_SimpleString("print sys.executable\n");
- PyRun_SimpleString("print sys.argv\n");
-
- /* Note that you can call any public function of the Python
- interpreter here, e.g. call_object(). */
-
- /* Some more application specific code */
- printf("\nGoodbye, cruel world\n");
-
- /* Exit, cleaning up the interpreter */
- Py_Exit(0);
- /*NOTREACHED*/
-}
-
-/* A static module */
-
-/* 'self' is not used */
-static PyObject *
-xyzzy_foo(PyObject *self, PyObject* args)
-{
- return PyInt_FromLong(42L);
-}
-
-static PyMethodDef xyzzy_methods[] = {
- {"foo", xyzzy_foo, METH_NOARGS,
- "Return the meaning of everything."},
- {NULL, NULL} /* sentinel */
-};
-
-void
-initxyzzy(void)
-{
- PyImport_AddModule("xyzzy");
- Py_InitModule("xyzzy", xyzzy_methods);
-}
diff --git a/Demo/embed/importexc.c b/Demo/embed/importexc.c
deleted file mode 100644
index 375ce1b..0000000
--- a/Demo/embed/importexc.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <Python.h>
-
-char* cmd = "import exceptions";
-
-int main()
-{
- Py_Initialize();
- PyEval_InitThreads();
- PyRun_SimpleString(cmd);
- Py_EndInterpreter(PyThreadState_Get());
-
- Py_NewInterpreter();
- PyRun_SimpleString(cmd);
- Py_Finalize();
-
- return 0;
-}
diff --git a/Demo/embed/loop.c b/Demo/embed/loop.c
deleted file mode 100644
index 2f7fe62..0000000
--- a/Demo/embed/loop.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Simple program that repeatedly calls Py_Initialize(), does something, and
- then calls Py_Finalize(). This should help finding leaks related to
- initialization. */
-
-#include "Python.h"
-
-main(int argc, char **argv)
-{
- int count = -1;
- char *command;
-
- if (argc < 2 || argc > 3) {
- fprintf(stderr, "usage: loop <python-command> [count]\n");
- exit(2);
- }
- command = argv[1];
-
- if (argc == 3) {
- count = atoi(argv[2]);
- }
-
- Py_SetProgramName(argv[0]);
-
- /* uncomment this if you don't want to load site.py */
- /* Py_NoSiteFlag = 1; */
-
- while (count == -1 || --count >= 0 ) {
- Py_Initialize();
- PyRun_SimpleString(command);
- Py_Finalize();
- }
- return 0;
-}
diff --git a/Demo/md5test/README b/Demo/md5test/README
deleted file mode 100644
index be7621e..0000000
--- a/Demo/md5test/README
+++ /dev/null
@@ -1,10 +0,0 @@
-This is the Python version of the MD5 test program from the MD5
-Internet Draft (Rivest and Dusse, The MD5 Message-Digest Algorithm, 10
-July 1991). The file "foo" contains the string "abc" with no trailing
-newline.
-
-When called without arguments, it acts as a filter. When called with
-"-x", it executes a self-test, and the output should literally match
-the output given in the RFC.
-
-Code by Jan-Hein B\"uhrman after the original in C.
diff --git a/Demo/md5test/foo b/Demo/md5test/foo
deleted file mode 100755
index f2ba8f8..0000000
--- a/Demo/md5test/foo
+++ /dev/null
@@ -1 +0,0 @@
-abc \ No newline at end of file
diff --git a/Demo/md5test/md5driver.py b/Demo/md5test/md5driver.py
deleted file mode 100644
index 25e7314..0000000
--- a/Demo/md5test/md5driver.py
+++ /dev/null
@@ -1,123 +0,0 @@
-import string
-import md5
-from sys import argv
-
-def MDPrint(str):
- outstr = ''
- for i in str:
- o = ord(i)
- outstr = (outstr
- + string.hexdigits[(o >> 4) & 0xF]
- + string.hexdigits[o & 0xF])
- print outstr,
-
-
-from time import time
-
-def makestr(start, end):
- result = ''
- for i in range(start, end + 1):
- result = result + chr(i)
-
- return result
-
-
-def MDTimeTrial():
- TEST_BLOCK_SIZE = 1000
- TEST_BLOCKS = 10000
-
- TEST_BYTES = TEST_BLOCK_SIZE * TEST_BLOCKS
-
- # initialize test data, need temporary string filler
-
- filsiz = 1 << 8
- filler = makestr(0, filsiz-1)
- data = filler * (TEST_BLOCK_SIZE // filsiz)
- data = data + filler[:(TEST_BLOCK_SIZE % filsiz)]
-
- del filsiz, filler
-
-
- # start timer
- print 'MD5 time trial. Processing', TEST_BYTES, 'characters...'
- t1 = time()
-
- mdContext = md5.new()
-
- for i in range(TEST_BLOCKS):
- mdContext.update(data)
-
- str = mdContext.digest()
- t2 = time()
-
- MDPrint(str)
- print 'is digest of test input.'
- print 'Seconds to process test input:', t2 - t1
- print 'Characters processed per second:', TEST_BYTES / (t2 - t1)
-
-
-def MDString(str):
- MDPrint(md5.new(str).digest())
- print '"' + str + '"'
-
-
-def MDFile(filename):
- f = open(filename, 'rb')
- mdContext = md5.new()
-
- while 1:
- data = f.read(1024)
- if not data:
- break
- mdContext.update(data)
-
- MDPrint(mdContext.digest())
- print filename
-
-
-import sys
-
-def MDFilter():
- mdContext = md5.new()
-
- while 1:
- data = sys.stdin.read(16)
- if not data:
- break
- mdContext.update(data)
-
- MDPrint(mdContext.digest())
- print
-
-
-def MDTestSuite():
- print 'MD5 test suite results:'
- MDString('')
- MDString('a')
- MDString('abc')
- MDString('message digest')
- MDString(makestr(ord('a'), ord('z')))
- MDString(makestr(ord('A'), ord('Z'))
- + makestr(ord('a'), ord('z'))
- + makestr(ord('0'), ord('9')))
- MDString((makestr(ord('1'), ord('9')) + '0') * 8)
-
- # Contents of file foo are "abc"
- MDFile('foo')
-
-
-# I don't wanna use getopt(), since I want to use the same i/f...
-def main():
- if len(argv) == 1:
- MDFilter()
- for arg in argv[1:]:
- if arg[:2] == '-s':
- MDString(arg[2:])
- elif arg == '-t':
- MDTimeTrial()
- elif arg == '-x':
- MDTestSuite()
- else:
- MDFile(arg)
-
-main()
diff --git a/Demo/metaclasses/Eiffel.py b/Demo/metaclasses/Eiffel.py
deleted file mode 100644
index 24fac14..0000000
--- a/Demo/metaclasses/Eiffel.py
+++ /dev/null
@@ -1,113 +0,0 @@
-"""Support Eiffel-style preconditions and postconditions.
-
-For example,
-
-class C:
- def m1(self, arg):
- require arg > 0
- return whatever
- ensure Result > arg
-
-can be written (clumsily, I agree) as:
-
-class C(Eiffel):
- def m1(self, arg):
- return whatever
- def m1_pre(self, arg):
- assert arg > 0
- def m1_post(self, Result, arg):
- assert Result > arg
-
-Pre- and post-conditions for a method, being implemented as methods
-themselves, are inherited independently from the method. This gives
-much of the same effect of Eiffel, where pre- and post-conditions are
-inherited when a method is overridden by a derived class. However,
-when a derived class in Python needs to extend a pre- or
-post-condition, it must manually merge the base class' pre- or
-post-condition with that defined in the derived class', for example:
-
-class D(C):
- def m1(self, arg):
- return arg**2
- def m1_post(self, Result, arg):
- C.m1_post(self, Result, arg)
- assert Result < 100
-
-This gives derived classes more freedom but also more responsibility
-than in Eiffel, where the compiler automatically takes care of this.
-
-In Eiffel, pre-conditions combine using contravariance, meaning a
-derived class can only make a pre-condition weaker; in Python, this is
-up to the derived class. For example, a derived class that takes away
-the requirement that arg > 0 could write:
-
- def m1_pre(self, arg):
- pass
-
-but one could equally write a derived class that makes a stronger
-requirement:
-
- def m1_pre(self, arg):
- require arg > 50
-
-It would be easy to modify the classes shown here so that pre- and
-post-conditions can be disabled (separately, on a per-class basis).
-
-A different design would have the pre- or post-condition testing
-functions return true for success and false for failure. This would
-make it possible to implement automatic combination of inherited
-and new pre-/post-conditions. All this is left as an exercise to the
-reader.
-
-"""
-
-from Meta import MetaClass, MetaHelper, MetaMethodWrapper
-
-class EiffelMethodWrapper(MetaMethodWrapper):
-
- def __init__(self, func, inst):
- MetaMethodWrapper.__init__(self, func, inst)
- # Note that the following causes recursive wrappers around
- # the pre-/post-condition testing methods. These are harmless
- # but inefficient; to avoid them, the lookup must be done
- # using the class.
- try:
- self.pre = getattr(inst, self.__name__ + "_pre")
- except AttributeError:
- self.pre = None
- try:
- self.post = getattr(inst, self.__name__ + "_post")
- except AttributeError:
- self.post = None
-
- def __call__(self, *args, **kw):
- if self.pre:
- apply(self.pre, args, kw)
- Result = apply(self.func, (self.inst,) + args, kw)
- if self.post:
- apply(self.post, (Result,) + args, kw)
- return Result
-
-class EiffelHelper(MetaHelper):
- __methodwrapper__ = EiffelMethodWrapper
-
-class EiffelMetaClass(MetaClass):
- __helper__ = EiffelHelper
-
-Eiffel = EiffelMetaClass('Eiffel', (), {})
-
-
-def _test():
- class C(Eiffel):
- def m1(self, arg):
- return arg+1
- def m1_pre(self, arg):
- assert arg > 0, "precondition for m1 failed"
- def m1_post(self, Result, arg):
- assert Result > arg
- x = C()
- x.m1(12)
-## x.m1(-1)
-
-if __name__ == '__main__':
- _test()
diff --git a/Demo/metaclasses/Enum.py b/Demo/metaclasses/Enum.py
deleted file mode 100644
index df1d814..0000000
--- a/Demo/metaclasses/Enum.py
+++ /dev/null
@@ -1,169 +0,0 @@
-"""Enumeration metaclass.
-
-XXX This is very much a work in progress.
-
-"""
-
-import string
-
-class EnumMetaClass:
- """Metaclass for enumeration.
-
- To define your own enumeration, do something like
-
- class Color(Enum):
- red = 1
- green = 2
- blue = 3
-
- Now, Color.red, Color.green and Color.blue behave totally
- different: they are enumerated values, not integers.
-
- Enumerations cannot be instantiated; however they can be
- subclassed.
-
- """
-
- def __init__(self, name, bases, dict):
- """Constructor -- create an enumeration.
-
- Called at the end of the class statement. The arguments are
- the name of the new class, a tuple containing the base
- classes, and a dictionary containing everything that was
- entered in the class' namespace during execution of the class
- statement. In the above example, it would be {'red': 1,
- 'green': 2, 'blue': 3}.
-
- """
- for base in bases:
- if base.__class__ is not EnumMetaClass:
- raise TypeError, "Enumeration base class must be enumeration"
- bases = filter(lambda x: x is not Enum, bases)
- self.__name__ = name
- self.__bases__ = bases
- self.__dict = {}
- for key, value in dict.items():
- self.__dict[key] = EnumInstance(name, key, value)
-
- def __getattr__(self, name):
- """Return an enumeration value.
-
- For example, Color.red returns the value corresponding to red.
-
- XXX Perhaps the values should be created in the constructor?
-
- This looks in the class dictionary and if it is not found
- there asks the base classes.
-
- The special attribute __members__ returns the list of names
- defined in this class (it does not merge in the names defined
- in base classes).
-
- """
- if name == '__members__':
- return self.__dict.keys()
-
- try:
- return self.__dict[name]
- except KeyError:
- for base in self.__bases__:
- try:
- return getattr(base, name)
- except AttributeError:
- continue
-
- raise AttributeError, name
-
- def __repr__(self):
- s = self.__name__
- if self.__bases__:
- s = s + '(' + string.join(map(lambda x: x.__name__,
- self.__bases__), ", ") + ')'
- if self.__dict:
- list = []
- for key, value in self.__dict.items():
- list.append("%s: %s" % (key, int(value)))
- s = "%s: {%s}" % (s, string.join(list, ", "))
- return s
-
-
-class EnumInstance:
- """Class to represent an enumeration value.
-
- EnumInstance('Color', 'red', 12) prints as 'Color.red' and behaves
- like the integer 12 when compared, but doesn't support arithmetic.
-
- XXX Should it record the actual enumeration rather than just its
- name?
-
- """
-
- def __init__(self, classname, enumname, value):
- self.__classname = classname
- self.__enumname = enumname
- self.__value = value
-
- def __int__(self):
- return self.__value
-
- def __repr__(self):
- return "EnumInstance(%r, %r, %r)" % (self.__classname,
- self.__enumname,
- self.__value)
-
- def __str__(self):
- return "%s.%s" % (self.__classname, self.__enumname)
-
- def __cmp__(self, other):
- return cmp(self.__value, int(other))
-
-
-# Create the base class for enumerations.
-# It is an empty enumeration.
-Enum = EnumMetaClass("Enum", (), {})
-
-
-def _test():
-
- class Color(Enum):
- red = 1
- green = 2
- blue = 3
-
- print Color.red
- print dir(Color)
-
- print Color.red == Color.red
- print Color.red == Color.blue
- print Color.red == 1
- print Color.red == 2
-
- class ExtendedColor(Color):
- white = 0
- orange = 4
- yellow = 5
- purple = 6
- black = 7
-
- print ExtendedColor.orange
- print ExtendedColor.red
-
- print Color.red == ExtendedColor.red
-
- class OtherColor(Enum):
- white = 4
- blue = 5
-
- class MergedColor(Color, OtherColor):
- pass
-
- print MergedColor.red
- print MergedColor.white
-
- print Color
- print ExtendedColor
- print OtherColor
- print MergedColor
-
-if __name__ == '__main__':
- _test()
diff --git a/Demo/metaclasses/Meta.py b/Demo/metaclasses/Meta.py
deleted file mode 100644
index 580f582..0000000
--- a/Demo/metaclasses/Meta.py
+++ /dev/null
@@ -1,118 +0,0 @@
-"""Generic metaclass.
-
-XXX This is very much a work in progress.
-
-"""
-
-import types
-
-class MetaMethodWrapper:
-
- def __init__(self, func, inst):
- self.func = func
- self.inst = inst
- self.__name__ = self.func.__name__
-
- def __call__(self, *args, **kw):
- return apply(self.func, (self.inst,) + args, kw)
-
-class MetaHelper:
-
- __methodwrapper__ = MetaMethodWrapper # For derived helpers to override
-
- def __helperinit__(self, formalclass):
- self.__formalclass__ = formalclass
-
- def __getattr__(self, name):
- # Invoked for any attr not in the instance's __dict__
- try:
- raw = self.__formalclass__.__getattr__(name)
- except AttributeError:
- try:
- ga = self.__formalclass__.__getattr__('__usergetattr__')
- except (KeyError, AttributeError):
- raise AttributeError, name
- return ga(self, name)
- if type(raw) != types.FunctionType:
- return raw
- return self.__methodwrapper__(raw, self)
-
-class MetaClass:
-
- """A generic metaclass.
-
- This can be subclassed to implement various kinds of meta-behavior.
-
- """
-
- __helper__ = MetaHelper # For derived metaclasses to override
-
- __inited = 0
-
- def __init__(self, name, bases, dict):
- try:
- ga = dict['__getattr__']
- except KeyError:
- pass
- else:
- dict['__usergetattr__'] = ga
- del dict['__getattr__']
- self.__name__ = name
- self.__bases__ = bases
- self.__realdict__ = dict
- self.__inited = 1
-
- def __getattr__(self, name):
- try:
- return self.__realdict__[name]
- except KeyError:
- for base in self.__bases__:
- try:
- return base.__getattr__(name)
- except AttributeError:
- pass
- raise AttributeError, name
-
- def __setattr__(self, name, value):
- if not self.__inited:
- self.__dict__[name] = value
- else:
- self.__realdict__[name] = value
-
- def __call__(self, *args, **kw):
- inst = self.__helper__()
- inst.__helperinit__(self)
- try:
- init = inst.__getattr__('__init__')
- except AttributeError:
- init = lambda: None
- apply(init, args, kw)
- return inst
-
-
-Meta = MetaClass('Meta', (), {})
-
-
-def _test():
- class C(Meta):
- def __init__(self, *args):
- print "__init__, args =", args
- def m1(self, x):
- print "m1(x=%r)" % (x,)
- print C
- x = C()
- print x
- x.m1(12)
- class D(C):
- def __getattr__(self, name):
- if name[:2] == '__': raise AttributeError, name
- return "getattr:%s" % name
- x = D()
- print x.foo
- print x._foo
-## print x.__foo
-## print x.__foo__
-
-
-if __name__ == '__main__':
- _test()
diff --git a/Demo/metaclasses/Simple.py b/Demo/metaclasses/Simple.py
deleted file mode 100644
index 03ed259..0000000
--- a/Demo/metaclasses/Simple.py
+++ /dev/null
@@ -1,45 +0,0 @@
-import types
-
-class Tracing:
- def __init__(self, name, bases, namespace):
- """Create a new class."""
- self.__name__ = name
- self.__bases__ = bases
- self.__namespace__ = namespace
- def __call__(self):
- """Create a new instance."""
- return Instance(self)
-
-class Instance:
- def __init__(self, klass):
- self.__klass__ = klass
- def __getattr__(self, name):
- try:
- value = self.__klass__.__namespace__[name]
- except KeyError:
- raise AttributeError, name
- if type(value) is not types.FunctionType:
- return value
- return BoundMethod(value, self)
-
-class BoundMethod:
- def __init__(self, function, instance):
- self.function = function
- self.instance = instance
- def __call__(self, *args):
- print "calling", self.function, "for", self.instance, "with", args
- return apply(self.function, (self.instance,) + args)
-
-Trace = Tracing('Trace', (), {})
-
-class MyTracedClass(Trace):
- def method1(self, a):
- self.a = a
- def method2(self):
- return self.a
-
-aninstance = MyTracedClass()
-
-aninstance.method1(10)
-
-print aninstance.method2()
diff --git a/Demo/metaclasses/Synch.py b/Demo/metaclasses/Synch.py
deleted file mode 100644
index 80e52d9..0000000
--- a/Demo/metaclasses/Synch.py
+++ /dev/null
@@ -1,256 +0,0 @@
-"""Synchronization metaclass.
-
-This metaclass makes it possible to declare synchronized methods.
-
-"""
-
-import thread
-
-# First we need to define a reentrant lock.
-# This is generally useful and should probably be in a standard Python
-# library module. For now, we in-line it.
-
-class Lock:
-
- """Reentrant lock.
-
- This is a mutex-like object which can be acquired by the same
- thread more than once. It keeps a reference count of the number
- of times it has been acquired by the same thread. Each acquire()
- call must be matched by a release() call and only the last
- release() call actually releases the lock for acquisition by
- another thread.
-
- The implementation uses two locks internally:
-
- __mutex is a short term lock used to protect the instance variables
- __wait is the lock for which other threads wait
-
- A thread intending to acquire both locks should acquire __wait
- first.
-
- The implementation uses two other instance variables, protected by
- locking __mutex:
-
- __tid is the thread ID of the thread that currently has the lock
- __count is the number of times the current thread has acquired it
-
- When the lock is released, __tid is None and __count is zero.
-
- """
-
- def __init__(self):
- """Constructor. Initialize all instance variables."""
- self.__mutex = thread.allocate_lock()
- self.__wait = thread.allocate_lock()
- self.__tid = None
- self.__count = 0
-
- def acquire(self, flag=1):
- """Acquire the lock.
-
- If the optional flag argument is false, returns immediately
- when it cannot acquire the __wait lock without blocking (it
- may still block for a little while in order to acquire the
- __mutex lock).
-
- The return value is only relevant when the flag argument is
- false; it is 1 if the lock is acquired, 0 if not.
-
- """
- self.__mutex.acquire()
- try:
- if self.__tid == thread.get_ident():
- self.__count = self.__count + 1
- return 1
- finally:
- self.__mutex.release()
- locked = self.__wait.acquire(flag)
- if not flag and not locked:
- return 0
- try:
- self.__mutex.acquire()
- assert self.__tid == None
- assert self.__count == 0
- self.__tid = thread.get_ident()
- self.__count = 1
- return 1
- finally:
- self.__mutex.release()
-
- def release(self):
- """Release the lock.
-
- If this thread doesn't currently have the lock, an assertion
- error is raised.
-
- Only allow another thread to acquire the lock when the count
- reaches zero after decrementing it.
-
- """
- self.__mutex.acquire()
- try:
- assert self.__tid == thread.get_ident()
- assert self.__count > 0
- self.__count = self.__count - 1
- if self.__count == 0:
- self.__tid = None
- self.__wait.release()
- finally:
- self.__mutex.release()
-
-
-def _testLock():
-
- done = []
-
- def f2(lock, done=done):
- lock.acquire()
- print "f2 running in thread %d\n" % thread.get_ident(),
- lock.release()
- done.append(1)
-
- def f1(lock, f2=f2, done=done):
- lock.acquire()
- print "f1 running in thread %d\n" % thread.get_ident(),
- try:
- f2(lock)
- finally:
- lock.release()
- done.append(1)
-
- lock = Lock()
- lock.acquire()
- f1(lock) # Adds 2 to done
- lock.release()
-
- lock.acquire()
-
- thread.start_new_thread(f1, (lock,)) # Adds 2
- thread.start_new_thread(f1, (lock, f1)) # Adds 3
- thread.start_new_thread(f2, (lock,)) # Adds 1
- thread.start_new_thread(f2, (lock,)) # Adds 1
-
- lock.release()
- import time
- while len(done) < 9:
- print len(done)
- time.sleep(0.001)
- print len(done)
-
-
-# Now, the Locking metaclass is a piece of cake.
-# As an example feature, methods whose name begins with exactly one
-# underscore are not synchronized.
-
-from Meta import MetaClass, MetaHelper, MetaMethodWrapper
-
-class LockingMethodWrapper(MetaMethodWrapper):
- def __call__(self, *args, **kw):
- if self.__name__[:1] == '_' and self.__name__[1:] != '_':
- return apply(self.func, (self.inst,) + args, kw)
- self.inst.__lock__.acquire()
- try:
- return apply(self.func, (self.inst,) + args, kw)
- finally:
- self.inst.__lock__.release()
-
-class LockingHelper(MetaHelper):
- __methodwrapper__ = LockingMethodWrapper
- def __helperinit__(self, formalclass):
- MetaHelper.__helperinit__(self, formalclass)
- self.__lock__ = Lock()
-
-class LockingMetaClass(MetaClass):
- __helper__ = LockingHelper
-
-Locking = LockingMetaClass('Locking', (), {})
-
-def _test():
- # For kicks, take away the Locking base class and see it die
- class Buffer(Locking):
- def __init__(self, initialsize):
- assert initialsize > 0
- self.size = initialsize
- self.buffer = [None]*self.size
- self.first = self.last = 0
- def put(self, item):
- # Do we need to grow the buffer?
- if (self.last+1) % self.size != self.first:
- # Insert the new item
- self.buffer[self.last] = item
- self.last = (self.last+1) % self.size
- return
- # Double the buffer size
- # First normalize it so that first==0 and last==size-1
- print "buffer =", self.buffer
- print "first = %d, last = %d, size = %d" % (
- self.first, self.last, self.size)
- if self.first <= self.last:
- temp = self.buffer[self.first:self.last]
- else:
- temp = self.buffer[self.first:] + self.buffer[:self.last]
- print "temp =", temp
- self.buffer = temp + [None]*(self.size+1)
- self.first = 0
- self.last = self.size-1
- self.size = self.size*2
- print "Buffer size doubled to", self.size
- print "new buffer =", self.buffer
- print "first = %d, last = %d, size = %d" % (
- self.first, self.last, self.size)
- self.put(item) # Recursive call to test the locking
- def get(self):
- # Is the buffer empty?
- if self.first == self.last:
- raise EOFError # Avoid defining a new exception
- item = self.buffer[self.first]
- self.first = (self.first+1) % self.size
- return item
-
- def producer(buffer, wait, n=1000):
- import time
- i = 0
- while i < n:
- print "put", i
- buffer.put(i)
- i = i+1
- print "Producer: done producing", n, "items"
- wait.release()
-
- def consumer(buffer, wait, n=1000):
- import time
- i = 0
- tout = 0.001
- while i < n:
- try:
- x = buffer.get()
- if x != i:
- raise AssertionError, \
- "get() returned %s, expected %s" % (x, i)
- print "got", i
- i = i+1
- tout = 0.001
- except EOFError:
- time.sleep(tout)
- tout = tout*2
- print "Consumer: done consuming", n, "items"
- wait.release()
-
- pwait = thread.allocate_lock()
- pwait.acquire()
- cwait = thread.allocate_lock()
- cwait.acquire()
- buffer = Buffer(1)
- n = 1000
- thread.start_new_thread(consumer, (buffer, cwait, n))
- thread.start_new_thread(producer, (buffer, pwait, n))
- pwait.acquire()
- print "Producer done"
- cwait.acquire()
- print "All done"
- print "buffer size ==", len(buffer.buffer)
-
-if __name__ == '__main__':
- _testLock()
- _test()
diff --git a/Demo/metaclasses/Trace.py b/Demo/metaclasses/Trace.py
deleted file mode 100644
index 69b9fab..0000000
--- a/Demo/metaclasses/Trace.py
+++ /dev/null
@@ -1,144 +0,0 @@
-"""Tracing metaclass.
-
-XXX This is very much a work in progress.
-
-"""
-
-import types, sys
-
-class TraceMetaClass:
- """Metaclass for tracing.
-
- Classes defined using this metaclass have an automatic tracing
- feature -- by setting the __trace_output__ instance (or class)
- variable to a file object, trace messages about all calls are
- written to the file. The trace formatting can be changed by
- defining a suitable __trace_call__ method.
-
- """
-
- __inited = 0
-
- def __init__(self, name, bases, dict):
- self.__name__ = name
- self.__bases__ = bases
- self.__dict = dict
- # XXX Can't define __dict__, alas
- self.__inited = 1
-
- def __getattr__(self, name):
- try:
- return self.__dict[name]
- except KeyError:
- for base in self.__bases__:
- try:
- return base.__getattr__(name)
- except AttributeError:
- pass
- raise AttributeError, name
-
- def __setattr__(self, name, value):
- if not self.__inited:
- self.__dict__[name] = value
- else:
- self.__dict[name] = value
-
- def __call__(self, *args, **kw):
- inst = TracingInstance()
- inst.__meta_init__(self)
- try:
- init = inst.__getattr__('__init__')
- except AttributeError:
- init = lambda: None
- apply(init, args, kw)
- return inst
-
- __trace_output__ = None
-
-class TracingInstance:
- """Helper class to represent an instance of a tracing class."""
-
- def __trace_call__(self, fp, fmt, *args):
- fp.write((fmt+'\n') % args)
-
- def __meta_init__(self, klass):
- self.__class = klass
-
- def __getattr__(self, name):
- # Invoked for any attr not in the instance's __dict__
- try:
- raw = self.__class.__getattr__(name)
- except AttributeError:
- raise AttributeError, name
- if type(raw) != types.FunctionType:
- return raw
- # It's a function
- fullname = self.__class.__name__ + "." + name
- if not self.__trace_output__ or name == '__trace_call__':
- return NotTracingWrapper(fullname, raw, self)
- else:
- return TracingWrapper(fullname, raw, self)
-
-class NotTracingWrapper:
- def __init__(self, name, func, inst):
- self.__name__ = name
- self.func = func
- self.inst = inst
- def __call__(self, *args, **kw):
- return apply(self.func, (self.inst,) + args, kw)
-
-class TracingWrapper(NotTracingWrapper):
- def __call__(self, *args, **kw):
- self.inst.__trace_call__(self.inst.__trace_output__,
- "calling %s, inst=%s, args=%s, kw=%s",
- self.__name__, self.inst, args, kw)
- try:
- rv = apply(self.func, (self.inst,) + args, kw)
- except:
- t, v, tb = sys.exc_info()
- self.inst.__trace_call__(self.inst.__trace_output__,
- "returning from %s with exception %s: %s",
- self.__name__, t, v)
- raise t, v, tb
- else:
- self.inst.__trace_call__(self.inst.__trace_output__,
- "returning from %s with value %s",
- self.__name__, rv)
- return rv
-
-Traced = TraceMetaClass('Traced', (), {'__trace_output__': None})
-
-
-def _test():
- global C, D
- class C(Traced):
- def __init__(self, x=0): self.x = x
- def m1(self, x): self.x = x
- def m2(self, y): return self.x + y
- __trace_output__ = sys.stdout
- class D(C):
- def m2(self, y): print "D.m2(%r)" % (y,); return C.m2(self, y)
- __trace_output__ = None
- x = C(4321)
- print x
- print x.x
- print x.m1(100)
- print x.m1(10)
- print x.m2(33)
- print x.m1(5)
- print x.m2(4000)
- print x.x
-
- print C.__init__
- print C.m2
- print D.__init__
- print D.m2
-
- y = D()
- print y
- print y.m1(10)
- print y.m2(100)
- print y.x
-
-if __name__ == '__main__':
- _test()
diff --git a/Demo/metaclasses/index.html b/Demo/metaclasses/index.html
deleted file mode 100644
index eee473a..0000000
--- a/Demo/metaclasses/index.html
+++ /dev/null
@@ -1,605 +0,0 @@
-<HTML>
-
-<HEAD>
-<TITLE>Metaclasses in Python 1.5</TITLE>
-</HEAD>
-
-<BODY BGCOLOR="FFFFFF">
-
-<H1>Metaclasses in Python 1.5</H1>
-<H2>(A.k.a. The Killer Joke :-)</H2>
-
-<HR>
-
-(<i>Postscript:</i> reading this essay is probably not the best way to
-understand the metaclass hook described here. See a <A
-HREF="meta-vladimir.txt">message posted by Vladimir Marangozov</A>
-which may give a gentler introduction to the matter. You may also
-want to search Deja News for messages with "metaclass" in the subject
-posted to comp.lang.python in July and August 1998.)
-
-<HR>
-
-<P>In previous Python releases (and still in 1.5), there is something
-called the ``Don Beaudry hook'', after its inventor and champion.
-This allows C extensions to provide alternate class behavior, thereby
-allowing the Python class syntax to be used to define other class-like
-entities. Don Beaudry has used this in his infamous <A
-HREF="http://maigret.cog.brown.edu/pyutil/">MESS</A> package; Jim
-Fulton has used it in his <A
-HREF="http://www.digicool.com/releases/ExtensionClass/">Extension
-Classes</A> package. (It has also been referred to as the ``Don
-Beaudry <i>hack</i>,'' but that's a misnomer. There's nothing hackish
-about it -- in fact, it is rather elegant and deep, even though
-there's something dark to it.)
-
-<P>(On first reading, you may want to skip directly to the examples in
-the section "Writing Metaclasses in Python" below, unless you want
-your head to explode.)
-
-<P>
-
-<HR>
-
-<P>Documentation of the Don Beaudry hook has purposefully been kept
-minimal, since it is a feature of incredible power, and is easily
-abused. Basically, it checks whether the <b>type of the base
-class</b> is callable, and if so, it is called to create the new
-class.
-
-<P>Note the two indirection levels. Take a simple example:
-
-<PRE>
-class B:
- pass
-
-class C(B):
- pass
-</PRE>
-
-Take a look at the second class definition, and try to fathom ``the
-type of the base class is callable.''
-
-<P>(Types are not classes, by the way. See questions 4.2, 4.19 and in
-particular 6.22 in the <A
-HREF="http://www.python.org/cgi-bin/faqw.py" >Python FAQ</A>
-for more on this topic.)
-
-<P>
-
-<UL>
-
-<LI>The <b>base class</b> is B; this one's easy.<P>
-
-<LI>Since B is a class, its type is ``class''; so the <b>type of the
-base class</b> is the type ``class''. This is also known as
-types.ClassType, assuming the standard module <code>types</code> has
-been imported.<P>
-
-<LI>Now is the type ``class'' <b>callable</b>? No, because types (in
-core Python) are never callable. Classes are callable (calling a
-class creates a new instance) but types aren't.<P>
-
-</UL>
-
-<P>So our conclusion is that in our example, the type of the base
-class (of C) is not callable. So the Don Beaudry hook does not apply,
-and the default class creation mechanism is used (which is also used
-when there is no base class). In fact, the Don Beaudry hook never
-applies when using only core Python, since the type of a core object
-is never callable.
-
-<P>So what do Don and Jim do in order to use Don's hook? Write an
-extension that defines at least two new Python object types. The
-first would be the type for ``class-like'' objects usable as a base
-class, to trigger Don's hook. This type must be made callable.
-That's why we need a second type. Whether an object is callable
-depends on its type. So whether a type object is callable depends on
-<i>its</i> type, which is a <i>meta-type</i>. (In core Python there
-is only one meta-type, the type ``type'' (types.TypeType), which is
-the type of all type objects, even itself.) A new meta-type must
-be defined that makes the type of the class-like objects callable.
-(Normally, a third type would also be needed, the new ``instance''
-type, but this is not an absolute requirement -- the new class type
-could return an object of some existing type when invoked to create an
-instance.)
-
-<P>Still confused? Here's a simple device due to Don himself to
-explain metaclasses. Take a simple class definition; assume B is a
-special class that triggers Don's hook:
-
-<PRE>
-class C(B):
- a = 1
- b = 2
-</PRE>
-
-This can be though of as equivalent to:
-
-<PRE>
-C = type(B)('C', (B,), {'a': 1, 'b': 2})
-</PRE>
-
-If that's too dense for you, here's the same thing written out using
-temporary variables:
-
-<PRE>
-creator = type(B) # The type of the base class
-name = 'C' # The name of the new class
-bases = (B,) # A tuple containing the base class(es)
-namespace = {'a': 1, 'b': 2} # The namespace of the class statement
-C = creator(name, bases, namespace)
-</PRE>
-
-This is analogous to what happens without the Don Beaudry hook, except
-that in that case the creator function is set to the default class
-creator.
-
-<P>In either case, the creator is called with three arguments. The
-first one, <i>name</i>, is the name of the new class (as given at the
-top of the class statement). The <i>bases</i> argument is a tuple of
-base classes (a singleton tuple if there's only one base class, like
-the example). Finally, <i>namespace</i> is a dictionary containing
-the local variables collected during execution of the class statement.
-
-<P>Note that the contents of the namespace dictionary is simply
-whatever names were defined in the class statement. A little-known
-fact is that when Python executes a class statement, it enters a new
-local namespace, and all assignments and function definitions take
-place in this namespace. Thus, after executing the following class
-statement:
-
-<PRE>
-class C:
- a = 1
- def f(s): pass
-</PRE>
-
-the class namespace's contents would be {'a': 1, 'f': &lt;function f
-...&gt;}.
-
-<P>But enough already about writing Python metaclasses in C; read the
-documentation of <A
-HREF="http://maigret.cog.brown.edu/pyutil/">MESS</A> or <A
-HREF="http://www.digicool.com/papers/ExtensionClass.html" >Extension
-Classes</A> for more information.
-
-<P>
-
-<HR>
-
-<H2>Writing Metaclasses in Python</H2>
-
-<P>In Python 1.5, the requirement to write a C extension in order to
-write metaclasses has been dropped (though you can still do
-it, of course). In addition to the check ``is the type of the base
-class callable,'' there's a check ``does the base class have a
-__class__ attribute.'' If so, it is assumed that the __class__
-attribute refers to a class.
-
-<P>Let's repeat our simple example from above:
-
-<PRE>
-class C(B):
- a = 1
- b = 2
-</PRE>
-
-Assuming B has a __class__ attribute, this translates into:
-
-<PRE>
-C = B.__class__('C', (B,), {'a': 1, 'b': 2})
-</PRE>
-
-This is exactly the same as before except that instead of type(B),
-B.__class__ is invoked. If you have read <A HREF=
-"http://www.python.org/cgi-bin/faqw.py?req=show&file=faq06.022.htp"
->FAQ question 6.22</A> you will understand that while there is a big
-technical difference between type(B) and B.__class__, they play the
-same role at different abstraction levels. And perhaps at some point
-in the future they will really be the same thing (at which point you
-would be able to derive subclasses from built-in types).
-
-<P>At this point it may be worth mentioning that C.__class__ is the
-same object as B.__class__, i.e., C's metaclass is the same as B's
-metaclass. In other words, subclassing an existing class creates a
-new (meta)inststance of the base class's metaclass.
-
-<P>Going back to the example, the class B.__class__ is instantiated,
-passing its constructor the same three arguments that are passed to
-the default class constructor or to an extension's metaclass:
-<i>name</i>, <i>bases</i>, and <i>namespace</i>.
-
-<P>It is easy to be confused by what exactly happens when using a
-metaclass, because we lose the absolute distinction between classes
-and instances: a class is an instance of a metaclass (a
-``metainstance''), but technically (i.e. in the eyes of the python
-runtime system), the metaclass is just a class, and the metainstance
-is just an instance. At the end of the class statement, the metaclass
-whose metainstance is used as a base class is instantiated, yielding a
-second metainstance (of the same metaclass). This metainstance is
-then used as a (normal, non-meta) class; instantiation of the class
-means calling the metainstance, and this will return a real instance.
-And what class is that an instance of? Conceptually, it is of course
-an instance of our metainstance; but in most cases the Python runtime
-system will see it as an instance of a a helper class used by the
-metaclass to implement its (non-meta) instances...
-
-<P>Hopefully an example will make things clearer. Let's presume we
-have a metaclass MetaClass1. It's helper class (for non-meta
-instances) is callled HelperClass1. We now (manually) instantiate
-MetaClass1 once to get an empty special base class:
-
-<PRE>
-BaseClass1 = MetaClass1("BaseClass1", (), {})
-</PRE>
-
-We can now use BaseClass1 as a base class in a class statement:
-
-<PRE>
-class MySpecialClass(BaseClass1):
- i = 1
- def f(s): pass
-</PRE>
-
-At this point, MySpecialClass is defined; it is a metainstance of
-MetaClass1 just like BaseClass1, and in fact the expression
-``BaseClass1.__class__ == MySpecialClass.__class__ == MetaClass1''
-yields true.
-
-<P>We are now ready to create instances of MySpecialClass. Let's
-assume that no constructor arguments are required:
-
-<PRE>
-x = MySpecialClass()
-y = MySpecialClass()
-print x.__class__, y.__class__
-</PRE>
-
-The print statement shows that x and y are instances of HelperClass1.
-How did this happen? MySpecialClass is an instance of MetaClass1
-(``meta'' is irrelevant here); when an instance is called, its
-__call__ method is invoked, and presumably the __call__ method defined
-by MetaClass1 returns an instance of HelperClass1.
-
-<P>Now let's see how we could use metaclasses -- what can we do
-with metaclasses that we can't easily do without them? Here's one
-idea: a metaclass could automatically insert trace calls for all
-method calls. Let's first develop a simplified example, without
-support for inheritance or other ``advanced'' Python features (we'll
-add those later).
-
-<PRE>
-import types
-
-class Tracing:
- def __init__(self, name, bases, namespace):
- """Create a new class."""
- self.__name__ = name
- self.__bases__ = bases
- self.__namespace__ = namespace
- def __call__(self):
- """Create a new instance."""
- return Instance(self)
-
-class Instance:
- def __init__(self, klass):
- self.__klass__ = klass
- def __getattr__(self, name):
- try:
- value = self.__klass__.__namespace__[name]
- except KeyError:
- raise AttributeError, name
- if type(value) is not types.FunctionType:
- return value
- return BoundMethod(value, self)
-
-class BoundMethod:
- def __init__(self, function, instance):
- self.function = function
- self.instance = instance
- def __call__(self, *args):
- print "calling", self.function, "for", self.instance, "with", args
- return apply(self.function, (self.instance,) + args)
-
-Trace = Tracing('Trace', (), {})
-
-class MyTracedClass(Trace):
- def method1(self, a):
- self.a = a
- def method2(self):
- return self.a
-
-aninstance = MyTracedClass()
-
-aninstance.method1(10)
-
-print "the answer is %d" % aninstance.method2()
-</PRE>
-
-Confused already? The intention is to read this from top down. The
-Tracing class is the metaclass we're defining. Its structure is
-really simple.
-
-<P>
-
-<UL>
-
-<LI>The __init__ method is invoked when a new Tracing instance is
-created, e.g. the definition of class MyTracedClass later in the
-example. It simply saves the class name, base classes and namespace
-as instance variables.<P>
-
-<LI>The __call__ method is invoked when a Tracing instance is called,
-e.g. the creation of aninstance later in the example. It returns an
-instance of the class Instance, which is defined next.<P>
-
-</UL>
-
-<P>The class Instance is the class used for all instances of classes
-built using the Tracing metaclass, e.g. aninstance. It has two
-methods:
-
-<P>
-
-<UL>
-
-<LI>The __init__ method is invoked from the Tracing.__call__ method
-above to initialize a new instance. It saves the class reference as
-an instance variable. It uses a funny name because the user's
-instance variables (e.g. self.a later in the example) live in the same
-namespace.<P>
-
-<LI>The __getattr__ method is invoked whenever the user code
-references an attribute of the instance that is not an instance
-variable (nor a class variable; but except for __init__ and
-__getattr__ there are no class variables). It will be called, for
-example, when aninstance.method1 is referenced in the example, with
-self set to aninstance and name set to the string "method1".<P>
-
-</UL>
-
-<P>The __getattr__ method looks the name up in the __namespace__
-dictionary. If it isn't found, it raises an AttributeError exception.
-(In a more realistic example, it would first have to look through the
-base classes as well.) If it is found, there are two possibilities:
-it's either a function or it isn't. If it's not a function, it is
-assumed to be a class variable, and its value is returned. If it's a
-function, we have to ``wrap'' it in instance of yet another helper
-class, BoundMethod.
-
-<P>The BoundMethod class is needed to implement a familiar feature:
-when a method is defined, it has an initial argument, self, which is
-automatically bound to the relevant instance when it is called. For
-example, aninstance.method1(10) is equivalent to method1(aninstance,
-10). In the example if this call, first a temporary BoundMethod
-instance is created with the following constructor call: temp =
-BoundMethod(method1, aninstance); then this instance is called as
-temp(10). After the call, the temporary instance is discarded.
-
-<P>
-
-<UL>
-
-<LI>The __init__ method is invoked for the constructor call
-BoundMethod(method1, aninstance). It simply saves away its
-arguments.<P>
-
-<LI>The __call__ method is invoked when the bound method instance is
-called, as in temp(10). It needs to call method1(aninstance, 10).
-However, even though self.function is now method1 and self.instance is
-aninstance, it can't call self.function(self.instance, args) directly,
-because it should work regardless of the number of arguments passed.
-(For simplicity, support for keyword arguments has been omitted.)<P>
-
-</UL>
-
-<P>In order to be able to support arbitrary argument lists, the
-__call__ method first constructs a new argument tuple. Conveniently,
-because of the notation *args in __call__'s own argument list, the
-arguments to __call__ (except for self) are placed in the tuple args.
-To construct the desired argument list, we concatenate a singleton
-tuple containing the instance with the args tuple: (self.instance,) +
-args. (Note the trailing comma used to construct the singleton
-tuple.) In our example, the resulting argument tuple is (aninstance,
-10).
-
-<P>The intrinsic function apply() takes a function and an argument
-tuple and calls the function for it. In our example, we are calling
-apply(method1, (aninstance, 10)) which is equivalent to calling
-method(aninstance, 10).
-
-<P>From here on, things should come together quite easily. The output
-of the example code is something like this:
-
-<PRE>
-calling &lt;function method1 at ae8d8&gt; for &lt;Instance instance at 95ab0&gt; with (10,)
-calling &lt;function method2 at ae900&gt; for &lt;Instance instance at 95ab0&gt; with ()
-the answer is 10
-</PRE>
-
-<P>That was about the shortest meaningful example that I could come up
-with. A real tracing metaclass (for example, <A
-HREF="#Trace">Trace.py</A> discussed below) needs to be more
-complicated in two dimensions.
-
-<P>First, it needs to support more advanced Python features such as
-class variables, inheritance, __init__ methods, and keyword arguments.
-
-<P>Second, it needs to provide a more flexible way to handle the
-actual tracing information; perhaps it should be possible to write
-your own tracing function that gets called, perhaps it should be
-possible to enable and disable tracing on a per-class or per-instance
-basis, and perhaps a filter so that only interesting calls are traced;
-it should also be able to trace the return value of the call (or the
-exception it raised if an error occurs). Even the Trace.py example
-doesn't support all these features yet.
-
-<P>
-
-<HR>
-
-<H1>Real-life Examples</H1>
-
-<P>Have a look at some very preliminary examples that I coded up to
-teach myself how to write metaclasses:
-
-<DL>
-
-<DT><A HREF="Enum.py">Enum.py</A>
-
-<DD>This (ab)uses the class syntax as an elegant way to define
-enumerated types. The resulting classes are never instantiated --
-rather, their class attributes are the enumerated values. For
-example:
-
-<PRE>
-class Color(Enum):
- red = 1
- green = 2
- blue = 3
-print Color.red
-</PRE>
-
-will print the string ``Color.red'', while ``Color.red==1'' is true,
-and ``Color.red + 1'' raise a TypeError exception.
-
-<P>
-
-<DT><A NAME=Trace></A><A HREF="Trace.py">Trace.py</A>
-
-<DD>The resulting classes work much like standard
-classes, but by setting a special class or instance attribute
-__trace_output__ to point to a file, all calls to the class's methods
-are traced. It was a bit of a struggle to get this right. This
-should probably redone using the generic metaclass below.
-
-<P>
-
-<DT><A HREF="Meta.py">Meta.py</A>
-
-<DD>A generic metaclass. This is an attempt at finding out how much
-standard class behavior can be mimicked by a metaclass. The
-preliminary answer appears to be that everything's fine as long as the
-class (or its clients) don't look at the instance's __class__
-attribute, nor at the class's __dict__ attribute. The use of
-__getattr__ internally makes the classic implementation of __getattr__
-hooks tough; we provide a similar hook _getattr_ instead.
-(__setattr__ and __delattr__ are not affected.)
-(XXX Hm. Could detect presence of __getattr__ and rename it.)
-
-<P>
-
-<DT><A HREF="Eiffel.py">Eiffel.py</A>
-
-<DD>Uses the above generic metaclass to implement Eiffel style
-pre-conditions and post-conditions.
-
-<P>
-
-<DT><A HREF="Synch.py">Synch.py</A>
-
-<DD>Uses the above generic metaclass to implement synchronized
-methods.
-
-<P>
-
-<DT><A HREF="Simple.py">Simple.py</A>
-
-<DD>The example module used above.
-
-<P>
-
-</DL>
-
-<P>A pattern seems to be emerging: almost all these uses of
-metaclasses (except for Enum, which is probably more cute than useful)
-mostly work by placing wrappers around method calls. An obvious
-problem with that is that it's not easy to combine the features of
-different metaclasses, while this would actually be quite useful: for
-example, I wouldn't mind getting a trace from the test run of the
-Synch module, and it would be interesting to add preconditions to it
-as well. This needs more research. Perhaps a metaclass could be
-provided that allows stackable wrappers...
-
-<P>
-
-<HR>
-
-<H2>Things You Could Do With Metaclasses</H2>
-
-<P>There are lots of things you could do with metaclasses. Most of
-these can also be done with creative use of __getattr__, but
-metaclasses make it easier to modify the attribute lookup behavior of
-classes. Here's a partial list.
-
-<P>
-
-<UL>
-
-<LI>Enforce different inheritance semantics, e.g. automatically call
-base class methods when a derived class overrides<P>
-
-<LI>Implement class methods (e.g. if the first argument is not named
-'self')<P>
-
-<LI>Implement that each instance is initialized with <b>copies</b> of
-all class variables<P>
-
-<LI>Implement a different way to store instance variables (e.g. in a
-list kept outside the instance but indexed by the instance's id())<P>
-
-<LI>Automatically wrap or trap all or certain methods
-
-<UL>
-
-<LI>for tracing
-
-<LI>for precondition and postcondition checking
-
-<LI>for synchronized methods
-
-<LI>for automatic value caching
-
-</UL>
-<P>
-
-<LI>When an attribute is a parameterless function, call it on
-reference (to mimic it being an instance variable); same on assignment<P>
-
-<LI>Instrumentation: see how many times various attributes are used<P>
-
-<LI>Different semantics for __setattr__ and __getattr__ (e.g. disable
-them when they are being used recursively)<P>
-
-<LI>Abuse class syntax for other things<P>
-
-<LI>Experiment with automatic type checking<P>
-
-<LI>Delegation (or acquisition)<P>
-
-<LI>Dynamic inheritance patterns<P>
-
-<LI>Automatic caching of methods<P>
-
-</UL>
-
-<P>
-
-<HR>
-
-<H4>Credits</H4>
-
-<P>Many thanks to David Ascher and Donald Beaudry for their comments
-on earlier draft of this paper. Also thanks to Matt Conway and Tommy
-Burnette for putting a seed for the idea of metaclasses in my
-mind, nearly three years ago, even though at the time my response was
-``you can do that with __getattr__ hooks...'' :-)
-
-<P>
-
-<HR>
-
-</BODY>
-
-</HTML>
diff --git a/Demo/metaclasses/meta-vladimir.txt b/Demo/metaclasses/meta-vladimir.txt
deleted file mode 100644
index 36406bb..0000000
--- a/Demo/metaclasses/meta-vladimir.txt
+++ /dev/null
@@ -1,256 +0,0 @@
-Subject: Re: The metaclass saga using Python
-From: Vladimir Marangozov <Vladimir.Marangozov@imag.fr>
-To: tim_one@email.msn.com (Tim Peters)
-Cc: python-list@cwi.nl
-Date: Wed, 5 Aug 1998 15:59:06 +0200 (DFT)
-
-[Tim]
->
-> building-on-examples-tends-to-prevent-abstract-thrashing-ly y'rs - tim
->
-
-OK, I stand corrected. I understand that anybody's interpretation of
-the meta-class concept is likely to be difficult to digest by others.
-
-Here's another try, expressing the same thing, but using the Python
-programming model, examples and, perhaps, more popular terms.
-
-1. Classes.
-
- This is pure Python of today. Sorry about the tutorial, but it is
- meant to illustrate the second part, which is the one we're
- interested in and which will follow the same development scenario.
- Besides, newbies are likely to understand that the discussion is
- affordable even for them :-)
-
- a) Class definition
-
- A class is meant to define the common properties of a set of objects.
- A class is a "package" of properties. The assembly of properties
- in a class package is sometimes called a class structure (which isn't
- always appropriate).
-
- >>> class A:
- attr1 = "Hello" # an attribute of A
- def method1(self, *args): pass # method1 of A
- def method2(self, *args): pass # method2 of A
- >>>
-
- So far, we defined the structure of the class A. The class A is
- of type <class>. We can check this by asking Python: "what is A?"
-
- >>> A # What is A?
- <class __main__.A at 2023e360>
-
- b) Class instantiation
-
- Creating an object with the properties defined in the class A is
- called instantiation of the class A. After an instantiation of A, we
- obtain a new object, called an instance, which has the properties
- packaged in the class A.
-
- >>> a = A() # 'a' is the 1st instance of A
- >>> a # What is 'a'?
- <__main__.A instance at 2022b9d0>
-
- >>> b = A() # 'b' is another instance of A
- >>> b # What is 'b'?
- <__main__.A instance at 2022b9c0>
-
- The objects, 'a' and 'b', are of type <instance> and they both have
- the same properties. Note, that 'a' and 'b' are different objects.
- (their adresses differ). This is a bit hard to see, so let's ask Python:
-
- >>> a == b # Is 'a' the same object as 'b'?
- 0 # No.
-
- Instance objects have one more special property, indicating the class
- they are an instance of. This property is named __class__.
-
- >>> a.__class__ # What is the class of 'a'?
- <class __main__.A at 2023e360> # 'a' is an instance of A
- >>> b.__class__ # What is the class of 'b'?
- <class __main__.A at 2023e360> # 'b' is an instance of A
- >>> a.__class__ == b.__class__ # Is it really the same class A?
- 1 # Yes.
-
- c) Class inheritance (class composition and specialization)
-
- Classes can be defined in terms of other existing classes (and only
- classes! -- don't bug me on this now). Thus, we can compose property
- packages and create new ones. We reuse the property set defined
- in a class by defining a new class, which "inherits" from the former.
- In other words, a class B which inherits from the class A, inherits
- the properties defined in A, or, B inherits the structure of A.
-
- In the same time, at the definition of the new class B, we can enrich
- the inherited set of properties by adding new ones and/or modify some
- of the inherited properties.
-
- >>> class B(A): # B inherits A's properties
- attr2 = "World" # additional attr2
- def method2(self, arg1): pass # method2 is redefined
- def method3(self, *args): pass # additional method3
-
- >>> B # What is B?
- <class __main__.B at 2023e500>
- >>> B == A # Is B the same class as A?
- 0 # No.
-
- Classes define one special property, indicating whether a class
- inherits the properties of another class. This property is called
- __bases__ and it contains a list (a tuple) of the classes the new
- class inherits from. The classes from which a class is inheriting the
- properties are called superclasses (in Python, we call them also --
- base classes).
-
- >>> A.__bases__ # Does A have any superclasses?
- () # No.
- >>> B.__bases__ # Does B have any superclasses?
- (<class __main__.A at 2023e360>,) # Yes. It has one superclass.
- >>> B.__bases__[0] == A # Is it really the class A?
- 1 # Yes, it is.
-
---------
-
- Congratulations on getting this far! This was the hard part.
- Now, let's continue with the easy one.
-
---------
-
-2. Meta-classes
-
- You have to admit, that an anonymous group of Python wizards are
- not satisfied with the property packaging facilities presented above.
- They say, that the Real-World bugs them with problems that cannot be
- modelled successfully with classes. Or, that the way classes are
- implemented in Python and the way classes and instances behave at
- runtime isn't always appropriate for reproducing the Real-World's
- behavior in a way that satisfies them.
-
- Hence, what they want is the following:
-
- a) leave objects as they are (instances of classes)
- b) leave classes as they are (property packages and object creators)
-
- BUT, at the same time:
-
- c) consider classes as being instances of mysterious objects.
- d) label mysterious objects "meta-classes".
-
- Easy, eh?
-
- You may ask: "Why on earth do they want to do that?".
- They answer: "Poor soul... Go and see how cruel the Real-World is!".
- You - fuzzy: "OK, will do!"
-
- And here we go for another round of what I said in section 1 -- Classes.
-
- However, be warned! The features we're going to talk about aren't fully
- implemented yet, because the Real-World don't let wizards to evaluate
- precisely how cruel it is, so the features are still highly-experimental.
-
- a) Meta-class definition
-
- A meta-class is meant to define the common properties of a set of
- classes. A meta-class is a "package" of properties. The assembly
- of properties in a meta-class package is sometimes called a meta-class
- structure (which isn't always appropriate).
-
- In Python, a meta-class definition would have looked like this:
-
- >>> metaclass M:
- attr1 = "Hello" # an attribute of M
- def method1(self, *args): pass # method1 of M
- def method2(self, *args): pass # method2 of M
- >>>
-
- So far, we defined the structure of the meta-class M. The meta-class
- M is of type <metaclass>. We cannot check this by asking Python, but
- if we could, it would have answered:
-
- >>> M # What is M?
- <metaclass __main__.M at 2023e4e0>
-
- b) Meta-class instantiation
-
- Creating an object with the properties defined in the meta-class M is
- called instantiation of the meta-class M. After an instantiation of M,
- we obtain a new object, called an class, but now it is called also
- a meta-instance, which has the properties packaged in the meta-class M.
-
- In Python, instantiating a meta-class would have looked like this:
-
- >>> A = M() # 'A' is the 1st instance of M
- >>> A # What is 'A'?
- <class __main__.A at 2022b9d0>
-
- >>> B = M() # 'B' is another instance of M
- >>> B # What is 'B'?
- <class __main__.B at 2022b9c0>
-
- The metaclass-instances, A and B, are of type <class> and they both
- have the same properties. Note, that A and B are different objects.
- (their adresses differ). This is a bit hard to see, but if it was
- possible to ask Python, it would have answered:
-
- >>> A == B # Is A the same class as B?
- 0 # No.
-
- Class objects have one more special property, indicating the meta-class
- they are an instance of. This property is named __metaclass__.
-
- >>> A.__metaclass__ # What is the meta-class of A?
- <metaclass __main__.M at 2023e4e0> # A is an instance of M
- >>> A.__metaclass__ # What is the meta-class of B?
- <metaclass __main__.M at 2023e4e0> # B is an instance of M
- >>> A.__metaclass__ == B.__metaclass__ # Is it the same meta-class M?
- 1 # Yes.
-
- c) Meta-class inheritance (meta-class composition and specialization)
-
- Meta-classes can be defined in terms of other existing meta-classes
- (and only meta-classes!). Thus, we can compose property packages and
- create new ones. We reuse the property set defined in a meta-class by
- defining a new meta-class, which "inherits" from the former.
- In other words, a meta-class N which inherits from the meta-class M,
- inherits the properties defined in M, or, N inherits the structure of M.
-
- In the same time, at the definition of the new meta-class N, we can
- enrich the inherited set of properties by adding new ones and/or modify
- some of the inherited properties.
-
- >>> metaclass N(M): # N inherits M's properties
- attr2 = "World" # additional attr2
- def method2(self, arg1): pass # method2 is redefined
- def method3(self, *args): pass # additional method3
-
- >>> N # What is N?
- <metaclass __main__.N at 2023e500>
- >>> N == M # Is N the same meta-class as M?
- 0 # No.
-
- Meta-classes define one special property, indicating whether a
- meta-class inherits the properties of another meta-class. This property
- is called __metabases__ and it contains a list (a tuple) of the
- meta-classes the new meta-class inherits from. The meta-classes from
- which a meta-class is inheriting the properties are called
- super-meta-classes (in Python, we call them also -- super meta-bases).
-
- >>> M.__metabases__ # Does M have any supermetaclasses?
- () # No.
- >>> N.__metabases__ # Does N have any supermetaclasses?
- (<metaclass __main__.M at 2023e360>,) # Yes. It has a supermetaclass.
- >>> N.__metabases__[0] == M # Is it really the meta-class M?
- 1 # Yes, it is.
-
---------
-
- Triple congratulations on getting this far!
- Now you know everything about meta-classes and the Real-World!
-
-<unless-wizards-want-meta-classes-be-instances-of-mysterious-objects!>
-
---
- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr
-http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252
diff --git a/Demo/newmetaclasses/Eiffel.py b/Demo/newmetaclasses/Eiffel.py
deleted file mode 100644
index 730a85d..0000000
--- a/Demo/newmetaclasses/Eiffel.py
+++ /dev/null
@@ -1,141 +0,0 @@
-"""Support Eiffel-style preconditions and postconditions."""
-
-from types import FunctionType as function
-
-class EiffelBaseMetaClass(type):
-
- def __new__(meta, name, bases, dict):
- meta.convert_methods(dict)
- return super(EiffelBaseMetaClass, meta).__new__(meta, name, bases,
- dict)
-
- @classmethod
- def convert_methods(cls, dict):
- """Replace functions in dict with EiffelMethod wrappers.
-
- The dict is modified in place.
-
- If a method ends in _pre or _post, it is removed from the dict
- regardless of whether there is a corresponding method.
- """
- # find methods with pre or post conditions
- methods = []
- for k, v in dict.iteritems():
- if k.endswith('_pre') or k.endswith('_post'):
- assert isinstance(v, function)
- elif isinstance(v, function):
- methods.append(k)
- for m in methods:
- pre = dict.get("%s_pre" % m)
- post = dict.get("%s_post" % m)
- if pre or post:
- dict[k] = cls.make_eiffel_method(dict[m], pre, post)
-
-class EiffelMetaClass1(EiffelBaseMetaClass):
- # an implementation of the "eiffel" meta class that uses nested functions
-
- @staticmethod
- def make_eiffel_method(func, pre, post):
- def method(self, *args, **kwargs):
- if pre:
- pre(self, *args, **kwargs)
- x = func(self, *args, **kwargs)
- if post:
- post(self, x, *args, **kwargs)
- return x
-
- if func.__doc__:
- method.__doc__ = func.__doc__
-
- return method
-
-class EiffelMethodWrapper:
-
- def __init__(self, inst, descr):
- self._inst = inst
- self._descr = descr
-
- def __call__(self, *args, **kwargs):
- return self._descr.callmethod(self._inst, args, kwargs)
-
-class EiffelDescriptor(object):
-
- def __init__(self, func, pre, post):
- self._func = func
- self._pre = pre
- self._post = post
-
- self.__name__ = func.__name__
- self.__doc__ = func.__doc__
-
- def __get__(self, obj, cls):
- return EiffelMethodWrapper(obj, self)
-
- def callmethod(self, inst, args, kwargs):
- if self._pre:
- self._pre(inst, *args, **kwargs)
- x = self._func(inst, *args, **kwargs)
- if self._post:
- self._post(inst, x, *args, **kwargs)
- return x
-
-class EiffelMetaClass2(EiffelBaseMetaClass):
- # an implementation of the "eiffel" meta class that uses descriptors
-
- make_eiffel_method = EiffelDescriptor
-
-def _test(metaclass):
- class Eiffel:
- __metaclass__ = metaclass
-
- class Test(Eiffel):
-
- def m(self, arg):
- """Make it a little larger"""
- return arg + 1
-
- def m2(self, arg):
- """Make it a little larger"""
- return arg + 1
-
- def m2_pre(self, arg):
- assert arg > 0
-
- def m2_post(self, result, arg):
- assert result > arg
-
- class Sub(Test):
- def m2(self, arg):
- return arg**2
- def m2_post(self, Result, arg):
- super(Sub, self).m2_post(Result, arg)
- assert Result < 100
-
- t = Test()
- t.m(1)
- t.m2(1)
- try:
- t.m2(0)
- except AssertionError:
- pass
- else:
- assert False
-
- s = Sub()
- try:
- s.m2(1)
- except AssertionError:
- pass # result == arg
- else:
- assert False
- try:
- s.m2(10)
- except AssertionError:
- pass # result == 100
- else:
- assert False
- s.m2(5)
-
-if __name__ == "__main__":
- _test(EiffelMetaClass1)
- _test(EiffelMetaClass2)
diff --git a/Demo/newmetaclasses/Enum.py b/Demo/newmetaclasses/Enum.py
deleted file mode 100644
index 2a5823b..0000000
--- a/Demo/newmetaclasses/Enum.py
+++ /dev/null
@@ -1,177 +0,0 @@
-"""Enumeration metaclass."""
-
-class EnumMetaclass(type):
- """Metaclass for enumeration.
-
- To define your own enumeration, do something like
-
- class Color(Enum):
- red = 1
- green = 2
- blue = 3
-
- Now, Color.red, Color.green and Color.blue behave totally
- different: they are enumerated values, not integers.
-
- Enumerations cannot be instantiated; however they can be
- subclassed.
- """
-
- def __init__(cls, name, bases, dict):
- super(EnumMetaclass, cls).__init__(name, bases, dict)
- cls._members = []
- for attr in dict.keys():
- if not (attr.startswith('__') and attr.endswith('__')):
- enumval = EnumInstance(name, attr, dict[attr])
- setattr(cls, attr, enumval)
- cls._members.append(attr)
-
- def __getattr__(cls, name):
- if name == "__members__":
- return cls._members
- raise AttributeError, name
-
- def __repr__(cls):
- s1 = s2 = ""
- enumbases = [base.__name__ for base in cls.__bases__
- if isinstance(base, EnumMetaclass) and not base is Enum]
- if enumbases:
- s1 = "(%s)" % ", ".join(enumbases)
- enumvalues = ["%s: %d" % (val, getattr(cls, val))
- for val in cls._members]
- if enumvalues:
- s2 = ": {%s}" % ", ".join(enumvalues)
- return "%s%s%s" % (cls.__name__, s1, s2)
-
-class FullEnumMetaclass(EnumMetaclass):
- """Metaclass for full enumerations.
-
- A full enumeration displays all the values defined in base classes.
- """
-
- def __init__(cls, name, bases, dict):
- super(FullEnumMetaclass, cls).__init__(name, bases, dict)
- for obj in cls.__mro__:
- if isinstance(obj, EnumMetaclass):
- for attr in obj._members:
- # XXX inefficient
- if not attr in cls._members:
- cls._members.append(attr)
-
-class EnumInstance(int):
- """Class to represent an enumeration value.
-
- EnumInstance('Color', 'red', 12) prints as 'Color.red' and behaves
- like the integer 12 when compared, but doesn't support arithmetic.
-
- XXX Should it record the actual enumeration rather than just its
- name?
- """
-
- def __new__(cls, classname, enumname, value):
- return int.__new__(cls, value)
-
- def __init__(self, classname, enumname, value):
- self.__classname = classname
- self.__enumname = enumname
-
- def __repr__(self):
- return "EnumInstance(%s, %s, %d)" % (self.__classname, self.__enumname,
- self)
-
- def __str__(self):
- return "%s.%s" % (self.__classname, self.__enumname)
-
-class Enum:
- __metaclass__ = EnumMetaclass
-
-class FullEnum:
- __metaclass__ = FullEnumMetaclass
-
-def _test():
-
- class Color(Enum):
- red = 1
- green = 2
- blue = 3
-
- print Color.red
-
- print repr(Color.red)
- print Color.red == Color.red
- print Color.red == Color.blue
- print Color.red == 1
- print Color.red == 2
-
- class ExtendedColor(Color):
- white = 0
- orange = 4
- yellow = 5
- purple = 6
- black = 7
-
- print ExtendedColor.orange
- print ExtendedColor.red
-
- print Color.red == ExtendedColor.red
-
- class OtherColor(Enum):
- white = 4
- blue = 5
-
- class MergedColor(Color, OtherColor):
- pass
-
- print MergedColor.red
- print MergedColor.white
-
- print Color
- print ExtendedColor
- print OtherColor
- print MergedColor
-
-def _test2():
-
- class Color(FullEnum):
- red = 1
- green = 2
- blue = 3
-
- print Color.red
-
- print repr(Color.red)
- print Color.red == Color.red
- print Color.red == Color.blue
- print Color.red == 1
- print Color.red == 2
-
- class ExtendedColor(Color):
- white = 0
- orange = 4
- yellow = 5
- purple = 6
- black = 7
-
- print ExtendedColor.orange
- print ExtendedColor.red
-
- print Color.red == ExtendedColor.red
-
- class OtherColor(FullEnum):
- white = 4
- blue = 5
-
- class MergedColor(Color, OtherColor):
- pass
-
- print MergedColor.red
- print MergedColor.white
-
- print Color
- print ExtendedColor
- print OtherColor
- print MergedColor
-
-if __name__ == '__main__':
- _test()
- _test2()
diff --git a/Demo/parser/FILES b/Demo/parser/FILES
deleted file mode 100644
index 1ff59a3..0000000
--- a/Demo/parser/FILES
+++ /dev/null
@@ -1,6 +0,0 @@
-Demo/parser
-Doc/libparser.tex
-Lib/AST.py
-Lib/symbol.py
-Lib/token.py
-Modules/parsermodule.c
diff --git a/Demo/parser/README b/Demo/parser/README
deleted file mode 100644
index fd5eb25..0000000
--- a/Demo/parser/README
+++ /dev/null
@@ -1,32 +0,0 @@
-These files are from the large example of using the `parser' module. Refer
-to the Python Library Reference for more information.
-
-It also contains examples for the AST parser.
-
-Files:
-------
-
- FILES -- list of files associated with the parser module.
-
- README -- this file.
-
- docstring.py -- sample source file containing only a module docstring.
-
- example.py -- module that uses the `parser' module to extract
- information from the parse tree of Python source
- code.
-
- simple.py -- sample source containing a "short form" definition.
-
- source.py -- sample source code used to demonstrate ability to
- handle nested constructs easily using the functions
- and classes in example.py.
-
- test_parser.py program to put the parser module through its paces.
-
- test_unparse.py tests for the unparse module
-
- unparse.py AST (2.7) based example to recreate source code
- from an AST.
-
-Enjoy!
diff --git a/Demo/parser/docstring.py b/Demo/parser/docstring.py
deleted file mode 100644
index 45a261b..0000000
--- a/Demo/parser/docstring.py
+++ /dev/null
@@ -1,2 +0,0 @@
-"""Some documentation.
-"""
diff --git a/Demo/parser/example.py b/Demo/parser/example.py
deleted file mode 100644
index 2aa9ec2..0000000
--- a/Demo/parser/example.py
+++ /dev/null
@@ -1,190 +0,0 @@
-"""Simple code to extract class & function docstrings from a module.
-
-This code is used as an example in the library reference manual in the
-section on using the parser module. Refer to the manual for a thorough
-discussion of the operation of this code.
-"""
-
-import os
-import parser
-import symbol
-import token
-import types
-
-from types import ListType, TupleType
-
-
-def get_docs(fileName):
- """Retrieve information from the parse tree of a source file.
-
- fileName
- Name of the file to read Python source code from.
- """
- source = open(fileName).read()
- basename = os.path.basename(os.path.splitext(fileName)[0])
- ast = parser.suite(source)
- return ModuleInfo(ast.totuple(), basename)
-
-
-class SuiteInfoBase:
- _docstring = ''
- _name = ''
-
- def __init__(self, tree = None):
- self._class_info = {}
- self._function_info = {}
- if tree:
- self._extract_info(tree)
-
- def _extract_info(self, tree):
- # extract docstring
- if len(tree) == 2:
- found, vars = match(DOCSTRING_STMT_PATTERN[1], tree[1])
- else:
- found, vars = match(DOCSTRING_STMT_PATTERN, tree[3])
- if found:
- self._docstring = eval(vars['docstring'])
- # discover inner definitions
- for node in tree[1:]:
- found, vars = match(COMPOUND_STMT_PATTERN, node)
- if found:
- cstmt = vars['compound']
- if cstmt[0] == symbol.funcdef:
- name = cstmt[2][1]
- self._function_info[name] = FunctionInfo(cstmt)
- elif cstmt[0] == symbol.classdef:
- name = cstmt[2][1]
- self._class_info[name] = ClassInfo(cstmt)
-
- def get_docstring(self):
- return self._docstring
-
- def get_name(self):
- return self._name
-
- def get_class_names(self):
- return self._class_info.keys()
-
- def get_class_info(self, name):
- return self._class_info[name]
-
- def __getitem__(self, name):
- try:
- return self._class_info[name]
- except KeyError:
- return self._function_info[name]
-
-
-class SuiteFuncInfo:
- # Mixin class providing access to function names and info.
-
- def get_function_names(self):
- return self._function_info.keys()
-
- def get_function_info(self, name):
- return self._function_info[name]
-
-
-class FunctionInfo(SuiteInfoBase, SuiteFuncInfo):
- def __init__(self, tree = None):
- self._name = tree[2][1]
- SuiteInfoBase.__init__(self, tree and tree[-1] or None)
-
-
-class ClassInfo(SuiteInfoBase):
- def __init__(self, tree = None):
- self._name = tree[2][1]
- SuiteInfoBase.__init__(self, tree and tree[-1] or None)
-
- def get_method_names(self):
- return self._function_info.keys()
-
- def get_method_info(self, name):
- return self._function_info[name]
-
-
-class ModuleInfo(SuiteInfoBase, SuiteFuncInfo):
- def __init__(self, tree = None, name = "<string>"):
- self._name = name
- SuiteInfoBase.__init__(self, tree)
- if tree:
- found, vars = match(DOCSTRING_STMT_PATTERN, tree[1])
- if found:
- self._docstring = vars["docstring"]
-
-
-def match(pattern, data, vars=None):
- """Match `data' to `pattern', with variable extraction.
-
- pattern
- Pattern to match against, possibly containing variables.
-
- data
- Data to be checked and against which variables are extracted.
-
- vars
- Dictionary of variables which have already been found. If not
- provided, an empty dictionary is created.
-
- The `pattern' value may contain variables of the form ['varname'] which
- are allowed to match anything. The value that is matched is returned as
- part of a dictionary which maps 'varname' to the matched value. 'varname'
- is not required to be a string object, but using strings makes patterns
- and the code which uses them more readable.
-
- This function returns two values: a boolean indicating whether a match
- was found and a dictionary mapping variable names to their associated
- values.
- """
- if vars is None:
- vars = {}
- if type(pattern) is ListType: # 'variables' are ['varname']
- vars[pattern[0]] = data
- return 1, vars
- if type(pattern) is not TupleType:
- return (pattern == data), vars
- if len(data) != len(pattern):
- return 0, vars
- for pattern, data in map(None, pattern, data):
- same, vars = match(pattern, data, vars)
- if not same:
- break
- return same, vars
-
-
-# This pattern identifies compound statements, allowing them to be readily
-# differentiated from simple statements.
-#
-COMPOUND_STMT_PATTERN = (
- symbol.stmt,
- (symbol.compound_stmt, ['compound'])
- )
-
-
-# This pattern will match a 'stmt' node which *might* represent a docstring;
-# docstrings require that the statement which provides the docstring be the
-# first statement in the class or function, which this pattern does not check.
-#
-DOCSTRING_STMT_PATTERN = (
- symbol.stmt,
- (symbol.simple_stmt,
- (symbol.small_stmt,
- (symbol.expr_stmt,
- (symbol.testlist,
- (symbol.test,
- (symbol.and_test,
- (symbol.not_test,
- (symbol.comparison,
- (symbol.expr,
- (symbol.xor_expr,
- (symbol.and_expr,
- (symbol.shift_expr,
- (symbol.arith_expr,
- (symbol.term,
- (symbol.factor,
- (symbol.power,
- (symbol.atom,
- (token.STRING, ['docstring'])
- )))))))))))))))),
- (token.NEWLINE, '')
- ))
diff --git a/Demo/parser/simple.py b/Demo/parser/simple.py
deleted file mode 100644
index 184e2fe..0000000
--- a/Demo/parser/simple.py
+++ /dev/null
@@ -1 +0,0 @@
-def f(): "maybe a docstring"
diff --git a/Demo/parser/source.py b/Demo/parser/source.py
deleted file mode 100644
index b900628..0000000
--- a/Demo/parser/source.py
+++ /dev/null
@@ -1,27 +0,0 @@
-"""Exmaple file to be parsed for the parsermodule example.
-
-The classes and functions in this module exist only to exhibit the ability
-of the handling information extraction from nested definitions using parse
-trees. They shouldn't interest you otherwise!
-"""
-
-class Simple:
- "This class does very little."
-
- def method(self):
- "This method does almost nothing."
- return 1
-
- class Nested:
- "This is a nested class."
-
- def nested_method(self):
- "Method of Nested class."
- def nested_function():
- "Function in method of Nested class."
- pass
- return nested_function
-
-def function():
- "This function lives at the module level."
- return 0
diff --git a/Demo/parser/test_parser.py b/Demo/parser/test_parser.py
deleted file mode 100755
index db4e6fe..0000000
--- a/Demo/parser/test_parser.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#! /usr/bin/env python
-# (Force the script to use the latest build.)
-#
-# test_parser.py
-
-import parser, traceback
-
-_numFailed = 0
-
-def testChunk(t, fileName):
- global _numFailed
- print '----', fileName,
- try:
- st = parser.suite(t)
- tup = parser.st2tuple(st)
- # this discards the first ST; a huge memory savings when running
- # against a large source file like Tkinter.py.
- st = None
- new = parser.tuple2st(tup)
- except parser.ParserError, err:
- print
- print 'parser module raised exception on input file', fileName + ':'
- traceback.print_exc()
- _numFailed = _numFailed + 1
- else:
- if tup != parser.st2tuple(new):
- print
- print 'parser module failed on input file', fileName
- _numFailed = _numFailed + 1
- else:
- print 'o.k.'
-
-def testFile(fileName):
- t = open(fileName).read()
- testChunk(t, fileName)
-
-def test():
- import sys
- args = sys.argv[1:]
- if not args:
- import glob
- args = glob.glob("*.py")
- args.sort()
- map(testFile, args)
- sys.exit(_numFailed != 0)
-
-if __name__ == '__main__':
- test()
diff --git a/Demo/parser/test_unparse.py b/Demo/parser/test_unparse.py
deleted file mode 100644
index 2ecfd37..0000000
--- a/Demo/parser/test_unparse.py
+++ /dev/null
@@ -1,213 +0,0 @@
-import unittest
-from test import test_support
-import cStringIO
-import sys
-import os
-import tokenize
-import ast
-import unparse
-
-def read_pyfile(filename):
- """Read and return the contents of a Python source file (as a
- string), taking into account the file encoding."""
- with open(filename, "r") as pyfile:
- source = pyfile.read()
- return source
-
-for_else = """\
-def f():
- for x in range(10):
- break
- else:
- y = 2
- z = 3
-"""
-
-while_else = """\
-def g():
- while True:
- break
- else:
- y = 2
- z = 3
-"""
-
-relative_import = """\
-from . import fred
-from .. import barney
-from .australia import shrimp as prawns
-"""
-
-class_decorator = """\
-@f1(arg)
-@f2
-class Foo: pass
-"""
-
-elif1 = """\
-if cond1:
- suite1
-elif cond2:
- suite2
-else:
- suite3
-"""
-
-elif2 = """\
-if cond1:
- suite1
-elif cond2:
- suite2
-"""
-
-try_except_finally = """\
-try:
- suite1
-except ex1:
- suite2
-except ex2:
- suite3
-else:
- suite4
-finally:
- suite5
-"""
-
-class ASTTestCase(unittest.TestCase):
- def assertASTEqual(self, ast1, ast2):
- dump1 = ast.dump(ast1)
- dump2 = ast.dump(ast2)
- self.assertEqual(ast.dump(ast1), ast.dump(ast2))
-
- def check_roundtrip(self, code1, filename="internal"):
- ast1 = compile(code1, filename, "exec", ast.PyCF_ONLY_AST)
- unparse_buffer = cStringIO.StringIO()
- unparse.Unparser(ast1, unparse_buffer)
- code2 = unparse_buffer.getvalue()
- ast2 = compile(code2, filename, "exec", ast.PyCF_ONLY_AST)
- self.assertASTEqual(ast1, ast2)
-
-class UnparseTestCase(ASTTestCase):
- # Tests for specific bugs found in earlier versions of unparse
-
- def test_del_statement(self):
- self.check_roundtrip("del x, y, z")
-
- def test_shifts(self):
- self.check_roundtrip("45 << 2")
- self.check_roundtrip("13 >> 7")
-
- def test_for_else(self):
- self.check_roundtrip(for_else)
-
- def test_while_else(self):
- self.check_roundtrip(while_else)
-
- def test_unary_parens(self):
- self.check_roundtrip("(-1)**7")
- self.check_roundtrip("(-1.)**8")
- self.check_roundtrip("(-1j)**6")
- self.check_roundtrip("not True or False")
- self.check_roundtrip("True or not False")
-
- def test_integer_parens(self):
- self.check_roundtrip("3 .__abs__()")
-
- def test_huge_float(self):
- self.check_roundtrip("1e1000")
- self.check_roundtrip("-1e1000")
- self.check_roundtrip("1e1000j")
- self.check_roundtrip("-1e1000j")
-
- def test_min_int(self):
- self.check_roundtrip(str(-sys.maxint-1))
- self.check_roundtrip("-(%s)" % (sys.maxint + 1))
-
- def test_imaginary_literals(self):
- self.check_roundtrip("7j")
- self.check_roundtrip("-7j")
- self.check_roundtrip("-(7j)")
- self.check_roundtrip("0j")
- self.check_roundtrip("-0j")
- self.check_roundtrip("-(0j)")
-
- def test_negative_zero(self):
- self.check_roundtrip("-0")
- self.check_roundtrip("-(0)")
- self.check_roundtrip("-0b0")
- self.check_roundtrip("-(0b0)")
- self.check_roundtrip("-0o0")
- self.check_roundtrip("-(0o0)")
- self.check_roundtrip("-0x0")
- self.check_roundtrip("-(0x0)")
-
- def test_lambda_parentheses(self):
- self.check_roundtrip("(lambda: int)()")
-
- def test_chained_comparisons(self):
- self.check_roundtrip("1 < 4 <= 5")
- self.check_roundtrip("a is b is c is not d")
-
- def test_function_arguments(self):
- self.check_roundtrip("def f(): pass")
- self.check_roundtrip("def f(a): pass")
- self.check_roundtrip("def f(b = 2): pass")
- self.check_roundtrip("def f(a, b): pass")
- self.check_roundtrip("def f(a, b = 2): pass")
- self.check_roundtrip("def f(a = 5, b = 2): pass")
- self.check_roundtrip("def f(*args, **kwargs): pass")
-
- def test_relative_import(self):
- self.check_roundtrip(relative_import)
-
- def test_bytes(self):
- self.check_roundtrip("b'123'")
-
- def test_set_literal(self):
- self.check_roundtrip("{'a', 'b', 'c'}")
-
- def test_set_comprehension(self):
- self.check_roundtrip("{x for x in range(5)}")
-
- def test_dict_comprehension(self):
- self.check_roundtrip("{x: x*x for x in range(10)}")
-
- def test_class_decorators(self):
- self.check_roundtrip(class_decorator)
-
- def test_elifs(self):
- self.check_roundtrip(elif1)
- self.check_roundtrip(elif2)
-
- def test_try_except_finally(self):
- self.check_roundtrip(try_except_finally)
-
-class DirectoryTestCase(ASTTestCase):
- """Test roundtrip behaviour on all files in Lib and Lib/test."""
-
- # test directories, relative to the root of the distribution
- test_directories = 'Lib', os.path.join('Lib', 'test')
-
- def test_files(self):
- # get names of files to test
- dist_dir = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)
-
- names = []
- for d in self.test_directories:
- test_dir = os.path.join(dist_dir, d)
- for n in os.listdir(test_dir):
- if n.endswith('.py') and not n.startswith('bad'):
- names.append(os.path.join(test_dir, n))
-
- for filename in names:
- if test_support.verbose:
- print('Testing %s' % filename)
- source = read_pyfile(filename)
- self.check_roundtrip(source)
-
-
-def test_main():
- test_support.run_unittest(UnparseTestCase, DirectoryTestCase)
-
-if __name__ == '__main__':
- test_main()
diff --git a/Demo/parser/unparse.py b/Demo/parser/unparse.py
deleted file mode 100644
index 1b1ff29..0000000
--- a/Demo/parser/unparse.py
+++ /dev/null
@@ -1,606 +0,0 @@
-"Usage: unparse.py <path to source file>"
-import sys
-import ast
-import cStringIO
-import os
-
-# Large float and imaginary literals get turned into infinities in the AST.
-# We unparse those infinities to INFSTR.
-INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1)
-
-def interleave(inter, f, seq):
- """Call f on each item in seq, calling inter() in between.
- """
- seq = iter(seq)
- try:
- f(next(seq))
- except StopIteration:
- pass
- else:
- for x in seq:
- inter()
- f(x)
-
-class Unparser:
- """Methods in this class recursively traverse an AST and
- output source code for the abstract syntax; original formatting
- is disregarded. """
-
- def __init__(self, tree, file = sys.stdout):
- """Unparser(tree, file=sys.stdout) -> None.
- Print the source for tree to file."""
- self.f = file
- self.future_imports = []
- self._indent = 0
- self.dispatch(tree)
- self.f.write("")
- self.f.flush()
-
- def fill(self, text = ""):
- "Indent a piece of text, according to the current indentation level"
- self.f.write("\n"+" "*self._indent + text)
-
- def write(self, text):
- "Append a piece of text to the current line."
- self.f.write(text)
-
- def enter(self):
- "Print ':', and increase the indentation."
- self.write(":")
- self._indent += 1
-
- def leave(self):
- "Decrease the indentation level."
- self._indent -= 1
-
- def dispatch(self, tree):
- "Dispatcher function, dispatching tree type T to method _T."
- if isinstance(tree, list):
- for t in tree:
- self.dispatch(t)
- return
- meth = getattr(self, "_"+tree.__class__.__name__)
- meth(tree)
-
-
- ############### Unparsing methods ######################
- # There should be one method per concrete grammar type #
- # Constructors should be grouped by sum type. Ideally, #
- # this would follow the order in the grammar, but #
- # currently doesn't. #
- ########################################################
-
- def _Module(self, tree):
- for stmt in tree.body:
- self.dispatch(stmt)
-
- # stmt
- def _Expr(self, tree):
- self.fill()
- self.dispatch(tree.value)
-
- def _Import(self, t):
- self.fill("import ")
- interleave(lambda: self.write(", "), self.dispatch, t.names)
-
- def _ImportFrom(self, t):
- # A from __future__ import may affect unparsing, so record it.
- if t.module and t.module == '__future__':
- self.future_imports.extend(n.name for n in t.names)
-
- self.fill("from ")
- self.write("." * t.level)
- if t.module:
- self.write(t.module)
- self.write(" import ")
- interleave(lambda: self.write(", "), self.dispatch, t.names)
-
- def _Assign(self, t):
- self.fill()
- for target in t.targets:
- self.dispatch(target)
- self.write(" = ")
- self.dispatch(t.value)
-
- def _AugAssign(self, t):
- self.fill()
- self.dispatch(t.target)
- self.write(" "+self.binop[t.op.__class__.__name__]+"= ")
- self.dispatch(t.value)
-
- def _Return(self, t):
- self.fill("return")
- if t.value:
- self.write(" ")
- self.dispatch(t.value)
-
- def _Pass(self, t):
- self.fill("pass")
-
- def _Break(self, t):
- self.fill("break")
-
- def _Continue(self, t):
- self.fill("continue")
-
- def _Delete(self, t):
- self.fill("del ")
- interleave(lambda: self.write(", "), self.dispatch, t.targets)
-
- def _Assert(self, t):
- self.fill("assert ")
- self.dispatch(t.test)
- if t.msg:
- self.write(", ")
- self.dispatch(t.msg)
-
- def _Exec(self, t):
- self.fill("exec ")
- self.dispatch(t.body)
- if t.globals:
- self.write(" in ")
- self.dispatch(t.globals)
- if t.locals:
- self.write(", ")
- self.dispatch(t.locals)
-
- def _Print(self, t):
- self.fill("print ")
- do_comma = False
- if t.dest:
- self.write(">>")
- self.dispatch(t.dest)
- do_comma = True
- for e in t.values:
- if do_comma:self.write(", ")
- else:do_comma=True
- self.dispatch(e)
- if not t.nl:
- self.write(",")
-
- def _Global(self, t):
- self.fill("global ")
- interleave(lambda: self.write(", "), self.write, t.names)
-
- def _Yield(self, t):
- self.write("(")
- self.write("yield")
- if t.value:
- self.write(" ")
- self.dispatch(t.value)
- self.write(")")
-
- def _Raise(self, t):
- self.fill('raise ')
- if t.type:
- self.dispatch(t.type)
- if t.inst:
- self.write(", ")
- self.dispatch(t.inst)
- if t.tback:
- self.write(", ")
- self.dispatch(t.tback)
-
- def _TryExcept(self, t):
- self.fill("try")
- self.enter()
- self.dispatch(t.body)
- self.leave()
-
- for ex in t.handlers:
- self.dispatch(ex)
- if t.orelse:
- self.fill("else")
- self.enter()
- self.dispatch(t.orelse)
- self.leave()
-
- def _TryFinally(self, t):
- if len(t.body) == 1 and isinstance(t.body[0], ast.TryExcept):
- # try-except-finally
- self.dispatch(t.body)
- else:
- self.fill("try")
- self.enter()
- self.dispatch(t.body)
- self.leave()
-
- self.fill("finally")
- self.enter()
- self.dispatch(t.finalbody)
- self.leave()
-
- def _ExceptHandler(self, t):
- self.fill("except")
- if t.type:
- self.write(" ")
- self.dispatch(t.type)
- if t.name:
- self.write(" as ")
- self.dispatch(t.name)
- self.enter()
- self.dispatch(t.body)
- self.leave()
-
- def _ClassDef(self, t):
- self.write("\n")
- for deco in t.decorator_list:
- self.fill("@")
- self.dispatch(deco)
- self.fill("class "+t.name)
- if t.bases:
- self.write("(")
- for a in t.bases:
- self.dispatch(a)
- self.write(", ")
- self.write(")")
- self.enter()
- self.dispatch(t.body)
- self.leave()
-
- def _FunctionDef(self, t):
- self.write("\n")
- for deco in t.decorator_list:
- self.fill("@")
- self.dispatch(deco)
- self.fill("def "+t.name + "(")
- self.dispatch(t.args)
- self.write(")")
- self.enter()
- self.dispatch(t.body)
- self.leave()
-
- def _For(self, t):
- self.fill("for ")
- self.dispatch(t.target)
- self.write(" in ")
- self.dispatch(t.iter)
- self.enter()
- self.dispatch(t.body)
- self.leave()
- if t.orelse:
- self.fill("else")
- self.enter()
- self.dispatch(t.orelse)
- self.leave()
-
- def _If(self, t):
- self.fill("if ")
- self.dispatch(t.test)
- self.enter()
- self.dispatch(t.body)
- self.leave()
- # collapse nested ifs into equivalent elifs.
- while (t.orelse and len(t.orelse) == 1 and
- isinstance(t.orelse[0], ast.If)):
- t = t.orelse[0]
- self.fill("elif ")
- self.dispatch(t.test)
- self.enter()
- self.dispatch(t.body)
- self.leave()
- # final else
- if t.orelse:
- self.fill("else")
- self.enter()
- self.dispatch(t.orelse)
- self.leave()
-
- def _While(self, t):
- self.fill("while ")
- self.dispatch(t.test)
- self.enter()
- self.dispatch(t.body)
- self.leave()
- if t.orelse:
- self.fill("else")
- self.enter()
- self.dispatch(t.orelse)
- self.leave()
-
- def _With(self, t):
- self.fill("with ")
- self.dispatch(t.context_expr)
- if t.optional_vars:
- self.write(" as ")
- self.dispatch(t.optional_vars)
- self.enter()
- self.dispatch(t.body)
- self.leave()
-
- # expr
- def _Str(self, tree):
- # if from __future__ import unicode_literals is in effect,
- # then we want to output string literals using a 'b' prefix
- # and unicode literals with no prefix.
- if "unicode_literals" not in self.future_imports:
- self.write(repr(tree.s))
- elif isinstance(tree.s, str):
- self.write("b" + repr(tree.s))
- elif isinstance(tree.s, unicode):
- self.write(repr(tree.s).lstrip("u"))
- else:
- assert False, "shouldn't get here"
-
- def _Name(self, t):
- self.write(t.id)
-
- def _Repr(self, t):
- self.write("`")
- self.dispatch(t.value)
- self.write("`")
-
- def _Num(self, t):
- repr_n = repr(t.n)
- # Parenthesize negative numbers, to avoid turning (-1)**2 into -1**2.
- if repr_n.startswith("-"):
- self.write("(")
- # Substitute overflowing decimal literal for AST infinities.
- self.write(repr_n.replace("inf", INFSTR))
- if repr_n.startswith("-"):
- self.write(")")
-
- def _List(self, t):
- self.write("[")
- interleave(lambda: self.write(", "), self.dispatch, t.elts)
- self.write("]")
-
- def _ListComp(self, t):
- self.write("[")
- self.dispatch(t.elt)
- for gen in t.generators:
- self.dispatch(gen)
- self.write("]")
-
- def _GeneratorExp(self, t):
- self.write("(")
- self.dispatch(t.elt)
- for gen in t.generators:
- self.dispatch(gen)
- self.write(")")
-
- def _SetComp(self, t):
- self.write("{")
- self.dispatch(t.elt)
- for gen in t.generators:
- self.dispatch(gen)
- self.write("}")
-
- def _DictComp(self, t):
- self.write("{")
- self.dispatch(t.key)
- self.write(": ")
- self.dispatch(t.value)
- for gen in t.generators:
- self.dispatch(gen)
- self.write("}")
-
- def _comprehension(self, t):
- self.write(" for ")
- self.dispatch(t.target)
- self.write(" in ")
- self.dispatch(t.iter)
- for if_clause in t.ifs:
- self.write(" if ")
- self.dispatch(if_clause)
-
- def _IfExp(self, t):
- self.write("(")
- self.dispatch(t.body)
- self.write(" if ")
- self.dispatch(t.test)
- self.write(" else ")
- self.dispatch(t.orelse)
- self.write(")")
-
- def _Set(self, t):
- assert(t.elts) # should be at least one element
- self.write("{")
- interleave(lambda: self.write(", "), self.dispatch, t.elts)
- self.write("}")
-
- def _Dict(self, t):
- self.write("{")
- def write_pair(pair):
- (k, v) = pair
- self.dispatch(k)
- self.write(": ")
- self.dispatch(v)
- interleave(lambda: self.write(", "), write_pair, zip(t.keys, t.values))
- self.write("}")
-
- def _Tuple(self, t):
- self.write("(")
- if len(t.elts) == 1:
- (elt,) = t.elts
- self.dispatch(elt)
- self.write(",")
- else:
- interleave(lambda: self.write(", "), self.dispatch, t.elts)
- self.write(")")
-
- unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"}
- def _UnaryOp(self, t):
- self.write("(")
- self.write(self.unop[t.op.__class__.__name__])
- self.write(" ")
- # If we're applying unary minus to a number, parenthesize the number.
- # This is necessary: -2147483648 is different from -(2147483648) on
- # a 32-bit machine (the first is an int, the second a long), and
- # -7j is different from -(7j). (The first has real part 0.0, the second
- # has real part -0.0.)
- if isinstance(t.op, ast.USub) and isinstance(t.operand, ast.Num):
- self.write("(")
- self.dispatch(t.operand)
- self.write(")")
- else:
- self.dispatch(t.operand)
- self.write(")")
-
- binop = { "Add":"+", "Sub":"-", "Mult":"*", "Div":"/", "Mod":"%",
- "LShift":"<<", "RShift":">>", "BitOr":"|", "BitXor":"^", "BitAnd":"&",
- "FloorDiv":"//", "Pow": "**"}
- def _BinOp(self, t):
- self.write("(")
- self.dispatch(t.left)
- self.write(" " + self.binop[t.op.__class__.__name__] + " ")
- self.dispatch(t.right)
- self.write(")")
-
- cmpops = {"Eq":"==", "NotEq":"!=", "Lt":"<", "LtE":"<=", "Gt":">", "GtE":">=",
- "Is":"is", "IsNot":"is not", "In":"in", "NotIn":"not in"}
- def _Compare(self, t):
- self.write("(")
- self.dispatch(t.left)
- for o, e in zip(t.ops, t.comparators):
- self.write(" " + self.cmpops[o.__class__.__name__] + " ")
- self.dispatch(e)
- self.write(")")
-
- boolops = {ast.And: 'and', ast.Or: 'or'}
- def _BoolOp(self, t):
- self.write("(")
- s = " %s " % self.boolops[t.op.__class__]
- interleave(lambda: self.write(s), self.dispatch, t.values)
- self.write(")")
-
- def _Attribute(self,t):
- self.dispatch(t.value)
- # Special case: 3.__abs__() is a syntax error, so if t.value
- # is an integer literal then we need to either parenthesize
- # it or add an extra space to get 3 .__abs__().
- if isinstance(t.value, ast.Num) and isinstance(t.value.n, int):
- self.write(" ")
- self.write(".")
- self.write(t.attr)
-
- def _Call(self, t):
- self.dispatch(t.func)
- self.write("(")
- comma = False
- for e in t.args:
- if comma: self.write(", ")
- else: comma = True
- self.dispatch(e)
- for e in t.keywords:
- if comma: self.write(", ")
- else: comma = True
- self.dispatch(e)
- if t.starargs:
- if comma: self.write(", ")
- else: comma = True
- self.write("*")
- self.dispatch(t.starargs)
- if t.kwargs:
- if comma: self.write(", ")
- else: comma = True
- self.write("**")
- self.dispatch(t.kwargs)
- self.write(")")
-
- def _Subscript(self, t):
- self.dispatch(t.value)
- self.write("[")
- self.dispatch(t.slice)
- self.write("]")
-
- # slice
- def _Ellipsis(self, t):
- self.write("...")
-
- def _Index(self, t):
- self.dispatch(t.value)
-
- def _Slice(self, t):
- if t.lower:
- self.dispatch(t.lower)
- self.write(":")
- if t.upper:
- self.dispatch(t.upper)
- if t.step:
- self.write(":")
- self.dispatch(t.step)
-
- def _ExtSlice(self, t):
- interleave(lambda: self.write(', '), self.dispatch, t.dims)
-
- # others
- def _arguments(self, t):
- first = True
- # normal arguments
- defaults = [None] * (len(t.args) - len(t.defaults)) + t.defaults
- for a,d in zip(t.args, defaults):
- if first:first = False
- else: self.write(", ")
- self.dispatch(a),
- if d:
- self.write("=")
- self.dispatch(d)
-
- # varargs
- if t.vararg:
- if first:first = False
- else: self.write(", ")
- self.write("*")
- self.write(t.vararg)
-
- # kwargs
- if t.kwarg:
- if first:first = False
- else: self.write(", ")
- self.write("**"+t.kwarg)
-
- def _keyword(self, t):
- self.write(t.arg)
- self.write("=")
- self.dispatch(t.value)
-
- def _Lambda(self, t):
- self.write("(")
- self.write("lambda ")
- self.dispatch(t.args)
- self.write(": ")
- self.dispatch(t.body)
- self.write(")")
-
- def _alias(self, t):
- self.write(t.name)
- if t.asname:
- self.write(" as "+t.asname)
-
-def roundtrip(filename, output=sys.stdout):
- with open(filename, "r") as pyfile:
- source = pyfile.read()
- tree = compile(source, filename, "exec", ast.PyCF_ONLY_AST)
- Unparser(tree, output)
-
-
-
-def testdir(a):
- try:
- names = [n for n in os.listdir(a) if n.endswith('.py')]
- except OSError:
- sys.stderr.write("Directory not readable: %s" % a)
- else:
- for n in names:
- fullname = os.path.join(a, n)
- if os.path.isfile(fullname):
- output = cStringIO.StringIO()
- print 'Testing %s' % fullname
- try:
- roundtrip(fullname, output)
- except Exception as e:
- print ' Failed to compile, exception is %s' % repr(e)
- elif os.path.isdir(fullname):
- testdir(fullname)
-
-def main(args):
- if args[0] == '--testdir':
- for a in args[1:]:
- testdir(a)
- else:
- for a in args:
- roundtrip(a)
-
-if __name__=='__main__':
- main(sys.argv[1:])
diff --git a/Demo/pdist/FSProxy.py b/Demo/pdist/FSProxy.py
deleted file mode 100644
index 871c84f..0000000
--- a/Demo/pdist/FSProxy.py
+++ /dev/null
@@ -1,301 +0,0 @@
-"""File System Proxy.
-
-Provide an OS-neutral view on a file system, locally or remotely.
-The functionality is geared towards implementing some sort of
-rdist-like utility between a Mac and a UNIX system.
-
-The module defines three classes:
-
-FSProxyLocal -- used for local access
-FSProxyServer -- used on the server side of remote access
-FSProxyClient -- used on the client side of remote access
-
-The remote classes are instantiated with an IP address and an optional
-verbosity flag.
-"""
-
-import server
-import client
-import md5
-import os
-import fnmatch
-from stat import *
-import time
-import fnmatch
-
-maxnamelen = 255
-
-skipnames = (os.curdir, os.pardir)
-
-
-class FSProxyLocal:
-
- def __init__(self):
- self._dirstack = []
- self._ignore = ['*.pyc'] + self._readignore()
-
- def _close(self):
- while self._dirstack:
- self.back()
-
- def _readignore(self):
- file = self._hide('ignore')
- try:
- f = open(file)
- except IOError:
- file = self._hide('synctree.ignorefiles')
- try:
- f = open(file)
- except IOError:
- return []
- ignore = []
- while 1:
- line = f.readline()
- if not line: break
- if line[-1] == '\n': line = line[:-1]
- ignore.append(line)
- f.close()
- return ignore
-
- def _hidden(self, name):
- return name[0] == '.'
-
- def _hide(self, name):
- return '.%s' % name
-
- def visible(self, name):
- if len(name) > maxnamelen: return 0
- if name[-1] == '~': return 0
- if name in skipnames: return 0
- if self._hidden(name): return 0
- head, tail = os.path.split(name)
- if head or not tail: return 0
- if os.path.islink(name): return 0
- if '\0' in open(name, 'rb').read(512): return 0
- for ign in self._ignore:
- if fnmatch.fnmatch(name, ign): return 0
- return 1
-
- def check(self, name):
- if not self.visible(name):
- raise os.error, "protected name %s" % repr(name)
-
- def checkfile(self, name):
- self.check(name)
- if not os.path.isfile(name):
- raise os.error, "not a plain file %s" % repr(name)
-
- def pwd(self):
- return os.getcwd()
-
- def cd(self, name):
- self.check(name)
- save = os.getcwd(), self._ignore
- os.chdir(name)
- self._dirstack.append(save)
- self._ignore = self._ignore + self._readignore()
-
- def back(self):
- if not self._dirstack:
- raise os.error, "empty directory stack"
- dir, ignore = self._dirstack[-1]
- os.chdir(dir)
- del self._dirstack[-1]
- self._ignore = ignore
-
- def _filter(self, files, pat = None):
- if pat:
- def keep(name, pat = pat):
- return fnmatch.fnmatch(name, pat)
- files = filter(keep, files)
- files = filter(self.visible, files)
- files.sort()
- return files
-
- def list(self, pat = None):
- files = os.listdir(os.curdir)
- return self._filter(files, pat)
-
- def listfiles(self, pat = None):
- files = os.listdir(os.curdir)
- files = filter(os.path.isfile, files)
- return self._filter(files, pat)
-
- def listsubdirs(self, pat = None):
- files = os.listdir(os.curdir)
- files = filter(os.path.isdir, files)
- return self._filter(files, pat)
-
- def exists(self, name):
- return self.visible(name) and os.path.exists(name)
-
- def isdir(self, name):
- return self.visible(name) and os.path.isdir(name)
-
- def islink(self, name):
- return self.visible(name) and os.path.islink(name)
-
- def isfile(self, name):
- return self.visible(name) and os.path.isfile(name)
-
- def sum(self, name):
- self.checkfile(name)
- BUFFERSIZE = 1024*8
- f = open(name)
- sum = md5.new()
- while 1:
- buffer = f.read(BUFFERSIZE)
- if not buffer:
- break
- sum.update(buffer)
- return sum.digest()
-
- def size(self, name):
- self.checkfile(name)
- return os.stat(name)[ST_SIZE]
-
- def mtime(self, name):
- self.checkfile(name)
- return time.localtime(os.stat(name)[ST_MTIME])
-
- def stat(self, name):
- self.checkfile(name)
- size = os.stat(name)[ST_SIZE]
- mtime = time.localtime(os.stat(name)[ST_MTIME])
- return size, mtime
-
- def info(self, name):
- sum = self.sum(name)
- size = os.stat(name)[ST_SIZE]
- mtime = time.localtime(os.stat(name)[ST_MTIME])
- return sum, size, mtime
-
- def _list(self, function, list):
- if list is None:
- list = self.listfiles()
- res = []
- for name in list:
- try:
- res.append((name, function(name)))
- except (os.error, IOError):
- res.append((name, None))
- return res
-
- def sumlist(self, list = None):
- return self._list(self.sum, list)
-
- def statlist(self, list = None):
- return self._list(self.stat, list)
-
- def mtimelist(self, list = None):
- return self._list(self.mtime, list)
-
- def sizelist(self, list = None):
- return self._list(self.size, list)
-
- def infolist(self, list = None):
- return self._list(self.info, list)
-
- def _dict(self, function, list):
- if list is None:
- list = self.listfiles()
- dict = {}
- for name in list:
- try:
- dict[name] = function(name)
- except (os.error, IOError):
- pass
- return dict
-
- def sumdict(self, list = None):
- return self.dict(self.sum, list)
-
- def sizedict(self, list = None):
- return self.dict(self.size, list)
-
- def mtimedict(self, list = None):
- return self.dict(self.mtime, list)
-
- def statdict(self, list = None):
- return self.dict(self.stat, list)
-
- def infodict(self, list = None):
- return self._dict(self.info, list)
-
- def read(self, name, offset = 0, length = -1):
- self.checkfile(name)
- f = open(name)
- f.seek(offset)
- if length == 0:
- data = ''
- elif length < 0:
- data = f.read()
- else:
- data = f.read(length)
- f.close()
- return data
-
- def create(self, name):
- self.check(name)
- if os.path.exists(name):
- self.checkfile(name)
- bname = name + '~'
- try:
- os.unlink(bname)
- except os.error:
- pass
- os.rename(name, bname)
- f = open(name, 'w')
- f.close()
-
- def write(self, name, data, offset = 0):
- self.checkfile(name)
- f = open(name, 'r+')
- f.seek(offset)
- f.write(data)
- f.close()
-
- def mkdir(self, name):
- self.check(name)
- os.mkdir(name, 0777)
-
- def rmdir(self, name):
- self.check(name)
- os.rmdir(name)
-
-
-class FSProxyServer(FSProxyLocal, server.Server):
-
- def __init__(self, address, verbose = server.VERBOSE):
- FSProxyLocal.__init__(self)
- server.Server.__init__(self, address, verbose)
-
- def _close(self):
- server.Server._close(self)
- FSProxyLocal._close(self)
-
- def _serve(self):
- server.Server._serve(self)
- # Retreat into start directory
- while self._dirstack: self.back()
-
-
-class FSProxyClient(client.Client):
-
- def __init__(self, address, verbose = client.VERBOSE):
- client.Client.__init__(self, address, verbose)
-
-
-def test():
- import string
- import sys
- if sys.argv[1:]:
- port = string.atoi(sys.argv[1])
- else:
- port = 4127
- proxy = FSProxyServer(('', port))
- proxy._serverloop()
-
-
-if __name__ == '__main__':
- test()
diff --git a/Demo/pdist/RCSProxy.py b/Demo/pdist/RCSProxy.py
deleted file mode 100755
index 87c65cc..0000000
--- a/Demo/pdist/RCSProxy.py
+++ /dev/null
@@ -1,198 +0,0 @@
-#! /usr/bin/env python
-
-"""RCS Proxy.
-
-Provide a simplified interface on RCS files, locally or remotely.
-The functionality is geared towards implementing some sort of
-remote CVS like utility. It is modeled after the similar module
-FSProxy.
-
-The module defines two classes:
-
-RCSProxyLocal -- used for local access
-RCSProxyServer -- used on the server side of remote access
-
-The corresponding client class, RCSProxyClient, is defined in module
-rcsclient.
-
-The remote classes are instantiated with an IP address and an optional
-verbosity flag.
-"""
-
-import server
-import md5
-import os
-import fnmatch
-import string
-import tempfile
-import rcslib
-
-
-class DirSupport:
-
- def __init__(self):
- self._dirstack = []
-
- def __del__(self):
- self._close()
-
- def _close(self):
- while self._dirstack:
- self.back()
-
- def pwd(self):
- return os.getcwd()
-
- def cd(self, name):
- save = os.getcwd()
- os.chdir(name)
- self._dirstack.append(save)
-
- def back(self):
- if not self._dirstack:
- raise os.error, "empty directory stack"
- dir = self._dirstack[-1]
- os.chdir(dir)
- del self._dirstack[-1]
-
- def listsubdirs(self, pat = None):
- files = os.listdir(os.curdir)
- files = filter(os.path.isdir, files)
- return self._filter(files, pat)
-
- def isdir(self, name):
- return os.path.isdir(name)
-
- def mkdir(self, name):
- os.mkdir(name, 0777)
-
- def rmdir(self, name):
- os.rmdir(name)
-
-
-class RCSProxyLocal(rcslib.RCS, DirSupport):
-
- def __init__(self):
- rcslib.RCS.__init__(self)
- DirSupport.__init__(self)
-
- def __del__(self):
- DirSupport.__del__(self)
- rcslib.RCS.__del__(self)
-
- def sumlist(self, list = None):
- return self._list(self.sum, list)
-
- def sumdict(self, list = None):
- return self._dict(self.sum, list)
-
- def sum(self, name_rev):
- f = self._open(name_rev)
- BUFFERSIZE = 1024*8
- sum = md5.new()
- while 1:
- buffer = f.read(BUFFERSIZE)
- if not buffer:
- break
- sum.update(buffer)
- self._closepipe(f)
- return sum.digest()
-
- def get(self, name_rev):
- f = self._open(name_rev)
- data = f.read()
- self._closepipe(f)
- return data
-
- def put(self, name_rev, data, message=None):
- name, rev = self._unmangle(name_rev)
- f = open(name, 'w')
- f.write(data)
- f.close()
- self.checkin(name_rev, message)
- self._remove(name)
-
- def _list(self, function, list = None):
- """INTERNAL: apply FUNCTION to all files in LIST.
-
- Return a list of the results.
-
- The list defaults to all files in the directory if None.
-
- """
- if list is None:
- list = self.listfiles()
- res = []
- for name in list:
- try:
- res.append((name, function(name)))
- except (os.error, IOError):
- res.append((name, None))
- return res
-
- def _dict(self, function, list = None):
- """INTERNAL: apply FUNCTION to all files in LIST.
-
- Return a dictionary mapping files to results.
-
- The list defaults to all files in the directory if None.
-
- """
- if list is None:
- list = self.listfiles()
- dict = {}
- for name in list:
- try:
- dict[name] = function(name)
- except (os.error, IOError):
- pass
- return dict
-
-
-class RCSProxyServer(RCSProxyLocal, server.SecureServer):
-
- def __init__(self, address, verbose = server.VERBOSE):
- RCSProxyLocal.__init__(self)
- server.SecureServer.__init__(self, address, verbose)
-
- def _close(self):
- server.SecureServer._close(self)
- RCSProxyLocal._close(self)
-
- def _serve(self):
- server.SecureServer._serve(self)
- # Retreat into start directory
- while self._dirstack: self.back()
-
-
-def test_server():
- import string
- import sys
- if sys.argv[1:]:
- port = string.atoi(sys.argv[1])
- else:
- port = 4127
- proxy = RCSProxyServer(('', port))
- proxy._serverloop()
-
-
-def test():
- import sys
- if not sys.argv[1:] or sys.argv[1] and sys.argv[1][0] in '0123456789':
- test_server()
- sys.exit(0)
- proxy = RCSProxyLocal()
- what = sys.argv[1]
- if hasattr(proxy, what):
- attr = getattr(proxy, what)
- if callable(attr):
- print apply(attr, tuple(sys.argv[2:]))
- else:
- print repr(attr)
- else:
- print "%s: no such attribute" % what
- sys.exit(2)
-
-
-if __name__ == '__main__':
- test()
diff --git a/Demo/pdist/README b/Demo/pdist/README
deleted file mode 100644
index b3fac24..0000000
--- a/Demo/pdist/README
+++ /dev/null
@@ -1,121 +0,0 @@
-Filesystem, RCS and CVS client and server classes
-=================================================
-
-*** See the security warning at the end of this file! ***
-
-This directory contains various modules and classes that support
-remote file system operations.
-
-CVS stuff
----------
-
-rcvs Script to put in your bin directory
-rcvs.py Remote CVS client command line interface
-
-cvslib.py CVS admin files classes (used by rrcs)
-cvslock.py CVS locking algorithms
-
-RCS stuff
----------
-
-rrcs Script to put in your bin directory
-rrcs.py Remote RCS client command line interface
-
-rcsclient.py Return an RCSProxyClient instance
- (has reasonable default server/port/directory)
-
-RCSProxy.py RCS proxy and server classes (on top of rcslib.py)
-
-rcslib.py Local-only RCS base class (affects stdout &
- local work files)
-
-FSProxy stuff
--------------
-
-sumtree.py Old demo for FSProxy
-cmptree.py First FSProxy client (used to sync from the Mac)
-FSProxy.py Filesystem interface classes
-
-Generic client/server stuff
----------------------------
-
-client.py Client class
-server.py Server class
-
-security.py Security mix-in class (not very secure I think)
-
-Other generic stuff
--------------------
-
-cmdfw.py CommandFrameWork class
- (used by rcvs, should be used by rrcs as well)
-
-
-Client/Server operation
------------------------
-
-The Client and Server classes implement a simple-minded RPC protocol,
-using Python's pickle module to transfer arguments, return values and
-exceptions with the most generality. The Server class is instantiated
-with a port number on which it should listen for requests; the Client
-class is instantiated with a host name and a port number where it
-should connect to. Once a client is connected, a TCP connection is
-maintained between client and server.
-
-The Server class currently handles only one connection at a time;
-however it could be rewritten to allow various modes of operations,
-using multiple threads or processes or the select() system call as
-desired to serve multiple clients simultaneously (when using select(),
-still handling one request at a time). This would not require
-rewriting of the Client class. It may also be possible to adapt the
-code to use UDP instead of TCP, but then both classes will have to be
-rewritten (and unless extensive acknowlegements and request serial
-numbers are used, the server should handle duplicate requests, so its
-semantics should be idempotent -- shrudder).
-
-Even though the FSProxy and RCSProxy modules define client classes,
-the client class is fully generic -- what methods it supports is
-determined entirely by the server. The server class, however, must be
-derived from. This is generally done as follows:
-
- from server import Server
- from client import Client
-
- # Define a class that performs the operations locally
- class MyClassLocal:
- def __init__(self): ...
- def _close(self): ...
-
- # Derive a server class using multiple inheritance
- class MyClassServer(MyClassLocal, Server):
- def __init__(self, address):
- # Must initialize MyClassLocal as well as Server
- MyClassLocal.__init__(self)
- Server.__init__(self, address)
- def _close(self):
- Server._close()
- MyClassLocal._close()
-
- # A dummy client class
- class MyClassClient(Client): pass
-
-Note that because MyClassLocal isn't used in the definition of
-MyClassClient, it would actually be better to place it in a separate
-module so the definition of MyClassLocal isn't executed when we only
-instantiate a client.
-
-The modules client and server should probably be renamed to Client and
-Server in order to match the class names.
-
-
-*** Security warning: this version requires that you have a file
-$HOME/.python_keyfile at the server and client side containing two
-comma- separated numbers. The security system at the moment makes no
-guarantees of actuallng being secure -- however it requires that the
-key file exists and contains the same numbers at both ends for this to
-work. (You can specify an alternative keyfile in $PYTHON_KEYFILE).
-Have a look at the Security class in security.py for details;
-basically, if the key file contains (x, y), then the security server
-class chooses a random number z (the challenge) in the range
-10..100000 and the client must be able to produce pow(z, x, y)
-(i.e. z**x mod y).
diff --git a/Demo/pdist/client.py b/Demo/pdist/client.py
deleted file mode 100644
index 3e97d84..0000000
--- a/Demo/pdist/client.py
+++ /dev/null
@@ -1,157 +0,0 @@
-"""RPC Client module."""
-
-import sys
-import socket
-import pickle
-import __builtin__
-import os
-
-
-# Default verbosity (0 = silent, 1 = print connections, 2 = print requests too)
-VERBOSE = 1
-
-
-class Client:
-
- """RPC Client class. No need to derive a class -- it's fully generic."""
-
- def __init__(self, address, verbose = VERBOSE):
- self._pre_init(address, verbose)
- self._post_init()
-
- def _pre_init(self, address, verbose = VERBOSE):
- if type(address) == type(0):
- address = ('', address)
- self._address = address
- self._verbose = verbose
- if self._verbose: print "Connecting to %s ..." % repr(address)
- self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self._socket.connect(address)
- if self._verbose: print "Connected."
- self._lastid = 0 # Last id for which a reply has been received
- self._nextid = 1 # Id of next request
- self._replies = {} # Unprocessed replies
- self._rf = self._socket.makefile('r')
- self._wf = self._socket.makefile('w')
-
- def _post_init(self):
- self._methods = self._call('.methods')
-
- def __del__(self):
- self._close()
-
- def _close(self):
- if self._rf: self._rf.close()
- self._rf = None
- if self._wf: self._wf.close()
- self._wf = None
- if self._socket: self._socket.close()
- self._socket = None
-
- def __getattr__(self, name):
- if name in self._methods:
- method = _stub(self, name)
- setattr(self, name, method) # XXX circular reference
- return method
- raise AttributeError, name
-
- def _setverbose(self, verbose):
- self._verbose = verbose
-
- def _call(self, name, *args):
- return self._vcall(name, args)
-
- def _vcall(self, name, args):
- return self._recv(self._vsend(name, args))
-
- def _send(self, name, *args):
- return self._vsend(name, args)
-
- def _send_noreply(self, name, *args):
- return self._vsend(name, args, 0)
-
- def _vsend_noreply(self, name, args):
- return self._vsend(name, args, 0)
-
- def _vsend(self, name, args, wantreply = 1):
- id = self._nextid
- self._nextid = id+1
- if not wantreply: id = -id
- request = (name, args, id)
- if self._verbose > 1: print "sending request: %s" % repr(request)
- wp = pickle.Pickler(self._wf)
- wp.dump(request)
- return id
-
- def _recv(self, id):
- exception, value, rid = self._vrecv(id)
- if rid != id:
- raise RuntimeError, "request/reply id mismatch: %d/%d" % (id, rid)
- if exception is None:
- return value
- x = exception
- if hasattr(__builtin__, exception):
- x = getattr(__builtin__, exception)
- elif exception in ('posix.error', 'mac.error'):
- x = os.error
- if x == exception:
- exception = x
- raise exception, value
-
- def _vrecv(self, id):
- self._flush()
- if self._replies.has_key(id):
- if self._verbose > 1: print "retrieving previous reply, id = %d" % id
- reply = self._replies[id]
- del self._replies[id]
- return reply
- aid = abs(id)
- while 1:
- if self._verbose > 1: print "waiting for reply, id = %d" % id
- rp = pickle.Unpickler(self._rf)
- reply = rp.load()
- del rp
- if self._verbose > 1: print "got reply: %s" % repr(reply)
- rid = reply[2]
- arid = abs(rid)
- if arid == aid:
- if self._verbose > 1: print "got it"
- return reply
- self._replies[rid] = reply
- if arid > aid:
- if self._verbose > 1: print "got higher id, assume all ok"
- return (None, None, id)
-
- def _flush(self):
- self._wf.flush()
-
-
-from security import Security
-
-
-class SecureClient(Client, Security):
-
- def __init__(self, *args):
- import string
- apply(self._pre_init, args)
- Security.__init__(self)
- self._wf.flush()
- line = self._rf.readline()
- challenge = string.atoi(string.strip(line))
- response = self._encode_challenge(challenge)
- line = repr(long(response))
- if line[-1] in 'Ll': line = line[:-1]
- self._wf.write(line + '\n')
- self._wf.flush()
- self._post_init()
-
-class _stub:
-
- """Helper class for Client -- each instance serves as a method of the client."""
-
- def __init__(self, client, name):
- self._client = client
- self._name = name
-
- def __call__(self, *args):
- return self._client._vcall(self._name, args)
diff --git a/Demo/pdist/cmdfw.py b/Demo/pdist/cmdfw.py
deleted file mode 100644
index e2edd0a..0000000
--- a/Demo/pdist/cmdfw.py
+++ /dev/null
@@ -1,144 +0,0 @@
-"Framework for command line interfaces like CVS. See class CmdFrameWork."
-
-
-class CommandFrameWork:
-
- """Framework class for command line interfaces like CVS.
-
- The general command line structure is
-
- command [flags] subcommand [subflags] [argument] ...
-
- There's a class variable GlobalFlags which specifies the
- global flags options. Subcommands are defined by defining
- methods named do_<subcommand>. Flags for the subcommand are
- defined by defining class or instance variables named
- flags_<subcommand>. If there's no command, method default()
- is called. The __doc__ strings for the do_ methods are used
- for the usage message, printed after the general usage message
- which is the class variable UsageMessage. The class variable
- PostUsageMessage is printed after all the do_ methods' __doc__
- strings. The method's return value can be a suggested exit
- status. [XXX Need to rewrite this to clarify it.]
-
- Common usage is to derive a class, instantiate it, and then call its
- run() method; by default this takes its arguments from sys.argv[1:].
- """
-
- UsageMessage = \
- "usage: (name)s [flags] subcommand [subflags] [argument] ..."
-
- PostUsageMessage = None
-
- GlobalFlags = ''
-
- def __init__(self):
- """Constructor, present for completeness."""
- pass
-
- def run(self, args = None):
- """Process flags, subcommand and options, then run it."""
- import getopt, sys
- if args is None: args = sys.argv[1:]
- try:
- opts, args = getopt.getopt(args, self.GlobalFlags)
- except getopt.error, msg:
- return self.usage(msg)
- self.options(opts)
- if not args:
- self.ready()
- return self.default()
- else:
- cmd = args[0]
- mname = 'do_' + cmd
- fname = 'flags_' + cmd
- try:
- method = getattr(self, mname)
- except AttributeError:
- return self.usage("command %r unknown" % (cmd,))
- try:
- flags = getattr(self, fname)
- except AttributeError:
- flags = ''
- try:
- opts, args = getopt.getopt(args[1:], flags)
- except getopt.error, msg:
- return self.usage(
- "subcommand %s: " % cmd + str(msg))
- self.ready()
- return method(opts, args)
-
- def options(self, opts):
- """Process the options retrieved by getopt.
- Override this if you have any options."""
- if opts:
- print "-"*40
- print "Options:"
- for o, a in opts:
- print 'option', o, 'value', repr(a)
- print "-"*40
-
- def ready(self):
- """Called just before calling the subcommand."""
- pass
-
- def usage(self, msg = None):
- """Print usage message. Return suitable exit code (2)."""
- if msg: print msg
- print self.UsageMessage % {'name': self.__class__.__name__}
- docstrings = {}
- c = self.__class__
- while 1:
- for name in dir(c):
- if name[:3] == 'do_':
- if docstrings.has_key(name):
- continue
- try:
- doc = getattr(c, name).__doc__
- except:
- doc = None
- if doc:
- docstrings[name] = doc
- if not c.__bases__:
- break
- c = c.__bases__[0]
- if docstrings:
- print "where subcommand can be:"
- names = docstrings.keys()
- names.sort()
- for name in names:
- print docstrings[name]
- if self.PostUsageMessage:
- print self.PostUsageMessage
- return 2
-
- def default(self):
- """Default method, called when no subcommand is given.
- You should always override this."""
- print "Nobody expects the Spanish Inquisition!"
-
-
-def test():
- """Test script -- called when this module is run as a script."""
- import sys
- class Hello(CommandFrameWork):
- def do_hello(self, opts, args):
- "hello -- print 'hello world', needs no arguments"
- print "Hello, world"
- x = Hello()
- tests = [
- [],
- ['hello'],
- ['spam'],
- ['-x'],
- ['hello', '-x'],
- None,
- ]
- for t in tests:
- print '-'*10, t, '-'*10
- sts = x.run(t)
- print "Exit status:", repr(sts)
-
-
-if __name__ == '__main__':
- test()
diff --git a/Demo/pdist/cmptree.py b/Demo/pdist/cmptree.py
deleted file mode 100644
index 2f781ab..0000000
--- a/Demo/pdist/cmptree.py
+++ /dev/null
@@ -1,208 +0,0 @@
-"""Compare local and remote dictionaries and transfer differing files -- like rdist."""
-
-import sys
-from repr import repr
-import FSProxy
-import time
-import os
-
-def main():
- pwd = os.getcwd()
- s = raw_input("chdir [%s] " % pwd)
- if s:
- os.chdir(s)
- pwd = os.getcwd()
- host = ask("host", 'voorn.cwi.nl')
- port = 4127
- verbose = 1
- mode = ''
- print """\
-Mode should be a string of characters, indicating what to do with differences.
-r - read different files to local file system
-w - write different files to remote file system
-c - create new files, either remote or local
-d - delete disappearing files, either remote or local
-"""
- s = raw_input("mode [%s] " % mode)
- if s: mode = s
- address = (host, port)
- t1 = time.time()
- local = FSProxy.FSProxyLocal()
- remote = FSProxy.FSProxyClient(address, verbose)
- compare(local, remote, mode)
- remote._close()
- local._close()
- t2 = time.time()
- dt = t2-t1
- mins, secs = divmod(dt, 60)
- print mins, "minutes and", round(secs), "seconds"
- raw_input("[Return to exit] ")
-
-def ask(prompt, default):
- s = raw_input("%s [%s] " % (prompt, default))
- return s or default
-
-def askint(prompt, default):
- s = raw_input("%s [%s] " % (prompt, str(default)))
- if s: return string.atoi(s)
- return default
-
-def compare(local, remote, mode):
- print
- print "PWD =", repr(os.getcwd())
- sums_id = remote._send('sumlist')
- subdirs_id = remote._send('listsubdirs')
- remote._flush()
- print "calculating local sums ..."
- lsumdict = {}
- for name, info in local.sumlist():
- lsumdict[name] = info
- print "getting remote sums ..."
- sums = remote._recv(sums_id)
- print "got", len(sums)
- rsumdict = {}
- for name, rsum in sums:
- rsumdict[name] = rsum
- if not lsumdict.has_key(name):
- print repr(name), "only remote"
- if 'r' in mode and 'c' in mode:
- recvfile(local, remote, name)
- else:
- lsum = lsumdict[name]
- if lsum != rsum:
- print repr(name),
- rmtime = remote.mtime(name)
- lmtime = local.mtime(name)
- if rmtime > lmtime:
- print "remote newer",
- if 'r' in mode:
- recvfile(local, remote, name)
- elif lmtime > rmtime:
- print "local newer",
- if 'w' in mode:
- sendfile(local, remote, name)
- else:
- print "same mtime but different sum?!?!",
- print
- for name in lsumdict.keys():
- if not rsumdict.keys():
- print repr(name), "only locally",
- fl()
- if 'w' in mode and 'c' in mode:
- sendfile(local, remote, name)
- elif 'r' in mode and 'd' in mode:
- os.unlink(name)
- print "removed."
- print
- print "gettin subdirs ..."
- subdirs = remote._recv(subdirs_id)
- common = []
- for name in subdirs:
- if local.isdir(name):
- print "Common subdirectory", repr(name)
- common.append(name)
- else:
- print "Remote subdirectory", repr(name), "not found locally"
- if 'r' in mode and 'c' in mode:
- pr = "Create local subdirectory %s? [y] " % \
- repr(name)
- if 'y' in mode:
- ok = 'y'
- else:
- ok = ask(pr, "y")
- if ok[:1] in ('y', 'Y'):
- local.mkdir(name)
- print "Subdirectory %s made" % \
- repr(name)
- common.append(name)
- lsubdirs = local.listsubdirs()
- for name in lsubdirs:
- if name not in subdirs:
- print "Local subdirectory", repr(name), "not found remotely"
- for name in common:
- print "Entering subdirectory", repr(name)
- local.cd(name)
- remote.cd(name)
- compare(local, remote, mode)
- remote.back()
- local.back()
-
-def sendfile(local, remote, name):
- try:
- remote.create(name)
- except (IOError, os.error), msg:
- print "cannot create:", msg
- return
-
- print "sending ...",
- fl()
-
- data = open(name).read()
-
- t1 = time.time()
-
- remote._send_noreply('write', name, data)
- remote._flush()
-
- t2 = time.time()
-
- dt = t2-t1
- print len(data), "bytes in", round(dt), "seconds",
- if dt:
- print "i.e.", round(len(data)/dt), "bytes/sec",
- print
-
-def recvfile(local, remote, name):
- ok = 0
- try:
- rv = recvfile_real(local, remote, name)
- ok = 1
- return rv
- finally:
- if not ok:
- print "*** recvfile of %r failed, deleting" % (name,)
- local.delete(name)
-
-def recvfile_real(local, remote, name):
- try:
- local.create(name)
- except (IOError, os.error), msg:
- print "cannot create:", msg
- return
-
- print "receiving ...",
- fl()
-
- f = open(name, 'w')
- t1 = time.time()
-
- length = 4*1024
- offset = 0
- id = remote._send('read', name, offset, length)
- remote._flush()
- while 1:
- newoffset = offset + length
- newid = remote._send('read', name, newoffset, length)
- data = remote._recv(id)
- id = newid
- if not data: break
- f.seek(offset)
- f.write(data)
- offset = newoffset
- size = f.tell()
-
- t2 = time.time()
- f.close()
-
- dt = t2-t1
- print size, "bytes in", round(dt), "seconds",
- if dt:
- print "i.e.", size//dt, "bytes/sec",
- print
- remote._recv(id) # ignored
-
-def fl():
- sys.stdout.flush()
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/pdist/cvslib.py b/Demo/pdist/cvslib.py
deleted file mode 100644
index ebcc697..0000000
--- a/Demo/pdist/cvslib.py
+++ /dev/null
@@ -1,364 +0,0 @@
-"""Utilities for CVS administration."""
-
-import string
-import os
-import time
-import md5
-import fnmatch
-
-if not hasattr(time, 'timezone'):
- time.timezone = 0
-
-class File:
-
- """Represent a file's status.
-
- Instance variables:
-
- file -- the filename (no slashes), None if uninitialized
- lseen -- true if the data for the local file is up to date
- eseen -- true if the data from the CVS/Entries entry is up to date
- (this implies that the entry must be written back)
- rseen -- true if the data for the remote file is up to date
- proxy -- RCSProxy instance used to contact the server, or None
-
- Note that lseen and rseen don't necessary mean that a local
- or remote file *exists* -- they indicate that we've checked it.
- However, eseen means that this instance corresponds to an
- entry in the CVS/Entries file.
-
- If lseen is true:
-
- lsum -- checksum of the local file, None if no local file
- lctime -- ctime of the local file, None if no local file
- lmtime -- mtime of the local file, None if no local file
-
- If eseen is true:
-
- erev -- revision, None if this is a no revision (not '0')
- enew -- true if this is an uncommitted added file
- edeleted -- true if this is an uncommitted removed file
- ectime -- ctime of last local file corresponding to erev
- emtime -- mtime of last local file corresponding to erev
- extra -- 5th string from CVS/Entries file
-
- If rseen is true:
-
- rrev -- revision of head, None if non-existent
- rsum -- checksum of that revision, Non if non-existent
-
- If eseen and rseen are both true:
-
- esum -- checksum of revision erev, None if no revision
-
- Note
- """
-
- def __init__(self, file = None):
- if file and '/' in file:
- raise ValueError, "no slash allowed in file"
- self.file = file
- self.lseen = self.eseen = self.rseen = 0
- self.proxy = None
-
- def __cmp__(self, other):
- return cmp(self.file, other.file)
-
- def getlocal(self):
- try:
- self.lmtime, self.lctime = os.stat(self.file)[-2:]
- except os.error:
- self.lmtime = self.lctime = self.lsum = None
- else:
- self.lsum = md5.new(open(self.file).read()).digest()
- self.lseen = 1
-
- def getentry(self, line):
- words = string.splitfields(line, '/')
- if self.file and words[1] != self.file:
- raise ValueError, "file name mismatch"
- self.file = words[1]
- self.erev = words[2]
- self.edeleted = 0
- self.enew = 0
- self.ectime = self.emtime = None
- if self.erev[:1] == '-':
- self.edeleted = 1
- self.erev = self.erev[1:]
- if self.erev == '0':
- self.erev = None
- self.enew = 1
- else:
- dates = words[3]
- self.ectime = unctime(dates[:24])
- self.emtime = unctime(dates[25:])
- self.extra = words[4]
- if self.rseen:
- self.getesum()
- self.eseen = 1
-
- def getremote(self, proxy = None):
- if proxy:
- self.proxy = proxy
- try:
- self.rrev = self.proxy.head(self.file)
- except (os.error, IOError):
- self.rrev = None
- if self.rrev:
- self.rsum = self.proxy.sum(self.file)
- else:
- self.rsum = None
- if self.eseen:
- self.getesum()
- self.rseen = 1
-
- def getesum(self):
- if self.erev == self.rrev:
- self.esum = self.rsum
- elif self.erev:
- name = (self.file, self.erev)
- self.esum = self.proxy.sum(name)
- else:
- self.esum = None
-
- def putentry(self):
- """Return a line suitable for inclusion in CVS/Entries.
-
- The returned line is terminated by a newline.
- If no entry should be written for this file,
- return "".
- """
- if not self.eseen:
- return ""
-
- rev = self.erev or '0'
- if self.edeleted:
- rev = '-' + rev
- if self.enew:
- dates = 'Initial ' + self.file
- else:
- dates = gmctime(self.ectime) + ' ' + \
- gmctime(self.emtime)
- return "/%s/%s/%s/%s/\n" % (
- self.file,
- rev,
- dates,
- self.extra)
-
- def report(self):
- print '-'*50
- def r(key, repr=repr, self=self):
- try:
- value = repr(getattr(self, key))
- except AttributeError:
- value = "?"
- print "%-15s:" % key, value
- r("file")
- if self.lseen:
- r("lsum", hexify)
- r("lctime", gmctime)
- r("lmtime", gmctime)
- if self.eseen:
- r("erev")
- r("enew")
- r("edeleted")
- r("ectime", gmctime)
- r("emtime", gmctime)
- if self.rseen:
- r("rrev")
- r("rsum", hexify)
- if self.eseen:
- r("esum", hexify)
-
-
-class CVS:
-
- """Represent the contents of a CVS admin file (and more).
-
- Class variables:
-
- FileClass -- the class to be instantiated for entries
- (this should be derived from class File above)
- IgnoreList -- shell patterns for local files to be ignored
-
- Instance variables:
-
- entries -- a dictionary containing File instances keyed by
- their file name
- proxy -- an RCSProxy instance, or None
- """
-
- FileClass = File
-
- IgnoreList = ['.*', '@*', ',*', '*~', '*.o', '*.a', '*.so', '*.pyc']
-
- def __init__(self):
- self.entries = {}
- self.proxy = None
-
- def setproxy(self, proxy):
- if proxy is self.proxy:
- return
- self.proxy = proxy
- for e in self.entries.values():
- e.rseen = 0
-
- def getentries(self):
- """Read the contents of CVS/Entries"""
- self.entries = {}
- f = self.cvsopen("Entries")
- while 1:
- line = f.readline()
- if not line: break
- e = self.FileClass()
- e.getentry(line)
- self.entries[e.file] = e
- f.close()
-
- def putentries(self):
- """Write CVS/Entries back"""
- f = self.cvsopen("Entries", 'w')
- for e in self.values():
- f.write(e.putentry())
- f.close()
-
- def getlocalfiles(self):
- list = self.entries.keys()
- addlist = os.listdir(os.curdir)
- for name in addlist:
- if name in list:
- continue
- if not self.ignored(name):
- list.append(name)
- list.sort()
- for file in list:
- try:
- e = self.entries[file]
- except KeyError:
- e = self.entries[file] = self.FileClass(file)
- e.getlocal()
-
- def getremotefiles(self, proxy = None):
- if proxy:
- self.proxy = proxy
- if not self.proxy:
- raise RuntimeError, "no RCS proxy"
- addlist = self.proxy.listfiles()
- for file in addlist:
- try:
- e = self.entries[file]
- except KeyError:
- e = self.entries[file] = self.FileClass(file)
- e.getremote(self.proxy)
-
- def report(self):
- for e in self.values():
- e.report()
- print '-'*50
-
- def keys(self):
- keys = self.entries.keys()
- keys.sort()
- return keys
-
- def values(self):
- def value(key, self=self):
- return self.entries[key]
- return map(value, self.keys())
-
- def items(self):
- def item(key, self=self):
- return (key, self.entries[key])
- return map(item, self.keys())
-
- def cvsexists(self, file):
- file = os.path.join("CVS", file)
- return os.path.exists(file)
-
- def cvsopen(self, file, mode = 'r'):
- file = os.path.join("CVS", file)
- if 'r' not in mode:
- self.backup(file)
- return open(file, mode)
-
- def backup(self, file):
- if os.path.isfile(file):
- bfile = file + '~'
- try: os.unlink(bfile)
- except os.error: pass
- os.rename(file, bfile)
-
- def ignored(self, file):
- if os.path.isdir(file): return True
- for pat in self.IgnoreList:
- if fnmatch.fnmatch(file, pat): return True
- return False
-
-
-# hexify and unhexify are useful to print MD5 checksums in hex format
-
-hexify_format = '%02x' * 16
-def hexify(sum):
- "Return a hex representation of a 16-byte string (e.g. an MD5 digest)"
- if sum is None:
- return "None"
- return hexify_format % tuple(map(ord, sum))
-
-def unhexify(hexsum):
- "Return the original from a hexified string"
- if hexsum == "None":
- return None
- sum = ''
- for i in range(0, len(hexsum), 2):
- sum = sum + chr(string.atoi(hexsum[i:i+2], 16))
- return sum
-
-
-unctime_monthmap = {}
-def unctime(date):
- if date == "None": return None
- if not unctime_monthmap:
- months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
- i = 0
- for m in months:
- i = i+1
- unctime_monthmap[m] = i
- words = string.split(date) # Day Mon DD HH:MM:SS YEAR
- year = string.atoi(words[4])
- month = unctime_monthmap[words[1]]
- day = string.atoi(words[2])
- [hh, mm, ss] = map(string.atoi, string.splitfields(words[3], ':'))
- ss = ss - time.timezone
- return time.mktime((year, month, day, hh, mm, ss, 0, 0, 0))
-
-def gmctime(t):
- if t is None: return "None"
- return time.asctime(time.gmtime(t))
-
-def test_unctime():
- now = int(time.time())
- t = time.gmtime(now)
- at = time.asctime(t)
- print 'GMT', now, at
- print 'timezone', time.timezone
- print 'local', time.ctime(now)
- u = unctime(at)
- print 'unctime()', u
- gu = time.gmtime(u)
- print '->', gu
- print time.asctime(gu)
-
-def test():
- x = CVS()
- x.getentries()
- x.getlocalfiles()
-## x.report()
- import rcsclient
- proxy = rcsclient.openrcsclient()
- x.getremotefiles(proxy)
- x.report()
-
-
-if __name__ == "__main__":
- test()
diff --git a/Demo/pdist/cvslock.py b/Demo/pdist/cvslock.py
deleted file mode 100644
index 8f6d008..0000000
--- a/Demo/pdist/cvslock.py
+++ /dev/null
@@ -1,280 +0,0 @@
-"""CVS locking algorithm.
-
-CVS locking strategy
-====================
-
-As reverse engineered from the CVS 1.3 sources (file lock.c):
-
-- Locking is done on a per repository basis (but a process can hold
-write locks for multiple directories); all lock files are placed in
-the repository and have names beginning with "#cvs.".
-
-- Before even attempting to lock, a file "#cvs.tfl.<pid>" is created
-(and removed again), to test that we can write the repository. [The
-algorithm can still be fooled (1) if the repository's mode is changed
-while attempting to lock; (2) if this file exists and is writable but
-the directory is not.]
-
-- While creating the actual read/write lock files (which may exist for
-a long time), a "meta-lock" is held. The meta-lock is a directory
-named "#cvs.lock" in the repository. The meta-lock is also held while
-a write lock is held.
-
-- To set a read lock:
-
- - acquire the meta-lock
- - create the file "#cvs.rfl.<pid>"
- - release the meta-lock
-
-- To set a write lock:
-
- - acquire the meta-lock
- - check that there are no files called "#cvs.rfl.*"
- - if there are, release the meta-lock, sleep, try again
- - create the file "#cvs.wfl.<pid>"
-
-- To release a write lock:
-
- - remove the file "#cvs.wfl.<pid>"
- - rmdir the meta-lock
-
-- To release a read lock:
-
- - remove the file "#cvs.rfl.<pid>"
-
-
-Additional notes
-----------------
-
-- A process should read-lock at most one repository at a time.
-
-- A process may write-lock as many repositories as it wishes (to avoid
-deadlocks, I presume it should always lock them top-down in the
-directory hierarchy).
-
-- A process should make sure it removes all its lock files and
-directories when it crashes.
-
-- Limitation: one user id should not be committing files into the same
-repository at the same time.
-
-
-Turn this into Python code
---------------------------
-
-rl = ReadLock(repository, waittime)
-
-wl = WriteLock(repository, waittime)
-
-list = MultipleWriteLock([repository1, repository2, ...], waittime)
-
-"""
-
-
-import os
-import time
-import stat
-import pwd
-
-
-# Default wait time
-DELAY = 10
-
-
-# XXX This should be the same on all Unix versions
-EEXIST = 17
-
-
-# Files used for locking (must match cvs.h in the CVS sources)
-CVSLCK = "#cvs.lck"
-CVSRFL = "#cvs.rfl."
-CVSWFL = "#cvs.wfl."
-
-
-class Error:
-
- def __init__(self, msg):
- self.msg = msg
-
- def __repr__(self):
- return repr(self.msg)
-
- def __str__(self):
- return str(self.msg)
-
-
-class Locked(Error):
- pass
-
-
-class Lock:
-
- def __init__(self, repository = ".", delay = DELAY):
- self.repository = repository
- self.delay = delay
- self.lockdir = None
- self.lockfile = None
- pid = repr(os.getpid())
- self.cvslck = self.join(CVSLCK)
- self.cvsrfl = self.join(CVSRFL + pid)
- self.cvswfl = self.join(CVSWFL + pid)
-
- def __del__(self):
- print "__del__"
- self.unlock()
-
- def setlockdir(self):
- while 1:
- try:
- self.lockdir = self.cvslck
- os.mkdir(self.cvslck, 0777)
- return
- except os.error, msg:
- self.lockdir = None
- if msg[0] == EEXIST:
- try:
- st = os.stat(self.cvslck)
- except os.error:
- continue
- self.sleep(st)
- continue
- raise Error("failed to lock %s: %s" % (
- self.repository, msg))
-
- def unlock(self):
- self.unlockfile()
- self.unlockdir()
-
- def unlockfile(self):
- if self.lockfile:
- print "unlink", self.lockfile
- try:
- os.unlink(self.lockfile)
- except os.error:
- pass
- self.lockfile = None
-
- def unlockdir(self):
- if self.lockdir:
- print "rmdir", self.lockdir
- try:
- os.rmdir(self.lockdir)
- except os.error:
- pass
- self.lockdir = None
-
- def sleep(self, st):
- sleep(st, self.repository, self.delay)
-
- def join(self, name):
- return os.path.join(self.repository, name)
-
-
-def sleep(st, repository, delay):
- if delay <= 0:
- raise Locked(st)
- uid = st[stat.ST_UID]
- try:
- pwent = pwd.getpwuid(uid)
- user = pwent[0]
- except KeyError:
- user = "uid %d" % uid
- print "[%s]" % time.ctime(time.time())[11:19],
- print "Waiting for %s's lock in" % user, repository
- time.sleep(delay)
-
-
-class ReadLock(Lock):
-
- def __init__(self, repository, delay = DELAY):
- Lock.__init__(self, repository, delay)
- ok = 0
- try:
- self.setlockdir()
- self.lockfile = self.cvsrfl
- fp = open(self.lockfile, 'w')
- fp.close()
- ok = 1
- finally:
- if not ok:
- self.unlockfile()
- self.unlockdir()
-
-
-class WriteLock(Lock):
-
- def __init__(self, repository, delay = DELAY):
- Lock.__init__(self, repository, delay)
- self.setlockdir()
- while 1:
- uid = self.readers_exist()
- if not uid:
- break
- self.unlockdir()
- self.sleep(uid)
- self.lockfile = self.cvswfl
- fp = open(self.lockfile, 'w')
- fp.close()
-
- def readers_exist(self):
- n = len(CVSRFL)
- for name in os.listdir(self.repository):
- if name[:n] == CVSRFL:
- try:
- st = os.stat(self.join(name))
- except os.error:
- continue
- return st
- return None
-
-
-def MultipleWriteLock(repositories, delay = DELAY):
- while 1:
- locks = []
- for r in repositories:
- try:
- locks.append(WriteLock(r, 0))
- except Locked, instance:
- del locks
- break
- else:
- break
- sleep(instance.msg, r, delay)
- return list
-
-
-def test():
- import sys
- if sys.argv[1:]:
- repository = sys.argv[1]
- else:
- repository = "."
- rl = None
- wl = None
- try:
- print "attempting write lock ..."
- wl = WriteLock(repository)
- print "got it."
- wl.unlock()
- print "attempting read lock ..."
- rl = ReadLock(repository)
- print "got it."
- rl.unlock()
- finally:
- print [1]
- sys.exc_traceback = None
- print [2]
- if rl:
- rl.unlock()
- print [3]
- if wl:
- wl.unlock()
- print [4]
- rl = None
- print [5]
- wl = None
- print [6]
-
-
-if __name__ == '__main__':
- test()
diff --git a/Demo/pdist/mac.py b/Demo/pdist/mac.py
deleted file mode 100644
index 107113c..0000000
--- a/Demo/pdist/mac.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import sys
-import string
-import rcvs
-
-def main():
- while 1:
- try:
- line = raw_input('$ ')
- except EOFError:
- break
- words = string.split(line)
- if not words:
- continue
- if words[0] != 'rcvs':
- words.insert(0, 'rcvs')
- sys.argv = words
- rcvs.main()
-
-main()
diff --git a/Demo/pdist/makechangelog.py b/Demo/pdist/makechangelog.py
deleted file mode 100755
index 1ffa588..0000000
--- a/Demo/pdist/makechangelog.py
+++ /dev/null
@@ -1,109 +0,0 @@
-#! /usr/bin/env python
-
-"""Turn a pile of RCS log output into ChangeLog file entries.
-
-"""
-
-import sys
-import string
-import re
-import getopt
-import time
-
-def main():
- args = sys.argv[1:]
- opts, args = getopt.getopt(args, 'p:')
- prefix = ''
- for o, a in opts:
- if p == '-p': prefix = a
-
- f = sys.stdin
- allrevs = []
- while 1:
- file = getnextfile(f)
- if not file: break
- revs = []
- while 1:
- rev = getnextrev(f, file)
- if not rev:
- break
- revs.append(rev)
- if revs:
- allrevs[len(allrevs):] = revs
- allrevs.sort()
- allrevs.reverse()
- for rev in allrevs:
- formatrev(rev, prefix)
-
-parsedateprog = re.compile(
- '^date: ([0-9]+)/([0-9]+)/([0-9]+) ' +
- '([0-9]+):([0-9]+):([0-9]+); author: ([^ ;]+)')
-
-authormap = {
- 'guido': 'Guido van Rossum <guido@cnri.reston.va.us>',
- 'jack': 'Jack Jansen <jack@cwi.nl>',
- 'sjoerd': 'Sjoerd Mullender <sjoerd@cwi.nl>',
- }
-
-def formatrev(rev, prefix):
- dateline, file, revline, log = rev
- if parsedateprog.match(dateline) >= 0:
- fields = parsedateprog.group(1, 2, 3, 4, 5, 6)
- author = parsedateprog.group(7)
- if authormap.has_key(author): author = authormap[author]
- tfields = map(string.atoi, fields) + [0, 0, 0]
- tfields[5] = tfields[5] - time.timezone
- t = time.mktime(tuple(tfields))
- print time.ctime(t), '', author
- words = string.split(log)
- words[:0] = ['*', prefix + file + ':']
- maxcol = 72-8
- col = maxcol
- for word in words:
- if col > 0 and col + len(word) >= maxcol:
- print
- print '\t' + word,
- col = -1
- else:
- print word,
- col = col + 1 + len(word)
- print
- print
-
-startprog = re.compile("^Working file: (.*)$")
-
-def getnextfile(f):
- while 1:
- line = f.readline()
- if not line: return None
- if startprog.match(line) >= 0:
- file = startprog.group(1)
- # Skip until first revision
- while 1:
- line = f.readline()
- if not line: return None
- if line[:10] == '='*10: return None
- if line[:10] == '-'*10: break
-## print "Skipped", line,
- return file
-## else:
-## print "Ignored", line,
-
-def getnextrev(f, file):
- # This is called when we are positioned just after a '---' separator
- revline = f.readline()
- dateline = f.readline()
- log = ''
- while 1:
- line = f.readline()
- if not line: break
- if line[:10] == '='*10:
- # Ignore the *last* log entry for each file since it
- # is the revision since which we are logging.
- return None
- if line[:10] == '-'*10: break
- log = log + line
- return dateline, file, revline, log
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/pdist/rcsbump b/Demo/pdist/rcsbump
deleted file mode 100755
index 4fa078e..0000000
--- a/Demo/pdist/rcsbump
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env python
-# -*- python -*-
-#
-# guido's version, from rcsbump,v 1.2 1995/06/22 21:27:27 bwarsaw Exp
-#
-# Python script for bumping up an RCS major revision number.
-
-import sys
-import re
-import rcslib
-import string
-
-WITHLOCK = 1
-majorrev_re = re.compile('^[0-9]+')
-
-dir = rcslib.RCS()
-
-if sys.argv[1:]:
- files = sys.argv[1:]
-else:
- files = dir.listfiles()
-
-for file in files:
- # get the major revnumber of the file
- headbranch = dir.info(file)['head']
- majorrev_re.match(headbranch)
- majorrev = string.atoi(majorrev_re.group(0)) + 1
-
- if not dir.islocked(file):
- dir.checkout(file, WITHLOCK)
-
- msg = "Bumping major revision number (to %d)" % majorrev
- dir.checkin((file, "%s.0" % majorrev), msg, "-f")
diff --git a/Demo/pdist/rcsclient.py b/Demo/pdist/rcsclient.py
deleted file mode 100644
index d8cb004..0000000
--- a/Demo/pdist/rcsclient.py
+++ /dev/null
@@ -1,71 +0,0 @@
-"""Customize this file to change the default client etc.
-
-(In general, it is probably be better to make local operation the
-default and to require something like an RCSSERVER environment
-variable to enable remote operation.)
-
-"""
-
-import string
-import os
-
-# These defaults don't belong here -- they should be taken from the
-# environment or from a hidden file in the current directory
-
-HOST = 'voorn.cwi.nl'
-PORT = 4127
-VERBOSE = 1
-LOCAL = 0
-
-import client
-
-
-class RCSProxyClient(client.SecureClient):
-
- def __init__(self, address, verbose = client.VERBOSE):
- client.SecureClient.__init__(self, address, verbose)
-
-
-def openrcsclient(opts = []):
- "open an RCSProxy client based on a list of options returned by getopt"
- import RCSProxy
- host = HOST
- port = PORT
- verbose = VERBOSE
- local = LOCAL
- directory = None
- for o, a in opts:
- if o == '-h':
- host = a
- if ':' in host:
- i = string.find(host, ':')
- host, p = host[:i], host[i+1:]
- if p:
- port = string.atoi(p)
- if o == '-p':
- port = string.atoi(a)
- if o == '-d':
- directory = a
- if o == '-v':
- verbose = verbose + 1
- if o == '-q':
- verbose = 0
- if o == '-L':
- local = 1
- if local:
- import RCSProxy
- x = RCSProxy.RCSProxyLocal()
- else:
- address = (host, port)
- x = RCSProxyClient(address, verbose)
- if not directory:
- try:
- directory = open(os.path.join("CVS", "Repository")).readline()
- except IOError:
- pass
- else:
- if directory[-1] == '\n':
- directory = directory[:-1]
- if directory:
- x.cd(directory)
- return x
diff --git a/Demo/pdist/rcslib.py b/Demo/pdist/rcslib.py
deleted file mode 100644
index 3e63869..0000000
--- a/Demo/pdist/rcslib.py
+++ /dev/null
@@ -1,334 +0,0 @@
-"""RCS interface module.
-
-Defines the class RCS, which represents a directory with rcs version
-files and (possibly) corresponding work files.
-
-"""
-
-
-import fnmatch
-import os
-import re
-import string
-import tempfile
-
-
-class RCS:
-
- """RCS interface class (local filesystem version).
-
- An instance of this class represents a directory with rcs version
- files and (possible) corresponding work files.
-
- Methods provide access to most rcs operations such as
- checkin/checkout, access to the rcs metadata (revisions, logs,
- branches etc.) as well as some filesystem operations such as
- listing all rcs version files.
-
- XXX BUGS / PROBLEMS
-
- - The instance always represents the current directory so it's not
- very useful to have more than one instance around simultaneously
-
- """
-
- # Characters allowed in work file names
- okchars = string.ascii_letters + string.digits + '-_=+'
-
- def __init__(self):
- """Constructor."""
- pass
-
- def __del__(self):
- """Destructor."""
- pass
-
- # --- Informational methods about a single file/revision ---
-
- def log(self, name_rev, otherflags = ''):
- """Return the full log text for NAME_REV as a string.
-
- Optional OTHERFLAGS are passed to rlog.
-
- """
- f = self._open(name_rev, 'rlog ' + otherflags)
- data = f.read()
- status = self._closepipe(f)
- if status:
- data = data + "%s: %s" % status
- elif data[-1] == '\n':
- data = data[:-1]
- return data
-
- def head(self, name_rev):
- """Return the head revision for NAME_REV"""
- dict = self.info(name_rev)
- return dict['head']
-
- def info(self, name_rev):
- """Return a dictionary of info (from rlog -h) for NAME_REV
-
- The dictionary's keys are the keywords that rlog prints
- (e.g. 'head' and its values are the corresponding data
- (e.g. '1.3').
-
- XXX symbolic names and locks are not returned
-
- """
- f = self._open(name_rev, 'rlog -h')
- dict = {}
- while 1:
- line = f.readline()
- if not line: break
- if line[0] == '\t':
- # XXX could be a lock or symbolic name
- # Anything else?
- continue
- i = string.find(line, ':')
- if i > 0:
- key, value = line[:i], string.strip(line[i+1:])
- dict[key] = value
- status = self._closepipe(f)
- if status:
- raise IOError, status
- return dict
-
- # --- Methods that change files ---
-
- def lock(self, name_rev):
- """Set an rcs lock on NAME_REV."""
- name, rev = self.checkfile(name_rev)
- cmd = "rcs -l%s %s" % (rev, name)
- return self._system(cmd)
-
- def unlock(self, name_rev):
- """Clear an rcs lock on NAME_REV."""
- name, rev = self.checkfile(name_rev)
- cmd = "rcs -u%s %s" % (rev, name)
- return self._system(cmd)
-
- def checkout(self, name_rev, withlock=0, otherflags=""):
- """Check out NAME_REV to its work file.
-
- If optional WITHLOCK is set, check out locked, else unlocked.
-
- The optional OTHERFLAGS is passed to co without
- interpretation.
-
- Any output from co goes to directly to stdout.
-
- """
- name, rev = self.checkfile(name_rev)
- if withlock: lockflag = "-l"
- else: lockflag = "-u"
- cmd = 'co %s%s %s %s' % (lockflag, rev, otherflags, name)
- return self._system(cmd)
-
- def checkin(self, name_rev, message=None, otherflags=""):
- """Check in NAME_REV from its work file.
-
- The optional MESSAGE argument becomes the checkin message
- (default "<none>" if None); or the file description if this is
- a new file.
-
- The optional OTHERFLAGS argument is passed to ci without
- interpretation.
-
- Any output from ci goes to directly to stdout.
-
- """
- name, rev = self._unmangle(name_rev)
- new = not self.isvalid(name)
- if not message: message = "<none>"
- if message and message[-1] != '\n':
- message = message + '\n'
- lockflag = "-u"
- if new:
- f = tempfile.NamedTemporaryFile()
- f.write(message)
- f.flush()
- cmd = 'ci %s%s -t%s %s %s' % \
- (lockflag, rev, f.name, otherflags, name)
- else:
- message = re.sub(r'([\"$`])', r'\\\1', message)
- cmd = 'ci %s%s -m"%s" %s %s' % \
- (lockflag, rev, message, otherflags, name)
- return self._system(cmd)
-
- # --- Exported support methods ---
-
- def listfiles(self, pat = None):
- """Return a list of all version files matching optional PATTERN."""
- files = os.listdir(os.curdir)
- files = filter(self._isrcs, files)
- if os.path.isdir('RCS'):
- files2 = os.listdir('RCS')
- files2 = filter(self._isrcs, files2)
- files = files + files2
- files = map(self.realname, files)
- return self._filter(files, pat)
-
- def isvalid(self, name):
- """Test whether NAME has a version file associated."""
- namev = self.rcsname(name)
- return (os.path.isfile(namev) or
- os.path.isfile(os.path.join('RCS', namev)))
-
- def rcsname(self, name):
- """Return the pathname of the version file for NAME.
-
- The argument can be a work file name or a version file name.
- If the version file does not exist, the name of the version
- file that would be created by "ci" is returned.
-
- """
- if self._isrcs(name): namev = name
- else: namev = name + ',v'
- if os.path.isfile(namev): return namev
- namev = os.path.join('RCS', os.path.basename(namev))
- if os.path.isfile(namev): return namev
- if os.path.isdir('RCS'):
- return os.path.join('RCS', namev)
- else:
- return namev
-
- def realname(self, namev):
- """Return the pathname of the work file for NAME.
-
- The argument can be a work file name or a version file name.
- If the work file does not exist, the name of the work file
- that would be created by "co" is returned.
-
- """
- if self._isrcs(namev): name = namev[:-2]
- else: name = namev
- if os.path.isfile(name): return name
- name = os.path.basename(name)
- return name
-
- def islocked(self, name_rev):
- """Test whether FILE (which must have a version file) is locked.
-
- XXX This does not tell you which revision number is locked and
- ignores any revision you may pass in (by virtue of using rlog
- -L -R).
-
- """
- f = self._open(name_rev, 'rlog -L -R')
- line = f.readline()
- status = self._closepipe(f)
- if status:
- raise IOError, status
- if not line: return None
- if line[-1] == '\n':
- line = line[:-1]
- return self.realname(name_rev) == self.realname(line)
-
- def checkfile(self, name_rev):
- """Normalize NAME_REV into a (NAME, REV) tuple.
-
- Raise an exception if there is no corresponding version file.
-
- """
- name, rev = self._unmangle(name_rev)
- if not self.isvalid(name):
- raise os.error, 'not an rcs file %r' % (name,)
- return name, rev
-
- # --- Internal methods ---
-
- def _open(self, name_rev, cmd = 'co -p', rflag = '-r'):
- """INTERNAL: open a read pipe to NAME_REV using optional COMMAND.
-
- Optional FLAG is used to indicate the revision (default -r).
-
- Default COMMAND is "co -p".
-
- Return a file object connected by a pipe to the command's
- output.
-
- """
- name, rev = self.checkfile(name_rev)
- namev = self.rcsname(name)
- if rev:
- cmd = cmd + ' ' + rflag + rev
- return os.popen("%s %r" % (cmd, namev))
-
- def _unmangle(self, name_rev):
- """INTERNAL: Normalize NAME_REV argument to (NAME, REV) tuple.
-
- Raise an exception if NAME contains invalid characters.
-
- A NAME_REV argument is either NAME string (implying REV='') or
- a tuple of the form (NAME, REV).
-
- """
- if type(name_rev) == type(''):
- name_rev = name, rev = name_rev, ''
- else:
- name, rev = name_rev
- for c in rev:
- if c not in self.okchars:
- raise ValueError, "bad char in rev"
- return name_rev
-
- def _closepipe(self, f):
- """INTERNAL: Close PIPE and print its exit status if nonzero."""
- sts = f.close()
- if not sts: return None
- detail, reason = divmod(sts, 256)
- if reason == 0: return 'exit', detail # Exit status
- signal = reason&0x7F
- if signal == 0x7F:
- code = 'stopped'
- signal = detail
- else:
- code = 'killed'
- if reason&0x80:
- code = code + '(coredump)'
- return code, signal
-
- def _system(self, cmd):
- """INTERNAL: run COMMAND in a subshell.
-
- Standard input for the command is taken from /dev/null.
-
- Raise IOError when the exit status is not zero.
-
- Return whatever the calling method should return; normally
- None.
-
- A derived class may override this method and redefine it to
- capture stdout/stderr of the command and return it.
-
- """
- cmd = cmd + " </dev/null"
- sts = os.system(cmd)
- if sts: raise IOError, "command exit status %d" % sts
-
- def _filter(self, files, pat = None):
- """INTERNAL: Return a sorted copy of the given list of FILES.
-
- If a second PATTERN argument is given, only files matching it
- are kept. No check for valid filenames is made.
-
- """
- if pat:
- def keep(name, pat = pat):
- return fnmatch.fnmatch(name, pat)
- files = filter(keep, files)
- else:
- files = files[:]
- files.sort()
- return files
-
- def _remove(self, fn):
- """INTERNAL: remove FILE without complaints."""
- try:
- os.unlink(fn)
- except os.error:
- pass
-
- def _isrcs(self, name):
- """INTERNAL: Test whether NAME ends in ',v'."""
- return name[-2:] == ',v'
diff --git a/Demo/pdist/rcvs b/Demo/pdist/rcvs
deleted file mode 100755
index f82a27a..0000000
--- a/Demo/pdist/rcvs
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env python
-
-import addpack
-addpack.addpack('/home/guido/src/python/Demo/pdist')
-
-import rcvs
-
-rcvs.main()
diff --git a/Demo/pdist/rcvs.py b/Demo/pdist/rcvs.py
deleted file mode 100755
index 8b8bae6..0000000
--- a/Demo/pdist/rcvs.py
+++ /dev/null
@@ -1,477 +0,0 @@
-#! /usr/bin/env python
-
-"""Remote CVS -- command line interface"""
-
-# XXX To do:
-#
-# Bugs:
-# - if the remote file is deleted, "rcvs update" will fail
-#
-# Functionality:
-# - cvs rm
-# - descend into directories (alraedy done for update)
-# - conflict resolution
-# - other relevant commands?
-# - branches
-#
-# - Finesses:
-# - retain file mode's x bits
-# - complain when "nothing known about filename"
-# - edit log message the way CVS lets you edit it
-# - cvs diff -rREVA -rREVB
-# - send mail the way CVS sends it
-#
-# Performance:
-# - cache remote checksums (for every revision ever seen!)
-# - translate symbolic revisions to numeric revisions
-#
-# Reliability:
-# - remote locking
-#
-# Security:
-# - Authenticated RPC?
-
-
-from cvslib import CVS, File
-import md5
-import os
-import string
-import sys
-from cmdfw import CommandFrameWork
-
-
-DEF_LOCAL = 1 # Default -l
-
-
-class MyFile(File):
-
- def action(self):
- """Return a code indicating the update status of this file.
-
- The possible return values are:
-
- '=' -- everything's fine
- '0' -- file doesn't exist anywhere
- '?' -- exists locally only
- 'A' -- new locally
- 'R' -- deleted locally
- 'U' -- changed remotely, no changes locally
- (includes new remotely or deleted remotely)
- 'M' -- changed locally, no changes remotely
- 'C' -- conflict: changed locally as well as remotely
- (includes cases where the file has been added
- or removed locally and remotely)
- 'D' -- deleted remotely
- 'N' -- new remotely
- 'r' -- get rid of entry
- 'c' -- create entry
- 'u' -- update entry
-
- (and probably others :-)
- """
- if not self.lseen:
- self.getlocal()
- if not self.rseen:
- self.getremote()
- if not self.eseen:
- if not self.lsum:
- if not self.rsum: return '0' # Never heard of
- else:
- return 'N' # New remotely
- else: # self.lsum
- if not self.rsum: return '?' # Local only
- # Local and remote, but no entry
- if self.lsum == self.rsum:
- return 'c' # Restore entry only
- else: return 'C' # Real conflict
- else: # self.eseen
- if not self.lsum:
- if self.edeleted:
- if self.rsum: return 'R' # Removed
- else: return 'r' # Get rid of entry
- else: # not self.edeleted
- if self.rsum:
- print "warning:",
- print self.file,
- print "was lost"
- return 'U'
- else: return 'r' # Get rid of entry
- else: # self.lsum
- if not self.rsum:
- if self.enew: return 'A' # New locally
- else: return 'D' # Deleted remotely
- else: # self.rsum
- if self.enew:
- if self.lsum == self.rsum:
- return 'u'
- else:
- return 'C'
- if self.lsum == self.esum:
- if self.esum == self.rsum:
- return '='
- else:
- return 'U'
- elif self.esum == self.rsum:
- return 'M'
- elif self.lsum == self.rsum:
- return 'u'
- else:
- return 'C'
-
- def update(self):
- code = self.action()
- if code == '=': return
- print code, self.file
- if code in ('U', 'N'):
- self.get()
- elif code == 'C':
- print "%s: conflict resolution not yet implemented" % \
- self.file
- elif code == 'D':
- remove(self.file)
- self.eseen = 0
- elif code == 'r':
- self.eseen = 0
- elif code in ('c', 'u'):
- self.eseen = 1
- self.erev = self.rrev
- self.enew = 0
- self.edeleted = 0
- self.esum = self.rsum
- self.emtime, self.ectime = os.stat(self.file)[-2:]
- self.extra = ''
-
- def commit(self, message = ""):
- code = self.action()
- if code in ('A', 'M'):
- self.put(message)
- return 1
- elif code == 'R':
- print "%s: committing removes not yet implemented" % \
- self.file
- elif code == 'C':
- print "%s: conflict resolution not yet implemented" % \
- self.file
-
- def diff(self, opts = []):
- self.action() # To update lseen, rseen
- flags = ''
- rev = self.rrev
- # XXX should support two rev options too!
- for o, a in opts:
- if o == '-r':
- rev = a
- else:
- flags = flags + ' ' + o + a
- if rev == self.rrev and self.lsum == self.rsum:
- return
- flags = flags[1:]
- fn = self.file
- data = self.proxy.get((fn, rev))
- sum = md5.new(data).digest()
- if self.lsum == sum:
- return
- import tempfile
- tf = tempfile.NamedTemporaryFile()
- tf.write(data)
- tf.flush()
- print 'diff %s -r%s %s' % (flags, rev, fn)
- sts = os.system('diff %s %s %s' % (flags, tf.name, fn))
- if sts:
- print '='*70
-
- def commitcheck(self):
- return self.action() != 'C'
-
- def put(self, message = ""):
- print "Checking in", self.file, "..."
- data = open(self.file).read()
- if not self.enew:
- self.proxy.lock(self.file)
- messages = self.proxy.put(self.file, data, message)
- if messages:
- print messages
- self.setentry(self.proxy.head(self.file), self.lsum)
-
- def get(self):
- data = self.proxy.get(self.file)
- f = open(self.file, 'w')
- f.write(data)
- f.close()
- self.setentry(self.rrev, self.rsum)
-
- def log(self, otherflags):
- print self.proxy.log(self.file, otherflags)
-
- def add(self):
- self.eseen = 0 # While we're hacking...
- self.esum = self.lsum
- self.emtime, self.ectime = 0, 0
- self.erev = ''
- self.enew = 1
- self.edeleted = 0
- self.eseen = 1 # Done
- self.extra = ''
-
- def setentry(self, erev, esum):
- self.eseen = 0 # While we're hacking...
- self.esum = esum
- self.emtime, self.ectime = os.stat(self.file)[-2:]
- self.erev = erev
- self.enew = 0
- self.edeleted = 0
- self.eseen = 1 # Done
- self.extra = ''
-
-
-SENDMAIL = "/usr/lib/sendmail -t"
-MAILFORM = """To: %s
-Subject: CVS changes: %s
-
-...Message from rcvs...
-
-Committed files:
- %s
-
-Log message:
- %s
-"""
-
-
-class RCVS(CVS):
-
- FileClass = MyFile
-
- def __init__(self):
- CVS.__init__(self)
-
- def update(self, files):
- for e in self.whichentries(files, 1):
- e.update()
-
- def commit(self, files, message = ""):
- list = self.whichentries(files)
- if not list: return
- ok = 1
- for e in list:
- if not e.commitcheck():
- ok = 0
- if not ok:
- print "correct above errors first"
- return
- if not message:
- message = raw_input("One-liner: ")
- committed = []
- for e in list:
- if e.commit(message):
- committed.append(e.file)
- self.mailinfo(committed, message)
-
- def mailinfo(self, files, message = ""):
- towhom = "sjoerd@cwi.nl, jack@cwi.nl" # XXX
- mailtext = MAILFORM % (towhom, string.join(files),
- string.join(files), message)
- print '-'*70
- print mailtext
- print '-'*70
- ok = raw_input("OK to mail to %s? " % towhom)
- if string.lower(string.strip(ok)) in ('y', 'ye', 'yes'):
- p = os.popen(SENDMAIL, "w")
- p.write(mailtext)
- sts = p.close()
- if sts:
- print "Sendmail exit status %s" % str(sts)
- else:
- print "Mail sent."
- else:
- print "No mail sent."
-
- def report(self, files):
- for e in self.whichentries(files):
- e.report()
-
- def diff(self, files, opts):
- for e in self.whichentries(files):
- e.diff(opts)
-
- def add(self, files):
- if not files:
- raise RuntimeError, "'cvs add' needs at least one file"
- list = []
- for e in self.whichentries(files, 1):
- e.add()
-
- def rm(self, files):
- if not files:
- raise RuntimeError, "'cvs rm' needs at least one file"
- raise RuntimeError, "'cvs rm' not yet imlemented"
-
- def log(self, files, opts):
- flags = ''
- for o, a in opts:
- flags = flags + ' ' + o + a
- for e in self.whichentries(files):
- e.log(flags)
-
- def whichentries(self, files, localfilestoo = 0):
- if files:
- list = []
- for file in files:
- if self.entries.has_key(file):
- e = self.entries[file]
- else:
- e = self.FileClass(file)
- self.entries[file] = e
- list.append(e)
- else:
- list = self.entries.values()
- for file in self.proxy.listfiles():
- if self.entries.has_key(file):
- continue
- e = self.FileClass(file)
- self.entries[file] = e
- list.append(e)
- if localfilestoo:
- for file in os.listdir(os.curdir):
- if not self.entries.has_key(file) \
- and not self.ignored(file):
- e = self.FileClass(file)
- self.entries[file] = e
- list.append(e)
- list.sort()
- if self.proxy:
- for e in list:
- if e.proxy is None:
- e.proxy = self.proxy
- return list
-
-
-class rcvs(CommandFrameWork):
-
- GlobalFlags = 'd:h:p:qvL'
- UsageMessage = \
-"usage: rcvs [-d directory] [-h host] [-p port] [-q] [-v] [subcommand arg ...]"
- PostUsageMessage = \
- "If no subcommand is given, the status of all files is listed"
-
- def __init__(self):
- """Constructor."""
- CommandFrameWork.__init__(self)
- self.proxy = None
- self.cvs = RCVS()
-
- def close(self):
- if self.proxy:
- self.proxy._close()
- self.proxy = None
-
- def recurse(self):
- self.close()
- names = os.listdir(os.curdir)
- for name in names:
- if name == os.curdir or name == os.pardir:
- continue
- if name == "CVS":
- continue
- if not os.path.isdir(name):
- continue
- if os.path.islink(name):
- continue
- print "--- entering subdirectory", name, "---"
- os.chdir(name)
- try:
- if os.path.isdir("CVS"):
- self.__class__().run()
- else:
- self.recurse()
- finally:
- os.chdir(os.pardir)
- print "--- left subdirectory", name, "---"
-
- def options(self, opts):
- self.opts = opts
-
- def ready(self):
- import rcsclient
- self.proxy = rcsclient.openrcsclient(self.opts)
- self.cvs.setproxy(self.proxy)
- self.cvs.getentries()
-
- def default(self):
- self.cvs.report([])
-
- def do_report(self, opts, files):
- self.cvs.report(files)
-
- def do_update(self, opts, files):
- """update [-l] [-R] [file] ..."""
- local = DEF_LOCAL
- for o, a in opts:
- if o == '-l': local = 1
- if o == '-R': local = 0
- self.cvs.update(files)
- self.cvs.putentries()
- if not local and not files:
- self.recurse()
- flags_update = '-lR'
- do_up = do_update
- flags_up = flags_update
-
- def do_commit(self, opts, files):
- """commit [-m message] [file] ..."""
- message = ""
- for o, a in opts:
- if o == '-m': message = a
- self.cvs.commit(files, message)
- self.cvs.putentries()
- flags_commit = 'm:'
- do_com = do_commit
- flags_com = flags_commit
-
- def do_diff(self, opts, files):
- """diff [difflags] [file] ..."""
- self.cvs.diff(files, opts)
- flags_diff = 'cbitwcefhnlr:sD:S:'
- do_dif = do_diff
- flags_dif = flags_diff
-
- def do_add(self, opts, files):
- """add file ..."""
- if not files:
- print "'rcvs add' requires at least one file"
- return
- self.cvs.add(files)
- self.cvs.putentries()
-
- def do_remove(self, opts, files):
- """remove file ..."""
- if not files:
- print "'rcvs remove' requires at least one file"
- return
- self.cvs.remove(files)
- self.cvs.putentries()
- do_rm = do_remove
-
- def do_log(self, opts, files):
- """log [rlog-options] [file] ..."""
- self.cvs.log(files, opts)
- flags_log = 'bhLNRtd:s:V:r:'
-
-
-def remove(fn):
- try:
- os.unlink(fn)
- except os.error:
- pass
-
-
-def main():
- r = rcvs()
- try:
- r.run()
- finally:
- r.close()
-
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/pdist/rrcs b/Demo/pdist/rrcs
deleted file mode 100755
index 31fc2c5..0000000
--- a/Demo/pdist/rrcs
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env python
-
-import addpack
-addpack.addpack('/home/guido/src/python/Demo/pdist')
-
-import rrcs
-
-rrcs.main()
diff --git a/Demo/pdist/rrcs.py b/Demo/pdist/rrcs.py
deleted file mode 100755
index 4d23e6c..0000000
--- a/Demo/pdist/rrcs.py
+++ /dev/null
@@ -1,160 +0,0 @@
-#! /usr/bin/env python
-
-"Remote RCS -- command line interface"
-
-import sys
-import os
-import getopt
-import string
-import md5
-import tempfile
-from rcsclient import openrcsclient
-
-def main():
- sys.stdout = sys.stderr
- try:
- opts, rest = getopt.getopt(sys.argv[1:], 'h:p:d:qvL')
- if not rest:
- cmd = 'head'
- else:
- cmd, rest = rest[0], rest[1:]
- if not commands.has_key(cmd):
- raise getopt.error, "unknown command"
- coptset, func = commands[cmd]
- copts, files = getopt.getopt(rest, coptset)
- except getopt.error, msg:
- print msg
- print "usage: rrcs [options] command [options] [file] ..."
- print "where command can be:"
- print " ci|put # checkin the given files"
- print " co|get # checkout"
- print " info # print header info"
- print " head # print revision of head branch"
- print " list # list filename if valid"
- print " log # print full log"
- print " diff # diff rcs file and work file"
- print "if no files are given, all remote rcs files are assumed"
- sys.exit(2)
- x = openrcsclient(opts)
- if not files:
- files = x.listfiles()
- for fn in files:
- try:
- func(x, copts, fn)
- except (IOError, os.error), msg:
- print "%s: %s" % (fn, msg)
-
-def checkin(x, copts, fn):
- f = open(fn)
- data = f.read()
- f.close()
- new = not x.isvalid(fn)
- if not new and same(x, copts, fn, data):
- print "%s: unchanged since last checkin" % fn
- return
- print "Checking in", fn, "..."
- message = asklogmessage(new)
- messages = x.put(fn, data, message)
- if messages:
- print messages
-
-def checkout(x, copts, fn):
- data = x.get(fn)
- f = open(fn, 'w')
- f.write(data)
- f.close()
-
-def lock(x, copts, fn):
- x.lock(fn)
-
-def unlock(x, copts, fn):
- x.unlock(fn)
-
-def info(x, copts, fn):
- dict = x.info(fn)
- keys = dict.keys()
- keys.sort()
- for key in keys:
- print key + ':', dict[key]
- print '='*70
-
-def head(x, copts, fn):
- head = x.head(fn)
- print fn, head
-
-def list(x, copts, fn):
- if x.isvalid(fn):
- print fn
-
-def log(x, copts, fn):
- flags = ''
- for o, a in copts:
- flags = flags + ' ' + o + a
- flags = flags[1:]
- messages = x.log(fn, flags)
- print messages
-
-def diff(x, copts, fn):
- if same(x, copts, fn):
- return
- flags = ''
- for o, a in copts:
- flags = flags + ' ' + o + a
- flags = flags[1:]
- data = x.get(fn)
- tf = tempfile.NamedTemporaryFile()
- tf.write(data)
- tf.flush()
- print 'diff %s -r%s %s' % (flags, x.head(fn), fn)
- sts = os.system('diff %s %s %s' % (flags, tf.name, fn))
- if sts:
- print '='*70
-
-def same(x, copts, fn, data = None):
- if data is None:
- f = open(fn)
- data = f.read()
- f.close()
- lsum = md5.new(data).digest()
- rsum = x.sum(fn)
- return lsum == rsum
-
-def asklogmessage(new):
- if new:
- print "enter description,",
- else:
- print "enter log message,",
- print "terminate with single '.' or end of file:"
- if new:
- print "NOTE: This is NOT the log message!"
- message = ""
- while 1:
- sys.stderr.write(">> ")
- sys.stderr.flush()
- line = sys.stdin.readline()
- if not line or line == '.\n': break
- message = message + line
- return message
-
-def remove(fn):
- try:
- os.unlink(fn)
- except os.error:
- pass
-
-commands = {
- 'ci': ('', checkin),
- 'put': ('', checkin),
- 'co': ('', checkout),
- 'get': ('', checkout),
- 'info': ('', info),
- 'head': ('', head),
- 'list': ('', list),
- 'lock': ('', lock),
- 'unlock': ('', unlock),
- 'log': ('bhLRtd:l:r:s:w:V:', log),
- 'diff': ('c', diff),
- }
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/pdist/security.py b/Demo/pdist/security.py
deleted file mode 100644
index b63081e..0000000
--- a/Demo/pdist/security.py
+++ /dev/null
@@ -1,33 +0,0 @@
-class Security:
-
- def __init__(self):
- import os
- env = os.environ
- if env.has_key('PYTHON_KEYFILE'):
- keyfile = env['PYTHON_KEYFILE']
- else:
- keyfile = '.python_keyfile'
- if env.has_key('HOME'):
- keyfile = os.path.join(env['HOME'], keyfile)
- if not os.path.exists(keyfile):
- import sys
- for dir in sys.path:
- kf = os.path.join(dir, keyfile)
- if os.path.exists(kf):
- keyfile = kf
- break
- try:
- self._key = eval(open(keyfile).readline())
- except IOError:
- raise IOError, "python keyfile %s: cannot open" % keyfile
-
- def _generate_challenge(self):
- import random
- return random.randint(100, 100000)
-
- def _compare_challenge_response(self, challenge, response):
- return self._encode_challenge(challenge) == response
-
- def _encode_challenge(self, challenge):
- p, m = self._key
- return pow(long(challenge), p, m)
diff --git a/Demo/pdist/server.py b/Demo/pdist/server.py
deleted file mode 100644
index e692eea..0000000
--- a/Demo/pdist/server.py
+++ /dev/null
@@ -1,145 +0,0 @@
-"""RPC Server module."""
-
-import sys
-import socket
-import pickle
-from fnmatch import fnmatch
-from repr import repr
-
-
-# Default verbosity (0 = silent, 1 = print connections, 2 = print requests too)
-VERBOSE = 1
-
-
-class Server:
-
- """RPC Server class. Derive a class to implement a particular service."""
-
- def __init__(self, address, verbose = VERBOSE):
- if type(address) == type(0):
- address = ('', address)
- self._address = address
- self._verbose = verbose
- self._socket = None
- self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self._socket.bind(address)
- self._socket.listen(1)
- self._listening = 1
-
- def _setverbose(self, verbose):
- self._verbose = verbose
-
- def __del__(self):
- self._close()
-
- def _close(self):
- self._listening = 0
- if self._socket:
- self._socket.close()
- self._socket = None
-
- def _serverloop(self):
- while self._listening:
- self._serve()
-
- def _serve(self):
- if self._verbose: print "Wait for connection ..."
- conn, address = self._socket.accept()
- if self._verbose: print "Accepted connection from %s" % repr(address)
- if not self._verify(conn, address):
- print "*** Connection from %s refused" % repr(address)
- conn.close()
- return
- rf = conn.makefile('r')
- wf = conn.makefile('w')
- ok = 1
- while ok:
- wf.flush()
- if self._verbose > 1: print "Wait for next request ..."
- ok = self._dorequest(rf, wf)
-
- _valid = ['192.16.201.*', '192.16.197.*', '132.151.1.*', '129.6.64.*']
-
- def _verify(self, conn, address):
- host, port = address
- for pat in self._valid:
- if fnmatch(host, pat): return 1
- return 0
-
- def _dorequest(self, rf, wf):
- rp = pickle.Unpickler(rf)
- try:
- request = rp.load()
- except EOFError:
- return 0
- if self._verbose > 1: print "Got request: %s" % repr(request)
- try:
- methodname, args, id = request
- if '.' in methodname:
- reply = (None, self._special(methodname, args), id)
- elif methodname[0] == '_':
- raise NameError, "illegal method name %s" % repr(methodname)
- else:
- method = getattr(self, methodname)
- reply = (None, apply(method, args), id)
- except:
- reply = (sys.exc_type, sys.exc_value, id)
- if id < 0 and reply[:2] == (None, None):
- if self._verbose > 1: print "Suppress reply"
- return 1
- if self._verbose > 1: print "Send reply: %s" % repr(reply)
- wp = pickle.Pickler(wf)
- wp.dump(reply)
- return 1
-
- def _special(self, methodname, args):
- if methodname == '.methods':
- if not hasattr(self, '_methods'):
- self._methods = tuple(self._listmethods())
- return self._methods
- raise NameError, "unrecognized special method name %s" % repr(methodname)
-
- def _listmethods(self, cl=None):
- if not cl: cl = self.__class__
- names = cl.__dict__.keys()
- names = filter(lambda x: x[0] != '_', names)
- names.sort()
- for base in cl.__bases__:
- basenames = self._listmethods(base)
- basenames = filter(lambda x, names=names: x not in names, basenames)
- names[len(names):] = basenames
- return names
-
-
-from security import Security
-
-
-class SecureServer(Server, Security):
-
- def __init__(self, *args):
- apply(Server.__init__, (self,) + args)
- Security.__init__(self)
-
- def _verify(self, conn, address):
- import string
- challenge = self._generate_challenge()
- conn.send("%d\n" % challenge)
- response = ""
- while "\n" not in response and len(response) < 100:
- data = conn.recv(100)
- if not data:
- break
- response = response + data
- try:
- response = string.atol(string.strip(response))
- except string.atol_error:
- if self._verbose > 0:
- print "Invalid response syntax", repr(response)
- return 0
- if not self._compare_challenge_response(challenge, response):
- if self._verbose > 0:
- print "Invalid response value", repr(response)
- return 0
- if self._verbose > 1:
- print "Response matches challenge. Go ahead!"
- return 1
diff --git a/Demo/pdist/sumtree.py b/Demo/pdist/sumtree.py
deleted file mode 100644
index 9291a56..0000000
--- a/Demo/pdist/sumtree.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import time
-import FSProxy
-
-def main():
- t1 = time.time()
- #proxy = FSProxy.FSProxyClient(('voorn.cwi.nl', 4127))
- proxy = FSProxy.FSProxyLocal()
- sumtree(proxy)
- proxy._close()
- t2 = time.time()
- print t2-t1, "seconds"
- raw_input("[Return to exit] ")
-
-def sumtree(proxy):
- print "PWD =", proxy.pwd()
- files = proxy.listfiles()
- proxy.infolist(files)
- subdirs = proxy.listsubdirs()
- for name in subdirs:
- proxy.cd(name)
- sumtree(proxy)
- proxy.back()
-
-main()
diff --git a/Demo/pysvr/Makefile b/Demo/pysvr/Makefile
deleted file mode 100644
index b4b9f3e..0000000
--- a/Demo/pysvr/Makefile
+++ /dev/null
@@ -1,57 +0,0 @@
-# Makefile for 'pysvr' application embedding Python.
-# Tailored for Python 1.5a3 or later.
-# Some details are specific for Solaris or CNRI.
-# Also see ## comments for tailoring.
-
-# Which C compiler
-CC=gcc
-##PURIFY=/usr/local/pure/purify
-LINKCC=$(PURIFY) $(CC)
-
-# Optimization preferences
-OPT=-g
-
-# Which Python version we're using
-VER=2.2
-
-# Expressions using the above definitions
-PYVER=python$(VER)
-
-# Use these defs when compiling against installed Python
-##INST=/usr/local
-##PYC=$(INST)/lib/$(PYVER)/config
-##PYINCL=-I$(INST)/include/$(PYVER) -I$(PYC)
-##PYLIBS=$(PYC)/lib$(PYVER).a
-
-# Use these defs when compiling against built Python
-PLAT=linux
-PYINCL=-I../../Include -I../../$(PLAT)
-PYLIBS=../../$(PLAT)/lib$(PYVER).a
-
-# Libraries to link with -- very installation dependent
-# (See LIBS= in Modules/Makefile in build tree)
-RLLIBS=-lreadline -ltermcap
-OTHERLIBS=-lnsl -lpthread -ldl -lm -ldb -lutil
-
-# Compilation and link flags -- no need to change normally
-CFLAGS=$(OPT)
-CPPFLAGS=$(PYINCL)
-LIBS=$(PYLIBS) $(RLLIBS) $(OTHERLIBS)
-
-# Default port for the pysvr application
-PORT=4000
-
-# Default target
-all: pysvr
-
-# Target to build pysvr
-pysvr: pysvr.o $(PYOBJS) $(PYLIBS)
- $(LINKCC) pysvr.o $(LIBS) -o pysvr
-
-# Target to build and run pysvr
-run: pysvr
- pysvr $(PORT)
-
-# Target to clean up the directory
-clean:
- -rm -f pysvr *.o *~ core
diff --git a/Demo/pysvr/README b/Demo/pysvr/README
deleted file mode 100644
index 5e64e38..0000000
--- a/Demo/pysvr/README
+++ /dev/null
@@ -1,9 +0,0 @@
-This is an example of a multi-threaded C application embedding a
-Python interpreter.
-
-The particular application is a multi-threaded telnet-like server that
-provides you with a Python prompt (instead of a shell prompt).
-
-The file pysvr.py is a prototype in Python.
-
-THIS APPLICATION IS NOT SECURE -- ONLY USE IT FOR TESTING!
diff --git a/Demo/pysvr/pysvr.c b/Demo/pysvr/pysvr.c
deleted file mode 100644
index 706cd2a..0000000
--- a/Demo/pysvr/pysvr.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/* A multi-threaded telnet-like server that gives a Python prompt.
-
-Usage: pysvr [port]
-
-For security reasons, it only accepts requests from the current host.
-This can still be insecure, but restricts violations from people who
-can log in on your machine. Use with caution!
-
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include <pthread.h>
-#include <getopt.h>
-
-/* XXX Umpfh.
- Python.h defines a typedef destructor, which conflicts with pthread.h.
- So Python.h must be included after pthread.h. */
-
-#include "Python.h"
-
-extern int Py_VerboseFlag;
-
-#ifndef PORT
-#define PORT 4000
-#endif
-
-struct workorder {
- int conn;
- struct sockaddr_in addr;
-};
-
-/* Forward */
-static void init_python(void);
-static void usage(void);
-static void oprogname(void);
-static void main_thread(int);
-static void create_thread(int, struct sockaddr_in *);
-static void *service_thread(struct workorder *);
-static void run_interpreter(FILE *, FILE *);
-static int run_command(char *, PyObject *);
-static void ps(void);
-
-static char *progname = "pysvr";
-
-static PyThreadState *gtstate;
-
-main(int argc, char **argv)
-{
- int port = PORT;
- int c;
-
- if (argc > 0 && argv[0] != NULL && argv[0][0] != '\0')
- progname = argv[0];
-
- while ((c = getopt(argc, argv, "v")) != EOF) {
- switch (c) {
- case 'v':
- Py_VerboseFlag++;
- break;
- default:
- usage();
- }
- }
-
- if (optind < argc) {
- if (optind+1 < argc) {
- oprogname();
- fprintf(stderr, "too many arguments\n");
- usage();
- }
- port = atoi(argv[optind]);
- if (port <= 0) {
- fprintf(stderr, "bad port (%s)\n", argv[optind]);
- usage();
- }
- }
-
- main_thread(port);
-
- fprintf(stderr, "Bye.\n");
-
- exit(0);
-}
-
-static char usage_line[] = "usage: %s [port]\n";
-
-static void
-usage(void)
-{
- fprintf(stderr, usage_line, progname);
- exit(2);
-}
-
-static void
-main_thread(int port)
-{
- int sock, conn, size, i;
- struct sockaddr_in addr, clientaddr;
-
- sock = socket(PF_INET, SOCK_STREAM, 0);
- if (sock < 0) {
- oprogname();
- perror("can't create socket");
- exit(1);
- }
-
-#ifdef SO_REUSEADDR
- i = 1;
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof i);
-#endif
-
- memset((char *)&addr, '\0', sizeof addr);
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = 0L;
- if (bind(sock, (struct sockaddr *)&addr, sizeof addr) < 0) {
- oprogname();
- perror("can't bind socket to address");
- exit(1);
- }
-
- if (listen(sock, 5) < 0) {
- oprogname();
- perror("can't listen on socket");
- exit(1);
- }
-
- fprintf(stderr, "Listening on port %d...\n", port);
-
- for (i = 0; ; i++) {
- size = sizeof clientaddr;
- memset((char *) &clientaddr, '\0', size);
- conn = accept(sock, (struct sockaddr *) &clientaddr, &size);
- if (conn < 0) {
- oprogname();
- perror("can't accept connection from socket");
- exit(1);
- }
-
- size = sizeof addr;
- memset((char *) &addr, '\0', size);
- if (getsockname(conn, (struct sockaddr *)&addr, &size) < 0) {
- oprogname();
- perror("can't get socket name of connection");
- exit(1);
- }
- if (clientaddr.sin_addr.s_addr != addr.sin_addr.s_addr) {
- oprogname();
- perror("connection from non-local host refused");
- fprintf(stderr, "(addr=%lx, clientaddr=%lx)\n",
- ntohl(addr.sin_addr.s_addr),
- ntohl(clientaddr.sin_addr.s_addr));
- close(conn);
- continue;
- }
- if (i == 4) {
- close(conn);
- break;
- }
- create_thread(conn, &clientaddr);
- }
-
- close(sock);
-
- if (gtstate) {
- PyEval_AcquireThread(gtstate);
- gtstate = NULL;
- Py_Finalize();
- /* And a second time, just because we can. */
- Py_Finalize(); /* This should be harmless. */
- }
- exit(0);
-}
-
-static void
-create_thread(int conn, struct sockaddr_in *addr)
-{
- struct workorder *work;
- pthread_t tdata;
-
- work = malloc(sizeof(struct workorder));
- if (work == NULL) {
- oprogname();
- fprintf(stderr, "out of memory for thread.\n");
- close(conn);
- return;
- }
- work->conn = conn;
- work->addr = *addr;
-
- init_python();
-
- if (pthread_create(&tdata, NULL, (void *)service_thread, work) < 0) {
- oprogname();
- perror("can't create new thread");
- close(conn);
- return;
- }
-
- if (pthread_detach(tdata) < 0) {
- oprogname();
- perror("can't detach from thread");
- }
-}
-
-static PyThreadState *the_tstate;
-static PyInterpreterState *the_interp;
-static PyObject *the_builtins;
-
-static void
-init_python(void)
-{
- if (gtstate)
- return;
- Py_Initialize(); /* Initialize the interpreter */
- PyEval_InitThreads(); /* Create (and acquire) the interpreter lock */
- gtstate = PyEval_SaveThread(); /* Release the thread state */
-}
-
-static void *
-service_thread(struct workorder *work)
-{
- FILE *input, *output;
-
- fprintf(stderr, "Start thread for connection %d.\n", work->conn);
-
- ps();
-
- input = fdopen(work->conn, "r");
- if (input == NULL) {
- oprogname();
- perror("can't create input stream");
- goto done;
- }
-
- output = fdopen(work->conn, "w");
- if (output == NULL) {
- oprogname();
- perror("can't create output stream");
- fclose(input);
- goto done;
- }
-
- setvbuf(input, NULL, _IONBF, 0);
- setvbuf(output, NULL, _IONBF, 0);
-
- run_interpreter(input, output);
-
- fclose(input);
- fclose(output);
-
- done:
- fprintf(stderr, "End thread for connection %d.\n", work->conn);
- close(work->conn);
- free(work);
-}
-
-static void
-oprogname(void)
-{
- int save = errno;
- fprintf(stderr, "%s: ", progname);
- errno = save;
-}
-
-static void
-run_interpreter(FILE *input, FILE *output)
-{
- PyThreadState *tstate;
- PyObject *new_stdin, *new_stdout;
- PyObject *mainmod, *globals;
- char buffer[1000];
- char *p, *q;
- int n, end;
-
- PyEval_AcquireLock();
- tstate = Py_NewInterpreter();
- if (tstate == NULL) {
- fprintf(output, "Sorry -- can't create an interpreter\n");
- return;
- }
-
- mainmod = PyImport_AddModule("__main__");
- globals = PyModule_GetDict(mainmod);
- Py_INCREF(globals);
-
- new_stdin = PyFile_FromFile(input, "<socket-in>", "r", NULL);
- new_stdout = PyFile_FromFile(output, "<socket-out>", "w", NULL);
-
- PySys_SetObject("stdin", new_stdin);
- PySys_SetObject("stdout", new_stdout);
- PySys_SetObject("stderr", new_stdout);
-
- for (n = 1; !PyErr_Occurred(); n++) {
- Py_BEGIN_ALLOW_THREADS
- fprintf(output, "%d> ", n);
- p = fgets(buffer, sizeof buffer, input);
- Py_END_ALLOW_THREADS
-
- if (p == NULL)
- break;
- if (p[0] == '\377' && p[1] == '\354')
- break;
-
- q = strrchr(p, '\r');
- if (q && q[1] == '\n' && q[2] == '\0') {
- *q++ = '\n';
- *q++ = '\0';
- }
-
- while (*p && isspace(*p))
- p++;
- if (p[0] == '#' || p[0] == '\0')
- continue;
-
- end = run_command(buffer, globals);
- if (end < 0)
- PyErr_Print();
-
- if (end)
- break;
- }
-
- Py_XDECREF(globals);
- Py_XDECREF(new_stdin);
- Py_XDECREF(new_stdout);
-
- Py_EndInterpreter(tstate);
- PyEval_ReleaseLock();
-
- fprintf(output, "Goodbye!\n");
-}
-
-static int
-run_command(char *buffer, PyObject *globals)
-{
- PyObject *m, *d, *v;
- fprintf(stderr, "run_command: %s", buffer);
- if (strchr(buffer, '\n') == NULL)
- fprintf(stderr, "\n");
- v = PyRun_String(buffer, Py_single_input, globals, globals);
- if (v == NULL) {
- if (PyErr_Occurred() == PyExc_SystemExit) {
- PyErr_Clear();
- return 1;
- }
- PyErr_Print();
- return 0;
- }
- Py_DECREF(v);
- return 0;
-}
-
-static void
-ps(void)
-{
- char buffer[100];
- PyOS_snprintf(buffer, sizeof(buffer),
- "ps -l -p %d </dev/null | sed 1d\n", getpid());
- system(buffer);
-}
diff --git a/Demo/pysvr/pysvr.py b/Demo/pysvr/pysvr.py
deleted file mode 100755
index dd0abdc..0000000
--- a/Demo/pysvr/pysvr.py
+++ /dev/null
@@ -1,124 +0,0 @@
-#! /usr/bin/env python
-
-"""A multi-threaded telnet-like server that gives a Python prompt.
-
-This is really a prototype for the same thing in C.
-
-Usage: pysvr.py [port]
-
-For security reasons, it only accepts requests from the current host.
-This can still be insecure, but restricts violations from people who
-can log in on your machine. Use with caution!
-
-"""
-
-import sys, os, string, getopt, thread, socket, traceback
-
-PORT = 4000 # Default port
-
-def main():
- try:
- opts, args = getopt.getopt(sys.argv[1:], "")
- if len(args) > 1:
- raise getopt.error, "Too many arguments."
- except getopt.error, msg:
- usage(msg)
- for o, a in opts:
- pass
- if args:
- try:
- port = string.atoi(args[0])
- except ValueError, msg:
- usage(msg)
- else:
- port = PORT
- main_thread(port)
-
-def usage(msg=None):
- sys.stdout = sys.stderr
- if msg:
- print msg
- print "\n", __doc__,
- sys.exit(2)
-
-def main_thread(port):
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sock.bind(("", port))
- sock.listen(5)
- print "Listening on port", port, "..."
- while 1:
- (conn, addr) = sock.accept()
- if addr[0] != conn.getsockname()[0]:
- conn.close()
- print "Refusing connection from non-local host", addr[0], "."
- continue
- thread.start_new_thread(service_thread, (conn, addr))
- del conn, addr
-
-def service_thread(conn, addr):
- (caddr, cport) = addr
- print "Thread %s has connection from %s.\n" % (str(thread.get_ident()),
- caddr),
- stdin = conn.makefile("r")
- stdout = conn.makefile("w", 0)
- run_interpreter(stdin, stdout)
- print "Thread %s is done.\n" % str(thread.get_ident()),
-
-def run_interpreter(stdin, stdout):
- globals = {}
- try:
- str(sys.ps1)
- except:
- sys.ps1 = ">>> "
- source = ""
- while 1:
- stdout.write(sys.ps1)
- line = stdin.readline()
- if line[:2] == '\377\354':
- line = ""
- if not line and not source:
- break
- if line[-2:] == '\r\n':
- line = line[:-2] + '\n'
- source = source + line
- try:
- code = compile_command(source)
- except SyntaxError, err:
- source = ""
- traceback.print_exception(SyntaxError, err, None, file=stdout)
- continue
- if not code:
- continue
- source = ""
- try:
- run_command(code, stdin, stdout, globals)
- except SystemExit, how:
- if how:
- try:
- how = str(how)
- except:
- how = ""
- stdout.write("Exit %s\n" % how)
- break
- stdout.write("\nGoodbye.\n")
-
-def run_command(code, stdin, stdout, globals):
- save = sys.stdin, sys.stdout, sys.stderr
- try:
- sys.stdout = sys.stderr = stdout
- sys.stdin = stdin
- try:
- exec code in globals
- except SystemExit, how:
- raise SystemExit, how, sys.exc_info()[2]
- except:
- type, value, tb = sys.exc_info()
- if tb: tb = tb.tb_next
- traceback.print_exception(type, value, tb)
- del tb
- finally:
- sys.stdin, sys.stdout, sys.stderr = save
-
-from code import compile_command
-
-main()
diff --git a/Demo/rpc/MANIFEST b/Demo/rpc/MANIFEST
deleted file mode 100644
index e65f3eb..0000000
--- a/Demo/rpc/MANIFEST
+++ /dev/null
@@ -1,10 +0,0 @@
- File Name Archive # Description
------------------------------------------------------------
- MANIFEST 1 This shipping list
- README 1
- T.py 1
- mountclient.py 1
- nfsclient.py 1
- rpc.py 1
- test 1
- xdr.py 1
diff --git a/Demo/rpc/README b/Demo/rpc/README
deleted file mode 100644
index 97948a3..0000000
--- a/Demo/rpc/README
+++ /dev/null
@@ -1,31 +0,0 @@
-This is a Python interface to Sun RPC, designed and implemented mostly
-by reading the Internet RFCs about the subject.
-
-*** NOTE: xdr.py has evolved into the standard module xdrlib.py ***
-
-There are two library modules, xdr.py and rpc.py, and several example
-clients: mountclient.py, nfsclient.py, and rnusersclient.py,
-implementing the NFS Mount protocol, (part of) the NFS protocol, and
-the "rnusers" protocol (used by rusers(1)), respectively. The latter
-demonstrates the use of broadcast via the Port mapper's CALLIT
-procedure.
-
-There is also a way to create servers in Python.
-
-To test the nfs client, run it from the shell with something like this:
-
- python -c 'import nfsclient; nfsclient.test()' [hostname [filesystemname]]
-
-When called without a filesystemname, it lists the filesystems at the
-host; default host is the local machine.
-
-Other clients are tested similarly.
-
-For hostname, use e.g. wuarchive.wustl.edu or gatekeeper.dec.com (two
-hosts that are known to export NFS filesystems with little restrictions).
-
-There are now two different RPC compilers:
-
-1) Wim Lewis rpcgen.py found on http://www.omnigroup.com/~wiml/soft/stale-index.html#python.
-
-2) Peter Åstrands rpcgen.py, which is part of "pynfs" (http://www.cendio.se/~peter/pynfs/).
diff --git a/Demo/rpc/T.py b/Demo/rpc/T.py
deleted file mode 100644
index 3325507..0000000
--- a/Demo/rpc/T.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Simple interface to report execution times of program fragments.
-# Call TSTART() to reset the timer, TSTOP(...) to report times.
-
-import sys, os, time
-
-def TSTART():
- global t0, t1
- u, s, cu, cs = os.times()
- t0 = u+cu, s+cs, time.time()
-
-def TSTOP(*label):
- global t0, t1
- u, s, cu, cs = os.times()
- t1 = u+cu, s+cs, time.time()
- tt = []
- for i in range(3):
- tt.append(t1[i] - t0[i])
- [u, s, r] = tt
- msg = ''
- for x in label: msg = msg + (x + ' ')
- msg = msg + '%r user, %r sys, %r real\n' % (u, s, r)
- sys.stderr.write(msg)
diff --git a/Demo/rpc/mountclient.py b/Demo/rpc/mountclient.py
deleted file mode 100644
index 4e8d92a..0000000
--- a/Demo/rpc/mountclient.py
+++ /dev/null
@@ -1,202 +0,0 @@
-# Mount RPC client -- RFC 1094 (NFS), Appendix A
-
-# This module demonstrates how to write your own RPC client in Python.
-# When this example was written, there was no RPC compiler for
-# Python. Without such a compiler, you must first create classes
-# derived from Packer and Unpacker to handle the data types for the
-# server you want to interface to. You then write the client class.
-# If you want to support both the TCP and the UDP version of a
-# protocol, use multiple inheritance as shown below.
-
-
-import rpc
-from rpc import Packer, Unpacker, TCPClient, UDPClient
-
-
-# Program number and version for the mount protocol
-MOUNTPROG = 100005
-MOUNTVERS = 1
-
-# Size of the 'fhandle' opaque structure
-FHSIZE = 32
-
-
-# Packer derived class for Mount protocol clients.
-# The only thing we need to pack beyond basic types is an 'fhandle'
-
-class MountPacker(Packer):
-
- def pack_fhandle(self, fhandle):
- self.pack_fopaque(FHSIZE, fhandle)
-
-
-# Unpacker derived class for Mount protocol clients.
-# The important types we need to unpack are fhandle, fhstatus,
-# mountlist and exportlist; mountstruct, exportstruct and groups are
-# used to unpack components of mountlist and exportlist and the
-# corresponding functions are passed as function argument to the
-# generic unpack_list function.
-
-class MountUnpacker(Unpacker):
-
- def unpack_fhandle(self):
- return self.unpack_fopaque(FHSIZE)
-
- def unpack_fhstatus(self):
- status = self.unpack_uint()
- if status == 0:
- fh = self.unpack_fhandle()
- else:
- fh = None
- return status, fh
-
- def unpack_mountlist(self):
- return self.unpack_list(self.unpack_mountstruct)
-
- def unpack_mountstruct(self):
- hostname = self.unpack_string()
- directory = self.unpack_string()
- return (hostname, directory)
-
- def unpack_exportlist(self):
- return self.unpack_list(self.unpack_exportstruct)
-
- def unpack_exportstruct(self):
- filesys = self.unpack_string()
- groups = self.unpack_groups()
- return (filesys, groups)
-
- def unpack_groups(self):
- return self.unpack_list(self.unpack_string)
-
-
-# These are the procedures specific to the Mount client class.
-# Think of this as a derived class of either TCPClient or UDPClient.
-
-class PartialMountClient:
-
- # This method is called by Client.__init__ to initialize
- # self.packer and self.unpacker
- def addpackers(self):
- self.packer = MountPacker()
- self.unpacker = MountUnpacker('')
-
- # This method is called by Client.__init__ to bind the socket
- # to a particular network interface and port. We use the
- # default network interface, but if we're running as root,
- # we want to bind to a reserved port
- def bindsocket(self):
- import os
- try:
- uid = os.getuid()
- except AttributeError:
- uid = 1
- if uid == 0:
- port = rpc.bindresvport(self.sock, '')
- # 'port' is not used
- else:
- self.sock.bind(('', 0))
-
- # This function is called to cough up a suitable
- # authentication object for a call to procedure 'proc'.
- def mkcred(self):
- if self.cred is None:
- self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default()
- return self.cred
-
- # The methods Mnt, Dump etc. each implement one Remote
- # Procedure Call. This is done by calling self.make_call()
- # with as arguments:
- #
- # - the procedure number
- # - the arguments (or None)
- # - the "packer" function for the arguments (or None)
- # - the "unpacker" function for the return value (or None)
- #
- # The packer and unpacker function, if not None, *must* be
- # methods of self.packer and self.unpacker, respectively.
- # A value of None means that there are no arguments or is no
- # return value, respectively.
- #
- # The return value from make_call() is the return value from
- # the remote procedure call, as unpacked by the "unpacker"
- # function, or None if the unpacker function is None.
- #
- # (Even if you expect a result of None, you should still
- # return the return value from make_call(), since this may be
- # needed by a broadcasting version of the class.)
- #
- # If the call fails, make_call() raises an exception
- # (this includes time-outs and invalid results).
- #
- # Note that (at least with the UDP protocol) there is no
- # guarantee that a call is executed at most once. When you do
- # get a reply, you know it has been executed at least once;
- # when you don't get a reply, you know nothing.
-
- def Mnt(self, directory):
- return self.make_call(1, directory, \
- self.packer.pack_string, \
- self.unpacker.unpack_fhstatus)
-
- def Dump(self):
- return self.make_call(2, None, \
- None, self.unpacker.unpack_mountlist)
-
- def Umnt(self, directory):
- return self.make_call(3, directory, \
- self.packer.pack_string, None)
-
- def Umntall(self):
- return self.make_call(4, None, None, None)
-
- def Export(self):
- return self.make_call(5, None, \
- None, self.unpacker.unpack_exportlist)
-
-
-# We turn the partial Mount client into a full one for either protocol
-# by use of multiple inheritance. (In general, when class C has base
-# classes B1...Bn, if x is an instance of class C, methods of x are
-# searched first in C, then in B1, then in B2, ..., finally in Bn.)
-
-class TCPMountClient(PartialMountClient, TCPClient):
-
- def __init__(self, host):
- TCPClient.__init__(self, host, MOUNTPROG, MOUNTVERS)
-
-
-class UDPMountClient(PartialMountClient, UDPClient):
-
- def __init__(self, host):
- UDPClient.__init__(self, host, MOUNTPROG, MOUNTVERS)
-
-
-# A little test program for the Mount client. This takes a host as
-# command line argument (default the local machine), prints its export
-# list, and attempts to mount and unmount each exported files system.
-# An optional first argument of -t or -u specifies the protocol to use
-# (TCP or UDP), default is UDP.
-
-def test():
- import sys
- if sys.argv[1:] and sys.argv[1] == '-t':
- C = TCPMountClient
- del sys.argv[1]
- elif sys.argv[1:] and sys.argv[1] == '-u':
- C = UDPMountClient
- del sys.argv[1]
- else:
- C = UDPMountClient
- if sys.argv[1:]: host = sys.argv[1]
- else: host = ''
- mcl = C(host)
- list = mcl.Export()
- for item in list:
- print item
- try:
- mcl.Mnt(item[0])
- except:
- print 'Sorry'
- continue
- mcl.Umnt(item[0])
diff --git a/Demo/rpc/nfsclient.py b/Demo/rpc/nfsclient.py
deleted file mode 100644
index dc91491..0000000
--- a/Demo/rpc/nfsclient.py
+++ /dev/null
@@ -1,201 +0,0 @@
-# NFS RPC client -- RFC 1094
-
-# XXX This is not yet complete.
-# XXX Only GETATTR, SETTTR, LOOKUP and READDIR are supported.
-
-# (See mountclient.py for some hints on how to write RPC clients in
-# Python in general)
-
-import rpc
-from rpc import UDPClient, TCPClient
-from mountclient import FHSIZE, MountPacker, MountUnpacker
-
-NFS_PROGRAM = 100003
-NFS_VERSION = 2
-
-# enum stat
-NFS_OK = 0
-# (...many error values...)
-
-# enum ftype
-NFNON = 0
-NFREG = 1
-NFDIR = 2
-NFBLK = 3
-NFCHR = 4
-NFLNK = 5
-
-
-class NFSPacker(MountPacker):
-
- def pack_sattrargs(self, sa):
- file, attributes = sa
- self.pack_fhandle(file)
- self.pack_sattr(attributes)
-
- def pack_sattr(self, sa):
- mode, uid, gid, size, atime, mtime = sa
- self.pack_uint(mode)
- self.pack_uint(uid)
- self.pack_uint(gid)
- self.pack_uint(size)
- self.pack_timeval(atime)
- self.pack_timeval(mtime)
-
- def pack_diropargs(self, da):
- dir, name = da
- self.pack_fhandle(dir)
- self.pack_string(name)
-
- def pack_readdirargs(self, ra):
- dir, cookie, count = ra
- self.pack_fhandle(dir)
- self.pack_uint(cookie)
- self.pack_uint(count)
-
- def pack_timeval(self, tv):
- secs, usecs = tv
- self.pack_uint(secs)
- self.pack_uint(usecs)
-
-
-class NFSUnpacker(MountUnpacker):
-
- def unpack_readdirres(self):
- status = self.unpack_enum()
- if status == NFS_OK:
- entries = self.unpack_list(self.unpack_entry)
- eof = self.unpack_bool()
- rest = (entries, eof)
- else:
- rest = None
- return (status, rest)
-
- def unpack_entry(self):
- fileid = self.unpack_uint()
- name = self.unpack_string()
- cookie = self.unpack_uint()
- return (fileid, name, cookie)
-
- def unpack_diropres(self):
- status = self.unpack_enum()
- if status == NFS_OK:
- fh = self.unpack_fhandle()
- fa = self.unpack_fattr()
- rest = (fh, fa)
- else:
- rest = None
- return (status, rest)
-
- def unpack_attrstat(self):
- status = self.unpack_enum()
- if status == NFS_OK:
- attributes = self.unpack_fattr()
- else:
- attributes = None
- return status, attributes
-
- def unpack_fattr(self):
- type = self.unpack_enum()
- mode = self.unpack_uint()
- nlink = self.unpack_uint()
- uid = self.unpack_uint()
- gid = self.unpack_uint()
- size = self.unpack_uint()
- blocksize = self.unpack_uint()
- rdev = self.unpack_uint()
- blocks = self.unpack_uint()
- fsid = self.unpack_uint()
- fileid = self.unpack_uint()
- atime = self.unpack_timeval()
- mtime = self.unpack_timeval()
- ctime = self.unpack_timeval()
- return (type, mode, nlink, uid, gid, size, blocksize, \
- rdev, blocks, fsid, fileid, atime, mtime, ctime)
-
- def unpack_timeval(self):
- secs = self.unpack_uint()
- usecs = self.unpack_uint()
- return (secs, usecs)
-
-
-class NFSClient(UDPClient):
-
- def __init__(self, host):
- UDPClient.__init__(self, host, NFS_PROGRAM, NFS_VERSION)
-
- def addpackers(self):
- self.packer = NFSPacker()
- self.unpacker = NFSUnpacker('')
-
- def mkcred(self):
- if self.cred is None:
- self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default()
- return self.cred
-
- def Getattr(self, fh):
- return self.make_call(1, fh, \
- self.packer.pack_fhandle, \
- self.unpacker.unpack_attrstat)
-
- def Setattr(self, sa):
- return self.make_call(2, sa, \
- self.packer.pack_sattrargs, \
- self.unpacker.unpack_attrstat)
-
- # Root() is obsolete
-
- def Lookup(self, da):
- return self.make_call(4, da, \
- self.packer.pack_diropargs, \
- self.unpacker.unpack_diropres)
-
- # ...
-
- def Readdir(self, ra):
- return self.make_call(16, ra, \
- self.packer.pack_readdirargs, \
- self.unpacker.unpack_readdirres)
-
- # Shorthand to get the entire contents of a directory
- def Listdir(self, dir):
- list = []
- ra = (dir, 0, 2000)
- while 1:
- (status, rest) = self.Readdir(ra)
- if status <> NFS_OK:
- break
- entries, eof = rest
- last_cookie = None
- for fileid, name, cookie in entries:
- list.append((fileid, name))
- last_cookie = cookie
- if eof or last_cookie is None:
- break
- ra = (ra[0], last_cookie, ra[2])
- return list
-
-
-def test():
- import sys
- if sys.argv[1:]: host = sys.argv[1]
- else: host = ''
- if sys.argv[2:]: filesys = sys.argv[2]
- else: filesys = None
- from mountclient import UDPMountClient, TCPMountClient
- mcl = TCPMountClient(host)
- if filesys is None:
- list = mcl.Export()
- for item in list:
- print item
- return
- sf = mcl.Mnt(filesys)
- print sf
- fh = sf[1]
- if fh:
- ncl = NFSClient(host)
- attrstat = ncl.Getattr(fh)
- print attrstat
- list = ncl.Listdir(fh)
- for item in list: print item
- mcl.Umnt(filesys)
diff --git a/Demo/rpc/rnusersclient.py b/Demo/rpc/rnusersclient.py
deleted file mode 100644
index 1f3a882..0000000
--- a/Demo/rpc/rnusersclient.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# Remote nusers client interface
-
-import rpc
-from rpc import Packer, Unpacker, UDPClient, BroadcastUDPClient
-
-
-class RnusersPacker(Packer):
- def pack_utmp(self, ui):
- ut_line, ut_name, ut_host, ut_time = utmp
- self.pack_string(ut_line)
- self.pack_string(ut_name)
- self.pack_string(ut_host)
- self.pack_int(ut_time)
- def pack_utmpidle(self, ui):
- ui_itmp, ui_idle = ui
- self.pack_utmp(ui_utmp)
- self.pack_uint(ui_idle)
- def pack_utmpidlearr(self, list):
- self.pack_array(list, self.pack_itmpidle)
-
-
-class RnusersUnpacker(Unpacker):
- def unpack_utmp(self):
- ut_line = self.unpack_string()
- ut_name = self.unpack_string()
- ut_host = self.unpack_string()
- ut_time = self.unpack_int()
- return ut_line, ut_name, ut_host, ut_time
- def unpack_utmpidle(self):
- ui_utmp = self.unpack_utmp()
- ui_idle = self.unpack_uint()
- return ui_utmp, ui_idle
- def unpack_utmpidlearr(self):
- return self.unpack_array(self.unpack_utmpidle)
-
-
-class PartialRnusersClient:
-
- def addpackers(self):
- self.packer = RnusersPacker()
- self.unpacker = RnusersUnpacker('')
-
- def Num(self):
- return self.make_call(1, None, None, self.unpacker.unpack_int)
-
- def Names(self):
- return self.make_call(2, None, \
- None, self.unpacker.unpack_utmpidlearr)
-
- def Allnames(self):
- return self.make_call(3, None, \
- None, self.unpacker.unpack_utmpidlearr)
-
-
-class RnusersClient(PartialRnusersClient, UDPClient):
-
- def __init__(self, host):
- UDPClient.__init__(self, host, 100002, 2)
-
-
-class BroadcastRnusersClient(PartialRnusersClient, BroadcastUDPClient):
-
- def __init__(self, bcastaddr):
- BroadcastUDPClient.__init__(self, bcastaddr, 100002, 2)
-
-
-def test():
- import sys
- if not sys.argv[1:]:
- testbcast()
- return
- else:
- host = sys.argv[1]
- c = RnusersClient(host)
- list = c.Names()
- for (line, name, host, time), idle in list:
- line = strip0(line)
- name = strip0(name)
- host = strip0(host)
- print "%r %r %r %s %s" % (name, host, line, time, idle)
-
-def testbcast():
- c = BroadcastRnusersClient('<broadcast>')
- def listit(list, fromaddr):
- host, port = fromaddr
- print host + '\t:',
- for (line, name, host, time), idle in list:
- print strip0(name),
- print
- c.set_reply_handler(listit)
- all = c.Names()
- print 'Total Count:', len(all)
-
-def strip0(s):
- while s and s[-1] == '\0': s = s[:-1]
- return s
-
-test()
diff --git a/Demo/rpc/rpc.py b/Demo/rpc/rpc.py
deleted file mode 100644
index 08ef2fb..0000000
--- a/Demo/rpc/rpc.py
+++ /dev/null
@@ -1,893 +0,0 @@
-# Sun RPC version 2 -- RFC1057.
-
-# XXX There should be separate exceptions for the various reasons why
-# XXX an RPC can fail, rather than using RuntimeError for everything
-
-# XXX Need to use class based exceptions rather than string exceptions
-
-# XXX The UDP version of the protocol resends requests when it does
-# XXX not receive a timely reply -- use only for idempotent calls!
-
-# XXX There is no provision for call timeout on TCP connections
-
-import xdr
-import socket
-import os
-
-RPCVERSION = 2
-
-CALL = 0
-REPLY = 1
-
-AUTH_NULL = 0
-AUTH_UNIX = 1
-AUTH_SHORT = 2
-AUTH_DES = 3
-
-MSG_ACCEPTED = 0
-MSG_DENIED = 1
-
-SUCCESS = 0 # RPC executed successfully
-PROG_UNAVAIL = 1 # remote hasn't exported program
-PROG_MISMATCH = 2 # remote can't support version #
-PROC_UNAVAIL = 3 # program can't support procedure
-GARBAGE_ARGS = 4 # procedure can't decode params
-
-RPC_MISMATCH = 0 # RPC version number != 2
-AUTH_ERROR = 1 # remote can't authenticate caller
-
-AUTH_BADCRED = 1 # bad credentials (seal broken)
-AUTH_REJECTEDCRED = 2 # client must begin new session
-AUTH_BADVERF = 3 # bad verifier (seal broken)
-AUTH_REJECTEDVERF = 4 # verifier expired or replayed
-AUTH_TOOWEAK = 5 # rejected for security reasons
-
-
-class Packer(xdr.Packer):
-
- def pack_auth(self, auth):
- flavor, stuff = auth
- self.pack_enum(flavor)
- self.pack_opaque(stuff)
-
- def pack_auth_unix(self, stamp, machinename, uid, gid, gids):
- self.pack_uint(stamp)
- self.pack_string(machinename)
- self.pack_uint(uid)
- self.pack_uint(gid)
- self.pack_uint(len(gids))
- for i in gids:
- self.pack_uint(i)
-
- def pack_callheader(self, xid, prog, vers, proc, cred, verf):
- self.pack_uint(xid)
- self.pack_enum(CALL)
- self.pack_uint(RPCVERSION)
- self.pack_uint(prog)
- self.pack_uint(vers)
- self.pack_uint(proc)
- self.pack_auth(cred)
- self.pack_auth(verf)
- # Caller must add procedure-specific part of call
-
- def pack_replyheader(self, xid, verf):
- self.pack_uint(xid)
- self.pack_enum(REPLY)
- self.pack_uint(MSG_ACCEPTED)
- self.pack_auth(verf)
- self.pack_enum(SUCCESS)
- # Caller must add procedure-specific part of reply
-
-
-# Exceptions
-class BadRPCFormat(Exception): pass
-class BadRPCVersion(Exception): pass
-class GarbageArgs(Exception): pass
-
-class Unpacker(xdr.Unpacker):
-
- def unpack_auth(self):
- flavor = self.unpack_enum()
- stuff = self.unpack_opaque()
- return (flavor, stuff)
-
- def unpack_callheader(self):
- xid = self.unpack_uint()
- temp = self.unpack_enum()
- if temp != CALL:
- raise BadRPCFormat, 'no CALL but %r' % (temp,)
- temp = self.unpack_uint()
- if temp != RPCVERSION:
- raise BadRPCVersion, 'bad RPC version %r' % (temp,)
- prog = self.unpack_uint()
- vers = self.unpack_uint()
- proc = self.unpack_uint()
- cred = self.unpack_auth()
- verf = self.unpack_auth()
- return xid, prog, vers, proc, cred, verf
- # Caller must add procedure-specific part of call
-
- def unpack_replyheader(self):
- xid = self.unpack_uint()
- mtype = self.unpack_enum()
- if mtype != REPLY:
- raise RuntimeError, 'no REPLY but %r' % (mtype,)
- stat = self.unpack_enum()
- if stat == MSG_DENIED:
- stat = self.unpack_enum()
- if stat == RPC_MISMATCH:
- low = self.unpack_uint()
- high = self.unpack_uint()
- raise RuntimeError, \
- 'MSG_DENIED: RPC_MISMATCH: %r' % ((low, high),)
- if stat == AUTH_ERROR:
- stat = self.unpack_uint()
- raise RuntimeError, \
- 'MSG_DENIED: AUTH_ERROR: %r' % (stat,)
- raise RuntimeError, 'MSG_DENIED: %r' % (stat,)
- if stat != MSG_ACCEPTED:
- raise RuntimeError, \
- 'Neither MSG_DENIED nor MSG_ACCEPTED: %r' % (stat,)
- verf = self.unpack_auth()
- stat = self.unpack_enum()
- if stat == PROG_UNAVAIL:
- raise RuntimeError, 'call failed: PROG_UNAVAIL'
- if stat == PROG_MISMATCH:
- low = self.unpack_uint()
- high = self.unpack_uint()
- raise RuntimeError, \
- 'call failed: PROG_MISMATCH: %r' % ((low, high),)
- if stat == PROC_UNAVAIL:
- raise RuntimeError, 'call failed: PROC_UNAVAIL'
- if stat == GARBAGE_ARGS:
- raise RuntimeError, 'call failed: GARBAGE_ARGS'
- if stat != SUCCESS:
- raise RuntimeError, 'call failed: %r' % (stat,)
- return xid, verf
- # Caller must get procedure-specific part of reply
-
-
-# Subroutines to create opaque authentication objects
-
-def make_auth_null():
- return ''
-
-def make_auth_unix(seed, host, uid, gid, groups):
- p = Packer()
- p.pack_auth_unix(seed, host, uid, gid, groups)
- return p.get_buf()
-
-def make_auth_unix_default():
- try:
- from os import getuid, getgid
- uid = getuid()
- gid = getgid()
- except ImportError:
- uid = gid = 0
- import time
- return make_auth_unix(int(time.time()-unix_epoch()), \
- socket.gethostname(), uid, gid, [])
-
-_unix_epoch = -1
-def unix_epoch():
- """Very painful calculation of when the Unix Epoch is.
-
- This is defined as the return value of time.time() on Jan 1st,
- 1970, 00:00:00 GMT.
-
- On a Unix system, this should always return 0.0. On a Mac, the
- calculations are needed -- and hard because of integer overflow
- and other limitations.
-
- """
- global _unix_epoch
- if _unix_epoch >= 0: return _unix_epoch
- import time
- now = time.time()
- localt = time.localtime(now) # (y, m, d, hh, mm, ss, ..., ..., ...)
- gmt = time.gmtime(now)
- offset = time.mktime(localt) - time.mktime(gmt)
- y, m, d, hh, mm, ss = 1970, 1, 1, 0, 0, 0
- offset, ss = divmod(ss + offset, 60)
- offset, mm = divmod(mm + offset, 60)
- offset, hh = divmod(hh + offset, 24)
- d = d + offset
- _unix_epoch = time.mktime((y, m, d, hh, mm, ss, 0, 0, 0))
- print "Unix epoch:", time.ctime(_unix_epoch)
- return _unix_epoch
-
-
-# Common base class for clients
-
-class Client:
-
- def __init__(self, host, prog, vers, port):
- self.host = host
- self.prog = prog
- self.vers = vers
- self.port = port
- self.makesocket() # Assigns to self.sock
- self.bindsocket()
- self.connsocket()
- self.lastxid = 0 # XXX should be more random?
- self.addpackers()
- self.cred = None
- self.verf = None
-
- def close(self):
- self.sock.close()
-
- def makesocket(self):
- # This MUST be overridden
- raise RuntimeError, 'makesocket not defined'
-
- def connsocket(self):
- # Override this if you don't want/need a connection
- self.sock.connect((self.host, self.port))
-
- def bindsocket(self):
- # Override this to bind to a different port (e.g. reserved)
- self.sock.bind(('', 0))
-
- def addpackers(self):
- # Override this to use derived classes from Packer/Unpacker
- self.packer = Packer()
- self.unpacker = Unpacker('')
-
- def make_call(self, proc, args, pack_func, unpack_func):
- # Don't normally override this (but see Broadcast)
- if pack_func is None and args is not None:
- raise TypeError, 'non-null args with null pack_func'
- self.start_call(proc)
- if pack_func:
- pack_func(args)
- self.do_call()
- if unpack_func:
- result = unpack_func()
- else:
- result = None
- self.unpacker.done()
- return result
-
- def start_call(self, proc):
- # Don't override this
- self.lastxid = xid = self.lastxid + 1
- cred = self.mkcred()
- verf = self.mkverf()
- p = self.packer
- p.reset()
- p.pack_callheader(xid, self.prog, self.vers, proc, cred, verf)
-
- def do_call(self):
- # This MUST be overridden
- raise RuntimeError, 'do_call not defined'
-
- def mkcred(self):
- # Override this to use more powerful credentials
- if self.cred is None:
- self.cred = (AUTH_NULL, make_auth_null())
- return self.cred
-
- def mkverf(self):
- # Override this to use a more powerful verifier
- if self.verf is None:
- self.verf = (AUTH_NULL, make_auth_null())
- return self.verf
-
- def call_0(self): # Procedure 0 is always like this
- return self.make_call(0, None, None, None)
-
-
-# Record-Marking standard support
-
-def sendfrag(sock, last, frag):
- x = len(frag)
- if last: x = x | 0x80000000L
- header = (chr(int(x>>24 & 0xff)) + chr(int(x>>16 & 0xff)) + \
- chr(int(x>>8 & 0xff)) + chr(int(x & 0xff)))
- sock.send(header + frag)
-
-def sendrecord(sock, record):
- sendfrag(sock, 1, record)
-
-def recvfrag(sock):
- header = sock.recv(4)
- if len(header) < 4:
- raise EOFError
- x = long(ord(header[0]))<<24 | ord(header[1])<<16 | \
- ord(header[2])<<8 | ord(header[3])
- last = ((x & 0x80000000) != 0)
- n = int(x & 0x7fffffff)
- frag = ''
- while n > 0:
- buf = sock.recv(n)
- if not buf: raise EOFError
- n = n - len(buf)
- frag = frag + buf
- return last, frag
-
-def recvrecord(sock):
- record = ''
- last = 0
- while not last:
- last, frag = recvfrag(sock)
- record = record + frag
- return record
-
-
-# Try to bind to a reserved port (must be root)
-
-last_resv_port_tried = None
-def bindresvport(sock, host):
- global last_resv_port_tried
- FIRST, LAST = 600, 1024 # Range of ports to try
- if last_resv_port_tried is None:
- import os
- last_resv_port_tried = FIRST + os.getpid() % (LAST-FIRST)
- for i in range(last_resv_port_tried, LAST) + \
- range(FIRST, last_resv_port_tried):
- last_resv_port_tried = i
- try:
- sock.bind((host, i))
- return last_resv_port_tried
- except socket.error, (errno, msg):
- if errno != 114:
- raise socket.error, (errno, msg)
- raise RuntimeError, 'can\'t assign reserved port'
-
-
-# Client using TCP to a specific port
-
-class RawTCPClient(Client):
-
- def makesocket(self):
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
- def do_call(self):
- call = self.packer.get_buf()
- sendrecord(self.sock, call)
- reply = recvrecord(self.sock)
- u = self.unpacker
- u.reset(reply)
- xid, verf = u.unpack_replyheader()
- if xid != self.lastxid:
- # Can't really happen since this is TCP...
- raise RuntimeError, 'wrong xid in reply %r instead of %r' % (
- xid, self.lastxid)
-
-
-# Client using UDP to a specific port
-
-class RawUDPClient(Client):
-
- def makesocket(self):
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-
- def do_call(self):
- call = self.packer.get_buf()
- self.sock.send(call)
- try:
- from select import select
- except ImportError:
- print 'WARNING: select not found, RPC may hang'
- select = None
- BUFSIZE = 8192 # Max UDP buffer size
- timeout = 1
- count = 5
- while 1:
- r, w, x = [self.sock], [], []
- if select:
- r, w, x = select(r, w, x, timeout)
- if self.sock not in r:
- count = count - 1
- if count < 0: raise RuntimeError, 'timeout'
- if timeout < 25: timeout = timeout *2
-## print 'RESEND', timeout, count
- self.sock.send(call)
- continue
- reply = self.sock.recv(BUFSIZE)
- u = self.unpacker
- u.reset(reply)
- xid, verf = u.unpack_replyheader()
- if xid != self.lastxid:
-## print 'BAD xid'
- continue
- break
-
-
-# Client using UDP broadcast to a specific port
-
-class RawBroadcastUDPClient(RawUDPClient):
-
- def __init__(self, bcastaddr, prog, vers, port):
- RawUDPClient.__init__(self, bcastaddr, prog, vers, port)
- self.reply_handler = None
- self.timeout = 30
-
- def connsocket(self):
- # Don't connect -- use sendto
- self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
-
- def set_reply_handler(self, reply_handler):
- self.reply_handler = reply_handler
-
- def set_timeout(self, timeout):
- self.timeout = timeout # Use None for infinite timeout
-
- def make_call(self, proc, args, pack_func, unpack_func):
- if pack_func is None and args is not None:
- raise TypeError, 'non-null args with null pack_func'
- self.start_call(proc)
- if pack_func:
- pack_func(args)
- call = self.packer.get_buf()
- self.sock.sendto(call, (self.host, self.port))
- try:
- from select import select
- except ImportError:
- print 'WARNING: select not found, broadcast will hang'
- select = None
- BUFSIZE = 8192 # Max UDP buffer size (for reply)
- replies = []
- if unpack_func is None:
- def dummy(): pass
- unpack_func = dummy
- while 1:
- r, w, x = [self.sock], [], []
- if select:
- if self.timeout is None:
- r, w, x = select(r, w, x)
- else:
- r, w, x = select(r, w, x, self.timeout)
- if self.sock not in r:
- break
- reply, fromaddr = self.sock.recvfrom(BUFSIZE)
- u = self.unpacker
- u.reset(reply)
- xid, verf = u.unpack_replyheader()
- if xid != self.lastxid:
-## print 'BAD xid'
- continue
- reply = unpack_func()
- self.unpacker.done()
- replies.append((reply, fromaddr))
- if self.reply_handler:
- self.reply_handler(reply, fromaddr)
- return replies
-
-
-# Port mapper interface
-
-# Program number, version and (fixed!) port number
-PMAP_PROG = 100000
-PMAP_VERS = 2
-PMAP_PORT = 111
-
-# Procedure numbers
-PMAPPROC_NULL = 0 # (void) -> void
-PMAPPROC_SET = 1 # (mapping) -> bool
-PMAPPROC_UNSET = 2 # (mapping) -> bool
-PMAPPROC_GETPORT = 3 # (mapping) -> unsigned int
-PMAPPROC_DUMP = 4 # (void) -> pmaplist
-PMAPPROC_CALLIT = 5 # (call_args) -> call_result
-
-# A mapping is (prog, vers, prot, port) and prot is one of:
-
-IPPROTO_TCP = 6
-IPPROTO_UDP = 17
-
-# A pmaplist is a variable-length list of mappings, as follows:
-# either (1, mapping, pmaplist) or (0).
-
-# A call_args is (prog, vers, proc, args) where args is opaque;
-# a call_result is (port, res) where res is opaque.
-
-
-class PortMapperPacker(Packer):
-
- def pack_mapping(self, mapping):
- prog, vers, prot, port = mapping
- self.pack_uint(prog)
- self.pack_uint(vers)
- self.pack_uint(prot)
- self.pack_uint(port)
-
- def pack_pmaplist(self, list):
- self.pack_list(list, self.pack_mapping)
-
- def pack_call_args(self, ca):
- prog, vers, proc, args = ca
- self.pack_uint(prog)
- self.pack_uint(vers)
- self.pack_uint(proc)
- self.pack_opaque(args)
-
-
-class PortMapperUnpacker(Unpacker):
-
- def unpack_mapping(self):
- prog = self.unpack_uint()
- vers = self.unpack_uint()
- prot = self.unpack_uint()
- port = self.unpack_uint()
- return prog, vers, prot, port
-
- def unpack_pmaplist(self):
- return self.unpack_list(self.unpack_mapping)
-
- def unpack_call_result(self):
- port = self.unpack_uint()
- res = self.unpack_opaque()
- return port, res
-
-
-class PartialPortMapperClient:
-
- def addpackers(self):
- self.packer = PortMapperPacker()
- self.unpacker = PortMapperUnpacker('')
-
- def Set(self, mapping):
- return self.make_call(PMAPPROC_SET, mapping, \
- self.packer.pack_mapping, \
- self.unpacker.unpack_uint)
-
- def Unset(self, mapping):
- return self.make_call(PMAPPROC_UNSET, mapping, \
- self.packer.pack_mapping, \
- self.unpacker.unpack_uint)
-
- def Getport(self, mapping):
- return self.make_call(PMAPPROC_GETPORT, mapping, \
- self.packer.pack_mapping, \
- self.unpacker.unpack_uint)
-
- def Dump(self):
- return self.make_call(PMAPPROC_DUMP, None, \
- None, \
- self.unpacker.unpack_pmaplist)
-
- def Callit(self, ca):
- return self.make_call(PMAPPROC_CALLIT, ca, \
- self.packer.pack_call_args, \
- self.unpacker.unpack_call_result)
-
-
-class TCPPortMapperClient(PartialPortMapperClient, RawTCPClient):
-
- def __init__(self, host):
- RawTCPClient.__init__(self, \
- host, PMAP_PROG, PMAP_VERS, PMAP_PORT)
-
-
-class UDPPortMapperClient(PartialPortMapperClient, RawUDPClient):
-
- def __init__(self, host):
- RawUDPClient.__init__(self, \
- host, PMAP_PROG, PMAP_VERS, PMAP_PORT)
-
-
-class BroadcastUDPPortMapperClient(PartialPortMapperClient, \
- RawBroadcastUDPClient):
-
- def __init__(self, bcastaddr):
- RawBroadcastUDPClient.__init__(self, \
- bcastaddr, PMAP_PROG, PMAP_VERS, PMAP_PORT)
-
-
-# Generic clients that find their server through the Port mapper
-
-class TCPClient(RawTCPClient):
-
- def __init__(self, host, prog, vers):
- pmap = TCPPortMapperClient(host)
- port = pmap.Getport((prog, vers, IPPROTO_TCP, 0))
- pmap.close()
- if port == 0:
- raise RuntimeError, 'program not registered'
- RawTCPClient.__init__(self, host, prog, vers, port)
-
-
-class UDPClient(RawUDPClient):
-
- def __init__(self, host, prog, vers):
- pmap = UDPPortMapperClient(host)
- port = pmap.Getport((prog, vers, IPPROTO_UDP, 0))
- pmap.close()
- if port == 0:
- raise RuntimeError, 'program not registered'
- RawUDPClient.__init__(self, host, prog, vers, port)
-
-
-class BroadcastUDPClient(Client):
-
- def __init__(self, bcastaddr, prog, vers):
- self.pmap = BroadcastUDPPortMapperClient(bcastaddr)
- self.pmap.set_reply_handler(self.my_reply_handler)
- self.prog = prog
- self.vers = vers
- self.user_reply_handler = None
- self.addpackers()
-
- def close(self):
- self.pmap.close()
-
- def set_reply_handler(self, reply_handler):
- self.user_reply_handler = reply_handler
-
- def set_timeout(self, timeout):
- self.pmap.set_timeout(timeout)
-
- def my_reply_handler(self, reply, fromaddr):
- port, res = reply
- self.unpacker.reset(res)
- result = self.unpack_func()
- self.unpacker.done()
- self.replies.append((result, fromaddr))
- if self.user_reply_handler is not None:
- self.user_reply_handler(result, fromaddr)
-
- def make_call(self, proc, args, pack_func, unpack_func):
- self.packer.reset()
- if pack_func:
- pack_func(args)
- if unpack_func is None:
- def dummy(): pass
- self.unpack_func = dummy
- else:
- self.unpack_func = unpack_func
- self.replies = []
- packed_args = self.packer.get_buf()
- dummy_replies = self.pmap.Callit( \
- (self.prog, self.vers, proc, packed_args))
- return self.replies
-
-
-# Server classes
-
-# These are not symmetric to the Client classes
-# XXX No attempt is made to provide authorization hooks yet
-
-class Server:
-
- def __init__(self, host, prog, vers, port):
- self.host = host # Should normally be '' for default interface
- self.prog = prog
- self.vers = vers
- self.port = port # Should normally be 0 for random port
- self.makesocket() # Assigns to self.sock and self.prot
- self.bindsocket()
- self.host, self.port = self.sock.getsockname()
- self.addpackers()
-
- def register(self):
- mapping = self.prog, self.vers, self.prot, self.port
- p = TCPPortMapperClient(self.host)
- if not p.Set(mapping):
- raise RuntimeError, 'register failed'
-
- def unregister(self):
- mapping = self.prog, self.vers, self.prot, self.port
- p = TCPPortMapperClient(self.host)
- if not p.Unset(mapping):
- raise RuntimeError, 'unregister failed'
-
- def handle(self, call):
- # Don't use unpack_header but parse the header piecewise
- # XXX I have no idea if I am using the right error responses!
- self.unpacker.reset(call)
- self.packer.reset()
- xid = self.unpacker.unpack_uint()
- self.packer.pack_uint(xid)
- temp = self.unpacker.unpack_enum()
- if temp != CALL:
- return None # Not worthy of a reply
- self.packer.pack_uint(REPLY)
- temp = self.unpacker.unpack_uint()
- if temp != RPCVERSION:
- self.packer.pack_uint(MSG_DENIED)
- self.packer.pack_uint(RPC_MISMATCH)
- self.packer.pack_uint(RPCVERSION)
- self.packer.pack_uint(RPCVERSION)
- return self.packer.get_buf()
- self.packer.pack_uint(MSG_ACCEPTED)
- self.packer.pack_auth((AUTH_NULL, make_auth_null()))
- prog = self.unpacker.unpack_uint()
- if prog != self.prog:
- self.packer.pack_uint(PROG_UNAVAIL)
- return self.packer.get_buf()
- vers = self.unpacker.unpack_uint()
- if vers != self.vers:
- self.packer.pack_uint(PROG_MISMATCH)
- self.packer.pack_uint(self.vers)
- self.packer.pack_uint(self.vers)
- return self.packer.get_buf()
- proc = self.unpacker.unpack_uint()
- methname = 'handle_' + repr(proc)
- try:
- meth = getattr(self, methname)
- except AttributeError:
- self.packer.pack_uint(PROC_UNAVAIL)
- return self.packer.get_buf()
- cred = self.unpacker.unpack_auth()
- verf = self.unpacker.unpack_auth()
- try:
- meth() # Unpack args, call turn_around(), pack reply
- except (EOFError, GarbageArgs):
- # Too few or too many arguments
- self.packer.reset()
- self.packer.pack_uint(xid)
- self.packer.pack_uint(REPLY)
- self.packer.pack_uint(MSG_ACCEPTED)
- self.packer.pack_auth((AUTH_NULL, make_auth_null()))
- self.packer.pack_uint(GARBAGE_ARGS)
- return self.packer.get_buf()
-
- def turn_around(self):
- try:
- self.unpacker.done()
- except RuntimeError:
- raise GarbageArgs
- self.packer.pack_uint(SUCCESS)
-
- def handle_0(self): # Handle NULL message
- self.turn_around()
-
- def makesocket(self):
- # This MUST be overridden
- raise RuntimeError, 'makesocket not defined'
-
- def bindsocket(self):
- # Override this to bind to a different port (e.g. reserved)
- self.sock.bind((self.host, self.port))
-
- def addpackers(self):
- # Override this to use derived classes from Packer/Unpacker
- self.packer = Packer()
- self.unpacker = Unpacker('')
-
-
-class TCPServer(Server):
-
- def makesocket(self):
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.prot = IPPROTO_TCP
-
- def loop(self):
- self.sock.listen(0)
- while 1:
- self.session(self.sock.accept())
-
- def session(self, connection):
- sock, (host, port) = connection
- while 1:
- try:
- call = recvrecord(sock)
- except EOFError:
- break
- except socket.error, msg:
- print 'socket error:', msg
- break
- reply = self.handle(call)
- if reply is not None:
- sendrecord(sock, reply)
-
- def forkingloop(self):
- # Like loop but uses forksession()
- self.sock.listen(0)
- while 1:
- self.forksession(self.sock.accept())
-
- def forksession(self, connection):
- # Like session but forks off a subprocess
- import os
- # Wait for deceased children
- try:
- while 1:
- pid, sts = os.waitpid(0, 1)
- except os.error:
- pass
- pid = None
- try:
- pid = os.fork()
- if pid: # Parent
- connection[0].close()
- return
- # Child
- self.session(connection)
- finally:
- # Make sure we don't fall through in the parent
- if pid == 0:
- os._exit(0)
-
-
-class UDPServer(Server):
-
- def makesocket(self):
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- self.prot = IPPROTO_UDP
-
- def loop(self):
- while 1:
- self.session()
-
- def session(self):
- call, host_port = self.sock.recvfrom(8192)
- reply = self.handle(call)
- if reply is not None:
- self.sock.sendto(reply, host_port)
-
-
-# Simple test program -- dump local portmapper status
-
-def test():
- pmap = UDPPortMapperClient('')
- list = pmap.Dump()
- list.sort()
- for prog, vers, prot, port in list:
- print prog, vers,
- if prot == IPPROTO_TCP: print 'tcp',
- elif prot == IPPROTO_UDP: print 'udp',
- else: print prot,
- print port
-
-
-# Test program for broadcast operation -- dump everybody's portmapper status
-
-def testbcast():
- import sys
- if sys.argv[1:]:
- bcastaddr = sys.argv[1]
- else:
- bcastaddr = '<broadcast>'
- def rh(reply, fromaddr):
- host, port = fromaddr
- print host + '\t' + repr(reply)
- pmap = BroadcastUDPPortMapperClient(bcastaddr)
- pmap.set_reply_handler(rh)
- pmap.set_timeout(5)
- replies = pmap.Getport((100002, 1, IPPROTO_UDP, 0))
-
-
-# Test program for server, with corresponding client
-# On machine A: python -c 'import rpc; rpc.testsvr()'
-# On machine B: python -c 'import rpc; rpc.testclt()' A
-# (A may be == B)
-
-def testsvr():
- # Simple test class -- proc 1 doubles its string argument as reply
- class S(UDPServer):
- def handle_1(self):
- arg = self.unpacker.unpack_string()
- self.turn_around()
- print 'RPC function 1 called, arg', repr(arg)
- self.packer.pack_string(arg + arg)
- #
- s = S('', 0x20000000, 1, 0)
- try:
- s.unregister()
- except RuntimeError, msg:
- print 'RuntimeError:', msg, '(ignored)'
- s.register()
- print 'Service started...'
- try:
- s.loop()
- finally:
- s.unregister()
- print 'Service interrupted.'
-
-
-def testclt():
- import sys
- if sys.argv[1:]: host = sys.argv[1]
- else: host = ''
- # Client for above server
- class C(UDPClient):
- def call_1(self, arg):
- return self.make_call(1, arg, \
- self.packer.pack_string, \
- self.unpacker.unpack_string)
- c = C(host, 0x20000000, 1)
- print 'making call...'
- reply = c.call_1('hello, world, ')
- print 'call returned', repr(reply)
diff --git a/Demo/rpc/test b/Demo/rpc/test
deleted file mode 100755
index ba220f2..0000000
--- a/Demo/rpc/test
+++ /dev/null
@@ -1,24 +0,0 @@
-: ${PYTHON=python}
-: ${SERVER=charon.cwi.nl}
-
-set -xe
-
-$PYTHON -c 'from rpc import test; test()'
-$PYTHON -c 'from rpc import test; test()' ${SERVER}
-
-$PYTHON -c 'from rpc import testsvr; testsvr()' &
-PID=$!
-sleep 2
-$PYTHON -c 'from rpc import testclt; testclt()'
-kill -2 $PID
-
-$PYTHON -c 'from mountclient import test; test()'
-$PYTHON -c 'from mountclient import test; test()' gatekeeper.dec.com
-
-$PYTHON -c 'from nfsclient import test; test()'
-$PYTHON -c 'from nfsclient import test; test()' gatekeeper.dec.com
-$PYTHON -c 'from nfsclient import test; test()' gatekeeper.dec.com /archive
-
-$PYTHON -c 'from rnusersclient import test; test()' ''
-
-$PYTHON -c 'from rpc import testbcast; testbcast()'
diff --git a/Demo/rpc/xdr.py b/Demo/rpc/xdr.py
deleted file mode 100644
index 041d51a..0000000
--- a/Demo/rpc/xdr.py
+++ /dev/null
@@ -1,200 +0,0 @@
-# Implement (a subset of) Sun XDR -- RFC1014.
-
-
-try:
- import struct
-except ImportError:
- struct = None
-
-
-Long = type(0L)
-
-
-class Packer:
-
- def __init__(self):
- self.reset()
-
- def reset(self):
- self.buf = ''
-
- def get_buf(self):
- return self.buf
-
- def pack_uint(self, x):
- self.buf = self.buf + \
- (chr(int(x>>24 & 0xff)) + chr(int(x>>16 & 0xff)) + \
- chr(int(x>>8 & 0xff)) + chr(int(x & 0xff)))
- if struct and struct.pack('l', 1) == '\0\0\0\1':
- def pack_uint(self, x):
- if type(x) == Long:
- x = int((x + 0x80000000L) % 0x100000000L \
- - 0x80000000L)
- self.buf = self.buf + struct.pack('l', x)
-
- pack_int = pack_uint
-
- pack_enum = pack_int
-
- def pack_bool(self, x):
- if x: self.buf = self.buf + '\0\0\0\1'
- else: self.buf = self.buf + '\0\0\0\0'
-
- def pack_uhyper(self, x):
- self.pack_uint(int(x>>32 & 0xffffffff))
- self.pack_uint(int(x & 0xffffffff))
-
- pack_hyper = pack_uhyper
-
- def pack_float(self, x):
- # XXX
- self.buf = self.buf + struct.pack('f', x)
-
- def pack_double(self, x):
- # XXX
- self.buf = self.buf + struct.pack('d', x)
-
- def pack_fstring(self, n, s):
- if n < 0:
- raise ValueError, 'fstring size must be nonnegative'
- n = ((n + 3)//4)*4
- data = s[:n]
- data = data + (n - len(data)) * '\0'
- self.buf = self.buf + data
-
- pack_fopaque = pack_fstring
-
- def pack_string(self, s):
- n = len(s)
- self.pack_uint(n)
- self.pack_fstring(n, s)
-
- pack_opaque = pack_string
-
- def pack_list(self, list, pack_item):
- for item in list:
- self.pack_uint(1)
- pack_item(item)
- self.pack_uint(0)
-
- def pack_farray(self, n, list, pack_item):
- if len(list) <> n:
- raise ValueError, 'wrong array size'
- for item in list:
- pack_item(item)
-
- def pack_array(self, list, pack_item):
- n = len(list)
- self.pack_uint(n)
- self.pack_farray(n, list, pack_item)
-
-
-class Unpacker:
-
- def __init__(self, data):
- self.reset(data)
-
- def reset(self, data):
- self.buf = data
- self.pos = 0
-
- def done(self):
- if self.pos < len(self.buf):
- raise RuntimeError, 'unextracted data remains'
-
- def unpack_uint(self):
- i = self.pos
- self.pos = j = i+4
- data = self.buf[i:j]
- if len(data) < 4:
- raise EOFError
- x = long(ord(data[0]))<<24 | ord(data[1])<<16 | \
- ord(data[2])<<8 | ord(data[3])
- # Return a Python long only if the value is not representable
- # as a nonnegative Python int
- if x < 0x80000000L: x = int(x)
- return x
- if struct and struct.unpack('l', '\0\0\0\1') == 1:
- def unpack_uint(self):
- i = self.pos
- self.pos = j = i+4
- data = self.buf[i:j]
- if len(data) < 4:
- raise EOFError
- return struct.unpack('l', data)
-
- def unpack_int(self):
- x = self.unpack_uint()
- if x >= 0x80000000L: x = x - 0x100000000L
- return int(x)
-
- unpack_enum = unpack_int
-
- unpack_bool = unpack_int
-
- def unpack_uhyper(self):
- hi = self.unpack_uint()
- lo = self.unpack_uint()
- return long(hi)<<32 | lo
-
- def unpack_hyper(self):
- x = self.unpack_uhyper()
- if x >= 0x8000000000000000L: x = x - 0x10000000000000000L
- return x
-
- def unpack_float(self):
- # XXX
- i = self.pos
- self.pos = j = i+4
- data = self.buf[i:j]
- if len(data) < 4:
- raise EOFError
- return struct.unpack('f', data)[0]
-
- def unpack_double(self):
- # XXX
- i = self.pos
- self.pos = j = i+8
- data = self.buf[i:j]
- if len(data) < 8:
- raise EOFError
- return struct.unpack('d', data)[0]
-
- def unpack_fstring(self, n):
- if n < 0:
- raise ValueError, 'fstring size must be nonnegative'
- i = self.pos
- j = i + (n+3)//4*4
- if j > len(self.buf):
- raise EOFError
- self.pos = j
- return self.buf[i:i+n]
-
- unpack_fopaque = unpack_fstring
-
- def unpack_string(self):
- n = self.unpack_uint()
- return self.unpack_fstring(n)
-
- unpack_opaque = unpack_string
-
- def unpack_list(self, unpack_item):
- list = []
- while 1:
- x = self.unpack_uint()
- if x == 0: break
- if x <> 1:
- raise RuntimeError, '0 or 1 expected, got %r' % (x, )
- item = unpack_item()
- list.append(item)
- return list
-
- def unpack_farray(self, n, unpack_item):
- list = []
- for i in range(n):
- list.append(unpack_item())
- return list
-
- def unpack_array(self, unpack_item):
- n = self.unpack_uint()
- return self.unpack_farray(n, unpack_item)
diff --git a/Demo/scripts/README b/Demo/scripts/README
deleted file mode 100644
index d19cc81..0000000
--- a/Demo/scripts/README
+++ /dev/null
@@ -1,22 +0,0 @@
-This directory contains a collection of executable Python scripts.
-
-See also the Tools/scripts directory!
-
-beer.py Print the classic 'bottles of beer' list
-eqfix.py Fix .py files to use the correct equality test operator
-fact.py Factorize numbers
-find-uname.py Search for Unicode characters using regexps
-from.py Summarize mailbox
-lpwatch.py Watch BSD line printer queues
-makedir.py Like mkdir -p
-markov.py Markov chain simulation of words or characters
-mboxconvert.py Convert MH or MMDF mailboxes to unix mailbox format
-morse.py Produce morse code (audible or on AIFF file)
-newslist.py List all newsgroups on a NNTP server as HTML pages
-pi.py Print all digits of pi -- given enough time and memory
-pp.py Emulate some Perl command line options
-primes.py Print prime numbers
-queens.py Dijkstra's solution to Wirth's "N Queens problem"
-script.py Equivalent to BSD script(1) -- by Steen Lumholt
-unbirthday.py Print unbirthday count
-update.py Update a bunch of files according to a script.
diff --git a/Demo/scripts/beer.py b/Demo/scripts/beer.py
deleted file mode 100755
index e331cc9..0000000
--- a/Demo/scripts/beer.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /usr/bin/env python
-
-# By GvR, demystified after a version by Fredrik Lundh.
-
-import sys
-
-n = 100
-if sys.argv[1:]:
- n = int(sys.argv[1])
-
-def bottle(n):
- if n == 0: return "no more bottles of beer"
- if n == 1: return "one bottle of beer"
- return str(n) + " bottles of beer"
-
-for i in range(n, 0, -1):
- print bottle(i), "on the wall,"
- print bottle(i) + "."
- print "Take one down, pass it around,"
- print bottle(i-1), "on the wall."
diff --git a/Demo/scripts/eqfix.py b/Demo/scripts/eqfix.py
deleted file mode 100755
index 35c43aa..0000000
--- a/Demo/scripts/eqfix.py
+++ /dev/null
@@ -1,198 +0,0 @@
-#! /usr/bin/env python
-
-# Fix Python source files to use the new equality test operator, i.e.,
-# if x = y: ...
-# is changed to
-# if x == y: ...
-# The script correctly tokenizes the Python program to reliably
-# distinguish between assignments and equality tests.
-#
-# Command line arguments are files or directories to be processed.
-# Directories are searched recursively for files whose name looks
-# like a python module.
-# Symbolic links are always ignored (except as explicit directory
-# arguments). Of course, the original file is kept as a back-up
-# (with a "~" attached to its name).
-# It complains about binaries (files containing null bytes)
-# and about files that are ostensibly not Python files: if the first
-# line starts with '#!' and does not contain the string 'python'.
-#
-# Changes made are reported to stdout in a diff-like format.
-#
-# Undoubtedly you can do this using find and sed or perl, but this is
-# a nice example of Python code that recurses down a directory tree
-# and uses regular expressions. Also note several subtleties like
-# preserving the file's mode and avoiding to even write a temp file
-# when no changes are needed for a file.
-#
-# NB: by changing only the function fixline() you can turn this
-# into a program for a different change to Python programs...
-
-import sys
-import re
-import os
-from stat import *
-import string
-
-err = sys.stderr.write
-dbg = err
-rep = sys.stdout.write
-
-def main():
- bad = 0
- if not sys.argv[1:]: # No arguments
- err('usage: ' + sys.argv[0] + ' file-or-directory ...\n')
- sys.exit(2)
- for arg in sys.argv[1:]:
- if os.path.isdir(arg):
- if recursedown(arg): bad = 1
- elif os.path.islink(arg):
- err(arg + ': will not process symbolic links\n')
- bad = 1
- else:
- if fix(arg): bad = 1
- sys.exit(bad)
-
-ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$')
-def ispython(name):
- return ispythonprog.match(name) >= 0
-
-def recursedown(dirname):
- dbg('recursedown(%r)\n' % (dirname,))
- bad = 0
- try:
- names = os.listdir(dirname)
- except os.error, msg:
- err('%s: cannot list directory: %r\n' % (dirname, msg))
- return 1
- names.sort()
- subdirs = []
- for name in names:
- if name in (os.curdir, os.pardir): continue
- fullname = os.path.join(dirname, name)
- if os.path.islink(fullname): pass
- elif os.path.isdir(fullname):
- subdirs.append(fullname)
- elif ispython(name):
- if fix(fullname): bad = 1
- for fullname in subdirs:
- if recursedown(fullname): bad = 1
- return bad
-
-def fix(filename):
-## dbg('fix(%r)\n' % (dirname,))
- try:
- f = open(filename, 'r')
- except IOError, msg:
- err('%s: cannot open: %r\n' % (filename, msg))
- return 1
- head, tail = os.path.split(filename)
- tempname = os.path.join(head, '@' + tail)
- g = None
- # If we find a match, we rewind the file and start over but
- # now copy everything to a temp file.
- lineno = 0
- while 1:
- line = f.readline()
- if not line: break
- lineno = lineno + 1
- if g is None and '\0' in line:
- # Check for binary files
- err(filename + ': contains null bytes; not fixed\n')
- f.close()
- return 1
- if lineno == 1 and g is None and line[:2] == '#!':
- # Check for non-Python scripts
- words = string.split(line[2:])
- if words and re.search('[pP]ython', words[0]) < 0:
- msg = filename + ': ' + words[0]
- msg = msg + ' script; not fixed\n'
- err(msg)
- f.close()
- return 1
- while line[-2:] == '\\\n':
- nextline = f.readline()
- if not nextline: break
- line = line + nextline
- lineno = lineno + 1
- newline = fixline(line)
- if newline != line:
- if g is None:
- try:
- g = open(tempname, 'w')
- except IOError, msg:
- f.close()
- err('%s: cannot create: %r\n' % (tempname, msg))
- return 1
- f.seek(0)
- lineno = 0
- rep(filename + ':\n')
- continue # restart from the beginning
- rep(repr(lineno) + '\n')
- rep('< ' + line)
- rep('> ' + newline)
- if g is not None:
- g.write(newline)
-
- # End of file
- f.close()
- if not g: return 0 # No changes
-
- # Finishing touch -- move files
-
- # First copy the file's mode to the temp file
- try:
- statbuf = os.stat(filename)
- os.chmod(tempname, statbuf[ST_MODE] & 07777)
- except os.error, msg:
- err('%s: warning: chmod failed (%r)\n' % (tempname, msg))
- # Then make a backup of the original file as filename~
- try:
- os.rename(filename, filename + '~')
- except os.error, msg:
- err('%s: warning: backup failed (%r)\n' % (filename, msg))
- # Now move the temp file to the original file
- try:
- os.rename(tempname, filename)
- except os.error, msg:
- err('%s: rename failed (%r)\n' % (filename, msg))
- return 1
- # Return succes
- return 0
-
-
-from tokenize import tokenprog
-
-match = {'if':':', 'elif':':', 'while':':', 'return':'\n', \
- '(':')', '[':']', '{':'}', '`':'`'}
-
-def fixline(line):
- # Quick check for easy case
- if '=' not in line: return line
-
- i, n = 0, len(line)
- stack = []
- while i < n:
- j = tokenprog.match(line, i)
- if j < 0:
- # A bad token; forget about the rest of this line
- print '(Syntax error:)'
- print line,
- return line
- a, b = tokenprog.regs[3] # Location of the token proper
- token = line[a:b]
- i = i+j
- if stack and token == stack[-1]:
- del stack[-1]
- elif match.has_key(token):
- stack.append(match[token])
- elif token == '=' and stack:
- line = line[:a] + '==' + line[b:]
- i, n = a + len('=='), len(line)
- elif token == '==' and not stack:
- print '(Warning: \'==\' at top level:)'
- print line,
- return line
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/scripts/fact.py b/Demo/scripts/fact.py
deleted file mode 100755
index 8ee2588..0000000
--- a/Demo/scripts/fact.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#! /usr/bin/env python
-
-# Factorize numbers.
-# The algorithm is not efficient, but easy to understand.
-# If there are large factors, it will take forever to find them,
-# because we try all odd numbers between 3 and sqrt(n)...
-
-import sys
-from math import sqrt
-
-def fact(n):
- if n < 1:
- raise ValueError('fact() argument should be >= 1')
- if n == 1:
- return [] # special case
- res = []
- # Treat even factors special, so we can use i += 2 later
- while n % 2 == 0:
- res.append(2)
- n //= 2
- # Try odd numbers up to sqrt(n)
- limit = sqrt(n+1)
- i = 3
- while i <= limit:
- if n % i == 0:
- res.append(i)
- n //= i
- limit = sqrt(n+1)
- else:
- i += 2
- if n != 1:
- res.append(n)
- return res
-
-def main():
- if len(sys.argv) > 1:
- source = sys.argv[1:]
- else:
- source = iter(raw_input, '')
- for arg in source:
- try:
- n = int(arg)
- except ValueError:
- print arg, 'is not an integer'
- else:
- print n, fact(n)
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/scripts/find-uname.py b/Demo/scripts/find-uname.py
deleted file mode 100755
index 958f8a4..0000000
--- a/Demo/scripts/find-uname.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/env python
-
-"""
-For each argument on the command line, look for it in the set of all Unicode
-names. Arguments are treated as case-insensitive regular expressions, e.g.:
-
- % find-uname 'small letter a$' 'horizontal line'
- *** small letter a$ matches ***
- LATIN SMALL LETTER A (97)
- COMBINING LATIN SMALL LETTER A (867)
- CYRILLIC SMALL LETTER A (1072)
- PARENTHESIZED LATIN SMALL LETTER A (9372)
- CIRCLED LATIN SMALL LETTER A (9424)
- FULLWIDTH LATIN SMALL LETTER A (65345)
- *** horizontal line matches ***
- HORIZONTAL LINE EXTENSION (9135)
-"""
-
-import unicodedata
-import sys
-import re
-
-def main(args):
- unicode_names = []
- for ix in range(sys.maxunicode+1):
- try:
- unicode_names.append((ix, unicodedata.name(unichr(ix))))
- except ValueError: # no name for the character
- pass
- for arg in args:
- pat = re.compile(arg, re.I)
- matches = [(y,x) for (x,y) in unicode_names
- if pat.search(y) is not None]
- if matches:
- print "***", arg, "matches", "***"
- for match in matches:
- print "%s (%d)" % match
-
-if __name__ == "__main__":
- main(sys.argv[1:])
diff --git a/Demo/scripts/from.py b/Demo/scripts/from.py
deleted file mode 100755
index 3c04fcd..0000000
--- a/Demo/scripts/from.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#! /usr/bin/env python
-
-# Print From and Subject of messages in $MAIL.
-# Extension to multiple mailboxes and other bells & whistles are left
-# as exercises for the reader.
-
-import sys, os
-
-# Open mailbox file. Exits with exception when this fails.
-
-try:
- mailbox = os.environ['MAIL']
-except (AttributeError, KeyError):
- sys.stderr.write('No environment variable $MAIL\n')
- sys.exit(2)
-
-try:
- mail = open(mailbox)
-except IOError:
- sys.exit('Cannot open mailbox file: ' + mailbox)
-
-while 1:
- line = mail.readline()
- if not line:
- break # EOF
- if line.startswith('From '):
- # Start of message found
- print line[:-1],
- while 1:
- line = mail.readline()
- if not line or line == '\n':
- break
- if line.startswith('Subject: '):
- print repr(line[9:-1]),
- print
diff --git a/Demo/scripts/lpwatch.py b/Demo/scripts/lpwatch.py
deleted file mode 100755
index 9d207b9..0000000
--- a/Demo/scripts/lpwatch.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#! /usr/bin/env python
-
-# Watch line printer queue(s).
-# Intended for BSD 4.3 lpq.
-
-import os
-import sys
-import time
-
-DEF_PRINTER = 'psc'
-DEF_DELAY = 10
-
-def main():
- delay = DEF_DELAY # XXX Use getopt() later
- try:
- thisuser = os.environ['LOGNAME']
- except:
- thisuser = os.environ['USER']
- printers = sys.argv[1:]
- if printers:
- # Strip '-P' from printer names just in case
- # the user specified it...
- for i, name in enumerate(printers):
- if name[:2] == '-P':
- printers[i] = name[2:]
- else:
- if os.environ.has_key('PRINTER'):
- printers = [os.environ['PRINTER']]
- else:
- printers = [DEF_PRINTER]
-
- clearhome = os.popen('clear', 'r').read()
-
- while True:
- text = clearhome
- for name in printers:
- text += makestatus(name, thisuser) + '\n'
- print text
- time.sleep(delay)
-
-def makestatus(name, thisuser):
- pipe = os.popen('lpq -P' + name + ' 2>&1', 'r')
- lines = []
- users = {}
- aheadbytes = 0
- aheadjobs = 0
- userseen = False
- totalbytes = 0
- totaljobs = 0
- for line in pipe:
- fields = line.split()
- n = len(fields)
- if len(fields) >= 6 and fields[n-1] == 'bytes':
- rank, user, job = fields[0:3]
- files = fields[3:-2]
- bytes = int(fields[n-2])
- if user == thisuser:
- userseen = True
- elif not userseen:
- aheadbytes += bytes
- aheadjobs += 1
- totalbytes += bytes
- totaljobs += 1
- ujobs, ubytes = users.get(user, (0, 0))
- ujobs += 1
- ubytes += bytes
- users[user] = ujobs, ubytes
- else:
- if fields and fields[0] != 'Rank':
- line = line.strip()
- if line == 'no entries':
- line = name + ': idle'
- elif line[-22:] == ' is ready and printing':
- line = name
- lines.append(line)
-
- if totaljobs:
- line = '%d K' % ((totalbytes+1023) // 1024)
- if totaljobs != len(users):
- line += ' (%d jobs)' % totaljobs
- if len(users) == 1:
- line += ' for %s' % (users.keys()[0],)
- else:
- line += ' for %d users' % len(users)
- if userseen:
- if aheadjobs == 0:
- line += ' (%s first)' % thisuser
- else:
- line += ' (%d K before %s)' % (
- (aheadbytes+1023) // 1024, thisuser)
- lines.append(line)
-
- sts = pipe.close()
- if sts:
- lines.append('lpq exit status %r' % (sts,))
- return ': '.join(lines)
-
-if __name__ == "__main__":
- try:
- main()
- except KeyboardInterrupt:
- pass
diff --git a/Demo/scripts/makedir.py b/Demo/scripts/makedir.py
deleted file mode 100755
index f70facd..0000000
--- a/Demo/scripts/makedir.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#! /usr/bin/env python
-
-# Like mkdir, but also make intermediate directories if necessary.
-# It is not an error if the given directory already exists (as long
-# as it is a directory).
-# Errors are not treated specially -- you just get a Python exception.
-
-import sys, os
-
-def main():
- for p in sys.argv[1:]:
- makedirs(p)
-
-def makedirs(p):
- if p and not os.path.isdir(p):
- head, tail = os.path.split(p)
- makedirs(head)
- os.mkdir(p, 0777)
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/scripts/markov.py b/Demo/scripts/markov.py
deleted file mode 100755
index df4dec0..0000000
--- a/Demo/scripts/markov.py
+++ /dev/null
@@ -1,121 +0,0 @@
-#! /usr/bin/env python
-
-class Markov:
- def __init__(self, histsize, choice):
- self.histsize = histsize
- self.choice = choice
- self.trans = {}
-
- def add(self, state, next):
- self.trans.setdefault(state, []).append(next)
-
- def put(self, seq):
- n = self.histsize
- add = self.add
- add(None, seq[:0])
- for i in range(len(seq)):
- add(seq[max(0, i-n):i], seq[i:i+1])
- add(seq[len(seq)-n:], None)
-
- def get(self):
- choice = self.choice
- trans = self.trans
- n = self.histsize
- seq = choice(trans[None])
- while True:
- subseq = seq[max(0, len(seq)-n):]
- options = trans[subseq]
- next = choice(options)
- if not next:
- break
- seq += next
- return seq
-
-
-def test():
- import sys, random, getopt
- args = sys.argv[1:]
- try:
- opts, args = getopt.getopt(args, '0123456789cdwq')
- except getopt.error:
- print 'Usage: %s [-#] [-cddqw] [file] ...' % sys.argv[0]
- print 'Options:'
- print '-#: 1-digit history size (default 2)'
- print '-c: characters (default)'
- print '-w: words'
- print '-d: more debugging output'
- print '-q: no debugging output'
- print 'Input files (default stdin) are split in paragraphs'
- print 'separated blank lines and each paragraph is split'
- print 'in words by whitespace, then reconcatenated with'
- print 'exactly one space separating words.'
- print 'Output consists of paragraphs separated by blank'
- print 'lines, where lines are no longer than 72 characters.'
- sys.exit(2)
- histsize = 2
- do_words = False
- debug = 1
- for o, a in opts:
- if '-0' <= o <= '-9': histsize = int(o[1:])
- if o == '-c': do_words = False
- if o == '-d': debug += 1
- if o == '-q': debug = 0
- if o == '-w': do_words = True
- if not args:
- args = ['-']
-
- m = Markov(histsize, random.choice)
- try:
- for filename in args:
- if filename == '-':
- f = sys.stdin
- if f.isatty():
- print 'Sorry, need stdin from file'
- continue
- else:
- f = open(filename, 'r')
- if debug: print 'processing', filename, '...'
- text = f.read()
- f.close()
- paralist = text.split('\n\n')
- for para in paralist:
- if debug > 1: print 'feeding ...'
- words = para.split()
- if words:
- if do_words:
- data = tuple(words)
- else:
- data = ' '.join(words)
- m.put(data)
- except KeyboardInterrupt:
- print 'Interrupted -- continue with data read so far'
- if not m.trans:
- print 'No valid input files'
- return
- if debug: print 'done.'
-
- if debug > 1:
- for key in m.trans.keys():
- if key is None or len(key) < histsize:
- print repr(key), m.trans[key]
- if histsize == 0: print repr(''), m.trans['']
- print
- while True:
- data = m.get()
- if do_words:
- words = data
- else:
- words = data.split()
- n = 0
- limit = 72
- for w in words:
- if n + len(w) > limit:
- print
- n = 0
- print w,
- n += len(w) + 1
- print
- print
-
-if __name__ == "__main__":
- test()
diff --git a/Demo/scripts/mboxconvert.py b/Demo/scripts/mboxconvert.py
deleted file mode 100755
index 8c462f3..0000000
--- a/Demo/scripts/mboxconvert.py
+++ /dev/null
@@ -1,124 +0,0 @@
-#! /usr/bin/env python
-
-# Convert MH directories (1 message per file) or MMDF mailboxes (4x^A
-# delimited) to unix mailbox (From ... delimited) on stdout.
-# If -f is given, files contain one message per file (e.g. MH messages)
-
-import rfc822
-import sys
-import time
-import os
-import stat
-import getopt
-import re
-
-def main():
- dofile = mmdf
- try:
- opts, args = getopt.getopt(sys.argv[1:], 'f')
- except getopt.error, msg:
- sys.stderr.write('%s\n' % msg)
- sys.exit(2)
- for o, a in opts:
- if o == '-f':
- dofile = message
- if not args:
- args = ['-']
- sts = 0
- for arg in args:
- if arg == '-' or arg == '':
- sts = dofile(sys.stdin) or sts
- elif os.path.isdir(arg):
- sts = mh(arg) or sts
- elif os.path.isfile(arg):
- try:
- f = open(arg)
- except IOError, msg:
- sys.stderr.write('%s: %s\n' % (arg, msg))
- sts = 1
- continue
- sts = dofile(f) or sts
- f.close()
- else:
- sys.stderr.write('%s: not found\n' % arg)
- sts = 1
- if sts:
- sys.exit(sts)
-
-numeric = re.compile('[1-9][0-9]*')
-
-def mh(dir):
- sts = 0
- msgs = os.listdir(dir)
- for msg in msgs:
- if numeric.match(msg) != len(msg):
- continue
- fn = os.path.join(dir, msg)
- try:
- f = open(fn)
- except IOError, msg:
- sys.stderr.write('%s: %s\n' % (fn, msg))
- sts = 1
- continue
- sts = message(f) or sts
- return sts
-
-def mmdf(f):
- sts = 0
- while 1:
- line = f.readline()
- if not line:
- break
- if line == '\1\1\1\1\n':
- sts = message(f, line) or sts
- else:
- sys.stderr.write(
- 'Bad line in MMFD mailbox: %r\n' % (line,))
- return sts
-
-counter = 0 # for generating unique Message-ID headers
-
-def message(f, delimiter = ''):
- sts = 0
- # Parse RFC822 header
- m = rfc822.Message(f)
- # Write unix header line
- fullname, email = m.getaddr('From')
- tt = m.getdate('Date')
- if tt:
- t = time.mktime(tt)
- else:
- sys.stderr.write(
- 'Unparseable date: %r\n' % (m.getheader('Date'),))
- t = os.fstat(f.fileno())[stat.ST_MTIME]
- print 'From', email, time.ctime(t)
- # Copy RFC822 header
- for line in m.headers:
- print line,
- # Invent Message-ID header if none is present
- if not m.has_key('message-id'):
- global counter
- counter = counter + 1
- msgid = "<%s.%d>" % (hex(t), counter)
- sys.stderr.write("Adding Message-ID %s (From %s)\n" %
- (msgid, email))
- print "Message-ID:", msgid
- print
- # Copy body
- while 1:
- line = f.readline()
- if line == delimiter:
- break
- if not line:
- sys.stderr.write('Unexpected EOF in message\n')
- sts = 1
- break
- if line[:5] == 'From ':
- line = '>' + line
- print line,
- # Print trailing newline
- print
- return sts
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/scripts/morse.py b/Demo/scripts/morse.py
deleted file mode 100755
index 265fae9..0000000
--- a/Demo/scripts/morse.py
+++ /dev/null
@@ -1,138 +0,0 @@
-#! /usr/bin/env python
-
-# DAH should be three DOTs.
-# Space between DOTs and DAHs should be one DOT.
-# Space between two letters should be one DAH.
-# Space between two words should be DOT DAH DAH.
-
-import sys, math, audiodev
-
-DOT = 30
-DAH = 3 * DOT
-OCTAVE = 2 # 1 == 441 Hz, 2 == 882 Hz, ...
-
-morsetab = {
- 'A': '.-', 'a': '.-',
- 'B': '-...', 'b': '-...',
- 'C': '-.-.', 'c': '-.-.',
- 'D': '-..', 'd': '-..',
- 'E': '.', 'e': '.',
- 'F': '..-.', 'f': '..-.',
- 'G': '--.', 'g': '--.',
- 'H': '....', 'h': '....',
- 'I': '..', 'i': '..',
- 'J': '.---', 'j': '.---',
- 'K': '-.-', 'k': '-.-',
- 'L': '.-..', 'l': '.-..',
- 'M': '--', 'm': '--',
- 'N': '-.', 'n': '-.',
- 'O': '---', 'o': '---',
- 'P': '.--.', 'p': '.--.',
- 'Q': '--.-', 'q': '--.-',
- 'R': '.-.', 'r': '.-.',
- 'S': '...', 's': '...',
- 'T': '-', 't': '-',
- 'U': '..-', 'u': '..-',
- 'V': '...-', 'v': '...-',
- 'W': '.--', 'w': '.--',
- 'X': '-..-', 'x': '-..-',
- 'Y': '-.--', 'y': '-.--',
- 'Z': '--..', 'z': '--..',
- '0': '-----', ',': '--..--',
- '1': '.----', '.': '.-.-.-',
- '2': '..---', '?': '..--..',
- '3': '...--', ';': '-.-.-.',
- '4': '....-', ':': '---...',
- '5': '.....', "'": '.----.',
- '6': '-....', '-': '-....-',
- '7': '--...', '/': '-..-.',
- '8': '---..', '(': '-.--.-',
- '9': '----.', ')': '-.--.-',
- ' ': ' ', '_': '..--.-',
-}
-
-nowave = '\0' * 200
-
-# If we play at 44.1 kHz (which we do), then if we produce one sine
-# wave in 100 samples, we get a tone of 441 Hz. If we produce two
-# sine waves in these 100 samples, we get a tone of 882 Hz. 882 Hz
-# appears to be a nice one for playing morse code.
-def mkwave(octave):
- sinewave = ''
- for i in range(100):
- val = int(math.sin(math.pi * i * octave / 50.0) * 30000)
- sinewave += chr((val >> 8) & 255) + chr(val & 255)
- return sinewave
-
-defaultwave = mkwave(OCTAVE)
-
-def main():
- import getopt
- try:
- opts, args = getopt.getopt(sys.argv[1:], 'o:p:')
- except getopt.error:
- sys.stderr.write('Usage ' + sys.argv[0] +
- ' [ -o outfile ] [ -p octave ] [ words ] ...\n')
- sys.exit(1)
- dev = None
- wave = defaultwave
- for o, a in opts:
- if o == '-o':
- import aifc
- dev = aifc.open(a, 'w')
- dev.setframerate(44100)
- dev.setsampwidth(2)
- dev.setnchannels(1)
- if o == '-p':
- wave = mkwave(int(a))
- if not dev:
- import audiodev
- dev = audiodev.AudioDev()
- dev.setoutrate(44100)
- dev.setsampwidth(2)
- dev.setnchannels(1)
- dev.close = dev.stop
- dev.writeframesraw = dev.writeframes
- if args:
- source = [' '.join(args)]
- else:
- source = iter(sys.stdin.readline, '')
- for line in source:
- mline = morse(line)
- play(mline, dev, wave)
- if hasattr(dev, 'wait'):
- dev.wait()
- dev.close()
-
-# Convert a string to morse code with \001 between the characters in
-# the string.
-def morse(line):
- res = ''
- for c in line:
- try:
- res += morsetab[c] + '\001'
- except KeyError:
- pass
- return res
-
-# Play a line of morse code.
-def play(line, dev, wave):
- for c in line:
- if c == '.':
- sine(dev, DOT, wave)
- elif c == '-':
- sine(dev, DAH, wave)
- else: # space
- pause(dev, DAH + DOT)
- pause(dev, DOT)
-
-def sine(dev, length, wave):
- for i in range(length):
- dev.writeframesraw(wave)
-
-def pause(dev, length):
- for i in range(length):
- dev.writeframesraw(nowave)
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/scripts/newslist.doc b/Demo/scripts/newslist.doc
deleted file mode 100755
index 87fd9ba..0000000
--- a/Demo/scripts/newslist.doc
+++ /dev/null
@@ -1,59 +0,0 @@
- NEWSLIST
- ========
- A program to assist HTTP browsing of newsgroups
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-WWW browsers such as NCSA Mosaic allow the user to read newsgroup
-articles by specifying the group name in a URL eg 'news:comp.answers'.
-
-To browse through many groups, though, (and there are several thousand
-of them) you really need a page or pages containing links to all the
-groups. There are some good ones out there, for example,
-
- http://info.cern.ch/hypertext/DataSources/News/Groups/Overview.html
-
-is the standard one at CERN, but it only shows the groups available there,
-which may be rather different from those available on your machine.
-
-Newslist is a program which creates a hierarchy of pages for you based
-on the groups available from YOUR server. It is written in python - a
-splendid interpreted object-oriented language which I suggest you get
-right now from the directory /pub/python at ftp.cwi.nl, if you haven't
-already got it.
-
-You should be able to see some sample output by looking at:
- http://pelican.cl.cam.ac.uk/newspage/root.html
-
-Descriptions of newsgroups can be added from a file with one group
-per line. eg:
-
- alt.foo Articles about foo
- comp.bar Programming in 'bar' and related languages
-
-A suitable list detailing most groups can be found at ftp.uu.net in
-/uunet-info/newsgroups.gz.
-
-Make sure you read the information at the beginning of the program source and
-configure the variables before running.
-
-In addition to python, you need:
-
- An NNTP-based news feed.
- A directory in which to put the pages.
-
-The programming is not very beautiful, but it works! It comes with no
-warranty, express or implied, but with the hope that some others may
-find it useful.
-
-Comments, improvements & suggestions welcomed.
-Quentin Stafford-Fraser
-
- ----------------------------------------------------------------------
- Quentin Stafford-Fraser
- http://pelican.cl.cam.ac.uk/people/qs101/me.html
-
- Cambridge University Computer Lab Rank Xerox Cambridge EuroPARC
- qs101@cl.cam.ac.uk fraser@europarc.xerox.com
- Tel: +44 223 334411 Tel: +44 223 341521
- Fax: +44 223 334679 Fax: +44 223 341510
- ----------------------------------------------------------------------
diff --git a/Demo/scripts/newslist.py b/Demo/scripts/newslist.py
deleted file mode 100755
index a91e901..0000000
--- a/Demo/scripts/newslist.py
+++ /dev/null
@@ -1,362 +0,0 @@
-#! /usr/bin/env python
-#######################################################################
-# Newslist $Revision$
-#
-# Syntax:
-# newslist [ -a ]
-#
-# This is a program to create a directory full of HTML pages
-# which between them contain links to all the newsgroups available
-# on your server.
-#
-# The -a option causes a complete list of all groups to be read from
-# the server rather than just the ones which have appeared since last
-# execution. This recreates the local list from scratch. Use this on
-# the first invocation of the program, and from time to time thereafter.
-# When new groups are first created they may appear on your server as
-# empty groups. By default, empty groups are ignored by the -a option.
-# However, these new groups will not be created again, and so will not
-# appear in the server's list of 'new groups' at a later date. Hence it
-# won't appear until you do a '-a' after some articles have appeared.
-#
-# I should really keep a list of ignored empty groups and re-check them
-# for articles on every run, but I haven't got around to it yet.
-#
-# This assumes an NNTP news feed.
-#
-# Feel free to copy, distribute and modify this code for
-# non-commercial use. If you make any useful modifications, let me
-# know!
-#
-# (c) Quentin Stafford-Fraser 1994
-# fraser@europarc.xerox.com qs101@cl.cam.ac.uk
-# #
-#######################################################################
-import sys, nntplib, marshal, time, os
-
-#######################################################################
-# Check these variables before running! #
-
-# Top directory.
-# Filenames which don't start with / are taken as being relative to this.
-topdir = os.path.expanduser('~/newspage')
-
-# The name of your NNTP host
-# eg.
-# newshost = 'nntp-serv.cl.cam.ac.uk'
-# or use following to get the name from the NNTPSERVER environment
-# variable:
-# newshost = os.environ['NNTPSERVER']
-newshost = 'news.example.com'
-
-# The filename for a local cache of the newsgroup list
-treefile = 'grouptree'
-
-# The filename for descriptions of newsgroups
-# I found a suitable one at ftp.uu.net in /uunet-info/newgroups.gz
-# You can set this to '' if you don't wish to use one.
-descfile = 'newsgroups'
-
-# The directory in which HTML pages should be created
-# eg.
-# pagedir = '/usr/local/lib/html/newspage'
-# pagedir = 'pages'
-pagedir = topdir
-
-# The html prefix which will refer to this directory
-# eg.
-# httppref = '/newspage/',
-# or leave blank for relative links between pages: (Recommended)
-# httppref = ''
-httppref = ''
-
-# The name of the 'root' news page in this directory.
-# A .html suffix will be added.
-rootpage = 'root'
-
-# Set skipempty to 0 if you wish to see links to empty groups as well.
-# Only affects the -a option.
-skipempty = 1
-
-# pagelinkicon can contain html to put an icon after links to
-# further pages. This helps to make important links stand out.
-# Set to '' if not wanted, or '...' is quite a good one.
-pagelinkicon = '... <img src="http://pelican.cl.cam.ac.uk/icons/page.xbm"> '
-
-# ---------------------------------------------------------------------
-# Less important personal preferences:
-
-# Sublistsize controls the maximum number of items the will appear as
-# an indented sub-list before the whole thing is moved onto a different
-# page. The smaller this is, the more pages you will have, but the
-# shorter each will be.
-sublistsize = 4
-
-# That should be all. #
-#######################################################################
-
-for dir in os.curdir, os.environ['HOME']:
- rcfile = os.path.join(dir, '.newslistrc.py')
- if os.path.exists(rcfile):
- print rcfile
- execfile(rcfile)
- break
-
-from nntplib import NNTP
-from stat import *
-
-rcsrev = '$Revision$'
-rcsrev = ' '.join(filter(lambda s: '$' not in s, rcsrev.split()))
-desc = {}
-
-# Make (possibly) relative filenames into absolute ones
-treefile = os.path.join(topdir,treefile)
-descfile = os.path.join(topdir,descfile)
-page = os.path.join(topdir,pagedir)
-
-# First the bits for creating trees ---------------------------
-
-# Addtotree creates/augments a tree from a list of group names
-def addtotree(tree, groups):
- print 'Updating tree...'
- for i in groups:
- parts = i.split('.')
- makeleaf(tree, parts)
-
-# Makeleaf makes a leaf and the branch leading to it if necessary
-def makeleaf(tree,path):
- j = path[0]
- l = len(path)
-
- if j not in tree:
- tree[j] = {}
- if l == 1:
- tree[j]['.'] = '.'
- if l > 1:
- makeleaf(tree[j],path[1:])
-
-# Then the bits for outputting trees as pages ----------------
-
-# Createpage creates an HTML file named <root>.html containing links
-# to those groups beginning with <root>.
-
-def createpage(root, tree, p):
- filename = os.path.join(pagedir, root+'.html')
- if root == rootpage:
- detail = ''
- else:
- detail = ' under ' + root
- with open(filename, 'w') as f:
- # f.write('Content-Type: text/html\n')
- f.write('<html>\n<head>\n')
- f.write('<title>Newsgroups available%s</title>\n' % detail)
- f.write('</head>\n<body>\n')
- f.write('<h1>Newsgroups available%s</h1>\n' % detail)
- f.write('<a href="%s%s.html">Back to top level</a><p>\n' %
- (httppref, rootpage))
- printtree(f, tree, 0, p)
- f.write('\n<p>')
- f.write("<i>This page automatically created by 'newslist' v. %s." %
- rcsrev)
- f.write(time.ctime(time.time()) + '</i>\n')
- f.write('</body>\n</html>\n')
-
-# Printtree prints the groups as a bulleted list. Groups with
-# more than <sublistsize> subgroups will be put on a separate page.
-# Other sets of subgroups are just indented.
-
-def printtree(f, tree, indent, p):
- l = len(tree)
-
- if l > sublistsize and indent > 0:
- # Create a new page and a link to it
- f.write('<li><b><a href="%s%s.html">' % (httppref, p[1:]))
- f.write(p[1:] + '.*')
- f.write('</a></b>%s\n' % pagelinkicon)
- createpage(p[1:], tree, p)
- return
-
- kl = tree.keys()
-
- if l > 1:
- kl.sort()
- if indent > 0:
- # Create a sub-list
- f.write('<li>%s\n<ul>' % p[1:])
- else:
- # Create a main list
- f.write('<ul>')
- indent = indent + 1
-
- for i in kl:
- if i == '.':
- # Output a newsgroup
- f.write('<li><a href="news:%s">%s</a> ' % (p[1:], p[1:]))
- if p[1:] in desc:
- f.write(' <i>%s</i>\n' % desc[p[1:]])
- else:
- f.write('\n')
- else:
- # Output a hierarchy
- printtree(f, tree[i], indent, p+'.'+i)
-
- if l > 1:
- f.write('\n</ul>')
-
-# Reading descriptions file ---------------------------------------
-
-# This returns a dict mapping group name to its description
-
-def readdesc(descfile):
- global desc
- desc = {}
-
- if descfile == '':
- return
-
- try:
- with open(descfile, 'r') as d:
- print 'Reading descriptions...'
- for l in d:
- bits = l.split()
- try:
- grp = bits[0]
- dsc = ' '.join(bits[1:])
- if len(dsc) > 1:
- desc[grp] = dsc
- except IndexError:
- pass
- except IOError:
- print 'Failed to open description file ' + descfile
- return
-
-# Check that ouput directory exists, ------------------------------
-# and offer to create it if not
-
-def checkopdir(pagedir):
- if not os.path.isdir(pagedir):
- print 'Directory %s does not exist.' % pagedir
- print 'Shall I create it for you? (y/n)'
- if sys.stdin.readline()[0] == 'y':
- try:
- os.mkdir(pagedir, 0777)
- except:
- print 'Sorry - failed!'
- sys.exit(1)
- else:
- print 'OK. Exiting.'
- sys.exit(1)
-
-# Read and write current local tree ----------------------------------
-
-def readlocallist(treefile):
- print 'Reading current local group list...'
- tree = {}
- try:
- treetime = time.localtime(os.stat(treefile)[ST_MTIME])
- except:
- print '\n*** Failed to open local group cache '+treefile
- print 'If this is the first time you have run newslist, then'
- print 'use the -a option to create it.'
- sys.exit(1)
- treedate = '%02d%02d%02d' % (treetime[0] % 100, treetime[1], treetime[2])
- try:
- with open(treefile, 'rb') as dump:
- tree = marshal.load(dump)
- except IOError:
- print 'Cannot open local group list ' + treefile
- return (tree, treedate)
-
-def writelocallist(treefile, tree):
- try:
- with open(treefile, 'wb') as dump:
- groups = marshal.dump(tree, dump)
- print 'Saved list to %s\n' % treefile
- except:
- print 'Sorry - failed to write to local group cache', treefile
- print 'Does it (or its directory) have the correct permissions?'
- sys.exit(1)
-
-# Return list of all groups on server -----------------------------
-
-def getallgroups(server):
- print 'Getting list of all groups...'
- treedate = '010101'
- info = server.list()[1]
- groups = []
- print 'Processing...'
- if skipempty:
- print '\nIgnoring following empty groups:'
- for i in info:
- grpname = i[0].split()[0]
- if skipempty and int(i[1]) < int(i[2]):
- print grpname + ' ',
- else:
- groups.append(grpname)
- print '\n'
- if skipempty:
- print '(End of empty groups)'
- return groups
-
-# Return list of new groups on server -----------------------------
-
-def getnewgroups(server, treedate):
- print 'Getting list of new groups since start of %s...' % treedate,
- info = server.newgroups(treedate, '000001')[1]
- print 'got %d.' % len(info)
- print 'Processing...',
- groups = []
- for i in info:
- grpname = i.split()[0]
- groups.append(grpname)
- print 'Done'
- return groups
-
-# Now the main program --------------------------------------------
-
-def main():
- tree = {}
-
- # Check that the output directory exists
- checkopdir(pagedir)
-
- try:
- print 'Connecting to %s...' % newshost
- if sys.version[0] == '0':
- s = NNTP.init(newshost)
- else:
- s = NNTP(newshost)
- connected = True
- except (nntplib.error_temp, nntplib.error_perm), x:
- print 'Error connecting to host:', x
- print 'I\'ll try to use just the local list.'
- connected = False
-
- # If -a is specified, read the full list of groups from server
- if connected and len(sys.argv) > 1 and sys.argv[1] == '-a':
- groups = getallgroups(s)
-
- # Otherwise just read the local file and then add
- # groups created since local file last modified.
- else:
-
- (tree, treedate) = readlocallist(treefile)
- if connected:
- groups = getnewgroups(s, treedate)
-
- if connected:
- addtotree(tree, groups)
- writelocallist(treefile,tree)
-
- # Read group descriptions
- readdesc(descfile)
-
- print 'Creating pages...'
- createpage(rootpage, tree, '')
- print 'Done'
-
-if __name__ == "__main__":
- main()
-
-# That's all folks
-######################################################################
diff --git a/Demo/scripts/pi.py b/Demo/scripts/pi.py
deleted file mode 100755
index 0740cd0..0000000
--- a/Demo/scripts/pi.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#! /usr/bin/env python
-
-# Print digits of pi forever.
-#
-# The algorithm, using Python's 'long' integers ("bignums"), works
-# with continued fractions, and was conceived by Lambert Meertens.
-#
-# See also the ABC Programmer's Handbook, by Geurts, Meertens & Pemberton,
-# published by Prentice-Hall (UK) Ltd., 1990.
-
-import sys
-
-def main():
- k, a, b, a1, b1 = 2, 4, 1, 12, 4
- while True:
- # Next approximation
- p, q, k = k*k, 2*k+1, k+1
- a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
- # Print common digits
- d, d1 = a//b, a1//b1
- while d == d1:
- output(d)
- a, a1 = 10*(a%b), 10*(a1%b1)
- d, d1 = a//b, a1//b1
-
-def output(d):
- # Use write() to avoid spaces between the digits
- sys.stdout.write(str(d))
- # Flush so the output is seen immediately
- sys.stdout.flush()
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/scripts/pp.py b/Demo/scripts/pp.py
deleted file mode 100755
index efbe5cf..0000000
--- a/Demo/scripts/pp.py
+++ /dev/null
@@ -1,129 +0,0 @@
-#! /usr/bin/env python
-
-# Emulate some Perl command line options.
-# Usage: pp [-a] [-c] [-d] [-e scriptline] [-F fieldsep] [-n] [-p] [file] ...
-# Where the options mean the following:
-# -a : together with -n or -p, splits each line into list F
-# -c : check syntax only, do not execute any code
-# -d : run the script under the debugger, pdb
-# -e scriptline : gives one line of the Python script; may be repeated
-# -F fieldsep : sets the field separator for the -a option [not in Perl]
-# -n : runs the script for each line of input
-# -p : prints the line after the script has run
-# When no script lines have been passed, the first file argument
-# contains the script. With -n or -p, the remaining arguments are
-# read as input to the script, line by line. If a file is '-'
-# or missing, standard input is read.
-
-# XXX To do:
-# - add -i extension option (change files in place)
-# - make a single loop over the files and lines (changes effect of 'break')?
-# - add an option to specify the record separator
-# - except for -n/-p, run directly from the file if at all possible
-
-import sys
-import getopt
-
-FS = ''
-SCRIPT = []
-AFLAG = 0
-CFLAG = 0
-DFLAG = 0
-NFLAG = 0
-PFLAG = 0
-
-try:
- optlist, ARGS = getopt.getopt(sys.argv[1:], 'acde:F:np')
-except getopt.error, msg:
- sys.stderr.write('%s: %s\n' % (sys.argv[0], msg))
- sys.exit(2)
-
-for option, optarg in optlist:
- if option == '-a':
- AFLAG = 1
- elif option == '-c':
- CFLAG = 1
- elif option == '-d':
- DFLAG = 1
- elif option == '-e':
- for line in optarg.split('\n'):
- SCRIPT.append(line)
- elif option == '-F':
- FS = optarg
- elif option == '-n':
- NFLAG = 1
- PFLAG = 0
- elif option == '-p':
- NFLAG = 1
- PFLAG = 1
- else:
- print option, 'not recognized???'
-
-if not ARGS: ARGS.append('-')
-
-if not SCRIPT:
- if ARGS[0] == '-':
- fp = sys.stdin
- else:
- fp = open(ARGS[0], 'r')
- while 1:
- line = fp.readline()
- if not line: break
- SCRIPT.append(line[:-1])
- del fp
- del ARGS[0]
- if not ARGS: ARGS.append('-')
-
-if CFLAG:
- prologue = ['if 0:']
- epilogue = []
-elif NFLAG:
- # Note that it is on purpose that AFLAG and PFLAG are
- # tested dynamically each time through the loop
- prologue = [
- 'LINECOUNT = 0',
- 'for FILE in ARGS:',
- ' \tif FILE == \'-\':',
- ' \t \tFP = sys.stdin',
- ' \telse:',
- ' \t \tFP = open(FILE, \'r\')',
- ' \tLINENO = 0',
- ' \twhile 1:',
- ' \t \tLINE = FP.readline()',
- ' \t \tif not LINE: break',
- ' \t \tLINENO = LINENO + 1',
- ' \t \tLINECOUNT = LINECOUNT + 1',
- ' \t \tL = LINE[:-1]',
- ' \t \taflag = AFLAG',
- ' \t \tif aflag:',
- ' \t \t \tif FS: F = L.split(FS)',
- ' \t \t \telse: F = L.split()'
- ]
- epilogue = [
- ' \t \tif not PFLAG: continue',
- ' \t \tif aflag:',
- ' \t \t \tif FS: print FS.join(F)',
- ' \t \t \telse: print \' \'.join(F)',
- ' \t \telse: print L',
- ]
-else:
- prologue = ['if 1:']
- epilogue = []
-
-# Note that we indent using tabs only, so that any indentation style
-# used in 'command' will come out right after re-indentation.
-
-program = '\n'.join(prologue) + '\n'
-for line in SCRIPT:
- program += ' \t \t' + line + '\n'
-program += '\n'.join(epilogue) + '\n'
-
-import tempfile
-fp = tempfile.NamedTemporaryFile()
-fp.write(program)
-fp.flush()
-if DFLAG:
- import pdb
- pdb.run('execfile(%r)' % (fp.name,))
-else:
- execfile(fp.name)
diff --git a/Demo/scripts/primes.py b/Demo/scripts/primes.py
deleted file mode 100755
index 2bf5ba2..0000000
--- a/Demo/scripts/primes.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#! /usr/bin/env python
-
-# Print prime numbers in a given range
-
-def primes(min, max):
- if max >= 2 >= min:
- print 2
- primes = [2]
- i = 3
- while i <= max:
- for p in primes:
- if i % p == 0 or p*p > i:
- break
- if i % p != 0:
- primes.append(i)
- if i >= min:
- print i
- i += 2
-
-def main():
- import sys
- min, max = 2, 0x7fffffff
- if sys.argv[1:]:
- min = int(sys.argv[1])
- if sys.argv[2:]:
- max = int(sys.argv[2])
- primes(min, max)
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/scripts/queens.py b/Demo/scripts/queens.py
deleted file mode 100755
index 866a7b2..0000000
--- a/Demo/scripts/queens.py
+++ /dev/null
@@ -1,85 +0,0 @@
-#! /usr/bin/env python
-
-"""N queens problem.
-
-The (well-known) problem is due to Niklaus Wirth.
-
-This solution is inspired by Dijkstra (Structured Programming). It is
-a classic recursive backtracking approach.
-
-"""
-
-N = 8 # Default; command line overrides
-
-class Queens:
-
- def __init__(self, n=N):
- self.n = n
- self.reset()
-
- def reset(self):
- n = self.n
- self.y = [None] * n # Where is the queen in column x
- self.row = [0] * n # Is row[y] safe?
- self.up = [0] * (2*n-1) # Is upward diagonal[x-y] safe?
- self.down = [0] * (2*n-1) # Is downward diagonal[x+y] safe?
- self.nfound = 0 # Instrumentation
-
- def solve(self, x=0): # Recursive solver
- for y in range(self.n):
- if self.safe(x, y):
- self.place(x, y)
- if x+1 == self.n:
- self.display()
- else:
- self.solve(x+1)
- self.remove(x, y)
-
- def safe(self, x, y):
- return not self.row[y] and not self.up[x-y] and not self.down[x+y]
-
- def place(self, x, y):
- self.y[x] = y
- self.row[y] = 1
- self.up[x-y] = 1
- self.down[x+y] = 1
-
- def remove(self, x, y):
- self.y[x] = None
- self.row[y] = 0
- self.up[x-y] = 0
- self.down[x+y] = 0
-
- silent = 0 # If true, count solutions only
-
- def display(self):
- self.nfound = self.nfound + 1
- if self.silent:
- return
- print '+-' + '--'*self.n + '+'
- for y in range(self.n-1, -1, -1):
- print '|',
- for x in range(self.n):
- if self.y[x] == y:
- print "Q",
- else:
- print ".",
- print '|'
- print '+-' + '--'*self.n + '+'
-
-def main():
- import sys
- silent = 0
- n = N
- if sys.argv[1:2] == ['-n']:
- silent = 1
- del sys.argv[1]
- if sys.argv[1:]:
- n = int(sys.argv[1])
- q = Queens(n)
- q.silent = silent
- q.solve()
- print "Found", q.nfound, "solutions."
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/scripts/script.py b/Demo/scripts/script.py
deleted file mode 100755
index a8aca4a..0000000
--- a/Demo/scripts/script.py
+++ /dev/null
@@ -1,42 +0,0 @@
-#! /usr/bin/env python
-
-# script.py -- Make typescript of terminal session.
-# Usage:
-# -a Append to typescript.
-# -p Use Python as shell.
-# Author: Steen Lumholt.
-
-
-import os, time, sys, getopt
-import pty
-
-def read(fd):
- data = os.read(fd, 1024)
- script.write(data)
- return data
-
-shell = 'sh'
-filename = 'typescript'
-mode = 'w'
-if os.environ.has_key('SHELL'):
- shell = os.environ['SHELL']
-
-try:
- opts, args = getopt.getopt(sys.argv[1:], 'ap')
-except getopt.error, msg:
- print '%s: %s' % (sys.argv[0], msg)
- sys.exit(2)
-
-for o, a in opts:
- if o == '-a':
- mode = 'a'
- elif o == '-p':
- shell = 'python'
-
-script = open(filename, mode)
-
-sys.stdout.write('Script started, file is %s\n' % filename)
-script.write('Script started on %s\n' % time.ctime(time.time()))
-pty.spawn(shell, read)
-script.write('Script done on %s\n' % time.ctime(time.time()))
-sys.stdout.write('Script done, file is %s\n' % filename)
diff --git a/Demo/scripts/unbirthday.py b/Demo/scripts/unbirthday.py
deleted file mode 100755
index 056ad44..0000000
--- a/Demo/scripts/unbirthday.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#! /usr/bin/env python
-
-# Calculate your unbirthday count (see Alice in Wonderland).
-# This is defined as the number of days from your birth until today
-# that weren't your birthday. (The day you were born is not counted).
-# Leap years make it interesting.
-
-import sys
-import time
-import calendar
-
-def main():
- if sys.argv[1:]:
- year = int(sys.argv[1])
- else:
- year = int(raw_input('In which year were you born? '))
- if 0 <= year < 100:
- print "I'll assume that by", year,
- year = year + 1900
- print 'you mean', year, 'and not the early Christian era'
- elif not (1850 <= year <= time.localtime()[0]):
- print "It's hard to believe you were born in", year
- return
-
- if sys.argv[2:]:
- month = int(sys.argv[2])
- else:
- month = int(raw_input('And in which month? (1-12) '))
- if not (1 <= month <= 12):
- print 'There is no month numbered', month
- return
-
- if sys.argv[3:]:
- day = int(sys.argv[3])
- else:
- day = int(raw_input('And on what day of that month? (1-31) '))
- if month == 2 and calendar.isleap(year):
- maxday = 29
- else:
- maxday = calendar.mdays[month]
- if not (1 <= day <= maxday):
- print 'There are no', day, 'days in that month!'
- return
-
- bdaytuple = (year, month, day)
- bdaydate = mkdate(bdaytuple)
- print 'You were born on', format(bdaytuple)
-
- todaytuple = time.localtime()[:3]
- todaydate = mkdate(todaytuple)
- print 'Today is', format(todaytuple)
-
- if bdaytuple > todaytuple:
- print 'You are a time traveler. Go back to the future!'
- return
-
- if bdaytuple == todaytuple:
- print 'You were born today. Have a nice life!'
- return
-
- days = todaydate - bdaydate
- print 'You have lived', days, 'days'
-
- age = 0
- for y in range(year, todaytuple[0] + 1):
- if bdaytuple < (y, month, day) <= todaytuple:
- age = age + 1
-
- print 'You are', age, 'years old'
-
- if todaytuple[1:] == bdaytuple[1:]:
- print 'Congratulations! Today is your', nth(age), 'birthday'
- print 'Yesterday was your',
- else:
- print 'Today is your',
- print nth(days - age), 'unbirthday'
-
-def format((year, month, day)):
- return '%d %s %d' % (day, calendar.month_name[month], year)
-
-def nth(n):
- if n == 1: return '1st'
- if n == 2: return '2nd'
- if n == 3: return '3rd'
- return '%dth' % n
-
-def mkdate((year, month, day)):
- # January 1st, in 0 A.D. is arbitrarily defined to be day 1,
- # even though that day never actually existed and the calendar
- # was different then...
- days = year*365 # years, roughly
- days = days + (year+3)//4 # plus leap years, roughly
- days = days - (year+99)//100 # minus non-leap years every century
- days = days + (year+399)//400 # plus leap years every 4 centirues
- for i in range(1, month):
- if i == 2 and calendar.isleap(year):
- days = days + 29
- else:
- days = days + calendar.mdays[i]
- days = days + day
- return days
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/scripts/update.py b/Demo/scripts/update.py
deleted file mode 100755
index c936026..0000000
--- a/Demo/scripts/update.py
+++ /dev/null
@@ -1,92 +0,0 @@
-#! /usr/bin/env python
-
-# Update a bunch of files according to a script.
-# The input file contains lines of the form <filename>:<lineno>:<text>,
-# meaning that the given line of the given file is to be replaced
-# by the given text. This is useful for performing global substitutions
-# on grep output:
-
-import os
-import sys
-import re
-
-pat = '^([^: \t\n]+):([1-9][0-9]*):'
-prog = re.compile(pat)
-
-class FileObj:
- def __init__(self, filename):
- self.filename = filename
- self.changed = 0
- try:
- self.lines = open(filename, 'r').readlines()
- except IOError, msg:
- print '*** Can\'t open "%s":' % filename, msg
- self.lines = None
- return
- print 'diffing', self.filename
-
- def finish(self):
- if not self.changed:
- print 'no changes to', self.filename
- return
- try:
- os.rename(self.filename, self.filename + '~')
- fp = open(self.filename, 'w')
- except (os.error, IOError), msg:
- print '*** Can\'t rewrite "%s":' % self.filename, msg
- return
- print 'writing', self.filename
- for line in self.lines:
- fp.write(line)
- fp.close()
- self.changed = 0
-
- def process(self, lineno, rest):
- if self.lines is None:
- print '(not processed): %s:%s:%s' % (
- self.filename, lineno, rest),
- return
- i = eval(lineno) - 1
- if not 0 <= i < len(self.lines):
- print '*** Line number out of range: %s:%s:%s' % (
- self.filename, lineno, rest),
- return
- if self.lines[i] == rest:
- print '(no change): %s:%s:%s' % (
- self.filename, lineno, rest),
- return
- if not self.changed:
- self.changed = 1
- print '%sc%s' % (lineno, lineno)
- print '<', self.lines[i],
- print '---'
- self.lines[i] = rest
- print '>', self.lines[i],
-
-def main():
- if sys.argv[1:]:
- try:
- fp = open(sys.argv[1], 'r')
- except IOError, msg:
- print 'Can\'t open "%s":' % sys.argv[1], msg
- sys.exit(1)
- else:
- fp = sys.stdin
- curfile = None
- while 1:
- line = fp.readline()
- if not line:
- if curfile: curfile.finish()
- break
- n = prog.match(line)
- if n < 0:
- print 'Funny line:', line,
- continue
- filename, lineno = prog.group(1, 2)
- if not curfile or filename <> curfile.filename:
- if curfile: curfile.finish()
- curfile = FileObj(filename)
- curfile.process(lineno, line[n:])
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/sockets/README b/Demo/sockets/README
deleted file mode 100644
index eba7c23..0000000
--- a/Demo/sockets/README
+++ /dev/null
@@ -1,14 +0,0 @@
-This directory contains some demonstrations of the socket module:
-
-broadcast.py Broadcast the time to radio.py.
-echosvr.py About the simplest TCP server possible.
-finger.py Client for the 'finger' protocol.
-ftp.py A very simple ftp client.
-gopher.py A simple gopher client.
-mcast.py IPv4/v6 multicast example
-radio.py Receive time broadcasts from broadcast.py.
-telnet.py Client for the 'telnet' protocol.
-throughput.py Client and server to measure TCP throughput.
-unixclient.py Unix socket example, client side
-unixserver.py Unix socket example, server side
-udpecho.py Client and server for the UDP echo protocol.
diff --git a/Demo/sockets/broadcast.py b/Demo/sockets/broadcast.py
deleted file mode 100644
index 6d2b1e8..0000000
--- a/Demo/sockets/broadcast.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Send UDP broadcast packets
-
-MYPORT = 50000
-
-import sys, time
-from socket import *
-
-s = socket(AF_INET, SOCK_DGRAM)
-s.bind(('', 0))
-s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
-
-while 1:
- data = repr(time.time()) + '\n'
- s.sendto(data, ('<broadcast>', MYPORT))
- time.sleep(2)
diff --git a/Demo/sockets/echosvr.py b/Demo/sockets/echosvr.py
deleted file mode 100755
index f8a9623..0000000
--- a/Demo/sockets/echosvr.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#! /usr/bin/env python
-
-# Python implementation of an 'echo' tcp server: echo all data it receives.
-#
-# This is the simplest possible server, servicing a single request only.
-
-import sys
-from socket import *
-
-# The standard echo port isn't very useful, it requires root permissions!
-# ECHO_PORT = 7
-ECHO_PORT = 50000 + 7
-BUFSIZE = 1024
-
-def main():
- if len(sys.argv) > 1:
- port = int(eval(sys.argv[1]))
- else:
- port = ECHO_PORT
- s = socket(AF_INET, SOCK_STREAM)
- s.bind(('', port))
- s.listen(1)
- conn, (remotehost, remoteport) = s.accept()
- print 'connected by', remotehost, remoteport
- while 1:
- data = conn.recv(BUFSIZE)
- if not data:
- break
- conn.send(data)
-
-main()
diff --git a/Demo/sockets/finger.py b/Demo/sockets/finger.py
deleted file mode 100755
index e8b9ed2..0000000
--- a/Demo/sockets/finger.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#! /usr/bin/env python
-
-# Python interface to the Internet finger daemon.
-#
-# Usage: finger [options] [user][@host] ...
-#
-# If no host is given, the finger daemon on the local host is contacted.
-# Options are passed uninterpreted to the finger daemon!
-
-
-import sys, string
-from socket import *
-
-
-# Hardcode the number of the finger port here.
-# It's not likely to change soon...
-#
-FINGER_PORT = 79
-
-
-# Function to do one remote finger invocation.
-# Output goes directly to stdout (although this can be changed).
-#
-def finger(host, args):
- s = socket(AF_INET, SOCK_STREAM)
- s.connect((host, FINGER_PORT))
- s.send(args + '\n')
- while 1:
- buf = s.recv(1024)
- if not buf: break
- sys.stdout.write(buf)
- sys.stdout.flush()
-
-
-# Main function: argument parsing.
-#
-def main():
- options = ''
- i = 1
- while i < len(sys.argv) and sys.argv[i][:1] == '-':
- options = options + sys.argv[i] + ' '
- i = i+1
- args = sys.argv[i:]
- if not args:
- args = ['']
- for arg in args:
- if '@' in arg:
- at = string.index(arg, '@')
- host = arg[at+1:]
- arg = arg[:at]
- else:
- host = ''
- finger(host, options + arg)
-
-
-# Call the main function.
-#
-main()
diff --git a/Demo/sockets/ftp.py b/Demo/sockets/ftp.py
deleted file mode 100644
index 8be0812..0000000
--- a/Demo/sockets/ftp.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# A simple FTP client.
-#
-# The information to write this program was gathered from RFC 959,
-# but this is not a complete implementation! Yet it shows how a simple
-# FTP client can be built, and you are welcome to extend it to suit
-# it to your needs...
-#
-# How it works (assuming you've read the RFC):
-#
-# User commands are passed uninterpreted to the server. However, the
-# user never needs to send a PORT command. Rather, the client opens a
-# port right away and sends the appropriate PORT command to the server.
-# When a response code 150 is received, this port is used to receive
-# the data (which is written to stdout in this version), and when the
-# data is exhausted, a new port is opened and a corresponding PORT
-# command sent. In order to avoid errors when reusing ports quickly
-# (and because there is no s.getsockname() method in Python yet) we
-# cycle through a number of ports in the 50000 range.
-
-
-import sys, posix, string
-from socket import *
-
-
-BUFSIZE = 1024
-
-# Default port numbers used by the FTP protocol.
-#
-FTP_PORT = 21
-FTP_DATA_PORT = FTP_PORT - 1
-
-# Change the data port to something not needing root permissions.
-#
-FTP_DATA_PORT = FTP_DATA_PORT + 50000
-
-
-# Main program (called at the end of this file).
-#
-def main():
- hostname = sys.argv[1]
- control(hostname)
-
-
-# Control process (user interface and user protocol interpreter).
-#
-def control(hostname):
- #
- # Create control connection
- #
- s = socket(AF_INET, SOCK_STREAM)
- s.connect((hostname, FTP_PORT))
- f = s.makefile('r') # Reading the replies is easier from a file...
- #
- # Control loop
- #
- r = None
- while 1:
- code = getreply(f)
- if code in ('221', 'EOF'): break
- if code == '150':
- getdata(r)
- code = getreply(f)
- r = None
- if not r:
- r = newdataport(s, f)
- cmd = getcommand()
- if not cmd: break
- s.send(cmd + '\r\n')
-
-
-# Create a new data port and send a PORT command to the server for it.
-# (Cycle through a number of ports to avoid problems with reusing
-# a port within a short time.)
-#
-nextport = 0
-#
-def newdataport(s, f):
- global nextport
- port = nextport + FTP_DATA_PORT
- nextport = (nextport+1) % 16
- r = socket(AF_INET, SOCK_STREAM)
- r.bind((gethostbyname(gethostname()), port))
- r.listen(1)
- sendportcmd(s, f, port)
- return r
-
-
-# Send an appropriate port command.
-#
-def sendportcmd(s, f, port):
- hostname = gethostname()
- hostaddr = gethostbyname(hostname)
- hbytes = string.splitfields(hostaddr, '.')
- pbytes = [repr(port//256), repr(port%256)]
- bytes = hbytes + pbytes
- cmd = 'PORT ' + string.joinfields(bytes, ',')
- s.send(cmd + '\r\n')
- code = getreply(f)
-
-
-# Process an ftp reply and return the 3-digit reply code (as a string).
-# The reply should be a line of text starting with a 3-digit number.
-# If the 4th char is '-', it is a multi-line reply and is
-# terminate by a line starting with the same 3-digit number.
-# Any text while receiving the reply is echoed to the file.
-#
-def getreply(f):
- line = f.readline()
- if not line: return 'EOF'
- print line,
- code = line[:3]
- if line[3:4] == '-':
- while 1:
- line = f.readline()
- if not line: break # Really an error
- print line,
- if line[:3] == code and line[3:4] != '-': break
- return code
-
-
-# Get the data from the data connection.
-#
-def getdata(r):
- print '(accepting data connection)'
- conn, host = r.accept()
- print '(data connection accepted)'
- while 1:
- data = conn.recv(BUFSIZE)
- if not data: break
- sys.stdout.write(data)
- print '(end of data connection)'
-
-# Get a command from the user.
-#
-def getcommand():
- try:
- while 1:
- line = raw_input('ftp.py> ')
- if line: return line
- except EOFError:
- return ''
-
-
-# Call the main program.
-#
-main()
diff --git a/Demo/sockets/gopher.py b/Demo/sockets/gopher.py
deleted file mode 100755
index cd76659..0000000
--- a/Demo/sockets/gopher.py
+++ /dev/null
@@ -1,347 +0,0 @@
-#! /usr/bin/env python
-
-# A simple gopher client.
-#
-# Usage: gopher [ [selector] host [port] ]
-
-import string
-import sys
-import os
-import socket
-
-# Default selector, host and port
-DEF_SELECTOR = ''
-DEF_HOST = 'gopher.micro.umn.edu'
-DEF_PORT = 70
-
-# Recognized file types
-T_TEXTFILE = '0'
-T_MENU = '1'
-T_CSO = '2'
-T_ERROR = '3'
-T_BINHEX = '4'
-T_DOS = '5'
-T_UUENCODE = '6'
-T_SEARCH = '7'
-T_TELNET = '8'
-T_BINARY = '9'
-T_REDUNDANT = '+'
-T_SOUND = 's'
-
-# Dictionary mapping types to strings
-typename = {'0': '<TEXT>', '1': '<DIR>', '2': '<CSO>', '3': '<ERROR>', \
- '4': '<BINHEX>', '5': '<DOS>', '6': '<UUENCODE>', '7': '<SEARCH>', \
- '8': '<TELNET>', '9': '<BINARY>', '+': '<REDUNDANT>', 's': '<SOUND>'}
-
-# Oft-used characters and strings
-CRLF = '\r\n'
-TAB = '\t'
-
-# Open a TCP connection to a given host and port
-def open_socket(host, port):
- if not port:
- port = DEF_PORT
- elif type(port) == type(''):
- port = string.atoi(port)
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect((host, port))
- return s
-
-# Send a selector to a given host and port, return a file with the reply
-def send_request(selector, host, port):
- s = open_socket(host, port)
- s.send(selector + CRLF)
- s.shutdown(1)
- return s.makefile('r')
-
-# Get a menu in the form of a list of entries
-def get_menu(selector, host, port):
- f = send_request(selector, host, port)
- list = []
- while 1:
- line = f.readline()
- if not line:
- print '(Unexpected EOF from server)'
- break
- if line[-2:] == CRLF:
- line = line[:-2]
- elif line[-1:] in CRLF:
- line = line[:-1]
- if line == '.':
- break
- if not line:
- print '(Empty line from server)'
- continue
- typechar = line[0]
- parts = string.splitfields(line[1:], TAB)
- if len(parts) < 4:
- print '(Bad line from server: %r)' % (line,)
- continue
- if len(parts) > 4:
- print '(Extra info from server: %r)' % (parts[4:],)
- parts.insert(0, typechar)
- list.append(parts)
- f.close()
- return list
-
-# Get a text file as a list of lines, with trailing CRLF stripped
-def get_textfile(selector, host, port):
- list = []
- get_alt_textfile(selector, host, port, list.append)
- return list
-
-# Get a text file and pass each line to a function, with trailing CRLF stripped
-def get_alt_textfile(selector, host, port, func):
- f = send_request(selector, host, port)
- while 1:
- line = f.readline()
- if not line:
- print '(Unexpected EOF from server)'
- break
- if line[-2:] == CRLF:
- line = line[:-2]
- elif line[-1:] in CRLF:
- line = line[:-1]
- if line == '.':
- break
- if line[:2] == '..':
- line = line[1:]
- func(line)
- f.close()
-
-# Get a binary file as one solid data block
-def get_binary(selector, host, port):
- f = send_request(selector, host, port)
- data = f.read()
- f.close()
- return data
-
-# Get a binary file and pass each block to a function
-def get_alt_binary(selector, host, port, func, blocksize):
- f = send_request(selector, host, port)
- while 1:
- data = f.read(blocksize)
- if not data:
- break
- func(data)
-
-# A *very* simple interactive browser
-
-# Browser main command, has default arguments
-def browser(*args):
- selector = DEF_SELECTOR
- host = DEF_HOST
- port = DEF_PORT
- n = len(args)
- if n > 0 and args[0]:
- selector = args[0]
- if n > 1 and args[1]:
- host = args[1]
- if n > 2 and args[2]:
- port = args[2]
- if n > 3:
- raise RuntimeError, 'too many args'
- try:
- browse_menu(selector, host, port)
- except socket.error, msg:
- print 'Socket error:', msg
- sys.exit(1)
- except KeyboardInterrupt:
- print '\n[Goodbye]'
-
-# Browse a menu
-def browse_menu(selector, host, port):
- list = get_menu(selector, host, port)
- while 1:
- print '----- MENU -----'
- print 'Selector:', repr(selector)
- print 'Host:', host, ' Port:', port
- print
- for i in range(len(list)):
- item = list[i]
- typechar, description = item[0], item[1]
- print string.rjust(repr(i+1), 3) + ':', description,
- if typename.has_key(typechar):
- print typename[typechar]
- else:
- print '<TYPE=' + repr(typechar) + '>'
- print
- while 1:
- try:
- str = raw_input('Choice [CR == up a level]: ')
- except EOFError:
- print
- return
- if not str:
- return
- try:
- choice = string.atoi(str)
- except string.atoi_error:
- print 'Choice must be a number; try again:'
- continue
- if not 0 < choice <= len(list):
- print 'Choice out of range; try again:'
- continue
- break
- item = list[choice-1]
- typechar = item[0]
- [i_selector, i_host, i_port] = item[2:5]
- if typebrowser.has_key(typechar):
- browserfunc = typebrowser[typechar]
- try:
- browserfunc(i_selector, i_host, i_port)
- except (IOError, socket.error):
- print '***', sys.exc_type, ':', sys.exc_value
- else:
- print 'Unsupported object type'
-
-# Browse a text file
-def browse_textfile(selector, host, port):
- x = None
- try:
- p = os.popen('${PAGER-more}', 'w')
- x = SaveLines(p)
- get_alt_textfile(selector, host, port, x.writeln)
- except IOError, msg:
- print 'IOError:', msg
- if x:
- x.close()
- f = open_savefile()
- if not f:
- return
- x = SaveLines(f)
- try:
- get_alt_textfile(selector, host, port, x.writeln)
- print 'Done.'
- except IOError, msg:
- print 'IOError:', msg
- x.close()
-
-# Browse a search index
-def browse_search(selector, host, port):
- while 1:
- print '----- SEARCH -----'
- print 'Selector:', repr(selector)
- print 'Host:', host, ' Port:', port
- print
- try:
- query = raw_input('Query [CR == up a level]: ')
- except EOFError:
- print
- break
- query = string.strip(query)
- if not query:
- break
- if '\t' in query:
- print 'Sorry, queries cannot contain tabs'
- continue
- browse_menu(selector + TAB + query, host, port)
-
-# "Browse" telnet-based information, i.e. open a telnet session
-def browse_telnet(selector, host, port):
- if selector:
- print 'Log in as', repr(selector)
- if type(port) <> type(''):
- port = repr(port)
- sts = os.system('set -x; exec telnet ' + host + ' ' + port)
- if sts:
- print 'Exit status:', sts
-
-# "Browse" a binary file, i.e. save it to a file
-def browse_binary(selector, host, port):
- f = open_savefile()
- if not f:
- return
- x = SaveWithProgress(f)
- get_alt_binary(selector, host, port, x.write, 8*1024)
- x.close()
-
-# "Browse" a sound file, i.e. play it or save it
-def browse_sound(selector, host, port):
- browse_binary(selector, host, port)
-
-# Dictionary mapping types to browser functions
-typebrowser = {'0': browse_textfile, '1': browse_menu, \
- '4': browse_binary, '5': browse_binary, '6': browse_textfile, \
- '7': browse_search, \
- '8': browse_telnet, '9': browse_binary, 's': browse_sound}
-
-# Class used to save lines, appending a newline to each line
-class SaveLines:
- def __init__(self, f):
- self.f = f
- def writeln(self, line):
- self.f.write(line + '\n')
- def close(self):
- sts = self.f.close()
- if sts:
- print 'Exit status:', sts
-
-# Class used to save data while showing progress
-class SaveWithProgress:
- def __init__(self, f):
- self.f = f
- def write(self, data):
- sys.stdout.write('#')
- sys.stdout.flush()
- self.f.write(data)
- def close(self):
- print
- sts = self.f.close()
- if sts:
- print 'Exit status:', sts
-
-# Ask for and open a save file, or return None if not to save
-def open_savefile():
- try:
- savefile = raw_input( \
- 'Save as file [CR == don\'t save; |pipeline or ~user/... OK]: ')
- except EOFError:
- print
- return None
- savefile = string.strip(savefile)
- if not savefile:
- return None
- if savefile[0] == '|':
- cmd = string.strip(savefile[1:])
- try:
- p = os.popen(cmd, 'w')
- except IOError, msg:
- print repr(cmd), ':', msg
- return None
- print 'Piping through', repr(cmd), '...'
- return p
- if savefile[0] == '~':
- savefile = os.path.expanduser(savefile)
- try:
- f = open(savefile, 'w')
- except IOError, msg:
- print repr(savefile), ':', msg
- return None
- print 'Saving to', repr(savefile), '...'
- return f
-
-# Test program
-def test():
- if sys.argv[4:]:
- print 'usage: gopher [ [selector] host [port] ]'
- sys.exit(2)
- elif sys.argv[3:]:
- browser(sys.argv[1], sys.argv[2], sys.argv[3])
- elif sys.argv[2:]:
- try:
- port = string.atoi(sys.argv[2])
- selector = ''
- host = sys.argv[1]
- except string.atoi_error:
- selector = sys.argv[1]
- host = sys.argv[2]
- port = ''
- browser(selector, host, port)
- elif sys.argv[1:]:
- browser('', sys.argv[1])
- else:
- browser()
-
-# Call the test program as a main program
-test()
diff --git a/Demo/sockets/mcast.py b/Demo/sockets/mcast.py
deleted file mode 100755
index 1873959..0000000
--- a/Demo/sockets/mcast.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/env python
-#
-# Send/receive UDP multicast packets.
-# Requires that your OS kernel supports IP multicast.
-#
-# Usage:
-# mcast -s (sender, IPv4)
-# mcast -s -6 (sender, IPv6)
-# mcast (receivers, IPv4)
-# mcast -6 (receivers, IPv6)
-
-MYPORT = 8123
-MYGROUP_4 = '225.0.0.250'
-MYGROUP_6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173'
-MYTTL = 1 # Increase to reach other networks
-
-import time
-import struct
-import socket
-import sys
-
-def main():
- group = MYGROUP_6 if "-6" in sys.argv[1:] else MYGROUP_4
-
- if "-s" in sys.argv[1:]:
- sender(group)
- else:
- receiver(group)
-
-
-def sender(group):
- addrinfo = socket.getaddrinfo(group, None)[0]
-
- s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)
-
- # Set Time-to-live (optional)
- ttl_bin = struct.pack('@i', MYTTL)
- if addrinfo[0] == socket.AF_INET: # IPv4
- s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin)
- else:
- s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin)
-
- while True:
- data = repr(time.time())
- s.sendto(data + '\0', (addrinfo[4][0], MYPORT))
- time.sleep(1)
-
-
-def receiver(group):
- # Look up multicast group address in name server and find out IP version
- addrinfo = socket.getaddrinfo(group, None)[0]
-
- # Create a socket
- s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)
-
- # Allow multiple copies of this program on one machine
- # (not strictly needed)
- s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-
- # Bind it to the port
- s.bind(('', MYPORT))
-
- group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0])
- # Join group
- if addrinfo[0] == socket.AF_INET: # IPv4
- mreq = group_bin + struct.pack('=I', socket.INADDR_ANY)
- s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
- else:
- mreq = group_bin + struct.pack('@I', 0)
- s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)
-
- # Loop, printing any data we receive
- while True:
- data, sender = s.recvfrom(1500)
- while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's
- print (str(sender) + ' ' + repr(data))
-
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/sockets/radio.py b/Demo/sockets/radio.py
deleted file mode 100644
index fa4ce75..0000000
--- a/Demo/sockets/radio.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Receive UDP packets transmitted by a broadcasting service
-
-MYPORT = 50000
-
-import sys
-from socket import *
-
-s = socket(AF_INET, SOCK_DGRAM)
-s.bind(('', MYPORT))
-
-while 1:
- data, wherefrom = s.recvfrom(1500, 0)
- sys.stderr.write(repr(wherefrom) + '\n')
- sys.stdout.write(data)
diff --git a/Demo/sockets/rpython.py b/Demo/sockets/rpython.py
deleted file mode 100755
index 8333d39..0000000
--- a/Demo/sockets/rpython.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#! /usr/bin/env python
-
-# Remote python client.
-# Execute Python commands remotely and send output back.
-
-import sys
-import string
-from socket import *
-
-PORT = 4127
-BUFSIZE = 1024
-
-def main():
- if len(sys.argv) < 3:
- print "usage: rpython host command"
- sys.exit(2)
- host = sys.argv[1]
- port = PORT
- i = string.find(host, ':')
- if i >= 0:
- port = string.atoi(port[i+1:])
- host = host[:i]
- command = string.join(sys.argv[2:])
- s = socket(AF_INET, SOCK_STREAM)
- s.connect((host, port))
- s.send(command)
- s.shutdown(1)
- reply = ''
- while 1:
- data = s.recv(BUFSIZE)
- if not data: break
- reply = reply + data
- print reply,
-
-main()
diff --git a/Demo/sockets/rpythond.py b/Demo/sockets/rpythond.py
deleted file mode 100755
index 81397d6..0000000
--- a/Demo/sockets/rpythond.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#! /usr/bin/env python
-
-# Remote python server.
-# Execute Python commands remotely and send output back.
-# WARNING: This version has a gaping security hole -- it accepts requests
-# from any host on the Internet!
-
-import sys
-from socket import *
-import StringIO
-import traceback
-
-PORT = 4127
-BUFSIZE = 1024
-
-def main():
- if len(sys.argv) > 1:
- port = int(eval(sys.argv[1]))
- else:
- port = PORT
- s = socket(AF_INET, SOCK_STREAM)
- s.bind(('', port))
- s.listen(1)
- while 1:
- conn, (remotehost, remoteport) = s.accept()
- print 'connected by', remotehost, remoteport
- request = ''
- while 1:
- data = conn.recv(BUFSIZE)
- if not data:
- break
- request = request + data
- reply = execute(request)
- conn.send(reply)
- conn.close()
-
-def execute(request):
- stdout = sys.stdout
- stderr = sys.stderr
- sys.stdout = sys.stderr = fakefile = StringIO.StringIO()
- try:
- try:
- exec request in {}, {}
- except:
- print
- traceback.print_exc(100)
- finally:
- sys.stderr = stderr
- sys.stdout = stdout
- return fakefile.getvalue()
-
-main()
diff --git a/Demo/sockets/telnet.py b/Demo/sockets/telnet.py
deleted file mode 100755
index d50c37f..0000000
--- a/Demo/sockets/telnet.py
+++ /dev/null
@@ -1,109 +0,0 @@
-#! /usr/bin/env python
-
-# Minimal interface to the Internet telnet protocol.
-#
-# It refuses all telnet options and does not recognize any of the other
-# telnet commands, but can still be used to connect in line-by-line mode.
-# It's also useful to play with a number of other services,
-# like time, finger, smtp and even ftp.
-#
-# Usage: telnet host [port]
-#
-# The port may be a service name or a decimal port number;
-# it defaults to 'telnet'.
-
-
-import sys, posix, time
-from socket import *
-
-BUFSIZE = 1024
-
-# Telnet protocol characters
-
-IAC = chr(255) # Interpret as command
-DONT = chr(254)
-DO = chr(253)
-WONT = chr(252)
-WILL = chr(251)
-
-def main():
- host = sys.argv[1]
- try:
- hostaddr = gethostbyname(host)
- except error:
- sys.stderr.write(sys.argv[1] + ': bad host name\n')
- sys.exit(2)
- #
- if len(sys.argv) > 2:
- servname = sys.argv[2]
- else:
- servname = 'telnet'
- #
- if '0' <= servname[:1] <= '9':
- port = eval(servname)
- else:
- try:
- port = getservbyname(servname, 'tcp')
- except error:
- sys.stderr.write(servname + ': bad tcp service name\n')
- sys.exit(2)
- #
- s = socket(AF_INET, SOCK_STREAM)
- #
- try:
- s.connect((host, port))
- except error, msg:
- sys.stderr.write('connect failed: ' + repr(msg) + '\n')
- sys.exit(1)
- #
- pid = posix.fork()
- #
- if pid == 0:
- # child -- read stdin, write socket
- while 1:
- line = sys.stdin.readline()
- s.send(line)
- else:
- # parent -- read socket, write stdout
- iac = 0 # Interpret next char as command
- opt = '' # Interpret next char as option
- while 1:
- data = s.recv(BUFSIZE)
- if not data:
- # EOF; kill child and exit
- sys.stderr.write( '(Closed by remote host)\n')
- posix.kill(pid, 9)
- sys.exit(1)
- cleandata = ''
- for c in data:
- if opt:
- print ord(c)
- s.send(opt + c)
- opt = ''
- elif iac:
- iac = 0
- if c == IAC:
- cleandata = cleandata + c
- elif c in (DO, DONT):
- if c == DO: print '(DO)',
- else: print '(DONT)',
- opt = IAC + WONT
- elif c in (WILL, WONT):
- if c == WILL: print '(WILL)',
- else: print '(WONT)',
- opt = IAC + DONT
- else:
- print '(command)', ord(c)
- elif c == IAC:
- iac = 1
- print '(IAC)',
- else:
- cleandata = cleandata + c
- sys.stdout.write(cleandata)
- sys.stdout.flush()
-
-
-try:
- main()
-except KeyboardInterrupt:
- pass
diff --git a/Demo/sockets/throughput.py b/Demo/sockets/throughput.py
deleted file mode 100755
index b8df1f3..0000000
--- a/Demo/sockets/throughput.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#! /usr/bin/env python
-
-# Test network throughput.
-#
-# Usage:
-# 1) on host_A: throughput -s [port] # start a server
-# 2) on host_B: throughput -c count host_A [port] # start a client
-#
-# The server will service multiple clients until it is killed.
-#
-# The client performs one transfer of count*BUFSIZE bytes and
-# measures the time it takes (roundtrip!).
-
-
-import sys, time
-from socket import *
-
-MY_PORT = 50000 + 42
-
-BUFSIZE = 1024
-
-
-def main():
- if len(sys.argv) < 2:
- usage()
- if sys.argv[1] == '-s':
- server()
- elif sys.argv[1] == '-c':
- client()
- else:
- usage()
-
-
-def usage():
- sys.stdout = sys.stderr
- print 'Usage: (on host_A) throughput -s [port]'
- print 'and then: (on host_B) throughput -c count host_A [port]'
- sys.exit(2)
-
-
-def server():
- if len(sys.argv) > 2:
- port = eval(sys.argv[2])
- else:
- port = MY_PORT
- s = socket(AF_INET, SOCK_STREAM)
- s.bind(('', port))
- s.listen(1)
- print 'Server ready...'
- while 1:
- conn, (host, remoteport) = s.accept()
- while 1:
- data = conn.recv(BUFSIZE)
- if not data:
- break
- del data
- conn.send('OK\n')
- conn.close()
- print 'Done with', host, 'port', remoteport
-
-
-def client():
- if len(sys.argv) < 4:
- usage()
- count = int(eval(sys.argv[2]))
- host = sys.argv[3]
- if len(sys.argv) > 4:
- port = eval(sys.argv[4])
- else:
- port = MY_PORT
- testdata = 'x' * (BUFSIZE-1) + '\n'
- t1 = time.time()
- s = socket(AF_INET, SOCK_STREAM)
- t2 = time.time()
- s.connect((host, port))
- t3 = time.time()
- i = 0
- while i < count:
- i = i+1
- s.send(testdata)
- s.shutdown(1) # Send EOF
- t4 = time.time()
- data = s.recv(BUFSIZE)
- t5 = time.time()
- print data
- print 'Raw timers:', t1, t2, t3, t4, t5
- print 'Intervals:', t2-t1, t3-t2, t4-t3, t5-t4
- print 'Total:', t5-t1
- print 'Throughput:', round((BUFSIZE*count*0.001) / (t5-t1), 3),
- print 'K/sec.'
-
-
-main()
diff --git a/Demo/sockets/udpecho.py b/Demo/sockets/udpecho.py
deleted file mode 100755
index 5181c82..0000000
--- a/Demo/sockets/udpecho.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#! /usr/bin/env python
-
-# Client and server for udp (datagram) echo.
-#
-# Usage: udpecho -s [port] (to start a server)
-# or: udpecho -c host [port] <file (client)
-
-import sys
-from socket import *
-
-ECHO_PORT = 50000 + 7
-BUFSIZE = 1024
-
-def main():
- if len(sys.argv) < 2:
- usage()
- if sys.argv[1] == '-s':
- server()
- elif sys.argv[1] == '-c':
- client()
- else:
- usage()
-
-def usage():
- sys.stdout = sys.stderr
- print 'Usage: udpecho -s [port] (server)'
- print 'or: udpecho -c host [port] <file (client)'
- sys.exit(2)
-
-def server():
- if len(sys.argv) > 2:
- port = eval(sys.argv[2])
- else:
- port = ECHO_PORT
- s = socket(AF_INET, SOCK_DGRAM)
- s.bind(('', port))
- print 'udp echo server ready'
- while 1:
- data, addr = s.recvfrom(BUFSIZE)
- print 'server received %r from %r' % (data, addr)
- s.sendto(data, addr)
-
-def client():
- if len(sys.argv) < 3:
- usage()
- host = sys.argv[2]
- if len(sys.argv) > 3:
- port = eval(sys.argv[3])
- else:
- port = ECHO_PORT
- addr = host, port
- s = socket(AF_INET, SOCK_DGRAM)
- s.bind(('', 0))
- print 'udp echo client ready, reading stdin'
- while 1:
- line = sys.stdin.readline()
- if not line:
- break
- s.sendto(line, addr)
- data, fromaddr = s.recvfrom(BUFSIZE)
- print 'client received %r from %r' % (data, fromaddr)
-
-main()
diff --git a/Demo/sockets/unicast.py b/Demo/sockets/unicast.py
deleted file mode 100644
index dd15e3c..0000000
--- a/Demo/sockets/unicast.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Send UDP broadcast packets
-
-MYPORT = 50000
-
-import sys, time
-from socket import *
-
-s = socket(AF_INET, SOCK_DGRAM)
-s.bind(('', 0))
-
-while 1:
- data = repr(time.time()) + '\n'
- s.sendto(data, ('', MYPORT))
- time.sleep(2)
diff --git a/Demo/sockets/unixclient.py b/Demo/sockets/unixclient.py
deleted file mode 100644
index fdbcc7a..0000000
--- a/Demo/sockets/unixclient.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# Echo client demo using Unix sockets
-# Piet van Oostrum
-
-from socket import *
-
-FILE = 'unix-socket'
-s = socket(AF_UNIX, SOCK_STREAM)
-s.connect(FILE)
-s.send('Hello, world')
-data = s.recv(1024)
-s.close()
-print 'Received', repr(data)
diff --git a/Demo/sockets/unixserver.py b/Demo/sockets/unixserver.py
deleted file mode 100644
index b73f857..0000000
--- a/Demo/sockets/unixserver.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Echo server demo using Unix sockets (handles one connection only)
-# Piet van Oostrum
-
-import os
-from socket import *
-
-FILE = 'unix-socket'
-s = socket(AF_UNIX, SOCK_STREAM)
-s.bind(FILE)
-
-print 'Sock name is: ['+s.getsockname()+']'
-
-# Wait for a connection
-s.listen(1)
-conn, addr = s.accept()
-
-while True:
- data = conn.recv(1024)
- if not data:
- break
- conn.send(data)
-
-conn.close()
-os.unlink(FILE)
diff --git a/Demo/threads/Coroutine.py b/Demo/threads/Coroutine.py
deleted file mode 100644
index 5de2b62..0000000
--- a/Demo/threads/Coroutine.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# Coroutine implementation using Python threads.
-#
-# Combines ideas from Guido's Generator module, and from the coroutine
-# features of Icon and Simula 67.
-#
-# To run a collection of functions as coroutines, you need to create
-# a Coroutine object to control them:
-# co = Coroutine()
-# and then 'create' a subsidiary object for each function in the
-# collection:
-# cof1 = co.create(f1 [, arg1, arg2, ...]) # [] means optional,
-# cof2 = co.create(f2 [, arg1, arg2, ...]) #... not list
-# cof3 = co.create(f3 [, arg1, arg2, ...])
-# etc. The functions need not be distinct; 'create'ing the same
-# function multiple times gives you independent instances of the
-# function.
-#
-# To start the coroutines running, use co.tran on one of the create'd
-# functions; e.g., co.tran(cof2). The routine that first executes
-# co.tran is called the "main coroutine". It's special in several
-# respects: it existed before you created the Coroutine object; if any of
-# the create'd coroutines exits (does a return, or suffers an unhandled
-# exception), EarlyExit error is raised in the main coroutine; and the
-# co.detach() method transfers control directly to the main coroutine
-# (you can't use co.tran() for this because the main coroutine doesn't
-# have a name ...).
-#
-# Coroutine objects support these methods:
-#
-# handle = .create(func [, arg1, arg2, ...])
-# Creates a coroutine for an invocation of func(arg1, arg2, ...),
-# and returns a handle ("name") for the coroutine so created. The
-# handle can be used as the target in a subsequent .tran().
-#
-# .tran(target, data=None)
-# Transfer control to the create'd coroutine "target", optionally
-# passing it an arbitrary piece of data. To the coroutine A that does
-# the .tran, .tran acts like an ordinary function call: another
-# coroutine B can .tran back to it later, and if it does A's .tran
-# returns the 'data' argument passed to B's tran. E.g.,
-#
-# in coroutine coA in coroutine coC in coroutine coB
-# x = co.tran(coC) co.tran(coB) co.tran(coA,12)
-# print x # 12
-#
-# The data-passing feature is taken from Icon, and greatly cuts
-# the need to use global variables for inter-coroutine communication.
-#
-# .back( data=None )
-# The same as .tran(invoker, data=None), where 'invoker' is the
-# coroutine that most recently .tran'ed control to the coroutine
-# doing the .back. This is akin to Icon's "&source".
-#
-# .detach( data=None )
-# The same as .tran(main, data=None), where 'main' is the
-# (unnameable!) coroutine that started it all. 'main' has all the
-# rights of any other coroutine: upon receiving control, it can
-# .tran to an arbitrary coroutine of its choosing, go .back to
-# the .detach'er, or .kill the whole thing.
-#
-# .kill()
-# Destroy all the coroutines, and return control to the main
-# coroutine. None of the create'ed coroutines can be resumed after a
-# .kill(). An EarlyExit exception does a .kill() automatically. It's
-# a good idea to .kill() coroutines you're done with, since the
-# current implementation consumes a thread for each coroutine that
-# may be resumed.
-
-import thread
-import sync
-
-class _CoEvent:
- def __init__(self, func):
- self.f = func
- self.e = sync.event()
-
- def __repr__(self):
- if self.f is None:
- return 'main coroutine'
- else:
- return 'coroutine for func ' + self.f.func_name
-
- def __hash__(self):
- return id(self)
-
- def __cmp__(x,y):
- return cmp(id(x), id(y))
-
- def resume(self):
- self.e.post()
-
- def wait(self):
- self.e.wait()
- self.e.clear()
-
-class Killed(Exception): pass
-class EarlyExit(Exception): pass
-
-class Coroutine:
- def __init__(self):
- self.active = self.main = _CoEvent(None)
- self.invokedby = {self.main: None}
- self.killed = 0
- self.value = None
- self.terminated_by = None
-
- def create(self, func, *args):
- me = _CoEvent(func)
- self.invokedby[me] = None
- thread.start_new_thread(self._start, (me,) + args)
- return me
-
- def _start(self, me, *args):
- me.wait()
- if not self.killed:
- try:
- try:
- apply(me.f, args)
- except Killed:
- pass
- finally:
- if not self.killed:
- self.terminated_by = me
- self.kill()
-
- def kill(self):
- if self.killed:
- raise TypeError, 'kill() called on dead coroutines'
- self.killed = 1
- for coroutine in self.invokedby.keys():
- coroutine.resume()
-
- def back(self, data=None):
- return self.tran( self.invokedby[self.active], data )
-
- def detach(self, data=None):
- return self.tran( self.main, data )
-
- def tran(self, target, data=None):
- if not self.invokedby.has_key(target):
- raise TypeError, '.tran target %r is not an active coroutine' % (target,)
- if self.killed:
- raise TypeError, '.tran target %r is killed' % (target,)
- self.value = data
- me = self.active
- self.invokedby[target] = me
- self.active = target
- target.resume()
-
- me.wait()
- if self.killed:
- if self.main is not me:
- raise Killed
- if self.terminated_by is not None:
- raise EarlyExit, '%r terminated early' % (self.terminated_by,)
-
- return self.value
-
-# end of module
diff --git a/Demo/threads/Generator.py b/Demo/threads/Generator.py
deleted file mode 100644
index 2e814a0..0000000
--- a/Demo/threads/Generator.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Generator implementation using threads
-
-import sys
-import thread
-
-class Killed(Exception):
- pass
-
-class Generator:
- # Constructor
- def __init__(self, func, args):
- self.getlock = thread.allocate_lock()
- self.putlock = thread.allocate_lock()
- self.getlock.acquire()
- self.putlock.acquire()
- self.func = func
- self.args = args
- self.done = 0
- self.killed = 0
- thread.start_new_thread(self._start, ())
-
- # Internal routine
- def _start(self):
- try:
- self.putlock.acquire()
- if not self.killed:
- try:
- apply(self.func, (self,) + self.args)
- except Killed:
- pass
- finally:
- if not self.killed:
- self.done = 1
- self.getlock.release()
-
- # Called by producer for each value; raise Killed if no more needed
- def put(self, value):
- if self.killed:
- raise TypeError, 'put() called on killed generator'
- self.value = value
- self.getlock.release() # Resume consumer thread
- self.putlock.acquire() # Wait for next get() call
- if self.killed:
- raise Killed
-
- # Called by producer to get next value; raise EOFError if no more
- def get(self):
- if self.killed:
- raise TypeError, 'get() called on killed generator'
- self.putlock.release() # Resume producer thread
- self.getlock.acquire() # Wait for value to appear
- if self.done:
- raise EOFError # Say there are no more values
- return self.value
-
- # Called by consumer if no more values wanted
- def kill(self):
- if self.killed:
- raise TypeError, 'kill() called on killed generator'
- self.killed = 1
- self.putlock.release()
-
- # Clone constructor
- def clone(self):
- return Generator(self.func, self.args)
-
-def pi(g):
- k, a, b, a1, b1 = 2L, 4L, 1L, 12L, 4L
- while 1:
- # Next approximation
- p, q, k = k*k, 2L*k+1L, k+1L
- a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
- # Print common digits
- d, d1 = a//b, a1//b1
- while d == d1:
- g.put(int(d))
- a, a1 = 10L*(a%b), 10L*(a1%b1)
- d, d1 = a//b, a1//b1
-
-def test():
- g = Generator(pi, ())
- g.kill()
- g = Generator(pi, ())
- for i in range(10): print g.get(),
- print
- h = g.clone()
- g.kill()
- while 1:
- print h.get(),
- sys.stdout.flush()
-
-test()
diff --git a/Demo/threads/README b/Demo/threads/README
deleted file mode 100644
index a379521..0000000
--- a/Demo/threads/README
+++ /dev/null
@@ -1,11 +0,0 @@
-This directory contains some demonstrations of the thread module.
-
-These are mostly "proof of concept" type applications:
-
-Generator.py Generator class implemented with threads.
-sync.py Condition variables primitives by Tim Peters.
-telnet.py Version of ../sockets/telnet.py using threads.
-
-Coroutine.py Coroutines using threads, by Tim Peters (22 May 94)
-fcmp.py Example of above, by Tim
-squasher.py Another example of above, also by Tim
diff --git a/Demo/threads/fcmp.py b/Demo/threads/fcmp.py
deleted file mode 100644
index 27af76d..0000000
--- a/Demo/threads/fcmp.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Coroutine example: controlling multiple instances of a single function
-
-from Coroutine import *
-
-# fringe visits a nested list in inorder, and detaches for each non-list
-# element; raises EarlyExit after the list is exhausted
-def fringe(co, list):
- for x in list:
- if type(x) is type([]):
- fringe(co, x)
- else:
- co.back(x)
-
-def printinorder(list):
- co = Coroutine()
- f = co.create(fringe, co, list)
- try:
- while 1:
- print co.tran(f),
- except EarlyExit:
- pass
- print
-
-printinorder([1,2,3]) # 1 2 3
-printinorder([[[[1,[2]]],3]]) # ditto
-x = [0, 1, [2, [3]], [4,5], [[[6]]] ]
-printinorder(x) # 0 1 2 3 4 5 6
-
-# fcmp lexicographically compares the fringes of two nested lists
-def fcmp(l1, l2):
- co1 = Coroutine(); f1 = co1.create(fringe, co1, l1)
- co2 = Coroutine(); f2 = co2.create(fringe, co2, l2)
- while 1:
- try:
- v1 = co1.tran(f1)
- except EarlyExit:
- try:
- v2 = co2.tran(f2)
- except EarlyExit:
- return 0
- co2.kill()
- return -1
- try:
- v2 = co2.tran(f2)
- except EarlyExit:
- co1.kill()
- return 1
- if v1 != v2:
- co1.kill(); co2.kill()
- return cmp(v1,v2)
-
-print fcmp(range(7), x) # 0; fringes are equal
-print fcmp(range(6), x) # -1; 1st list ends early
-print fcmp(x, range(6)) # 1; 2nd list ends early
-print fcmp(range(8), x) # 1; 2nd list ends early
-print fcmp(x, range(8)) # -1; 1st list ends early
-print fcmp([1,[[2],8]],
- [[[1],2],8]) # 0
-print fcmp([1,[[3],8]],
- [[[1],2],8]) # 1
-print fcmp([1,[[2],8]],
- [[[1],2],9]) # -1
-
-# end of example
diff --git a/Demo/threads/find.py b/Demo/threads/find.py
deleted file mode 100644
index 7d5edc1..0000000
--- a/Demo/threads/find.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# A parallelized "find(1)" using the thread module.
-
-# This demonstrates the use of a work queue and worker threads.
-# It really does do more stats/sec when using multiple threads,
-# although the improvement is only about 20-30 percent.
-# (That was 8 years ago. In 2002, on Linux, I can't measure
-# a speedup. :-( )
-
-# I'm too lazy to write a command line parser for the full find(1)
-# command line syntax, so the predicate it searches for is wired-in,
-# see function selector() below. (It currently searches for files with
-# world write permission.)
-
-# Usage: parfind.py [-w nworkers] [directory] ...
-# Default nworkers is 4
-
-
-import sys
-import getopt
-import string
-import time
-import os
-from stat import *
-import thread
-
-
-# Work queue class. Usage:
-# wq = WorkQ()
-# wq.addwork(func, (arg1, arg2, ...)) # one or more calls
-# wq.run(nworkers)
-# The work is done when wq.run() completes.
-# The function calls executed by the workers may add more work.
-# Don't use keyboard interrupts!
-
-class WorkQ:
-
- # Invariants:
-
- # - busy and work are only modified when mutex is locked
- # - len(work) is the number of jobs ready to be taken
- # - busy is the number of jobs being done
- # - todo is locked iff there is no work and somebody is busy
-
- def __init__(self):
- self.mutex = thread.allocate()
- self.todo = thread.allocate()
- self.todo.acquire()
- self.work = []
- self.busy = 0
-
- def addwork(self, func, args):
- job = (func, args)
- self.mutex.acquire()
- self.work.append(job)
- self.mutex.release()
- if len(self.work) == 1:
- self.todo.release()
-
- def _getwork(self):
- self.todo.acquire()
- self.mutex.acquire()
- if self.busy == 0 and len(self.work) == 0:
- self.mutex.release()
- self.todo.release()
- return None
- job = self.work[0]
- del self.work[0]
- self.busy = self.busy + 1
- self.mutex.release()
- if len(self.work) > 0:
- self.todo.release()
- return job
-
- def _donework(self):
- self.mutex.acquire()
- self.busy = self.busy - 1
- if self.busy == 0 and len(self.work) == 0:
- self.todo.release()
- self.mutex.release()
-
- def _worker(self):
- time.sleep(0.00001) # Let other threads run
- while 1:
- job = self._getwork()
- if not job:
- break
- func, args = job
- apply(func, args)
- self._donework()
-
- def run(self, nworkers):
- if not self.work:
- return # Nothing to do
- for i in range(nworkers-1):
- thread.start_new(self._worker, ())
- self._worker()
- self.todo.acquire()
-
-
-# Main program
-
-def main():
- nworkers = 4
- opts, args = getopt.getopt(sys.argv[1:], '-w:')
- for opt, arg in opts:
- if opt == '-w':
- nworkers = string.atoi(arg)
- if not args:
- args = [os.curdir]
-
- wq = WorkQ()
- for dir in args:
- wq.addwork(find, (dir, selector, wq))
-
- t1 = time.time()
- wq.run(nworkers)
- t2 = time.time()
-
- sys.stderr.write('Total time %r sec.\n' % (t2-t1))
-
-
-# The predicate -- defines what files we look for.
-# Feel free to change this to suit your purpose
-
-def selector(dir, name, fullname, stat):
- # Look for world writable files that are not symlinks
- return (stat[ST_MODE] & 0002) != 0 and not S_ISLNK(stat[ST_MODE])
-
-
-# The find procedure -- calls wq.addwork() for subdirectories
-
-def find(dir, pred, wq):
- try:
- names = os.listdir(dir)
- except os.error, msg:
- print repr(dir), ':', msg
- return
- for name in names:
- if name not in (os.curdir, os.pardir):
- fullname = os.path.join(dir, name)
- try:
- stat = os.lstat(fullname)
- except os.error, msg:
- print repr(fullname), ':', msg
- continue
- if pred(dir, name, fullname, stat):
- print fullname
- if S_ISDIR(stat[ST_MODE]):
- if not os.path.ismount(fullname):
- wq.addwork(find, (fullname, pred, wq))
-
-
-# Call the main program
-
-main()
diff --git a/Demo/threads/squasher.py b/Demo/threads/squasher.py
deleted file mode 100644
index 0d59cb8..0000000
--- a/Demo/threads/squasher.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# Coroutine example: general coroutine transfers
-#
-# The program is a variation of a Simula 67 program due to Dahl & Hoare,
-# (Dahl/Dijkstra/Hoare, Structured Programming; Academic Press, 1972)
-# who in turn credit the original example to Conway.
-#
-# We have a number of input lines, terminated by a 0 byte. The problem
-# is to squash them together into output lines containing 72 characters
-# each. A semicolon must be added between input lines. Runs of blanks
-# and tabs in input lines must be squashed into single blanks.
-# Occurrences of "**" in input lines must be replaced by "^".
-#
-# Here's a test case:
-
-test = """\
- d = sqrt(b**2 - 4*a*c)
-twoa = 2*a
- L = -b/twoa
- R = d/twoa
- A1 = L + R
- A2 = L - R\0
-"""
-
-# The program should print:
-
-# d = sqrt(b^2 - 4*a*c);twoa = 2*a; L = -b/twoa; R = d/twoa; A1 = L + R;
-#A2 = L - R
-#done
-
-# getline: delivers the next input line to its invoker
-# disassembler: grabs input lines from getline, and delivers them one
-# character at a time to squasher, also inserting a semicolon into
-# the stream between lines
-# squasher: grabs characters from disassembler and passes them on to
-# assembler, first replacing "**" with "^" and squashing runs of
-# whitespace
-# assembler: grabs characters from squasher and packs them into lines
-# with 72 character each, delivering each such line to putline;
-# when it sees a null byte, passes the last line to putline and
-# then kills all the coroutines
-# putline: grabs lines from assembler, and just prints them
-
-from Coroutine import *
-
-def getline(text):
- for line in string.splitfields(text, '\n'):
- co.tran(codisassembler, line)
-
-def disassembler():
- while 1:
- card = co.tran(cogetline)
- for i in range(len(card)):
- co.tran(cosquasher, card[i])
- co.tran(cosquasher, ';')
-
-def squasher():
- while 1:
- ch = co.tran(codisassembler)
- if ch == '*':
- ch2 = co.tran(codisassembler)
- if ch2 == '*':
- ch = '^'
- else:
- co.tran(coassembler, ch)
- ch = ch2
- if ch in ' \t':
- while 1:
- ch2 = co.tran(codisassembler)
- if ch2 not in ' \t':
- break
- co.tran(coassembler, ' ')
- ch = ch2
- co.tran(coassembler, ch)
-
-def assembler():
- line = ''
- while 1:
- ch = co.tran(cosquasher)
- if ch == '\0':
- break
- if len(line) == 72:
- co.tran(coputline, line)
- line = ''
- line = line + ch
- line = line + ' ' * (72 - len(line))
- co.tran(coputline, line)
- co.kill()
-
-def putline():
- while 1:
- line = co.tran(coassembler)
- print line
-
-import string
-co = Coroutine()
-cogetline = co.create(getline, test)
-coputline = co.create(putline)
-coassembler = co.create(assembler)
-codisassembler = co.create(disassembler)
-cosquasher = co.create(squasher)
-
-co.tran(coputline)
-print 'done'
-
-# end of example
diff --git a/Demo/threads/sync.py b/Demo/threads/sync.py
deleted file mode 100644
index a344abe..0000000
--- a/Demo/threads/sync.py
+++ /dev/null
@@ -1,603 +0,0 @@
-# Defines classes that provide synchronization objects. Note that use of
-# this module requires that your Python support threads.
-#
-# condition(lock=None) # a POSIX-like condition-variable object
-# barrier(n) # an n-thread barrier
-# event() # an event object
-# semaphore(n=1) # a semaphore object, with initial count n
-# mrsw() # a multiple-reader single-writer lock
-#
-# CONDITIONS
-#
-# A condition object is created via
-# import this_module
-# your_condition_object = this_module.condition(lock=None)
-#
-# As explained below, a condition object has a lock associated with it,
-# used in the protocol to protect condition data. You can specify a
-# lock to use in the constructor, else the constructor will allocate
-# an anonymous lock for you. Specifying a lock explicitly can be useful
-# when more than one condition keys off the same set of shared data.
-#
-# Methods:
-# .acquire()
-# acquire the lock associated with the condition
-# .release()
-# release the lock associated with the condition
-# .wait()
-# block the thread until such time as some other thread does a
-# .signal or .broadcast on the same condition, and release the
-# lock associated with the condition. The lock associated with
-# the condition MUST be in the acquired state at the time
-# .wait is invoked.
-# .signal()
-# wake up exactly one thread (if any) that previously did a .wait
-# on the condition; that thread will awaken with the lock associated
-# with the condition in the acquired state. If no threads are
-# .wait'ing, this is a nop. If more than one thread is .wait'ing on
-# the condition, any of them may be awakened.
-# .broadcast()
-# wake up all threads (if any) that are .wait'ing on the condition;
-# the threads are woken up serially, each with the lock in the
-# acquired state, so should .release() as soon as possible. If no
-# threads are .wait'ing, this is a nop.
-#
-# Note that if a thread does a .wait *while* a signal/broadcast is
-# in progress, it's guaranteeed to block until a subsequent
-# signal/broadcast.
-#
-# Secret feature: `broadcast' actually takes an integer argument,
-# and will wake up exactly that many waiting threads (or the total
-# number waiting, if that's less). Use of this is dubious, though,
-# and probably won't be supported if this form of condition is
-# reimplemented in C.
-#
-# DIFFERENCES FROM POSIX
-#
-# + A separate mutex is not needed to guard condition data. Instead, a
-# condition object can (must) be .acquire'ed and .release'ed directly.
-# This eliminates a common error in using POSIX conditions.
-#
-# + Because of implementation difficulties, a POSIX `signal' wakes up
-# _at least_ one .wait'ing thread. Race conditions make it difficult
-# to stop that. This implementation guarantees to wake up only one,
-# but you probably shouldn't rely on that.
-#
-# PROTOCOL
-#
-# Condition objects are used to block threads until "some condition" is
-# true. E.g., a thread may wish to wait until a producer pumps out data
-# for it to consume, or a server may wish to wait until someone requests
-# its services, or perhaps a whole bunch of threads want to wait until a
-# preceding pass over the data is complete. Early models for conditions
-# relied on some other thread figuring out when a blocked thread's
-# condition was true, and made the other thread responsible both for
-# waking up the blocked thread and guaranteeing that it woke up with all
-# data in a correct state. This proved to be very delicate in practice,
-# and gave conditions a bad name in some circles.
-#
-# The POSIX model addresses these problems by making a thread responsible
-# for ensuring that its own state is correct when it wakes, and relies
-# on a rigid protocol to make this easy; so long as you stick to the
-# protocol, POSIX conditions are easy to "get right":
-#
-# A) The thread that's waiting for some arbitrarily-complex condition
-# (ACC) to become true does:
-#
-# condition.acquire()
-# while not (code to evaluate the ACC):
-# condition.wait()
-# # That blocks the thread, *and* releases the lock. When a
-# # condition.signal() happens, it will wake up some thread that
-# # did a .wait, *and* acquire the lock again before .wait
-# # returns.
-# #
-# # Because the lock is acquired at this point, the state used
-# # in evaluating the ACC is frozen, so it's safe to go back &
-# # reevaluate the ACC.
-#
-# # At this point, ACC is true, and the thread has the condition
-# # locked.
-# # So code here can safely muck with the shared state that
-# # went into evaluating the ACC -- if it wants to.
-# # When done mucking with the shared state, do
-# condition.release()
-#
-# B) Threads that are mucking with shared state that may affect the
-# ACC do:
-#
-# condition.acquire()
-# # muck with shared state
-# condition.release()
-# if it's possible that ACC is true now:
-# condition.signal() # or .broadcast()
-#
-# Note: You may prefer to put the "if" clause before the release().
-# That's fine, but do note that anyone waiting on the signal will
-# stay blocked until the release() is done (since acquiring the
-# condition is part of what .wait() does before it returns).
-#
-# TRICK OF THE TRADE
-#
-# With simpler forms of conditions, it can be impossible to know when
-# a thread that's supposed to do a .wait has actually done it. But
-# because this form of condition releases a lock as _part_ of doing a
-# wait, the state of that lock can be used to guarantee it.
-#
-# E.g., suppose thread A spawns thread B and later wants to wait for B to
-# complete:
-#
-# In A: In B:
-#
-# B_done = condition() ... do work ...
-# B_done.acquire() B_done.acquire(); B_done.release()
-# spawn B B_done.signal()
-# ... some time later ... ... and B exits ...
-# B_done.wait()
-#
-# Because B_done was in the acquire'd state at the time B was spawned,
-# B's attempt to acquire B_done can't succeed until A has done its
-# B_done.wait() (which releases B_done). So B's B_done.signal() is
-# guaranteed to be seen by the .wait(). Without the lock trick, B
-# may signal before A .waits, and then A would wait forever.
-#
-# BARRIERS
-#
-# A barrier object is created via
-# import this_module
-# your_barrier = this_module.barrier(num_threads)
-#
-# Methods:
-# .enter()
-# the thread blocks until num_threads threads in all have done
-# .enter(). Then the num_threads threads that .enter'ed resume,
-# and the barrier resets to capture the next num_threads threads
-# that .enter it.
-#
-# EVENTS
-#
-# An event object is created via
-# import this_module
-# your_event = this_module.event()
-#
-# An event has two states, `posted' and `cleared'. An event is
-# created in the cleared state.
-#
-# Methods:
-#
-# .post()
-# Put the event in the posted state, and resume all threads
-# .wait'ing on the event (if any).
-#
-# .clear()
-# Put the event in the cleared state.
-#
-# .is_posted()
-# Returns 0 if the event is in the cleared state, or 1 if the event
-# is in the posted state.
-#
-# .wait()
-# If the event is in the posted state, returns immediately.
-# If the event is in the cleared state, blocks the calling thread
-# until the event is .post'ed by another thread.
-#
-# Note that an event, once posted, remains posted until explicitly
-# cleared. Relative to conditions, this is both the strength & weakness
-# of events. It's a strength because the .post'ing thread doesn't have to
-# worry about whether the threads it's trying to communicate with have
-# already done a .wait (a condition .signal is seen only by threads that
-# do a .wait _prior_ to the .signal; a .signal does not persist). But
-# it's a weakness because .clear'ing an event is error-prone: it's easy
-# to mistakenly .clear an event before all the threads you intended to
-# see the event get around to .wait'ing on it. But so long as you don't
-# need to .clear an event, events are easy to use safely.
-#
-# SEMAPHORES
-#
-# A semaphore object is created via
-# import this_module
-# your_semaphore = this_module.semaphore(count=1)
-#
-# A semaphore has an integer count associated with it. The initial value
-# of the count is specified by the optional argument (which defaults to
-# 1) passed to the semaphore constructor.
-#
-# Methods:
-#
-# .p()
-# If the semaphore's count is greater than 0, decrements the count
-# by 1 and returns.
-# Else if the semaphore's count is 0, blocks the calling thread
-# until a subsequent .v() increases the count. When that happens,
-# the count will be decremented by 1 and the calling thread resumed.
-#
-# .v()
-# Increments the semaphore's count by 1, and wakes up a thread (if
-# any) blocked by a .p(). It's an (detected) error for a .v() to
-# increase the semaphore's count to a value larger than the initial
-# count.
-#
-# MULTIPLE-READER SINGLE-WRITER LOCKS
-#
-# A mrsw lock is created via
-# import this_module
-# your_mrsw_lock = this_module.mrsw()
-#
-# This kind of lock is often useful with complex shared data structures.
-# The object lets any number of "readers" proceed, so long as no thread
-# wishes to "write". When a (one or more) thread declares its intention
-# to "write" (e.g., to update a shared structure), all current readers
-# are allowed to finish, and then a writer gets exclusive access; all
-# other readers & writers are blocked until the current writer completes.
-# Finally, if some thread is waiting to write and another is waiting to
-# read, the writer takes precedence.
-#
-# Methods:
-#
-# .read_in()
-# If no thread is writing or waiting to write, returns immediately.
-# Else blocks until no thread is writing or waiting to write. So
-# long as some thread has completed a .read_in but not a .read_out,
-# writers are blocked.
-#
-# .read_out()
-# Use sometime after a .read_in to declare that the thread is done
-# reading. When all threads complete reading, a writer can proceed.
-#
-# .write_in()
-# If no thread is writing (has completed a .write_in, but hasn't yet
-# done a .write_out) or reading (similarly), returns immediately.
-# Else blocks the calling thread, and threads waiting to read, until
-# the current writer completes writing or all the current readers
-# complete reading; if then more than one thread is waiting to
-# write, one of them is allowed to proceed, but which one is not
-# specified.
-#
-# .write_out()
-# Use sometime after a .write_in to declare that the thread is done
-# writing. Then if some other thread is waiting to write, it's
-# allowed to proceed. Else all threads (if any) waiting to read are
-# allowed to proceed.
-#
-# .write_to_read()
-# Use instead of a .write_in to declare that the thread is done
-# writing but wants to continue reading without other writers
-# intervening. If there are other threads waiting to write, they
-# are allowed to proceed only if the current thread calls
-# .read_out; threads waiting to read are only allowed to proceed
-# if there are no threads waiting to write. (This is a
-# weakness of the interface!)
-
-import thread
-
-class condition:
- def __init__(self, lock=None):
- # the lock actually used by .acquire() and .release()
- if lock is None:
- self.mutex = thread.allocate_lock()
- else:
- if hasattr(lock, 'acquire') and \
- hasattr(lock, 'release'):
- self.mutex = lock
- else:
- raise TypeError, 'condition constructor requires ' \
- 'a lock argument'
-
- # lock used to block threads until a signal
- self.checkout = thread.allocate_lock()
- self.checkout.acquire()
-
- # internal critical-section lock, & the data it protects
- self.idlock = thread.allocate_lock()
- self.id = 0
- self.waiting = 0 # num waiters subject to current release
- self.pending = 0 # num waiters awaiting next signal
- self.torelease = 0 # num waiters to release
- self.releasing = 0 # 1 iff release is in progress
-
- def acquire(self):
- self.mutex.acquire()
-
- def release(self):
- self.mutex.release()
-
- def wait(self):
- mutex, checkout, idlock = self.mutex, self.checkout, self.idlock
- if not mutex.locked():
- raise ValueError, \
- "condition must be .acquire'd when .wait() invoked"
-
- idlock.acquire()
- myid = self.id
- self.pending = self.pending + 1
- idlock.release()
-
- mutex.release()
-
- while 1:
- checkout.acquire(); idlock.acquire()
- if myid < self.id:
- break
- checkout.release(); idlock.release()
-
- self.waiting = self.waiting - 1
- self.torelease = self.torelease - 1
- if self.torelease:
- checkout.release()
- else:
- self.releasing = 0
- if self.waiting == self.pending == 0:
- self.id = 0
- idlock.release()
- mutex.acquire()
-
- def signal(self):
- self.broadcast(1)
-
- def broadcast(self, num = -1):
- if num < -1:
- raise ValueError, '.broadcast called with num %r' % (num,)
- if num == 0:
- return
- self.idlock.acquire()
- if self.pending:
- self.waiting = self.waiting + self.pending
- self.pending = 0
- self.id = self.id + 1
- if num == -1:
- self.torelease = self.waiting
- else:
- self.torelease = min( self.waiting,
- self.torelease + num )
- if self.torelease and not self.releasing:
- self.releasing = 1
- self.checkout.release()
- self.idlock.release()
-
-class barrier:
- def __init__(self, n):
- self.n = n
- self.togo = n
- self.full = condition()
-
- def enter(self):
- full = self.full
- full.acquire()
- self.togo = self.togo - 1
- if self.togo:
- full.wait()
- else:
- self.togo = self.n
- full.broadcast()
- full.release()
-
-class event:
- def __init__(self):
- self.state = 0
- self.posted = condition()
-
- def post(self):
- self.posted.acquire()
- self.state = 1
- self.posted.broadcast()
- self.posted.release()
-
- def clear(self):
- self.posted.acquire()
- self.state = 0
- self.posted.release()
-
- def is_posted(self):
- self.posted.acquire()
- answer = self.state
- self.posted.release()
- return answer
-
- def wait(self):
- self.posted.acquire()
- if not self.state:
- self.posted.wait()
- self.posted.release()
-
-class semaphore:
- def __init__(self, count=1):
- if count <= 0:
- raise ValueError, 'semaphore count %d; must be >= 1' % count
- self.count = count
- self.maxcount = count
- self.nonzero = condition()
-
- def p(self):
- self.nonzero.acquire()
- while self.count == 0:
- self.nonzero.wait()
- self.count = self.count - 1
- self.nonzero.release()
-
- def v(self):
- self.nonzero.acquire()
- if self.count == self.maxcount:
- raise ValueError, '.v() tried to raise semaphore count above ' \
- 'initial value %r' % self.maxcount
- self.count = self.count + 1
- self.nonzero.signal()
- self.nonzero.release()
-
-class mrsw:
- def __init__(self):
- # critical-section lock & the data it protects
- self.rwOK = thread.allocate_lock()
- self.nr = 0 # number readers actively reading (not just waiting)
- self.nw = 0 # number writers either waiting to write or writing
- self.writing = 0 # 1 iff some thread is writing
-
- # conditions
- self.readOK = condition(self.rwOK) # OK to unblock readers
- self.writeOK = condition(self.rwOK) # OK to unblock writers
-
- def read_in(self):
- self.rwOK.acquire()
- while self.nw:
- self.readOK.wait()
- self.nr = self.nr + 1
- self.rwOK.release()
-
- def read_out(self):
- self.rwOK.acquire()
- if self.nr <= 0:
- raise ValueError, \
- '.read_out() invoked without an active reader'
- self.nr = self.nr - 1
- if self.nr == 0:
- self.writeOK.signal()
- self.rwOK.release()
-
- def write_in(self):
- self.rwOK.acquire()
- self.nw = self.nw + 1
- while self.writing or self.nr:
- self.writeOK.wait()
- self.writing = 1
- self.rwOK.release()
-
- def write_out(self):
- self.rwOK.acquire()
- if not self.writing:
- raise ValueError, \
- '.write_out() invoked without an active writer'
- self.writing = 0
- self.nw = self.nw - 1
- if self.nw:
- self.writeOK.signal()
- else:
- self.readOK.broadcast()
- self.rwOK.release()
-
- def write_to_read(self):
- self.rwOK.acquire()
- if not self.writing:
- raise ValueError, \
- '.write_to_read() invoked without an active writer'
- self.writing = 0
- self.nw = self.nw - 1
- self.nr = self.nr + 1
- if not self.nw:
- self.readOK.broadcast()
- self.rwOK.release()
-
-# The rest of the file is a test case, that runs a number of parallelized
-# quicksorts in parallel. If it works, you'll get about 600 lines of
-# tracing output, with a line like
-# test passed! 209 threads created in all
-# as the last line. The content and order of preceding lines will
-# vary across runs.
-
-def _new_thread(func, *args):
- global TID
- tid.acquire(); id = TID = TID+1; tid.release()
- io.acquire(); alive.append(id); \
- print 'starting thread', id, '--', len(alive), 'alive'; \
- io.release()
- thread.start_new_thread( func, (id,) + args )
-
-def _qsort(tid, a, l, r, finished):
- # sort a[l:r]; post finished when done
- io.acquire(); print 'thread', tid, 'qsort', l, r; io.release()
- if r-l > 1:
- pivot = a[l]
- j = l+1 # make a[l:j] <= pivot, and a[j:r] > pivot
- for i in range(j, r):
- if a[i] <= pivot:
- a[j], a[i] = a[i], a[j]
- j = j + 1
- a[l], a[j-1] = a[j-1], pivot
-
- l_subarray_sorted = event()
- r_subarray_sorted = event()
- _new_thread(_qsort, a, l, j-1, l_subarray_sorted)
- _new_thread(_qsort, a, j, r, r_subarray_sorted)
- l_subarray_sorted.wait()
- r_subarray_sorted.wait()
-
- io.acquire(); print 'thread', tid, 'qsort done'; \
- alive.remove(tid); io.release()
- finished.post()
-
-def _randarray(tid, a, finished):
- io.acquire(); print 'thread', tid, 'randomizing array'; \
- io.release()
- for i in range(1, len(a)):
- wh.acquire(); j = randint(0,i); wh.release()
- a[i], a[j] = a[j], a[i]
- io.acquire(); print 'thread', tid, 'randomizing done'; \
- alive.remove(tid); io.release()
- finished.post()
-
-def _check_sort(a):
- if a != range(len(a)):
- raise ValueError, ('a not sorted', a)
-
-def _run_one_sort(tid, a, bar, done):
- # randomize a, and quicksort it
- # for variety, all the threads running this enter a barrier
- # at the end, and post `done' after the barrier exits
- io.acquire(); print 'thread', tid, 'randomizing', a; \
- io.release()
- finished = event()
- _new_thread(_randarray, a, finished)
- finished.wait()
-
- io.acquire(); print 'thread', tid, 'sorting', a; io.release()
- finished.clear()
- _new_thread(_qsort, a, 0, len(a), finished)
- finished.wait()
- _check_sort(a)
-
- io.acquire(); print 'thread', tid, 'entering barrier'; \
- io.release()
- bar.enter()
- io.acquire(); print 'thread', tid, 'leaving barrier'; \
- io.release()
- io.acquire(); alive.remove(tid); io.release()
- bar.enter() # make sure they've all removed themselves from alive
- ## before 'done' is posted
- bar.enter() # just to be cruel
- done.post()
-
-def test():
- global TID, tid, io, wh, randint, alive
- import random
- randint = random.randint
-
- TID = 0 # thread ID (1, 2, ...)
- tid = thread.allocate_lock() # for changing TID
- io = thread.allocate_lock() # for printing, and 'alive'
- wh = thread.allocate_lock() # for calls to random
- alive = [] # IDs of active threads
-
- NSORTS = 5
- arrays = []
- for i in range(NSORTS):
- arrays.append( range( (i+1)*10 ) )
-
- bar = barrier(NSORTS)
- finished = event()
- for i in range(NSORTS):
- _new_thread(_run_one_sort, arrays[i], bar, finished)
- finished.wait()
-
- print 'all threads done, and checking results ...'
- if alive:
- raise ValueError, ('threads still alive at end', alive)
- for i in range(NSORTS):
- a = arrays[i]
- if len(a) != (i+1)*10:
- raise ValueError, ('length of array', i, 'screwed up')
- _check_sort(a)
-
- print 'test passed!', TID, 'threads created in all'
-
-if __name__ == '__main__':
- test()
-
-# end of module
diff --git a/Demo/threads/telnet.py b/Demo/threads/telnet.py
deleted file mode 100644
index 707a353..0000000
--- a/Demo/threads/telnet.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# Minimal interface to the Internet telnet protocol.
-#
-# *** modified to use threads ***
-#
-# It refuses all telnet options and does not recognize any of the other
-# telnet commands, but can still be used to connect in line-by-line mode.
-# It's also useful to play with a number of other services,
-# like time, finger, smtp and even ftp.
-#
-# Usage: telnet host [port]
-#
-# The port may be a service name or a decimal port number;
-# it defaults to 'telnet'.
-
-
-import sys, os, time
-from socket import *
-import thread
-
-BUFSIZE = 8*1024
-
-# Telnet protocol characters
-
-IAC = chr(255) # Interpret as command
-DONT = chr(254)
-DO = chr(253)
-WONT = chr(252)
-WILL = chr(251)
-
-def main():
- if len(sys.argv) < 2:
- sys.stderr.write('usage: telnet hostname [port]\n')
- sys.exit(2)
- host = sys.argv[1]
- try:
- hostaddr = gethostbyname(host)
- except error:
- sys.stderr.write(sys.argv[1] + ': bad host name\n')
- sys.exit(2)
- #
- if len(sys.argv) > 2:
- servname = sys.argv[2]
- else:
- servname = 'telnet'
- #
- if '0' <= servname[:1] <= '9':
- port = eval(servname)
- else:
- try:
- port = getservbyname(servname, 'tcp')
- except error:
- sys.stderr.write(servname + ': bad tcp service name\n')
- sys.exit(2)
- #
- s = socket(AF_INET, SOCK_STREAM)
- #
- try:
- s.connect((host, port))
- except error, msg:
- sys.stderr.write('connect failed: %r\n' % (msg,))
- sys.exit(1)
- #
- thread.start_new(child, (s,))
- parent(s)
-
-def parent(s):
- # read socket, write stdout
- iac = 0 # Interpret next char as command
- opt = '' # Interpret next char as option
- while 1:
- data, dummy = s.recvfrom(BUFSIZE)
- if not data:
- # EOF -- exit
- sys.stderr.write( '(Closed by remote host)\n')
- sys.exit(1)
- cleandata = ''
- for c in data:
- if opt:
- print ord(c)
-## print '(replying: %r)' % (opt+c,)
- s.send(opt + c)
- opt = ''
- elif iac:
- iac = 0
- if c == IAC:
- cleandata = cleandata + c
- elif c in (DO, DONT):
- if c == DO: print '(DO)',
- else: print '(DONT)',
- opt = IAC + WONT
- elif c in (WILL, WONT):
- if c == WILL: print '(WILL)',
- else: print '(WONT)',
- opt = IAC + DONT
- else:
- print '(command)', ord(c)
- elif c == IAC:
- iac = 1
- print '(IAC)',
- else:
- cleandata = cleandata + c
- sys.stdout.write(cleandata)
- sys.stdout.flush()
-## print 'Out:', repr(cleandata)
-
-def child(s):
- # read stdin, write socket
- while 1:
- line = sys.stdin.readline()
-## print 'Got:', repr(line)
- if not line: break
- s.send(line)
-
-main()
diff --git a/Demo/tix/INSTALL.txt b/Demo/tix/INSTALL.txt
deleted file mode 100644
index ac70b68..0000000
--- a/Demo/tix/INSTALL.txt
+++ /dev/null
@@ -1,89 +0,0 @@
-$Id$
-
-Installing Tix.py
-----------------
-
-0) To use Tix.py, you need Tcl/Tk (V8.3.3), Tix (V8.1.1) and Python (V2.1.1).
- Tix.py has been written and tested on a Intel Pentium running RH Linux 5.2
- and Mandrake Linux 7.0 and Windows with the above mentioned packages.
-
- Older versions, e.g. Tix 4.1 and Tk 8.0, might also work.
-
- There is nothing OS-specific in Tix.py itself so it should work on
- any machine with Tix and Python installed. You can get Tcl and Tk
- from http://dev.scriptics.com and Tix from http://tix.sourceforge.net.
-
-1) Build and install Tcl/Tk 8.3. Build and install Tix 8.1.
- Ensure that Tix is properly installed by running tixwish and executing
- the demo programs. Under Unix, use the --enable-shared configure option
- for all three. We recommend tcl8.3.3 for this release of Tix.py.
-
-2a) If you have a distribution like ActiveState with a tcl subdirectory
- of $PYTHONHOME, which contains the directories tcl8.3 and tk8.3,
- make a directory tix8.1 as well. Recursively copy the files from
- <tix>/library to $PYTHONHOME/lib/tix8.1, and copy the dynamic library
- (tix8183.dll or libtix8.1.8.3.so) to the same place as the tcl dynamic
- libraries ($PYTHONHOME/Dlls or lib/python-2.1/lib-dynload). In this
- case you are all installed, and you can skip to the end.
-
-2b) Modify Modules/Setup.dist and setup.py to change the version of the
- tix library from tix4.1.8.0 to tix8.1.8.3
- These modified files can be used for Tkinter with or without Tix.
-
-3) The default is to build dynamically, and use the Tcl 'package require'.
- To build statically, modify the Modules/Setup file to link in the Tix
- library according to the comments in the file. On Linux this looks like:
-
-# *** Always uncomment this (leave the leading underscore in!):
-_tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \
-# *** Uncomment and edit to reflect where your Tcl/Tk libraries are:
- -L/usr/local/lib \
-# *** Uncomment and edit to reflect where your Tcl/Tk headers are:
- -I/usr/local/include \
-# *** Uncomment and edit to reflect where your X11 header files are:
- -I/usr/X11R6/include \
-# *** Or uncomment this for Solaris:
-# -I/usr/openwin/include \
-# *** Uncomment and edit for BLT extension only:
-# -DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \
-# *** Uncomment and edit for PIL (TkImaging) extension only:
-# (See http://www.pythonware.com/products/pil/ for more info)
-# -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \
-# *** Uncomment and edit for TOGL extension only:
-# -DWITH_TOGL togl.c \
-# *** Uncomment and edit for Tix extension only:
- -DWITH_TIX -ltix8.1.8.3 \
-# *** Uncomment and edit to reflect your Tcl/Tk versions:
- -ltk8.3 -ltcl8.3 \
-# *** Uncomment and edit to reflect where your X11 libraries are:
- -L/usr/X11R6/lib \
-# *** Or uncomment this for Solaris:
-# -L/usr/openwin/lib \
-# *** Uncomment these for TOGL extension only:
-# -lGL -lGLU -lXext -lXmu \
-# *** Uncomment for AIX:
-# -lld \
-# *** Always uncomment this; X11 libraries to link with:
- -lX11
-
-4) Rebuild Python and reinstall.
-
-You should now have a working Tix implementation in Python. To see if all
-is as it should be, run the 'tixwidgets.py' script in the Demo/tix directory.
-Under X windows, do
- /usr/local/bin/python Demo/tix/tixwidgets.py
-
-If this does not work, you may need to tell python where to find
-the Tcl, Tk and Tix library files. This is done by setting the
-TCL_LIBRARY, TK_LIBRARY and TIX_LIBRARY environment variables. Try this:
-
- env TCL_LIBRARY=/usr/local/lib/tcl8.3 \
- TK_LIBRARY=/usr/local/lib/tk8.3 \
- TIX_LIBRARY=/usr/local/lib/tix8.1 \
- /usr/local/bin/python Demo/tix/tixwidgets.py
-
-
-If you find any bugs or have suggestions for improvement, please report them
-via http://tix.sourceforge.net
-
-
diff --git a/Demo/tix/README.txt b/Demo/tix/README.txt
deleted file mode 100644
index e0196ac..0000000
--- a/Demo/tix/README.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-About Tix.py
------------
-
-Tix.py is based on an idea of Jean-Marc Lugrin (lugrin@ms.com) who wrote
-pytix (another Python-Tix marriage). Tix widgets are an attractive and
-useful extension to Tk. See http://tix.sourceforge.net
-for more details about Tix and how to get it.
-
-Features:
- 1) It is almost complete.
- 2) Tix widgets are represented by classes in Python. Sub-widgets
- are members of the mega-widget class. For example, if a
- particular TixWidget (e.g. ScrolledText) has an embedded widget
- (Text in this case), it is possible to call the methods of the
- child directly.
- 3) The members of the class are created automatically. In the case
- of widgets like ButtonBox, the members are added dynamically.
-
-
diff --git a/Demo/tix/bitmaps/about.xpm b/Demo/tix/bitmaps/about.xpm
deleted file mode 100755
index 33ffcc0..0000000
--- a/Demo/tix/bitmaps/about.xpm
+++ /dev/null
@@ -1,50 +0,0 @@
-/* XPM */
-static char * about_xpm[] = {
-"50 40 7 1",
-" s None c None",
-". c black",
-"X c white",
-"o c gray70",
-"O c navy",
-"+ c red",
-"@ c yellow",
-" ",
-" ",
-" ",
-" ................................. ",
-" ..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXoo. ",
-" .XooooooooooooooooooooooooooooooXo. ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXooXo. ",
-" ..oooooooooooooooooooooooooooooooXo. ",
-" ...............................XoXo. ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.++++ ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo+++ ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo+++++ ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo++++++ ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo+++ + ",
-" .OOOOO@@@@@OOOOOOOOOOOOOOOOOOO.Xo++. ",
-" .OOOOOOO@OOOOO@OOOOOOOOOOOOOOO.XoXo. ",
-" .OOOOOOO@OOOOOOOOOOOOOOOOOOOOO.XoXo. ",
-" .OOOOOOO@OOOO@@OOO@OOO@OOOOOOO.XoXo. ",
-" .OOOOOOO@OOOOO@OOOO@O@OOOOOOOO.XoXo. ",
-" .OOOOOOO@OOOOO@OOOOO@OOOOOOOOO.XoXo. ",
-" .OOOOOOO@OOOOO@OOOOO@OOOOOOOOO.XoXo. ",
-" .OOOOOOO@OOOOO@OOOO@O@OOOOOOOO.XoXo. ",
-" .OOOOOOO@OOOO@@@OO@OOO@OOOOOOO.XoXo. ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo.. ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo ",
-" OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.X. ",
-" ............................. ",
-" ",
-" ",
-" "};
diff --git a/Demo/tix/bitmaps/bold.xbm b/Demo/tix/bitmaps/bold.xbm
deleted file mode 100755
index ebff8d1..0000000
--- a/Demo/tix/bitmaps/bold.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define bold_width 16
-#define bold_height 16
-static unsigned char bold_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x0f, 0x18, 0x1c, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x1c, 0xf8, 0x0f, 0xf8, 0x0f, 0x18, 0x18, 0x18, 0x30,
- 0x18, 0x30, 0x18, 0x38, 0xfc, 0x3f, 0xfc, 0x1f};
diff --git a/Demo/tix/bitmaps/capital.xbm b/Demo/tix/bitmaps/capital.xbm
deleted file mode 100755
index fb4e070..0000000
--- a/Demo/tix/bitmaps/capital.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define capital_width 16
-#define capital_height 16
-static unsigned char capital_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x08, 0x30, 0x0c, 0x30, 0x06,
- 0x30, 0x03, 0xb0, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x01, 0xb0, 0x03,
- 0x30, 0x07, 0x30, 0x0e, 0x30, 0x1c, 0x00, 0x00};
diff --git a/Demo/tix/bitmaps/centerj.xbm b/Demo/tix/bitmaps/centerj.xbm
deleted file mode 100755
index 9d2c064..0000000
--- a/Demo/tix/bitmaps/centerj.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define centerj_width 16
-#define centerj_height 16
-static unsigned char centerj_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3e, 0x00, 0x00, 0xc0, 0x0d,
- 0x00, 0x00, 0x58, 0x77, 0x00, 0x00, 0xb0, 0x3b, 0x00, 0x00, 0xdc, 0xf7,
- 0x00, 0x00, 0xf0, 0x3e, 0x00, 0x00, 0xd8, 0x7e};
diff --git a/Demo/tix/bitmaps/combobox.xbm b/Demo/tix/bitmaps/combobox.xbm
deleted file mode 100755
index f5947f5..0000000
--- a/Demo/tix/bitmaps/combobox.xbm
+++ /dev/null
@@ -1,14 +0,0 @@
-#define combobox_width 32
-#define combobox_height 32
-static unsigned char combobox_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xfc, 0xff, 0xff, 0x3e, 0x04, 0x00, 0x80, 0x2a, 0x04, 0x00, 0x80, 0x2a,
- 0x04, 0x00, 0x80, 0x2a, 0x04, 0x00, 0x80, 0x2b, 0xfc, 0xff, 0xff, 0x3e,
- 0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x2a,
- 0x28, 0x49, 0x00, 0x2a, 0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x22,
- 0x08, 0x00, 0x00, 0x22, 0x28, 0x49, 0x12, 0x22, 0x08, 0x00, 0x00, 0x22,
- 0x08, 0x00, 0x00, 0x22, 0x08, 0x00, 0x00, 0x22, 0x28, 0x49, 0x02, 0x22,
- 0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x2a, 0x08, 0x00, 0x00, 0x2a,
- 0xf8, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/Demo/tix/bitmaps/combobox.xpm b/Demo/tix/bitmaps/combobox.xpm
deleted file mode 100755
index d0234ab..0000000
--- a/Demo/tix/bitmaps/combobox.xpm
+++ /dev/null
@@ -1,49 +0,0 @@
-/* XPM */
-static char * combobox_xpm[] = {
-"50 40 6 1",
-" s None c None",
-". c black",
-"X c white",
-"o c #FFFF80808080",
-"O c gray70",
-"+ c #808000008080",
-" ",
-" ",
-" ",
-" .................................... XXXXXXX ",
-" .ooooooooooooooooooooooooooooooooooX X . . ",
-" .ooooooooooooooooooooooooooooooooooX X . . ",
-" .oooo.oooooooooooooooooooooooooooooX X . . ",
-" .oo.o..oo.o.oo.o.ooooooooooooooooooX X . . ",
-" .o..o.o.o.oo.oo.oo.ooooooooooooooooX X ... . ",
-" .oo.oo.oo.o.oo.ooo.ooooooooooooooooX X . . ",
-" .ooooooooooooooooooooooooooooooooooX X . ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X...... ",
-" ",
-" ",
-" ",
-" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
-" X............................................ ",
-" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ",
-" X.O+OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OX OX. ",
-" X.O++OOO+OO+++OOOOOOOOOOOOOOOOOOOOOOOX.X ..X. ",
-" X.O+O+O+OOO+O+OOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ",
-" X.O++OOO+OO+++OOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ",
-" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.XXXXX. ",
-" X.O.....X..........................OOX.X .X. ",
-" X.OX...XXX.X.XX.XX.................OOX.X .X. ",
-" X.OX.X..X..X.XX..XX.X..............OOX.X .X. ",
-" X.O.X...X..X.X...X..X..............OOX.X .X. ",
-" X.OOOOOOOOOOOOOOOOOOOOOOOO+OOOOOOOOOOX.X .X. ",
-" X.OOOOOOOOO+OOO+OOOOO+OOOO+OOOOOOOOOOX.X .X. ",
-" X.O+++OO+OO+O+OO++O++OO+OO+OOOOOOOOOOX.X...X. ",
-" X.OO+OO++OO+O+OO+OOO+OO+O++OOOOOOOOOOX.OOOOX. ",
-" X.OOOOOOOO+OOOOO++OO+OOOOOOOOOOOOOOOOX.OOOOX. ",
-" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.X .X. ",
-" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.O .OX. ",
-" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ",
-" X.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.XXXXX. ",
-" X............................................ ",
-" ",
-" ",
-" "};
diff --git a/Demo/tix/bitmaps/combobox.xpm.1 b/Demo/tix/bitmaps/combobox.xpm.1
deleted file mode 100755
index 63792a4..0000000
--- a/Demo/tix/bitmaps/combobox.xpm.1
+++ /dev/null
@@ -1,47 +0,0 @@
-/* XPM */
-static char * combobox_xpm[] = {
-"50 40 4 1",
-" s None c None",
-". c black",
-"X c #FFFF80808080",
-"o c gray70",
-" ",
-" ",
-" ",
-" .................................... ....... ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . ... . ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . ",
-" .................................... ....... ",
-" ",
-" ............................................. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .o...................................o.ooooo. ",
-" .o...................................o.ooooo. ",
-" .o...................................o.ooooo. ",
-" .o...................................o.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
-" ............................................. ",
-" ",
-" ",
-" ",
-" ",
-" "};
diff --git a/Demo/tix/bitmaps/drivea.xbm b/Demo/tix/bitmaps/drivea.xbm
deleted file mode 100755
index 83c636c..0000000
--- a/Demo/tix/bitmaps/drivea.xbm
+++ /dev/null
@@ -1,14 +0,0 @@
-#define drivea_width 32
-#define drivea_height 32
-static unsigned char drivea_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xf8, 0xff, 0xff, 0x1f, 0x08, 0x00, 0x00, 0x18, 0xa8, 0xaa, 0xaa, 0x1a,
- 0x48, 0x55, 0xd5, 0x1d, 0xa8, 0xaa, 0xaa, 0x1b, 0x48, 0x55, 0x55, 0x1d,
- 0xa8, 0xfa, 0xaf, 0x1a, 0xc8, 0xff, 0xff, 0x1d, 0xa8, 0xfa, 0xaf, 0x1a,
- 0x48, 0x55, 0x55, 0x1d, 0xa8, 0xaa, 0xaa, 0x1a, 0x48, 0x55, 0x55, 0x1d,
- 0xa8, 0xaa, 0xaa, 0x1a, 0xf8, 0xff, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/Demo/tix/bitmaps/drivea.xpm b/Demo/tix/bitmaps/drivea.xpm
deleted file mode 100755
index 4d274b9..0000000
--- a/Demo/tix/bitmaps/drivea.xpm
+++ /dev/null
@@ -1,43 +0,0 @@
-/* XPM */
-static char * drivea_xpm[] = {
-/* width height ncolors chars_per_pixel */
-"32 32 5 1",
-/* colors */
-" s None c None",
-". c #000000000000",
-"X c white",
-"o c #c000c000c000",
-"O c #800080008000",
-/* pixels */
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" .......................... ",
-" .XXXXXXXXXXXXXXXXXXXXXXXo. ",
-" .XooooooooooooooooooooooO. ",
-" .Xooooooooooooooooo..oooO. ",
-" .Xooooooooooooooooo..oooO. ",
-" .XooooooooooooooooooooooO. ",
-" .Xoooooooo.......oooooooO. ",
-" .Xoo...................oO. ",
-" .Xoooooooo.......oooooooO. ",
-" .XooooooooooooooooooooooO. ",
-" .XooooooooooooooooooooooO. ",
-" .XooooooooooooooooooooooO. ",
-" .XooooooooooooooooooooooO. ",
-" .oOOOOOOOOOOOOOOOOOOOOOOO. ",
-" .......................... ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
diff --git a/Demo/tix/bitmaps/exit.xpm b/Demo/tix/bitmaps/exit.xpm
deleted file mode 100755
index 505a07b..0000000
--- a/Demo/tix/bitmaps/exit.xpm
+++ /dev/null
@@ -1,48 +0,0 @@
-/* XPM */
-static char * exit_xpm[] = {
-"50 40 5 1",
-" s None c None",
-". c black",
-"X c white",
-"o c #000080800000",
-"O c yellow",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ....................................... ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. ",
-" .XoooooooooooooooooooooooooooooooooooX. ",
-" .XoooooooooooooooooooooooooooooooooooX. ",
-" .XoooooooooooooooooooooooOoooooooooooX. ",
-" .XoooooooooooooooooooooooOOooooooooooX. ",
-" .XoooooooooooooooooooooooOOOoooooooooX. ",
-" .XoooooOOOOOOOOOOOOOOOOOOOOOOooooooooX. ",
-" .XoooooOOOOOOOOOOOOOOOOOOOOOOOoooooooX. ",
-" .XoooooOOOOOOOOOOOOOOOOOOOOOOOOooooooX. ",
-" .XoooooOOOOOOOOOOOOOOOOOOOOOOOOOoooooX. ",
-" .XoooooOOOOOOOOOOOOOOOOOOOOOOOOooooooX. ",
-" .XoooooOOOOOOOOOOOOOOOOOOOOOOOoooooooX. ",
-" .XoooooOOOOOOOOOOOOOOOOOOOOOOooooooooX. ",
-" .XoooooooooooooooooooooooOOOoooooooooX. ",
-" .XoooooooooooooooooooooooOOooooooooooX. ",
-" .XoooooooooooooooooooooooOoooooooooooX. ",
-" .XoooooooooooooooooooooooooooooooooooX. ",
-" .XoooooooooooooooooooooooooooooooooooX. ",
-" .XoooooooooooooooooooooooooooooooooooX. ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. ",
-" ....................................... ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
diff --git a/Demo/tix/bitmaps/filebox.xbm b/Demo/tix/bitmaps/filebox.xbm
deleted file mode 100755
index c8f7ac2..0000000
--- a/Demo/tix/bitmaps/filebox.xbm
+++ /dev/null
@@ -1,14 +0,0 @@
-#define filebox_width 32
-#define filebox_height 32
-static unsigned char filebox_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x3f, 0x04, 0x00, 0x00, 0x20,
- 0xe4, 0xff, 0xff, 0x27, 0x24, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x24,
- 0xe4, 0xff, 0xff, 0x27, 0x04, 0x00, 0x00, 0x20, 0xe4, 0x7f, 0xfe, 0x27,
- 0x24, 0x50, 0x02, 0x25, 0x24, 0x40, 0x02, 0x24, 0x24, 0x50, 0x02, 0x25,
- 0x24, 0x40, 0x02, 0x24, 0x24, 0x50, 0x02, 0x25, 0x24, 0x40, 0x02, 0x24,
- 0x24, 0x50, 0x02, 0x25, 0xe4, 0x7f, 0xfe, 0x27, 0x04, 0x00, 0x00, 0x20,
- 0xe4, 0xff, 0xff, 0x27, 0x24, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x24,
- 0xe4, 0xff, 0xff, 0x27, 0x04, 0x00, 0x00, 0x20, 0xfc, 0xff, 0xff, 0x3f,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/Demo/tix/bitmaps/filebox.xpm b/Demo/tix/bitmaps/filebox.xpm
deleted file mode 100755
index 7377ee6..0000000
--- a/Demo/tix/bitmaps/filebox.xpm
+++ /dev/null
@@ -1,49 +0,0 @@
-/* XPM */
-static char * filebox_xpm[] = {
-"50 40 6 1",
-" s None c None",
-". c white",
-"X c gray80",
-"o c black",
-"O c #FFFF80808080",
-"+ c gray70",
-" ",
-" ",
-" ",
-" ............................................ ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXooXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXooXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXooooooooooooooooooooooooooooooooooooo.XXo ",
-" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XXo ",
-" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XXo ",
-" .XX......................................XXo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXoooooooooooooooo.XXXXoooooooooooooooo.XXo ",
-" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
-" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
-" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
-" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
-" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
-" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
-" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
-" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
-" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
-" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
-" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
-" .XX.................XXXX.................XXo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXooXooXoXooXoXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXooXooXoXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXoooooooooooooooooooooooooooooooooooooo.Xo ",
-" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo ",
-" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo ",
-" .XX.......................................Xo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .ooooooooooooooooooooooooooooooooooooooooooo ",
-" ",
-" ",
-" "};
diff --git a/Demo/tix/bitmaps/italic.xbm b/Demo/tix/bitmaps/italic.xbm
deleted file mode 100755
index 169c3cb..0000000
--- a/Demo/tix/bitmaps/italic.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define italic_width 16
-#define italic_height 16
-static unsigned char italic_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x80, 0x3f, 0x00, 0x06, 0x00, 0x06,
- 0x00, 0x03, 0x00, 0x03, 0x80, 0x01, 0x80, 0x01, 0xc0, 0x00, 0xc0, 0x00,
- 0x60, 0x00, 0x60, 0x00, 0xfc, 0x01, 0xfc, 0x01};
diff --git a/Demo/tix/bitmaps/justify.xbm b/Demo/tix/bitmaps/justify.xbm
deleted file mode 100755
index bba660a..0000000
--- a/Demo/tix/bitmaps/justify.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define justify_width 16
-#define justify_height 16
-static unsigned char justify_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xdb, 0x00, 0x00, 0x7c, 0xdb,
- 0x00, 0x00, 0xbc, 0xf7, 0x00, 0x00, 0xdc, 0xde, 0x00, 0x00, 0x6c, 0xdf,
- 0x00, 0x00, 0x6c, 0xef, 0x00, 0x00, 0xdc, 0xdf};
diff --git a/Demo/tix/bitmaps/leftj.xbm b/Demo/tix/bitmaps/leftj.xbm
deleted file mode 100755
index 5f8e006..0000000
--- a/Demo/tix/bitmaps/leftj.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define leftj_width 16
-#define leftj_height 16
-static unsigned char leftj_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x6d, 0x00, 0x00, 0xdc, 0x01,
- 0x00, 0x00, 0xec, 0x0e, 0x00, 0x00, 0xfc, 0x7e, 0x00, 0x00, 0xdc, 0x03,
- 0x00, 0x00, 0x6c, 0x3b, 0x00, 0x00, 0x6c, 0x1f};
diff --git a/Demo/tix/bitmaps/netw.xbm b/Demo/tix/bitmaps/netw.xbm
deleted file mode 100755
index a684d65..0000000
--- a/Demo/tix/bitmaps/netw.xbm
+++ /dev/null
@@ -1,14 +0,0 @@
-#define netw_width 32
-#define netw_height 32
-static unsigned char netw_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x02, 0x40,
- 0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x52,
- 0x00, 0x00, 0x0a, 0x52, 0x00, 0x00, 0x8a, 0x51, 0x00, 0x00, 0x0a, 0x50,
- 0x00, 0x00, 0x4a, 0x50, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x50,
- 0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x02, 0x40, 0xfe, 0x7f, 0x52, 0x55,
- 0x02, 0x40, 0xaa, 0x6a, 0xfa, 0x5f, 0xfe, 0x7f, 0x0a, 0x50, 0xfe, 0x7f,
- 0x0a, 0x52, 0x80, 0x00, 0x0a, 0x52, 0x80, 0x00, 0x8a, 0x51, 0x80, 0x00,
- 0x0a, 0x50, 0x80, 0x00, 0x4a, 0x50, 0x80, 0x00, 0x0a, 0x50, 0xe0, 0x03,
- 0x0a, 0x50, 0x20, 0x02, 0xfa, 0xdf, 0x3f, 0x03, 0x02, 0x40, 0xa0, 0x02,
- 0x52, 0x55, 0xe0, 0x03, 0xaa, 0x6a, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00,
- 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/Demo/tix/bitmaps/netw.xpm b/Demo/tix/bitmaps/netw.xpm
deleted file mode 100755
index fff6593..0000000
--- a/Demo/tix/bitmaps/netw.xpm
+++ /dev/null
@@ -1,45 +0,0 @@
-/* XPM */
-static char * netw_xpm[] = {
-/* width height ncolors chars_per_pixel */
-"32 32 7 1",
-/* colors */
-" s None c None",
-". c #000000000000",
-"X c white",
-"o c #c000c000c000",
-"O c #404040",
-"+ c blue",
-"@ c red",
-/* pixels */
-" ",
-" .............. ",
-" .XXXXXXXXXXXX. ",
-" .XooooooooooO. ",
-" .Xo.......XoO. ",
-" .Xo.++++o+XoO. ",
-" .Xo.++++o+XoO. ",
-" .Xo.++oo++XoO. ",
-" .Xo.++++++XoO. ",
-" .Xo.+o++++XoO. ",
-" .Xo.++++++XoO. ",
-" .Xo.XXXXXXXoO. ",
-" .XooooooooooO. ",
-" .Xo@ooo....oO. ",
-" .............. .XooooooooooO. ",
-" .XXXXXXXXXXXX. .XooooooooooO. ",
-" .XooooooooooO. .OOOOOOOOOOOO. ",
-" .Xo.......XoO. .............. ",
-" .Xo.++++o+XoO. @ ",
-" .Xo.++++o+XoO. @ ",
-" .Xo.++oo++XoO. @ ",
-" .Xo.++++++XoO. @ ",
-" .Xo.+o++++XoO. @ ",
-" .Xo.++++++XoO. ..... ",
-" .Xo.XXXXXXXoO. .XXX. ",
-" .XooooooooooO.@@@@@@.X O. ",
-" .Xo@ooo....oO. .OOO. ",
-" .XooooooooooO. ..... ",
-" .XooooooooooO. ",
-" .OOOOOOOOOOOO. ",
-" .............. ",
-" "};
diff --git a/Demo/tix/bitmaps/optmenu.xpm b/Demo/tix/bitmaps/optmenu.xpm
deleted file mode 100755
index 63bab81..0000000
--- a/Demo/tix/bitmaps/optmenu.xpm
+++ /dev/null
@@ -1,48 +0,0 @@
-/* XPM */
-static char * optmenu_xpm[] = {
-"50 40 5 1",
-" s None c None",
-". c white",
-"X c gray80",
-"o c gray50",
-"O c black",
-" ",
-" ",
-" .............................. ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXXOXOXXOXXOXXXXOOXXXXXXXXXXo ",
-" .XXXOXOXXOXOXXXOXXOXXXXXXXXXXo ",
-" .XXXXOXXOXXOXXXOXXXOXXXXXXXXXo ",
-" .XXXXOXXXOXXOOXXOXOXXXXXXXXXXo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo.............o ",
-" .............................o o ",
-" ..XXXOXXXXXOXXXXXXXXOXXXXXXXOo o ",
-" ..XXOXOXOXXOXOXXXOXXOXXXXXXXOo ...... o ",
-" ..XXXOXXXOXXOXXXOXXXOXXXXXXXOo . o o ",
-" ..XXOXXXOXXXOXOXXOXXOXXXXXXXOo . o o ",
-" ..XXXXXXXXXXXXXXXXXXXXXXXXXXOo .ooooo o ",
-" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOo o ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo o ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXooooooooooooooo ",
-" .XXXXOXXXXXOXXXXXXXXXXXXXXXXXo ",
-" .XXXOXXXXXXXXXOXXXXXXXXXXXXXXo ",
-" .XXXXOXXOXXOXOXOXXXXXXXXXXXXXo ",
-" .XXXXXOXXOXOXXXXXXXXXXXXXXXXXo ",
-" .XXXXXXXXXXXXXOXXXXXXXXXXXXXXo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXXOXOXXXXXXXOXOXXXXXOXXXXXXo ",
-" .XXXXXOXOXOXXOXXXXXOXXOXXXXXXo ",
-" .XXXXOXXOXOXOXXXOXOXOXXOXXXXXo ",
-" .XXXOXXXXOXXOXXXOXXOXXXXOXXXXo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
-" oooooooooooooooooooooooooooooo ",
-" ",
-" ",
-" ",
-" "};
diff --git a/Demo/tix/bitmaps/rightj.xbm b/Demo/tix/bitmaps/rightj.xbm
deleted file mode 100755
index 1d438e0..0000000
--- a/Demo/tix/bitmaps/rightj.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define rightj_width 16
-#define rightj_height 16
-static unsigned char rightj_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdb, 0x00, 0x00, 0x70, 0xdb,
- 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0xd8, 0xde, 0x00, 0x00, 0xc0, 0xdd,
- 0x00, 0x00, 0xa0, 0xef, 0x00, 0x00, 0xd8, 0xde};
diff --git a/Demo/tix/bitmaps/select.xpm b/Demo/tix/bitmaps/select.xpm
deleted file mode 100755
index 392e5a0..0000000
--- a/Demo/tix/bitmaps/select.xpm
+++ /dev/null
@@ -1,52 +0,0 @@
-/* XPM */
-static char * select_xpm[] = {
-"50 40 9 1",
-" s None c None",
-". c black",
-"X c gray95",
-"o c gray50",
-"O c gray70",
-"+ c navy",
-"@ c #000080800000",
-"# c #808000000000",
-"$ c white",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" .............................................. ",
-" .XXXXXXXXXXooooooooooooXXXXXXXXXXXoXXXXXXXXXX. ",
-" .X ooOOOOOOOOOOXX oX o. ",
-" .X ooOOOOOOOOOOXX oX o. ",
-" .X ++++ ooOOOOOOOOOOXX ... oX @ o. ",
-" .X +++++ ooOOOOOOOOOOXX . . oX @@@ o. ",
-" .X +++ + ooOOOOOOOOOOXX . . oX @ @ o. ",
-" .X + + ooOO#####OOOXX . . oX @ @ o. ",
-" .X + + ooOO#OOO##OOXX . oX @ @ o. ",
-" .X + + ooO##OOOO##OXX . oX @ @ o. ",
-" .X ++ ++ ooO###OOO#OOXX . oX @ @ o. ",
-" .X +++++++ ooO#######OOXX . oX @ @ o. ",
-" .X + + ooO##O#OO#OOXX . oX @ @ o. ",
-" .X + ++ ooO##OOOOO#OXX . . oX @ @ o. ",
-" .X + + ooOO#OOOOO#OXX . . oX @ @@ o. ",
-" .X + ++ ooOO#OOOOO#OXX .... oX @@@@@ o. ",
-" .X ooOO######OOXX oX o. ",
-" .X ooOOOOOOOOOOXX $oX o. ",
-" .XoooooooooooXXXXXXXXXXXoooooooooooXooooooooo. ",
-" .............................................. ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
diff --git a/Demo/tix/bitmaps/tix.gif b/Demo/tix/bitmaps/tix.gif
deleted file mode 100755
index e7d51a0..0000000
--- a/Demo/tix/bitmaps/tix.gif
+++ /dev/null
Binary files differ
diff --git a/Demo/tix/bitmaps/underline.xbm b/Demo/tix/bitmaps/underline.xbm
deleted file mode 100755
index f07bb46..0000000
--- a/Demo/tix/bitmaps/underline.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define underline_width 16
-#define underline_height 16
-static unsigned char underline_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x38, 0x1c,
- 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x70, 0x0e,
- 0xf0, 0x0f, 0xe0, 0x07, 0x00, 0x00, 0xf8, 0x1f};
diff --git a/Demo/tix/grid.py b/Demo/tix/grid.py
deleted file mode 100644
index 07ca87f..0000000
--- a/Demo/tix/grid.py
+++ /dev/null
@@ -1,28 +0,0 @@
-###
-import Tix as tk
-from pprint import pprint
-
-r= tk.Tk()
-r.title("test")
-
-l=tk.Label(r, name="a_label")
-l.pack()
-
-class MyGrid(tk.Grid):
- def __init__(self, *args, **kwargs):
- kwargs['editnotify']= self.editnotify
- tk.Grid.__init__(self, *args, **kwargs)
- def editnotify(self, x, y):
- return True
-
-g = MyGrid(r, name="a_grid",
-selectunit="cell")
-g.pack(fill=tk.BOTH)
-for x in xrange(5):
- for y in xrange(5):
- g.set(x,y,text=str((x,y)))
-
-c = tk.Button(r, text="Close", command=r.destroy)
-c.pack()
-
-tk.mainloop()
diff --git a/Demo/tix/samples/Balloon.py b/Demo/tix/samples/Balloon.py
deleted file mode 100644
index 2295905..0000000
--- a/Demo/tix/samples/Balloon.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix Demostration Program
-#
-# This sample program is structured in such a way so that it can be
-# executed from the Tix demo program "tixwidgets.py": it must have a
-# procedure called "RunSample". It should also have the "if" statment
-# at the end of this file so that it can be run as a standalone
-# program.
-
-# This file demonstrates the use of the tixBalloon widget, which provides
-# a interesting way to give help tips about elements in your user interface.
-# Your can display the help message in a "balloon" and a status bar widget.
-#
-
-import Tix
-
-TCL_ALL_EVENTS = 0
-
-def RunSample (root):
- balloon = DemoBalloon(root)
- balloon.mainloop()
- balloon.destroy()
-
-class DemoBalloon:
- def __init__(self, w):
- self.root = w
- self.exit = -1
-
- z = w.winfo_toplevel()
- z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
-
- status = Tix.Label(w, width=40, relief=Tix.SUNKEN, bd=1)
- status.pack(side=Tix.BOTTOM, fill=Tix.Y, padx=2, pady=1)
-
- # Create two mysterious widgets that need balloon help
- button1 = Tix.Button(w, text='Something Unexpected',
- command=self.quitcmd)
- button2 = Tix.Button(w, text='Something Else Unexpected')
- button2['command'] = lambda w=button2: w.destroy()
- button1.pack(side=Tix.TOP, expand=1)
- button2.pack(side=Tix.TOP, expand=1)
-
- # Create the balloon widget and associate it with the widgets that we want
- # to provide tips for:
- b = Tix.Balloon(w, statusbar=status)
-
- b.bind_widget(button1, balloonmsg='Close Window',
- statusmsg='Press this button to close this window')
- b.bind_widget(button2, balloonmsg='Self-destruct button',
- statusmsg='Press this button and it will destroy itself')
-
- def quitcmd (self):
- self.exit = 0
-
- def mainloop(self):
- foundEvent = 1
- while self.exit < 0 and foundEvent > 0:
- foundEvent = self.root.tk.dooneevent(TCL_ALL_EVENTS)
-
- def destroy (self):
- self.root.destroy()
-
-if __name__ == '__main__':
- root = Tix.Tk()
- RunSample(root)
diff --git a/Demo/tix/samples/BtnBox.py b/Demo/tix/samples/BtnBox.py
deleted file mode 100644
index af2a2a8..0000000
--- a/Demo/tix/samples/BtnBox.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix Demostration Program
-#
-# This sample program is structured in such a way so that it can be
-# executed from the Tix demo program "tixwidgets.py": it must have a
-# procedure called "RunSample". It should also have the "if" statment
-# at the end of this file so that it can be run as a standalone
-# program.
-
-# This file demonstrates the use of the tixButtonBox widget, which is a
-# group of TK buttons. You can use it to manage the buttons in a dialog box,
-# for example.
-#
-
-import Tix
-
-def RunSample(w):
- # Create the label on the top of the dialog box
- #
- top = Tix.Label(w, padx=20, pady=10, bd=1, relief=Tix.RAISED,
- anchor=Tix.CENTER, text='This dialog box is\n a demonstration of the\n tixButtonBox widget')
-
- # Create the button box and add a few buttons in it. Set the
- # -width of all the buttons to the same value so that they
- # appear in the same size.
- #
- # Note that the -text, -underline, -command and -width options are all
- # standard options of the button widgets.
- #
- box = Tix.ButtonBox(w, orientation=Tix.HORIZONTAL)
- box.add('ok', text='OK', underline=0, width=5,
- command=lambda w=w: w.destroy())
- box.add('close', text='Cancel', underline=0, width=5,
- command=lambda w=w: w.destroy())
- box.pack(side=Tix.BOTTOM, fill=Tix.X)
- top.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
-
-if __name__ == '__main__':
- root = Tix.Tk()
- RunSample(root)
- root.mainloop()
diff --git a/Demo/tix/samples/CmpImg.py b/Demo/tix/samples/CmpImg.py
deleted file mode 100644
index 4720a10..0000000
--- a/Demo/tix/samples/CmpImg.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix Demostration Program
-#
-# This sample program is structured in such a way so that it can be
-# executed from the Tix demo program "tixwidgets.py": it must have a
-# procedure called "RunSample". It should also have the "if" statment
-# at the end of this file so that it can be run as a standalone
-# program.
-
-# This file demonstrates the use of the compound images: it uses compound
-# images to display a text string together with a pixmap inside
-# buttons
-#
-
-import Tix
-
-network_pixmap = """/* XPM */
-static char * netw_xpm[] = {
-/* width height ncolors chars_per_pixel */
-"32 32 7 1",
-/* colors */
-" s None c None",
-". c #000000000000",
-"X c white",
-"o c #c000c000c000",
-"O c #404040",
-"+ c blue",
-"@ c red",
-/* pixels */
-" ",
-" .............. ",
-" .XXXXXXXXXXXX. ",
-" .XooooooooooO. ",
-" .Xo.......XoO. ",
-" .Xo.++++o+XoO. ",
-" .Xo.++++o+XoO. ",
-" .Xo.++oo++XoO. ",
-" .Xo.++++++XoO. ",
-" .Xo.+o++++XoO. ",
-" .Xo.++++++XoO. ",
-" .Xo.XXXXXXXoO. ",
-" .XooooooooooO. ",
-" .Xo@ooo....oO. ",
-" .............. .XooooooooooO. ",
-" .XXXXXXXXXXXX. .XooooooooooO. ",
-" .XooooooooooO. .OOOOOOOOOOOO. ",
-" .Xo.......XoO. .............. ",
-" .Xo.++++o+XoO. @ ",
-" .Xo.++++o+XoO. @ ",
-" .Xo.++oo++XoO. @ ",
-" .Xo.++++++XoO. @ ",
-" .Xo.+o++++XoO. @ ",
-" .Xo.++++++XoO. ..... ",
-" .Xo.XXXXXXXoO. .XXX. ",
-" .XooooooooooO.@@@@@@.X O. ",
-" .Xo@ooo....oO. .OOO. ",
-" .XooooooooooO. ..... ",
-" .XooooooooooO. ",
-" .OOOOOOOOOOOO. ",
-" .............. ",
-" "};
-"""
-
-hard_disk_pixmap = """/* XPM */
-static char * drivea_xpm[] = {
-/* width height ncolors chars_per_pixel */
-"32 32 5 1",
-/* colors */
-" s None c None",
-". c #000000000000",
-"X c white",
-"o c #c000c000c000",
-"O c #800080008000",
-/* pixels */
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" .......................... ",
-" .XXXXXXXXXXXXXXXXXXXXXXXo. ",
-" .XooooooooooooooooooooooO. ",
-" .Xooooooooooooooooo..oooO. ",
-" .Xooooooooooooooooo..oooO. ",
-" .XooooooooooooooooooooooO. ",
-" .Xoooooooo.......oooooooO. ",
-" .Xoo...................oO. ",
-" .Xoooooooo.......oooooooO. ",
-" .XooooooooooooooooooooooO. ",
-" .XooooooooooooooooooooooO. ",
-" .XooooooooooooooooooooooO. ",
-" .XooooooooooooooooooooooO. ",
-" .oOOOOOOOOOOOOOOOOOOOOOOO. ",
-" .......................... ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
-"""
-
-network_bitmap = """
-#define netw_width 32
-#define netw_height 32
-static unsigned char netw_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x02, 0x40,
- 0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x52,
- 0x00, 0x00, 0x0a, 0x52, 0x00, 0x00, 0x8a, 0x51, 0x00, 0x00, 0x0a, 0x50,
- 0x00, 0x00, 0x4a, 0x50, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x50,
- 0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x02, 0x40, 0xfe, 0x7f, 0x52, 0x55,
- 0x02, 0x40, 0xaa, 0x6a, 0xfa, 0x5f, 0xfe, 0x7f, 0x0a, 0x50, 0xfe, 0x7f,
- 0x0a, 0x52, 0x80, 0x00, 0x0a, 0x52, 0x80, 0x00, 0x8a, 0x51, 0x80, 0x00,
- 0x0a, 0x50, 0x80, 0x00, 0x4a, 0x50, 0x80, 0x00, 0x0a, 0x50, 0xe0, 0x03,
- 0x0a, 0x50, 0x20, 0x02, 0xfa, 0xdf, 0x3f, 0x03, 0x02, 0x40, 0xa0, 0x02,
- 0x52, 0x55, 0xe0, 0x03, 0xaa, 0x6a, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00,
- 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-"""
-
-hard_disk_bitmap = """
-#define drivea_width 32
-#define drivea_height 32
-static unsigned char drivea_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xf8, 0xff, 0xff, 0x1f, 0x08, 0x00, 0x00, 0x18, 0xa8, 0xaa, 0xaa, 0x1a,
- 0x48, 0x55, 0xd5, 0x1d, 0xa8, 0xaa, 0xaa, 0x1b, 0x48, 0x55, 0x55, 0x1d,
- 0xa8, 0xfa, 0xaf, 0x1a, 0xc8, 0xff, 0xff, 0x1d, 0xa8, 0xfa, 0xaf, 0x1a,
- 0x48, 0x55, 0x55, 0x1d, 0xa8, 0xaa, 0xaa, 0x1a, 0x48, 0x55, 0x55, 0x1d,
- 0xa8, 0xaa, 0xaa, 0x1a, 0xf8, 0xff, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-"""
-
-def RunSample(w):
- w.img0 = Tix.Image('pixmap', data=network_pixmap)
- if not w.img0:
- w.img0 = Tix.Image('bitmap', data=network_bitmap)
- w.img1 = Tix.Image('pixmap', data=hard_disk_pixmap)
- if not w.img0:
- w.img1 = Tix.Image('bitmap', data=hard_disk_bitmap)
-
- hdd = Tix.Button(w, padx=4, pady=1, width=120)
- net = Tix.Button(w, padx=4, pady=1, width=120)
-
- # Create the first image: we create a line, then put a string,
- # a space and a image into this line, from left to right.
- # The result: we have a one-line image that consists of three
- # individual items
- #
- # The tk.calls should be methods in Tix ...
- w.hdd_img = Tix.Image('compound', window=hdd)
- w.hdd_img.tk.call(str(w.hdd_img), 'add', 'line')
- w.hdd_img.tk.call(str(w.hdd_img), 'add', 'text', '-text', 'Hard Disk',
- '-underline', '0')
- w.hdd_img.tk.call(str(w.hdd_img), 'add', 'space', '-width', '7')
- w.hdd_img.tk.call(str(w.hdd_img), 'add', 'image', '-image', w.img1)
-
- # Put this image into the first button
- #
- hdd['image'] = w.hdd_img
-
- # Next button
- w.net_img = Tix.Image('compound', window=net)
- w.net_img.tk.call(str(w.net_img), 'add', 'line')
- w.net_img.tk.call(str(w.net_img), 'add', 'text', '-text', 'Network',
- '-underline', '0')
- w.net_img.tk.call(str(w.net_img), 'add', 'space', '-width', '7')
- w.net_img.tk.call(str(w.net_img), 'add', 'image', '-image', w.img0)
-
- # Put this image into the first button
- #
- net['image'] = w.net_img
-
- close = Tix.Button(w, pady=1, text='Close',
- command=lambda w=w: w.destroy())
-
- hdd.pack(side=Tix.LEFT, padx=10, pady=10, fill=Tix.Y, expand=1)
- net.pack(side=Tix.LEFT, padx=10, pady=10, fill=Tix.Y, expand=1)
- close.pack(side=Tix.LEFT, padx=10, pady=10, fill=Tix.Y, expand=1)
-
-if __name__ == '__main__':
- root = Tix.Tk()
- RunSample(root)
- root.mainloop()
diff --git a/Demo/tix/samples/ComboBox.py b/Demo/tix/samples/ComboBox.py
deleted file mode 100644
index 9140987..0000000
--- a/Demo/tix/samples/ComboBox.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix Demostration Program
-#
-# This sample program is structured in such a way so that it can be
-# executed from the Tix demo program "tixwidgets.py": it must have a
-# procedure called "RunSample". It should also have the "if" statment
-# at the end of this file so that it can be run as a standalone
-# program.
-
-# This file demonstrates the use of the tixComboBox widget, which is close
-# to the MS Window Combo Box control.
-#
-import Tix
-
-def RunSample(w):
- global demo_month, demo_year
-
- top = Tix.Frame(w, bd=1, relief=Tix.RAISED)
-
- demo_month = Tix.StringVar()
- demo_year = Tix.StringVar()
-
- # $w.top.a is a drop-down combo box. It is not editable -- who wants
- # to invent new months?
- #
- # [Hint] The -options switch sets the options of the subwidgets.
- # [Hint] We set the label.width subwidget option of both comboboxes to
- # be 10 so that their labels appear to be aligned.
- #
- a = Tix.ComboBox(top, label="Month: ", dropdown=1,
- command=select_month, editable=0, variable=demo_month,
- options='listbox.height 6 label.width 10 label.anchor e')
-
- # $w.top.b is a non-drop-down combo box. It is not editable: we provide
- # four choices for the user, but he can enter an alternative year if he
- # wants to.
- #
- # [Hint] Use the padY and anchor options of the label subwidget to
- # align the label with the entry subwidget.
- # [Hint] Notice that you should use padY (the NAME of the option) and not
- # pady (the SWITCH of the option).
- #
- b = Tix.ComboBox(top, label="Year: ", dropdown=0,
- command=select_year, editable=1, variable=demo_year,
- options='listbox.height 4 label.padY 5 label.width 10 label.anchor ne')
-
- a.pack(side=Tix.TOP, anchor=Tix.W)
- b.pack(side=Tix.TOP, anchor=Tix.W)
-
- a.insert(Tix.END, 'January')
- a.insert(Tix.END, 'February')
- a.insert(Tix.END, 'March')
- a.insert(Tix.END, 'April')
- a.insert(Tix.END, 'May')
- a.insert(Tix.END, 'June')
- a.insert(Tix.END, 'July')
- a.insert(Tix.END, 'August')
- a.insert(Tix.END, 'September')
- a.insert(Tix.END, 'October')
- a.insert(Tix.END, 'November')
- a.insert(Tix.END, 'December')
-
- b.insert(Tix.END, '1992')
- b.insert(Tix.END, '1993')
- b.insert(Tix.END, '1994')
- b.insert(Tix.END, '1995')
- b.insert(Tix.END, '1996')
-
- # Use "tixSetSilent" to set the values of the combo box if you
- # don't want your -command procedures (cbx:select_month and
- # cbx:select_year) to be called.
- #
- a.set_silent('January')
- b.set_silent('1995')
-
- box = Tix.ButtonBox(w, orientation=Tix.HORIZONTAL)
- box.add('ok', text='Ok', underline=0, width=6,
- command=lambda w=w: ok_command(w))
- box.add('cancel', text='Cancel', underline=0, width=6,
- command=lambda w=w: w.destroy())
- box.pack(side=Tix.BOTTOM, fill=Tix.X)
- top.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
-
-def select_month(event=None):
- # tixDemo:Status "Month = %s" % demo_month.get()
- pass
-
-def select_year(event=None):
- # tixDemo:Status "Year = %s" % demo_year.get()
- pass
-
-def ok_command(w):
- # tixDemo:Status "Month = %s, Year= %s" % (demo_month.get(), demo_year.get())
- w.destroy()
-
-if __name__ == '__main__':
- root = Tix.Tk()
- RunSample(root)
- root.mainloop()
diff --git a/Demo/tix/samples/Control.py b/Demo/tix/samples/Control.py
deleted file mode 100644
index 3a344c1..0000000
--- a/Demo/tix/samples/Control.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix Demostration Program
-#
-# This sample program is structured in such a way so that it can be
-# executed from the Tix demo program "tixwidgets.py": it must have a
-# procedure called "RunSample". It should also have the "if" statment
-# at the end of this file so that it can be run as a standalone
-# program.
-
-# This file demonstrates the use of the tixControl widget -- it is an
-# entry widget with up/down arrow buttons. You can use the arrow buttons
-# to adjust the value inside the entry widget.
-#
-# This example program uses three Control widgets. One lets you select
-# integer values; one lets you select floating point values and the last
-# one lets you select a few names.
-
-import Tix
-
-TCL_ALL_EVENTS = 0
-
-def RunSample (root):
- control = DemoControl(root)
- control.mainloop()
- control.destroy()
-
-class DemoControl:
- def __init__(self, w):
- self.root = w
- self.exit = -1
-
- global demo_maker, demo_thrust, demo_num_engines
-
- demo_maker = Tix.StringVar()
- demo_thrust = Tix.DoubleVar()
- demo_num_engines = Tix.IntVar()
- demo_maker.set('P&W')
- demo_thrust.set(20000.0)
- demo_num_engines.set(2)
-
- top = Tix.Frame(w, bd=1, relief=Tix.RAISED)
-
- # $w.top.a allows only integer values
- #
- # [Hint] The -options switch sets the options of the subwidgets.
- # [Hint] We set the label.width subwidget option of the Controls to
- # be 16 so that their labels appear to be aligned.
- #
- a = Tix.Control(top, label='Number of Engines: ', integer=1,
- variable=demo_num_engines, min=1, max=4,
- options='entry.width 10 label.width 20 label.anchor e')
-
- b = Tix.Control(top, label='Thrust: ', integer=0,
- min='10000.0', max='60000.0', step=500,
- variable=demo_thrust,
- options='entry.width 10 label.width 20 label.anchor e')
-
- c = Tix.Control(top, label='Engine Maker: ', value='P&W',
- variable=demo_maker,
- options='entry.width 10 label.width 20 label.anchor e')
-
- # We can't define these in the init because the widget 'c' doesn't
- # exist yet and we need to reference it
- c['incrcmd'] = lambda w=c: adjust_maker(w, 1)
- c['decrcmd'] = lambda w=c: adjust_maker(w, -1)
- c['validatecmd'] = lambda w=c: validate_maker(w)
-
- a.pack(side=Tix.TOP, anchor=Tix.W)
- b.pack(side=Tix.TOP, anchor=Tix.W)
- c.pack(side=Tix.TOP, anchor=Tix.W)
-
- box = Tix.ButtonBox(w, orientation=Tix.HORIZONTAL)
- box.add('ok', text='Ok', underline=0, width=6,
- command=self.okcmd)
- box.add('cancel', text='Cancel', underline=0, width=6,
- command=self.quitcmd)
- box.pack(side=Tix.BOTTOM, fill=Tix.X)
- top.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
-
- def okcmd (self):
- # tixDemo:Status "Selected %d of %s engines each of thrust %d", (demo_num_engines.get(), demo_maker.get(), demo_thrust.get())
- self.quitcmd()
-
- def quitcmd (self):
- self.exit = 0
-
- def mainloop(self):
- while self.exit < 0:
- self.root.tk.dooneevent(TCL_ALL_EVENTS)
-
- def destroy (self):
- self.root.destroy()
-
-maker_list = ['P&W', 'GE', 'Rolls Royce']
-
-def adjust_maker(w, inc):
- i = maker_list.index(demo_maker.get())
- i = i + inc
- if i >= len(maker_list):
- i = 0
- elif i < 0:
- i = len(maker_list) - 1
-
- # In Tcl/Tix we should return the string maker_list[i]. We can't
- # do that in Tkinter so we set the global variable. (This works).
- demo_maker.set(maker_list[i])
-
-def validate_maker(w):
- try:
- i = maker_list.index(demo_maker.get())
- except ValueError:
- # Works here though. Why ? Beats me.
- return maker_list[0]
- # Works here though. Why ? Beats me.
- return maker_list[i]
-
-if __name__ == '__main__':
- root = Tix.Tk()
- RunSample(root)
diff --git a/Demo/tix/samples/DirList.py b/Demo/tix/samples/DirList.py
deleted file mode 100644
index 5fd8c0d..0000000
--- a/Demo/tix/samples/DirList.py
+++ /dev/null
@@ -1,131 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix Demostration Program
-#
-# This sample program is structured in such a way so that it can be
-# executed from the Tix demo program "tixwidgets.py": it must have a
-# procedure called "RunSample". It should also have the "if" statment
-# at the end of this file so that it can be run as a standalone
-# program using tixwish.
-
-# This file demonstrates the use of the tixDirList widget -- you can
-# use it for the user to select a directory. For example, an installation
-# program can use the tixDirList widget to ask the user to select the
-# installation directory for an application.
-#
-
-import Tix, os, copy
-from Tkconstants import *
-
-TCL_ALL_EVENTS = 0
-
-def RunSample (root):
- dirlist = DemoDirList(root)
- dirlist.mainloop()
- dirlist.destroy()
-
-class DemoDirList:
- def __init__(self, w):
- self.root = w
- self.exit = -1
-
- z = w.winfo_toplevel()
- z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
-
- # Create the tixDirList and the tixLabelEntry widgets on the on the top
- # of the dialog box
-
- # bg = root.tk.eval('tix option get bg')
- # adding bg=bg crashes Windows pythonw tk8.3.3 Python 2.1.0
-
- top = Tix.Frame( w, relief=RAISED, bd=1)
-
- # Create the DirList widget. By default it will show the current
- # directory
- #
- #
- top.dir = Tix.DirList(top)
- top.dir.hlist['width'] = 40
-
- # When the user presses the ".." button, the selected directory
- # is "transferred" into the entry widget
- #
- top.btn = Tix.Button(top, text = " >> ", pady = 0)
-
- # We use a LabelEntry to hold the installation directory. The user
- # can choose from the DirList widget, or he can type in the directory
- # manually
- #
- top.ent = Tix.LabelEntry(top, label="Installation Directory:",
- labelside = 'top',
- options = '''
- entry.width 40
- label.anchor w
- ''')
-
- font = self.root.tk.eval('tix option get fixed_font')
- # font = self.root.master.tix_option_get('fixed_font')
- top.ent.entry['font'] = font
-
- self.dlist_dir = copy.copy(os.curdir)
- # This should work setting the entry's textvariable
- top.ent.entry['textvariable'] = self.dlist_dir
- top.btn['command'] = lambda dir=top.dir, ent=top.ent, self=self: \
- self.copy_name(dir,ent)
-
- # top.ent.entry.insert(0,'tix'+repr(self))
- top.ent.entry.bind('<Return>', lambda self=self: self.okcmd () )
-
- top.pack( expand='yes', fill='both', side=TOP)
- top.dir.pack( expand=1, fill=BOTH, padx=4, pady=4, side=LEFT)
- top.btn.pack( anchor='s', padx=4, pady=4, side=LEFT)
- top.ent.pack( expand=1, fill=X, anchor='s', padx=4, pady=4, side=LEFT)
-
- # Use a ButtonBox to hold the buttons.
- #
- box = Tix.ButtonBox (w, orientation='horizontal')
- box.add ('ok', text='Ok', underline=0, width=6,
- command = lambda self=self: self.okcmd () )
- box.add ('cancel', text='Cancel', underline=0, width=6,
- command = lambda self=self: self.quitcmd () )
-
- box.pack( anchor='s', fill='x', side=BOTTOM)
-
- def copy_name (self, dir, ent):
- # This should work as it is the entry's textvariable
- self.dlist_dir = dir.cget('value')
- # but it isn't so I'll do it manually
- ent.entry.delete(0,'end')
- ent.entry.insert(0, self.dlist_dir)
-
- def okcmd (self):
- # tixDemo:Status "You have selected the directory" + self.dlist_dir
- self.quitcmd()
-
- def quitcmd (self):
- self.exit = 0
-
- def mainloop(self):
- while self.exit < 0:
- self.root.tk.dooneevent(TCL_ALL_EVENTS)
-
- def destroy (self):
- self.root.destroy()
-
-# This "if" statement makes it possible to run this script file inside or
-# outside of the main demo program "tixwidgets.py".
-#
-if __name__== '__main__' :
- import tkMessageBox, traceback
-
- try:
- root=Tix.Tk()
- RunSample(root)
- except:
- t, v, tb = sys.exc_info()
- text = "Error running the demo script:\n"
- for line in traceback.format_exception(t,v,tb):
- text = text + line + '\n'
- d = tkMessageBox.showerror ( 'Tix Demo Error', text)
diff --git a/Demo/tix/samples/DirTree.py b/Demo/tix/samples/DirTree.py
deleted file mode 100644
index 2e4fe0b..0000000
--- a/Demo/tix/samples/DirTree.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix Demostration Program
-#
-# This sample program is structured in such a way so that it can be
-# executed from the Tix demo program "tixwidgets.py": it must have a
-# procedure called "RunSample". It should also have the "if" statment
-# at the end of this file so that it can be run as a standalone
-# program using tixwish.
-
-# This file demonstrates the use of the tixDirTree widget -- you can
-# use it for the user to select a directory. For example, an installation
-# program can use the tixDirTree widget to ask the user to select the
-# installation directory for an application.
-#
-
-import Tix, os, copy
-from Tkconstants import *
-
-TCL_ALL_EVENTS = 0
-
-def RunSample (root):
- dirtree = DemoDirTree(root)
- dirtree.mainloop()
- dirtree.destroy()
-
-class DemoDirTree:
- def __init__(self, w):
- self.root = w
- self.exit = -1
-
- z = w.winfo_toplevel()
- z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
-
- # Create the tixDirTree and the tixLabelEntry widgets on the on the top
- # of the dialog box
-
- # bg = root.tk.eval('tix option get bg')
- # adding bg=bg crashes Windows pythonw tk8.3.3 Python 2.1.0
-
- top = Tix.Frame( w, relief=RAISED, bd=1)
-
- # Create the DirTree widget. By default it will show the current
- # directory
- #
- #
- top.dir = Tix.DirTree(top)
- top.dir.hlist['width'] = 40
-
- # When the user presses the ".." button, the selected directory
- # is "transferred" into the entry widget
- #
- top.btn = Tix.Button(top, text = " >> ", pady = 0)
-
- # We use a LabelEntry to hold the installation directory. The user
- # can choose from the DirTree widget, or he can type in the directory
- # manually
- #
- top.ent = Tix.LabelEntry(top, label="Installation Directory:",
- labelside = 'top',
- options = '''
- entry.width 40
- label.anchor w
- ''')
-
- self.dlist_dir = copy.copy(os.curdir)
- top.ent.entry['textvariable'] = self.dlist_dir
- top.btn['command'] = lambda dir=top.dir, ent=top.ent, self=self: \
- self.copy_name(dir,ent)
-
- top.ent.entry.bind('<Return>', lambda self=self: self.okcmd () )
-
- top.pack( expand='yes', fill='both', side=TOP)
- top.dir.pack( expand=1, fill=BOTH, padx=4, pady=4, side=LEFT)
- top.btn.pack( anchor='s', padx=4, pady=4, side=LEFT)
- top.ent.pack( expand=1, fill=X, anchor='s', padx=4, pady=4, side=LEFT)
-
- # Use a ButtonBox to hold the buttons.
- #
- box = Tix.ButtonBox (w, orientation='horizontal')
- box.add ('ok', text='Ok', underline=0, width=6,
- command = lambda self=self: self.okcmd () )
- box.add ('cancel', text='Cancel', underline=0, width=6,
- command = lambda self=self: self.quitcmd () )
-
- box.pack( anchor='s', fill='x', side=BOTTOM)
-
- def copy_name (self, dir, ent):
- # This should work as it is the entry's textvariable
- self.dlist_dir = dir.cget('value')
- # but it isn't so I'll do it manually
- ent.entry.delete(0,'end')
- ent.entry.insert(0, self.dlist_dir)
-
- def okcmd (self):
- # tixDemo:Status "You have selected the directory" + self.dlist_dir
- self.quitcmd()
-
- def quitcmd (self):
- # tixDemo:Status "You have selected the directory" + self.dlist_dir
- self.exit = 0
-
- def mainloop(self):
- while self.exit < 0:
- self.root.tk.dooneevent(TCL_ALL_EVENTS)
-
- def destroy (self):
- self.root.destroy()
-
-# This "if" statement makes it possible to run this script file inside or
-# outside of the main demo program "tixwidgets.py".
-#
-if __name__== '__main__' :
- root=Tix.Tk()
- RunSample(root)
diff --git a/Demo/tix/samples/NoteBook.py b/Demo/tix/samples/NoteBook.py
deleted file mode 100644
index 1e0da3e..0000000
--- a/Demo/tix/samples/NoteBook.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix Demostration Program
-#
-# This sample program is structured in such a way so that it can be
-# executed from the Tix demo program "tixwidgets.py": it must have a
-# procedure called "RunSample". It should also have the "if" statment
-# at the end of this file so that it can be run as a standalone
-# program.
-
-# This file demonstrates the use of the tixNoteBook widget, which allows
-# you to lay out your interface using a "notebook" metaphore
-#
-import Tix
-
-def RunSample(w):
- global root
- root = w
-
- # We use these options to set the sizes of the subwidgets inside the
- # notebook, so that they are well-aligned on the screen.
- prefix = Tix.OptionName(w)
- if prefix:
- prefix = '*'+prefix
- else:
- prefix = ''
- w.option_add(prefix+'*TixControl*entry.width', 10)
- w.option_add(prefix+'*TixControl*label.width', 18)
- w.option_add(prefix+'*TixControl*label.anchor', Tix.E)
- w.option_add(prefix+'*TixNoteBook*tagPadX', 8)
-
- # Create the notebook widget and set its backpagecolor to gray.
- # Note that the -backpagecolor option belongs to the "nbframe"
- # subwidget.
- nb = Tix.NoteBook(w, name='nb', ipadx=6, ipady=6)
- nb['bg'] = 'gray'
- nb.nbframe['backpagecolor'] = 'gray'
-
- # Create the two tabs on the notebook. The -underline option
- # puts a underline on the first character of the labels of the tabs.
- # Keyboard accelerators will be defined automatically according
- # to the underlined character.
- nb.add('hard_disk', label="Hard Disk", underline=0)
- nb.add('network', label="Network", underline=0)
-
- nb.pack(expand=1, fill=Tix.BOTH, padx=5, pady=5 ,side=Tix.TOP)
-
- #----------------------------------------
- # Create the first page
- #----------------------------------------
- # Create two frames: one for the common buttons, one for the
- # other widgets
- #
- tab=nb.hard_disk
- f = Tix.Frame(tab)
- common = Tix.Frame(tab)
-
- f.pack(side=Tix.LEFT, padx=2, pady=2, fill=Tix.BOTH, expand=1)
- common.pack(side=Tix.RIGHT, padx=2, fill=Tix.Y)
-
- a = Tix.Control(f, value=12, label='Access time: ')
- w = Tix.Control(f, value=400, label='Write Throughput: ')
- r = Tix.Control(f, value=400, label='Read Throughput: ')
- c = Tix.Control(f, value=1021, label='Capacity: ')
-
- a.pack(side=Tix.TOP, padx=20, pady=2)
- w.pack(side=Tix.TOP, padx=20, pady=2)
- r.pack(side=Tix.TOP, padx=20, pady=2)
- c.pack(side=Tix.TOP, padx=20, pady=2)
-
- # Create the common buttons
- createCommonButtons(common)
-
- #----------------------------------------
- # Create the second page
- #----------------------------------------
-
- tab = nb.network
-
- f = Tix.Frame(tab)
- common = Tix.Frame(tab)
-
- f.pack(side=Tix.LEFT, padx=2, pady=2, fill=Tix.BOTH, expand=1)
- common.pack(side=Tix.RIGHT, padx=2, fill=Tix.Y)
-
- a = Tix.Control(f, value=12, label='Access time: ')
- w = Tix.Control(f, value=400, label='Write Throughput: ')
- r = Tix.Control(f, value=400, label='Read Throughput: ')
- c = Tix.Control(f, value=1021, label='Capacity: ')
- u = Tix.Control(f, value=10, label='Users: ')
-
- a.pack(side=Tix.TOP, padx=20, pady=2)
- w.pack(side=Tix.TOP, padx=20, pady=2)
- r.pack(side=Tix.TOP, padx=20, pady=2)
- c.pack(side=Tix.TOP, padx=20, pady=2)
- u.pack(side=Tix.TOP, padx=20, pady=2)
-
- createCommonButtons(common)
-
-def doDestroy():
- global root
- root.destroy()
-
-def createCommonButtons(master):
- ok = Tix.Button(master, name='ok', text='OK', width=6,
- command=doDestroy)
- cancel = Tix.Button(master, name='cancel',
- text='Cancel', width=6,
- command=doDestroy)
-
- ok.pack(side=Tix.TOP, padx=2, pady=2)
- cancel.pack(side=Tix.TOP, padx=2, pady=2)
-
-if __name__ == '__main__':
- root = Tix.Tk()
- RunSample(root)
- root.mainloop()
diff --git a/Demo/tix/samples/OptMenu.py b/Demo/tix/samples/OptMenu.py
deleted file mode 100644
index 1d39420..0000000
--- a/Demo/tix/samples/OptMenu.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix Demostration Program
-#
-# This sample program is structured in such a way so that it can be
-# executed from the Tix demo program "tixwidgets.py": it must have a
-# procedure called "RunSample". It should also have the "if" statment
-# at the end of this file so that it can be run as a standalone
-# program.
-
-# This file demonstrates the use of the tixOptionMenu widget -- you can
-# use it for the user to choose from a fixed set of options
-#
-import Tix
-
-options = {'text':'Plain Text', 'post':'PostScript', 'html':'HTML',
- 'tex':'LaTeX', 'rtf':'Rich Text Format'}
-
-def RunSample(w):
- global demo_opt_from, demo_opt_to
-
- demo_opt_from = Tix.StringVar()
- demo_opt_to = Tix.StringVar()
-
- top = Tix.Frame(w, bd=1, relief=Tix.RAISED)
-
- from_file = Tix.OptionMenu(top, label="From File Format : ",
- variable=demo_opt_from,
- options = 'label.width 19 label.anchor e menubutton.width 15')
-
- to_file = Tix.OptionMenu(top, label="To File Format : ",
- variable=demo_opt_to,
- options='label.width 19 label.anchor e menubutton.width 15')
-
- # Add the available options to the two OptionMenu widgets
- #
- # [Hint] You have to add the options first before you set the
- # global variables "demo_opt_from" and "demo_opt_to". Otherwise
- # the OptionMenu widget will complain about "unknown options"!
- #
- for opt in options.keys():
- from_file.add_command(opt, label=options[opt])
- to_file.add_command(opt, label=options[opt])
-
- demo_opt_from.set('html')
- demo_opt_to.set('post')
-
- from_file.pack(side=Tix.TOP, anchor=Tix.W, pady=3, padx=6)
- to_file.pack(side=Tix.TOP, anchor=Tix.W, pady=3, padx=6)
-
- box = Tix.ButtonBox(w, orientation=Tix.HORIZONTAL)
- box.add('ok', text='Ok', underline=0, width=6,
- command=lambda w=w: ok_command(w))
- box.add('cancel', text='Cancel', underline=0, width=6,
- command=lambda w=w: w.destroy())
- box.pack(side=Tix.BOTTOM, fill=Tix.X)
- top.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
-
-def ok_command(w):
- # tixDemo:Status "Convert file from %s to %s" % ( demo_opt_from.get(), demo_opt_to.get())
- w.destroy()
-
-if __name__ == '__main__':
- root = Tix.Tk()
- RunSample(root)
- root.mainloop()
diff --git a/Demo/tix/samples/PanedWin.py b/Demo/tix/samples/PanedWin.py
deleted file mode 100644
index 3efc731..0000000
--- a/Demo/tix/samples/PanedWin.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix Demostration Program
-#
-# This sample program is structured in such a way so that it can be
-# executed from the Tix demo program "tixwidgets.py": it must have a
-# procedure called "RunSample". It should also have the "if" statment
-# at the end of this file so that it can be run as a standalone
-# program.
-
-# This file demonstrates the use of the tixPanedWindow widget. This program
-# is a dummy news reader: the user can adjust the sizes of the list
-# of artical names and the size of the text widget that shows the body
-# of the article.
-
-import Tix
-
-TCL_ALL_EVENTS = 0
-
-def RunSample (root):
- panedwin = DemoPanedwin(root)
- panedwin.mainloop()
- panedwin.destroy()
-
-class DemoPanedwin:
- def __init__(self, w):
- self.root = w
- self.exit = -1
-
- z = w.winfo_toplevel()
- z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
-
- group = Tix.LabelEntry(w, label='Newsgroup:', options='entry.width 25')
- group.entry.insert(0,'comp.lang.python')
- pane = Tix.PanedWindow(w, orientation='vertical')
-
- p1 = pane.add('list', min=70, size=100)
- p2 = pane.add('text', min=70)
- list = Tix.ScrolledListBox(p1)
- list.listbox['width'] = 80
- list.listbox['height'] = 5
- text = Tix.ScrolledText(p2)
- text.text['width'] = 80
- text.text['height'] = 20
-
- list.listbox.insert(Tix.END, " 12324 Re: Tkinter is good for your health")
- list.listbox.insert(Tix.END, "+ 12325 Re: Tkinter is good for your health")
- list.listbox.insert(Tix.END, "+ 12326 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(Tix.END, " 12327 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(Tix.END, "+ 12328 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(Tix.END, " 12329 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(Tix.END, "+ 12330 Re: Tix is even better for your health (Was: Tkinter is good...)")
-
- text.text['bg'] = list.listbox['bg']
- text.text['wrap'] = 'none'
- text.text.insert(Tix.END, """
- Mon, 19 Jun 1995 11:39:52 comp.lang.python Thread 34 of 220
- Lines 353 A new way to put text and bitmaps together iNo responses
- ioi@blue.seas.upenn.edu Ioi K. Lam at University of Pennsylvania
-
- Hi,
-
- I have implemented a new image type called "compound". It allows you
- to glue together a bunch of bitmaps, images and text strings together
- to form a bigger image. Then you can use this image with widgets that
- support the -image option. For example, you can display a text string string
- together with a bitmap, at the same time, inside a TK button widget.
- """)
- text.text['state'] = 'disabled'
-
- list.pack(expand=1, fill=Tix.BOTH, padx=4, pady=6)
- text.pack(expand=1, fill=Tix.BOTH, padx=4, pady=6)
-
- group.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
- pane.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH, expand=1)
-
- box = Tix.ButtonBox(w, orientation=Tix.HORIZONTAL)
- box.add('ok', text='Ok', underline=0, width=6,
- command=self.quitcmd)
- box.add('cancel', text='Cancel', underline=0, width=6,
- command=self.quitcmd)
- box.pack(side=Tix.BOTTOM, fill=Tix.X)
-
- def quitcmd (self):
- self.exit = 0
-
- def mainloop(self):
- while self.exit < 0:
- self.root.tk.dooneevent(TCL_ALL_EVENTS)
-
- def destroy (self):
- self.root.destroy()
-
-if __name__ == '__main__':
- root = Tix.Tk()
- RunSample(root)
diff --git a/Demo/tix/samples/PopMenu.py b/Demo/tix/samples/PopMenu.py
deleted file mode 100644
index 32f3229..0000000
--- a/Demo/tix/samples/PopMenu.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix Demostration Program
-#
-# This sample program is structured in such a way so that it can be
-# executed from the Tix demo program "tixwidgets.py": it must have a
-# procedure called "RunSample". It should also have the "if" statment
-# at the end of this file so that it can be run as a standalone
-# program using tixwish.
-
-# This file demonstrates the use of the tixPopupMenu widget.
-#
-import Tix
-
-def RunSample(w):
- # We create the frame and the button, then we'll bind the PopupMenu
- # to both widgets. The result is, when you press the right mouse
- # button over $w.top or $w.top.but, the PopupMenu will come up.
- #
- top = Tix.Frame(w, relief=Tix.RAISED, bd=1)
- but = Tix.Button(top, text='Press the right mouse button over this button or its surrounding area')
- but.pack(expand=1, fill=Tix.BOTH, padx=50, pady=50)
-
- p = Tix.PopupMenu(top, title='Popup Test')
- p.bind_widget(top)
- p.bind_widget(but)
-
- # Set the entries inside the PopupMenu widget.
- # [Hint] You have to manipulate the "menu" subwidget.
- # $w.top.p itself is NOT a menu widget.
- # [Hint] Watch carefully how the sub-menu is created
- #
- p.menu.add_command(label='Desktop', underline=0)
- p.menu.add_command(label='Select', underline=0)
- p.menu.add_command(label='Find', underline=0)
- p.menu.add_command(label='System', underline=1)
- p.menu.add_command(label='Help', underline=0)
- m1 = Tix.Menu(p.menu)
- m1.add_command(label='Hello')
- p.menu.add_cascade(label='More', menu=m1)
-
- but.pack(side=Tix.TOP, padx=40, pady=50)
-
- box = Tix.ButtonBox(w, orientation=Tix.HORIZONTAL)
- box.add('ok', text='Ok', underline=0, width=6,
- command=lambda w=w: w.destroy())
- box.add('cancel', text='Cancel', underline=0, width=6,
- command=lambda w=w: w.destroy())
- box.pack(side=Tix.BOTTOM, fill=Tix.X)
- top.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
-
-if __name__ == '__main__':
- root = Tix.Tk()
- RunSample(root)
- root.mainloop()
diff --git a/Demo/tix/samples/SHList1.py b/Demo/tix/samples/SHList1.py
deleted file mode 100644
index 7ca7b3e..0000000
--- a/Demo/tix/samples/SHList1.py
+++ /dev/null
@@ -1,131 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix Demostration Program
-#
-# This sample program is structured in such a way so that it can be
-# executed from the Tix demo program "tixwidgets.py": it must have a
-# procedure called "RunSample". It should also have the "if" statment
-# at the end of this file so that it can be run as a standalone
-# program using tixwish.
-
-# This file demonstrates the use of the tixScrolledHList widget.
-#
-
-import Tix
-
-TCL_ALL_EVENTS = 0
-
-def RunSample (root):
- shlist = DemoSHList(root)
- shlist.mainloop()
- shlist.destroy()
-
-class DemoSHList:
- def __init__(self, w):
- self.root = w
- self.exit = -1
-
- z = w.winfo_toplevel()
- z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
-
- # We create the frame and the ScrolledHList widget
- # at the top of the dialog box
- #
- top = Tix.Frame( w, relief=Tix.RAISED, bd=1)
-
- # Put a simple hierachy into the HList (two levels). Use colors and
- # separator widgets (frames) to make the list look fancy
- #
- top.a = Tix.ScrolledHList(top)
- top.a.pack( expand=1, fill=Tix.BOTH, padx=10, pady=10, side=Tix.TOP)
-
- # This is our little relational database
- #
- bosses = [
- ('jeff', 'Jeff Waxman'),
- ('john', 'John Lee'),
- ('peter', 'Peter Kenson')
- ]
-
- employees = [
- ('alex', 'john', 'Alex Kellman'),
- ('alan', 'john', 'Alan Adams'),
- ('andy', 'peter', 'Andreas Crawford'),
- ('doug', 'jeff', 'Douglas Bloom'),
- ('jon', 'peter', 'Jon Baraki'),
- ('chris', 'jeff', 'Chris Geoffrey'),
- ('chuck', 'jeff', 'Chuck McLean')
- ]
-
- hlist=top.a.hlist
-
- # Let configure the appearance of the HList subwidget
- #
- hlist.config( separator='.', width=25, drawbranch=0, indent=10)
-
- count=0
- for boss,name in bosses :
- if count :
- f=Tix.Frame(hlist, name='sep%d' % count, height=2, width=150,
- bd=2, relief=Tix.SUNKEN )
-
- hlist.add_child( itemtype=Tix.WINDOW,
- window=f, state=Tix.DISABLED )
-
- hlist.add(boss, itemtype=Tix.TEXT, text=name)
- count = count+1
-
-
- for person,boss,name in employees :
- # '.' is the separator character we chose above
- #
- key= boss + '.' + person
- # ^^^^ ^^^^^^
- # parent entryPath / child's name
-
- hlist.add( key, text=name )
-
- # [Hint] Make sure the keys (e.g. 'boss.person') you choose
- # are unique names. If you cannot be sure of this (because of
- # the structure of your database, e.g.) you can use the
- # "add_child" command instead:
- #
- # hlist.addchild( boss, text=name)
- # ^^^^
- # parent entryPath
-
-
- # Use a ButtonBox to hold the buttons.
- #
- box= Tix.ButtonBox(top, orientation=Tix.HORIZONTAL )
- box.add( 'ok', text='Ok', underline=0, width=6,
- command = self.okcmd)
-
- box.add( 'cancel', text='Cancel', underline=0, width=6,
- command = self.quitcmd)
-
- box.pack( side=Tix.BOTTOM, fill=Tix.X)
- top.pack( side=Tix.TOP, fill=Tix.BOTH, expand=1 )
-
- def okcmd (self):
- self.quitcmd()
-
- def quitcmd (self):
- self.exit = 0
-
- def mainloop(self):
- while self.exit < 0:
- self.root.tk.dooneevent(TCL_ALL_EVENTS)
-
- def destroy (self):
- self.root.destroy()
-
-
-# This "if" statement makes it possible to run this script file inside or
-# outside of the main demo program "tixwidgets.py".
-#
-if __name__== '__main__' :
- root=Tix.Tk()
- RunSample(root)
diff --git a/Demo/tix/samples/SHList2.py b/Demo/tix/samples/SHList2.py
deleted file mode 100644
index 17fd551..0000000
--- a/Demo/tix/samples/SHList2.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix Demostration Program
-#
-# This sample program is structured in such a way so that it can be
-# executed from the Tix demo program "tixwidget": it must have a
-# procedure called "RunSample". It should also have the "if" statment
-# at the end of this file so that it can be run as a standalone
-# program using tixwish.
-
-# This file demonstrates how to use multiple columns and multiple styles
-# in the tixHList widget
-#
-# In a tixHList widget, you can have one ore more columns.
-#
-
-import Tix
-
-TCL_ALL_EVENTS = 0
-
-def RunSample (root):
- shlist = DemoSHList(root)
- shlist.mainloop()
- shlist.destroy()
-
-class DemoSHList:
- def __init__(self, w):
- self.root = w
- self.exit = -1
-
- z = w.winfo_toplevel()
- z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
-
- # We create the frame and the ScrolledHList widget
- # at the top of the dialog box
- #
- top = Tix.Frame( w, relief=Tix.RAISED, bd=1)
-
- # Put a simple hierachy into the HList (two levels). Use colors and
- # separator widgets (frames) to make the list look fancy
- #
- top.a = Tix.ScrolledHList(top, options='hlist.columns 3 hlist.header 1' )
- top.a.pack( expand=1, fill=Tix.BOTH, padx=10, pady=10, side=Tix.TOP)
-
- hlist=top.a.hlist
-
- # Create the title for the HList widget
- # >> Notice that we have set the hlist.header subwidget option to true
- # so that the header is displayed
- #
-
- boldfont=hlist.tk.call('tix','option','get','bold_font')
-
- # First some styles for the headers
- style={}
- style['header'] = Tix.DisplayStyle(Tix.TEXT, refwindow=hlist,
- anchor=Tix.CENTER, padx=8, pady=2, font = boldfont )
-
- hlist.header_create(0, itemtype=Tix.TEXT, text='Name',
- style=style['header'])
- hlist.header_create(1, itemtype=Tix.TEXT, text='Position',
- style=style['header'])
-
- # Notice that we use 3 columns in the hlist widget. This way when the user
- # expands the windows wide, the right side of the header doesn't look
- # chopped off. The following line ensures that the 3 column header is
- # not shown unless the hlist window is wider than its contents.
- #
- hlist.column_width(2,0)
-
- # This is our little relational database
- #
- boss = ('doe', 'John Doe', 'Director')
-
- managers = [
- ('jeff', 'Jeff Waxman', 'Manager'),
- ('john', 'John Lee', 'Manager'),
- ('peter', 'Peter Kenson', 'Manager')
- ]
-
- employees = [
- ('alex', 'john', 'Alex Kellman', 'Clerk'),
- ('alan', 'john', 'Alan Adams', 'Clerk'),
- ('andy', 'peter', 'Andreas Crawford', 'Salesman'),
- ('doug', 'jeff', 'Douglas Bloom', 'Clerk'),
- ('jon', 'peter', 'Jon Baraki', 'Salesman'),
- ('chris', 'jeff', 'Chris Geoffrey', 'Clerk'),
- ('chuck', 'jeff', 'Chuck McLean', 'Cleaner')
- ]
-
- style['mgr_name'] = Tix.DisplayStyle(Tix.TEXT, refwindow=hlist)
-
- style['mgr_posn'] = Tix.DisplayStyle(Tix.TEXT, padx=8, refwindow=hlist)
-
- style['empl_name'] = Tix.DisplayStyle(Tix.TEXT, refwindow=hlist)
-
- style['empl_posn'] = Tix.DisplayStyle(Tix.TEXT, padx=8, refwindow=hlist)
-
- # Let configure the appearance of the HList subwidget
- #
- hlist.config(separator='.', width=25, drawbranch=0, indent=10)
- hlist.column_width(0, chars=20)
-
- # Create the boss
- #
- hlist.add ('.', itemtype=Tix.TEXT, text=boss[1],
- style=style['mgr_name'])
- hlist.item_create('.', 1, itemtype=Tix.TEXT, text=boss[2],
- style=style['mgr_posn'])
-
- # Create the managers
- #
-
- for key,name,posn in managers :
- e= '.'+ key
- hlist.add(e, itemtype=Tix.TEXT, text=name,
- style=style['mgr_name'])
- hlist.item_create(e, 1, itemtype=Tix.TEXT, text=posn,
- style=style['mgr_posn'])
-
-
- for key,mgr,name,posn in employees :
- # "." is the separator character we chose above
-
- entrypath = '.' + mgr + '.' + key
-
- # ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
- # parent entryPath / child's name
-
- hlist.add(entrypath, text=name, style=style['empl_name'])
- hlist.item_create(entrypath, 1, itemtype=Tix.TEXT,
- text = posn, style = style['empl_posn'] )
-
-
- # Use a ButtonBox to hold the buttons.
- #
- box= Tix.ButtonBox(top, orientation=Tix.HORIZONTAL )
- box.add( 'ok', text='Ok', underline=0, width=6,
- command = self.okcmd )
-
- box.add( 'cancel', text='Cancel', underline=0, width=6,
- command = self.quitcmd )
-
- box.pack( side=Tix.BOTTOM, fill=Tix.X)
- top.pack( side=Tix.TOP, fill=Tix.BOTH, expand=1 )
-
- def okcmd (self):
- self.quitcmd()
-
- def quitcmd (self):
- self.exit = 0
-
- def mainloop(self):
- while self.exit < 0:
- self.root.tk.dooneevent(TCL_ALL_EVENTS)
-
- def destroy (self):
- self.root.destroy()
-
-
-# This "if" statement makes it possible to run this script file inside or
-# outside of the main demo program "tixwidgets.py".
-#
-if __name__== '__main__' :
- root=Tix.Tk()
- RunSample(root)
diff --git a/Demo/tix/samples/Tree.py b/Demo/tix/samples/Tree.py
deleted file mode 100644
index 9a7e481..0000000
--- a/Demo/tix/samples/Tree.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix Demostration Program
-#
-# This sample program is structured in such a way so that it can be
-# executed from the Tix demo program "tixwidgets.py": it must have a
-# procedure called "RunSample". It should also have the "if" statment
-# at the end of this file so that it can be run as a standalone
-# program.
-
-# This file demonstrates how to use the TixTree widget to display
-# dynamic hierachical data (the files in the Unix file system)
-#
-
-import Tix, os
-
-def RunSample(w):
- top = Tix.Frame(w, relief=Tix.RAISED, bd=1)
- tree = Tix.Tree(top, options='separator "/"')
- tree.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10, side=Tix.LEFT)
- tree['opencmd'] = lambda dir=None, w=tree: opendir(w, dir)
-
- # The / directory is added in the "open" mode. The user can open it
- # and then browse its subdirectories ...
- adddir(tree, "/")
-
- box = Tix.ButtonBox(w, orientation=Tix.HORIZONTAL)
- box.add('ok', text='Ok', underline=0, command=w.destroy, width=6)
- box.add('cancel', text='Cancel', underline=0, command=w.destroy, width=6)
- box.pack(side=Tix.BOTTOM, fill=Tix.X)
- top.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
-
-def adddir(tree, dir):
- if dir == '/':
- text = '/'
- else:
- text = os.path.basename(dir)
- tree.hlist.add(dir, itemtype=Tix.IMAGETEXT, text=text,
- image=tree.tk.call('tix', 'getimage', 'folder'))
- try:
- os.listdir(dir)
- tree.setmode(dir, 'open')
- except os.error:
- # No read permission ?
- pass
-
-# This function is called whenever the user presses the (+) indicator or
-# double clicks on a directory whose mode is "open". It loads the files
-# inside that directory into the Tree widget.
-#
-# Note we didn't specify the closecmd option for the Tree widget, so it
-# performs the default action when the user presses the (-) indicator or
-# double clicks on a directory whose mode is "close": hide all of its child
-# entries
-def opendir(tree, dir):
- entries = tree.hlist.info_children(dir)
- if entries:
- # We have already loaded this directory. Let's just
- # show all the child entries
- #
- # Note: since we load the directory only once, it will not be
- # refreshed if the you add or remove files from this
- # directory.
- #
- for entry in entries:
- tree.hlist.show_entry(entry)
- files = os.listdir(dir)
- for file in files:
- if os.path.isdir(dir + '/' + file):
- adddir(tree, dir + '/' + file)
- else:
- tree.hlist.add(dir + '/' + file, itemtype=Tix.IMAGETEXT, text=file,
- image=tree.tk.call('tix', 'getimage', 'file'))
-
-if __name__ == '__main__':
- root = Tix.Tk()
- RunSample(root)
- root.mainloop()
diff --git a/Demo/tix/tixwidgets.py b/Demo/tix/tixwidgets.py
deleted file mode 100644
index 3cf34b7..0000000
--- a/Demo/tix/tixwidgets.py
+++ /dev/null
@@ -1,1003 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# tixwidgets.py --
-#
-# For Tix, see http://tix.sourceforge.net
-#
-# This is a demo program of some of the Tix widgets available in Python.
-# If you have installed Python & Tix properly, you can execute this as
-#
-# % python tixwidgets.py
-#
-
-import os, os.path, sys, Tix
-from Tkconstants import *
-import traceback, tkMessageBox
-
-TCL_DONT_WAIT = 1<<1
-TCL_WINDOW_EVENTS = 1<<2
-TCL_FILE_EVENTS = 1<<3
-TCL_TIMER_EVENTS = 1<<4
-TCL_IDLE_EVENTS = 1<<5
-TCL_ALL_EVENTS = 0
-
-class Demo:
- def __init__(self, top):
- self.root = top
- self.exit = -1
-
- self.dir = None # script directory
- self.balloon = None # balloon widget
- self.useBalloons = Tix.StringVar()
- self.useBalloons.set('0')
- self.statusbar = None # status bar widget
- self.welmsg = None # Msg widget
- self.welfont = '' # font name
- self.welsize = '' # font size
-
- progname = sys.argv[0]
- dirname = os.path.dirname(progname)
- if dirname and dirname != os.curdir:
- self.dir = dirname
- index = -1
- for i in range(len(sys.path)):
- p = sys.path[i]
- if p in ("", os.curdir):
- index = i
- if index >= 0:
- sys.path[index] = dirname
- else:
- sys.path.insert(0, dirname)
- else:
- self.dir = os.getcwd()
- sys.path.insert(0, self.dir+'/samples')
-
- def MkMainMenu(self):
- top = self.root
- w = Tix.Frame(top, bd=2, relief=RAISED)
- file = Tix.Menubutton(w, text='File', underline=0, takefocus=0)
- help = Tix.Menubutton(w, text='Help', underline=0, takefocus=0)
- file.pack(side=LEFT)
- help.pack(side=RIGHT)
- fm = Tix.Menu(file, tearoff=0)
- file['menu'] = fm
- hm = Tix.Menu(help, tearoff=0)
- help['menu'] = hm
-
- fm.add_command(label='Exit', underline=1,
- command = lambda self=self: self.quitcmd () )
- hm.add_checkbutton(label='BalloonHelp', underline=0, command=ToggleHelp,
- variable=self.useBalloons)
- # The trace variable option doesn't seem to work, instead I use 'command'
- #apply(w.tk.call, ('trace', 'variable', self.useBalloons, 'w',
- # ToggleHelp))
-
- return w
-
- def MkMainNotebook(self):
- top = self.root
- w = Tix.NoteBook(top, ipadx=5, ipady=5, options="""
- tagPadX 6
- tagPadY 4
- borderWidth 2
- """)
- # This may be required if there is no *Background option
- top['bg'] = w['bg']
-
- w.add('wel', label='Welcome', underline=0,
- createcmd=lambda w=w, name='wel': MkWelcome(w, name))
- w.add('cho', label='Choosers', underline=0,
- createcmd=lambda w=w, name='cho': MkChoosers(w, name))
- w.add('scr', label='Scrolled Widgets', underline=0,
- createcmd=lambda w=w, name='scr': MkScroll(w, name))
- w.add('mgr', label='Manager Widgets', underline=0,
- createcmd=lambda w=w, name='mgr': MkManager(w, name))
- w.add('dir', label='Directory List', underline=0,
- createcmd=lambda w=w, name='dir': MkDirList(w, name))
- w.add('exp', label='Run Sample Programs', underline=0,
- createcmd=lambda w=w, name='exp': MkSample(w, name))
- return w
-
- def MkMainStatus(self):
- global demo
- top = self.root
-
- w = Tix.Frame(top, relief=Tix.RAISED, bd=1)
- demo.statusbar = Tix.Label(w, relief=Tix.SUNKEN, bd=1)
- demo.statusbar.form(padx=3, pady=3, left=0, right='%70')
- return w
-
- def build(self):
- root = self.root
- z = root.winfo_toplevel()
- z.wm_title('Tix Widget Demonstration')
- if z.winfo_screenwidth() <= 800:
- z.geometry('790x590+10+10')
- else:
- z.geometry('890x640+10+10')
- demo.balloon = Tix.Balloon(root)
- frame1 = self.MkMainMenu()
- frame2 = self.MkMainNotebook()
- frame3 = self.MkMainStatus()
- frame1.pack(side=TOP, fill=X)
- frame3.pack(side=BOTTOM, fill=X)
- frame2.pack(side=TOP, expand=1, fill=BOTH, padx=4, pady=4)
- demo.balloon['statusbar'] = demo.statusbar
- z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
-
- # To show Tcl errors - uncomment this to see the listbox bug.
- # Tkinter defines a Tcl tkerror procedure that in effect
- # silences all background Tcl error reporting.
- # root.tk.eval('if {[info commands tkerror] != ""} {rename tkerror pytkerror}')
- def quitcmd (self):
- """Quit our mainloop. It is up to you to call root.destroy() after."""
- self.exit = 0
-
- def loop(self):
- """This is an explict replacement for _tkinter mainloop()
- It lets you catch keyboard interrupts easier, and avoids
- the 20 msec. dead sleep() which burns a constant CPU."""
- while self.exit < 0:
- # There are 2 whiles here. The outer one lets you continue
- # after a ^C interrupt.
- try:
- # This is the replacement for _tkinter mainloop()
- # It blocks waiting for the next Tcl event using select.
- while self.exit < 0:
- self.root.tk.dooneevent(TCL_ALL_EVENTS)
- except SystemExit:
- # Tkinter uses SystemExit to exit
- #print 'Exit'
- self.exit = 1
- return
- except KeyboardInterrupt:
- if tkMessageBox.askquestion ('Interrupt', 'Really Quit?') == 'yes':
- # self.tk.eval('exit')
- self.exit = 1
- return
- continue
- except:
- # Otherwise it's some other error - be nice and say why
- t, v, tb = sys.exc_info()
- text = ""
- for line in traceback.format_exception(t,v,tb):
- text += line + '\n'
- try: tkMessageBox.showerror ('Error', text)
- except: pass
- self.exit = 1
- raise SystemExit, 1
-
- def destroy (self):
- self.root.destroy()
-
-def RunMain(root):
- global demo
-
- demo = Demo(root)
-
- demo.build()
- demo.loop()
- demo.destroy()
-
-# Tabs
-def MkWelcome(nb, name):
- w = nb.page(name)
- bar = MkWelcomeBar(w)
- text = MkWelcomeText(w)
- bar.pack(side=TOP, fill=X, padx=2, pady=2)
- text.pack(side=TOP, fill=BOTH, expand=1)
-
-def MkWelcomeBar(top):
- global demo
-
- w = Tix.Frame(top, bd=2, relief=Tix.GROOVE)
- b1 = Tix.ComboBox(w, command=lambda w=top: MainTextFont(w))
- b2 = Tix.ComboBox(w, command=lambda w=top: MainTextFont(w))
- b1.entry['width'] = 15
- b1.slistbox.listbox['height'] = 3
- b2.entry['width'] = 4
- b2.slistbox.listbox['height'] = 3
-
- demo.welfont = b1
- demo.welsize = b2
-
- b1.insert(Tix.END, 'Courier')
- b1.insert(Tix.END, 'Helvetica')
- b1.insert(Tix.END, 'Lucida')
- b1.insert(Tix.END, 'Times Roman')
-
- b2.insert(Tix.END, '8')
- b2.insert(Tix.END, '10')
- b2.insert(Tix.END, '12')
- b2.insert(Tix.END, '14')
- b2.insert(Tix.END, '18')
-
- b1.pick(1)
- b2.pick(3)
-
- b1.pack(side=Tix.LEFT, padx=4, pady=4)
- b2.pack(side=Tix.LEFT, padx=4, pady=4)
-
- demo.balloon.bind_widget(b1, msg='Choose\na font',
- statusmsg='Choose a font for this page')
- demo.balloon.bind_widget(b2, msg='Point size',
- statusmsg='Choose the font size for this page')
- return w
-
-def MkWelcomeText(top):
- global demo
-
- w = Tix.ScrolledWindow(top, scrollbar='auto')
- win = w.window
- text = 'Welcome to TIX in Python'
- title = Tix.Label(win,
- bd=0, width=30, anchor=Tix.N, text=text)
- msg = Tix.Message(win,
- bd=0, width=400, anchor=Tix.N,
- text='Tix is a set of mega-widgets based on TK. This program \
-demonstrates the widgets in the Tix widget set. You can choose the pages \
-in this window to look at the corresponding widgets. \n\n\
-To quit this program, choose the "File | Exit" command.\n\n\
-For more information, see http://tix.sourceforge.net.')
- title.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10)
- msg.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10)
- demo.welmsg = msg
- return w
-
-def MainTextFont(w):
- global demo
-
- if not demo.welmsg:
- return
- font = demo.welfont['value']
- point = demo.welsize['value']
- if font == 'Times Roman':
- font = 'times'
- fontstr = '%s %s' % (font, point)
- demo.welmsg['font'] = fontstr
-
-def ToggleHelp():
- if demo.useBalloons.get() == '1':
- demo.balloon['state'] = 'both'
- else:
- demo.balloon['state'] = 'none'
-
-def MkChoosers(nb, name):
- w = nb.page(name)
- options = "label.padX 4"
-
- til = Tix.LabelFrame(w, label='Chooser Widgets', options=options)
- cbx = Tix.LabelFrame(w, label='tixComboBox', options=options)
- ctl = Tix.LabelFrame(w, label='tixControl', options=options)
- sel = Tix.LabelFrame(w, label='tixSelect', options=options)
- opt = Tix.LabelFrame(w, label='tixOptionMenu', options=options)
- fil = Tix.LabelFrame(w, label='tixFileEntry', options=options)
- fbx = Tix.LabelFrame(w, label='tixFileSelectBox', options=options)
- tbr = Tix.LabelFrame(w, label='Tool Bar', options=options)
-
- MkTitle(til.frame)
- MkCombo(cbx.frame)
- MkControl(ctl.frame)
- MkSelect(sel.frame)
- MkOptMenu(opt.frame)
- MkFileEnt(fil.frame)
- MkFileBox(fbx.frame)
- MkToolBar(tbr.frame)
-
- # First column: comBox and selector
- cbx.form(top=0, left=0, right='%33')
- sel.form(left=0, right='&'+str(cbx), top=cbx)
- opt.form(left=0, right='&'+str(cbx), top=sel, bottom=-1)
-
- # Second column: title .. etc
- til.form(left=cbx, top=0,right='%66')
- ctl.form(left=cbx, right='&'+str(til), top=til)
- fil.form(left=cbx, right='&'+str(til), top=ctl)
- tbr.form(left=cbx, right='&'+str(til), top=fil, bottom=-1)
-
- #
- # Third column: file selection
- fbx.form(right=-1, top=0, left='%66')
-
-def MkCombo(w):
- options="label.width %d label.anchor %s entry.width %d" % (10, Tix.E, 14)
-
- static = Tix.ComboBox(w, label='Static', editable=0, options=options)
- editable = Tix.ComboBox(w, label='Editable', editable=1, options=options)
- history = Tix.ComboBox(w, label='History', editable=1, history=1,
- anchor=Tix.E, options=options)
- static.insert(Tix.END, 'January')
- static.insert(Tix.END, 'February')
- static.insert(Tix.END, 'March')
- static.insert(Tix.END, 'April')
- static.insert(Tix.END, 'May')
- static.insert(Tix.END, 'June')
- static.insert(Tix.END, 'July')
- static.insert(Tix.END, 'August')
- static.insert(Tix.END, 'September')
- static.insert(Tix.END, 'October')
- static.insert(Tix.END, 'November')
- static.insert(Tix.END, 'December')
-
- editable.insert(Tix.END, 'Angola')
- editable.insert(Tix.END, 'Bangladesh')
- editable.insert(Tix.END, 'China')
- editable.insert(Tix.END, 'Denmark')
- editable.insert(Tix.END, 'Ecuador')
-
- history.insert(Tix.END, '/usr/bin/ksh')
- history.insert(Tix.END, '/usr/local/lib/python')
- history.insert(Tix.END, '/var/adm')
-
- static.pack(side=Tix.TOP, padx=5, pady=3)
- editable.pack(side=Tix.TOP, padx=5, pady=3)
- history.pack(side=Tix.TOP, padx=5, pady=3)
-
-states = ['Bengal', 'Delhi', 'Karnataka', 'Tamil Nadu']
-
-def spin_cmd(w, inc):
- idx = states.index(demo_spintxt.get()) + inc
- if idx < 0:
- idx = len(states) - 1
- elif idx >= len(states):
- idx = 0
-# following doesn't work.
-# return states[idx]
- demo_spintxt.set(states[idx]) # this works
-
-def spin_validate(w):
- global states, demo_spintxt
-
- try:
- i = states.index(demo_spintxt.get())
- except ValueError:
- return states[0]
- return states[i]
- # why this procedure works as opposed to the previous one beats me.
-
-def MkControl(w):
- global demo_spintxt
-
- options="label.width %d label.anchor %s entry.width %d" % (10, Tix.E, 13)
-
- demo_spintxt = Tix.StringVar()
- demo_spintxt.set(states[0])
- simple = Tix.Control(w, label='Numbers', options=options)
- spintxt = Tix.Control(w, label='States', variable=demo_spintxt,
- options=options)
- spintxt['incrcmd'] = lambda w=spintxt: spin_cmd(w, 1)
- spintxt['decrcmd'] = lambda w=spintxt: spin_cmd(w, -1)
- spintxt['validatecmd'] = lambda w=spintxt: spin_validate(w)
-
- simple.pack(side=Tix.TOP, padx=5, pady=3)
- spintxt.pack(side=Tix.TOP, padx=5, pady=3)
-
-def MkSelect(w):
- options = "label.anchor %s" % Tix.CENTER
-
- sel1 = Tix.Select(w, label='Mere Mortals', allowzero=1, radio=1,
- orientation=Tix.VERTICAL,
- labelside=Tix.TOP,
- options=options)
- sel2 = Tix.Select(w, label='Geeks', allowzero=1, radio=0,
- orientation=Tix.VERTICAL,
- labelside= Tix.TOP,
- options=options)
-
- sel1.add('eat', text='Eat')
- sel1.add('work', text='Work')
- sel1.add('play', text='Play')
- sel1.add('party', text='Party')
- sel1.add('sleep', text='Sleep')
-
- sel2.add('eat', text='Eat')
- sel2.add('prog1', text='Program')
- sel2.add('prog2', text='Program')
- sel2.add('prog3', text='Program')
- sel2.add('sleep', text='Sleep')
-
- sel1.pack(side=Tix.LEFT, padx=5, pady=3, fill=Tix.X)
- sel2.pack(side=Tix.LEFT, padx=5, pady=3, fill=Tix.X)
-
-def MkOptMenu(w):
- options='menubutton.width 15 label.anchor %s' % Tix.E
-
- m = Tix.OptionMenu(w, label='File Format : ', options=options)
- m.add_command('text', label='Plain Text')
- m.add_command('post', label='PostScript')
- m.add_command('format', label='Formatted Text')
- m.add_command('html', label='HTML')
- m.add_command('sep')
- m.add_command('tex', label='LaTeX')
- m.add_command('rtf', label='Rich Text Format')
-
- m.pack(fill=Tix.X, padx=5, pady=3)
-
-def MkFileEnt(w):
- msg = Tix.Message(w,
- relief=Tix.FLAT, width=240, anchor=Tix.N,
- text='Press the "open file" icon button and a TixFileSelectDialog will popup.')
- ent = Tix.FileEntry(w, label='Select a file : ')
- msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
- ent.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
-
-def MkFileBox(w):
- """The FileSelectBox is a Motif-style box with various enhancements.
- For example, you can adjust the size of the two listboxes
- and your past selections are recorded.
- """
- msg = Tix.Message(w,
- relief=Tix.FLAT, width=240, anchor=Tix.N,
- text='The Tix FileSelectBox is a Motif-style box with various enhancements. For example, you can adjust the size of the two listboxes and your past selections are recorded.')
- box = Tix.FileSelectBox(w)
- msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
- box.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
-
-def MkToolBar(w):
- """The Select widget is also good for arranging buttons in a tool bar.
- """
- global demo
-
- options='frame.borderWidth 1'
-
- msg = Tix.Message(w,
- relief=Tix.FLAT, width=240, anchor=Tix.N,
- text='The Select widget is also good for arranging buttons in a tool bar.')
- bar = Tix.Frame(w, bd=2, relief=Tix.RAISED)
- font = Tix.Select(w, allowzero=1, radio=0, label='', options=options)
- para = Tix.Select(w, allowzero=0, radio=1, label='', options=options)
-
- font.add('bold', bitmap='@' + demo.dir + '/bitmaps/bold.xbm')
- font.add('italic', bitmap='@' + demo.dir + '/bitmaps/italic.xbm')
- font.add('underline', bitmap='@' + demo.dir + '/bitmaps/underline.xbm')
- font.add('capital', bitmap='@' + demo.dir + '/bitmaps/capital.xbm')
-
- para.add('left', bitmap='@' + demo.dir + '/bitmaps/leftj.xbm')
- para.add('right', bitmap='@' + demo.dir + '/bitmaps/rightj.xbm')
- para.add('center', bitmap='@' + demo.dir + '/bitmaps/centerj.xbm')
- para.add('justify', bitmap='@' + demo.dir + '/bitmaps/justify.xbm')
-
- msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
- bar.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
- font.pack({'in':bar}, side=Tix.LEFT, padx=3, pady=3)
- para.pack({'in':bar}, side=Tix.LEFT, padx=3, pady=3)
-
-def MkTitle(w):
- msg = Tix.Message(w,
- relief=Tix.FLAT, width=240, anchor=Tix.N,
- text='There are many types of "chooser" widgets that allow the user to input different types of information')
- msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
-
-def MkScroll(nb, name):
- w = nb.page(name)
- options='label.padX 4'
-
- sls = Tix.LabelFrame(w, label='Tix.ScrolledListBox', options=options)
- swn = Tix.LabelFrame(w, label='Tix.ScrolledWindow', options=options)
- stx = Tix.LabelFrame(w, label='Tix.ScrolledText', options=options)
-
- MkSList(sls.frame)
- MkSWindow(swn.frame)
- MkSText(stx.frame)
-
- sls.form(top=0, left=0, right='%33', bottom=-1)
- swn.form(top=0, left=sls, right='%66', bottom=-1)
- stx.form(top=0, left=swn, right=-1, bottom=-1)
-
-
-def MkSList(w):
- """This TixScrolledListBox is configured so that it uses scrollbars
- only when it is necessary. Use the handles to resize the listbox and
- watch the scrollbars automatically appear and disappear. """
- top = Tix.Frame(w, width=300, height=330)
- bot = Tix.Frame(w)
- msg = Tix.Message(top,
- relief=Tix.FLAT, width=200, anchor=Tix.N,
- text='This TixScrolledListBox is configured so that it uses scrollbars only when it is necessary. Use the handles to resize the listbox and watch the scrollbars automatically appear and disappear.')
-
- list = Tix.ScrolledListBox(top, scrollbar='auto')
- list.place(x=50, y=150, width=120, height=80)
- list.listbox.insert(Tix.END, 'Alabama')
- list.listbox.insert(Tix.END, 'California')
- list.listbox.insert(Tix.END, 'Montana')
- list.listbox.insert(Tix.END, 'New Jersey')
- list.listbox.insert(Tix.END, 'New York')
- list.listbox.insert(Tix.END, 'Pennsylvania')
- list.listbox.insert(Tix.END, 'Washington')
-
- rh = Tix.ResizeHandle(top, bg='black',
- relief=Tix.RAISED,
- handlesize=8, gridded=1, minwidth=50, minheight=30)
- btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=list: SList_reset(w,x))
- top.propagate(0)
- msg.pack(fill=Tix.X)
- btn.pack(anchor=Tix.CENTER)
- top.pack(expand=1, fill=Tix.BOTH)
- bot.pack(fill=Tix.BOTH)
- list.bind('<Map>', func=lambda arg=0, rh=rh, list=list:
- list.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(list)))
-
-def SList_reset(rh, list):
- list.place(x=50, y=150, width=120, height=80)
- list.update()
- rh.attach_widget(list)
-
-def MkSWindow(w):
- """The ScrolledWindow widget allows you to scroll any kind of Tk
- widget. It is more versatile than a scrolled canvas widget.
- """
- global demo
-
- text = 'The Tix ScrolledWindow widget allows you to scroll any kind of Tk widget. It is more versatile than a scrolled canvas widget.'
-
- file = os.path.join(demo.dir, 'bitmaps', 'tix.gif')
- if not os.path.isfile(file):
- text += ' (Image missing)'
-
- top = Tix.Frame(w, width=330, height=330)
- bot = Tix.Frame(w)
- msg = Tix.Message(top,
- relief=Tix.FLAT, width=200, anchor=Tix.N,
- text=text)
-
- win = Tix.ScrolledWindow(top, scrollbar='auto')
-
- image1 = win.window.image_create('photo', file=file)
- lbl = Tix.Label(win.window, image=image1)
- lbl.pack(expand=1, fill=Tix.BOTH)
-
- win.place(x=30, y=150, width=190, height=120)
-
- rh = Tix.ResizeHandle(top, bg='black',
- relief=Tix.RAISED,
- handlesize=8, gridded=1, minwidth=50, minheight=30)
- btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SWindow_reset(w,x))
- top.propagate(0)
- msg.pack(fill=Tix.X)
- btn.pack(anchor=Tix.CENTER)
- top.pack(expand=1, fill=Tix.BOTH)
- bot.pack(fill=Tix.BOTH)
-
- win.bind('<Map>', func=lambda arg=0, rh=rh, win=win:
- win.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(win)))
-
-def SWindow_reset(rh, win):
- win.place(x=30, y=150, width=190, height=120)
- win.update()
- rh.attach_widget(win)
-
-def MkSText(w):
- """The TixScrolledWindow widget allows you to scroll any kind of Tk
- widget. It is more versatile than a scrolled canvas widget."""
- top = Tix.Frame(w, width=330, height=330)
- bot = Tix.Frame(w)
- msg = Tix.Message(top,
- relief=Tix.FLAT, width=200, anchor=Tix.N,
- text='The Tix ScrolledWindow widget allows you to scroll any kind of Tk widget. It is more versatile than a scrolled canvas widget.')
-
- win = Tix.ScrolledText(top, scrollbar='auto')
- win.text['wrap'] = 'none'
- win.text.insert(Tix.END, '''When -scrollbar is set to "auto", the
-scrollbars are shown only when needed.
-Additional modifiers can be used to force a
-scrollbar to be shown or hidden. For example,
-"auto -y" means the horizontal scrollbar
-should be shown when needed but the vertical
-scrollbar should always be hidden;
-"auto +x" means the vertical scrollbar
-should be shown when needed but the horizontal
-scrollbar should always be shown, and so on.'''
-)
- win.place(x=30, y=150, width=190, height=100)
-
- rh = Tix.ResizeHandle(top, bg='black',
- relief=Tix.RAISED,
- handlesize=8, gridded=1, minwidth=50, minheight=30)
- btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SText_reset(w,x))
- top.propagate(0)
- msg.pack(fill=Tix.X)
- btn.pack(anchor=Tix.CENTER)
- top.pack(expand=1, fill=Tix.BOTH)
- bot.pack(fill=Tix.BOTH)
- win.bind('<Map>', func=lambda arg=0, rh=rh, win=win:
- win.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(win)))
-
-def SText_reset(rh, win):
- win.place(x=30, y=150, width=190, height=120)
- win.update()
- rh.attach_widget(win)
-
-def MkManager(nb, name):
- w = nb.page(name)
- options='label.padX 4'
-
- pane = Tix.LabelFrame(w, label='Tix.PanedWindow', options=options)
- note = Tix.LabelFrame(w, label='Tix.NoteBook', options=options)
-
- MkPanedWindow(pane.frame)
- MkNoteBook(note.frame)
-
- pane.form(top=0, left=0, right=note, bottom=-1)
- note.form(top=0, right=-1, bottom=-1)
-
-def MkPanedWindow(w):
- """The PanedWindow widget allows the user to interactively manipulate
- the sizes of several panes. The panes can be arranged either vertically
- or horizontally.
- """
- msg = Tix.Message(w,
- relief=Tix.FLAT, width=240, anchor=Tix.N,
- text='The PanedWindow widget allows the user to interactively manipulate the sizes of several panes. The panes can be arranged either vertically or horizontally.')
- group = Tix.LabelEntry(w, label='Newsgroup:', options='entry.width 25')
- group.entry.insert(0,'comp.lang.python')
- pane = Tix.PanedWindow(w, orientation='vertical')
-
- p1 = pane.add('list', min=70, size=100)
- p2 = pane.add('text', min=70)
- list = Tix.ScrolledListBox(p1)
- text = Tix.ScrolledText(p2)
-
- list.listbox.insert(Tix.END, " 12324 Re: Tkinter is good for your health")
- list.listbox.insert(Tix.END, "+ 12325 Re: Tkinter is good for your health")
- list.listbox.insert(Tix.END, "+ 12326 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(Tix.END, " 12327 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(Tix.END, "+ 12328 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(Tix.END, " 12329 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(Tix.END, "+ 12330 Re: Tix is even better for your health (Was: Tkinter is good...)")
-
- text.text['bg'] = list.listbox['bg']
- text.text['wrap'] = 'none'
- text.text.insert(Tix.END, """
-Mon, 19 Jun 1995 11:39:52 comp.lang.python Thread 34 of 220
-Lines 353 A new way to put text and bitmaps together iNo responses
-ioi@blue.seas.upenn.edu Ioi K. Lam at University of Pennsylvania
-
-Hi,
-
-I have implemented a new image type called "compound". It allows you
-to glue together a bunch of bitmaps, images and text strings together
-to form a bigger image. Then you can use this image with widgets that
-support the -image option. For example, you can display a text string
-together with a bitmap, at the same time, inside a TK button widget.
-""")
- list.pack(expand=1, fill=Tix.BOTH, padx=4, pady=6)
- text.pack(expand=1, fill=Tix.BOTH, padx=4, pady=6)
-
- msg.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
- group.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
- pane.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH, expand=1)
-
-def MkNoteBook(w):
- msg = Tix.Message(w,
- relief=Tix.FLAT, width=240, anchor=Tix.N,
- text='The NoteBook widget allows you to layout a complex interface into individual pages.')
- # prefix = Tix.OptionName(w)
- # if not prefix: prefix = ''
- # w.option_add('*' + prefix + '*TixNoteBook*tagPadX', 8)
- options = "entry.width %d label.width %d label.anchor %s" % (10, 18, Tix.E)
-
- nb = Tix.NoteBook(w, ipadx=6, ipady=6, options=options)
- nb.add('hard_disk', label="Hard Disk", underline=0)
- nb.add('network', label="Network", underline=0)
-
- # Frame for the buttons that are present on all pages
- common = Tix.Frame(nb.hard_disk)
- common.pack(side=Tix.RIGHT, padx=2, pady=2, fill=Tix.Y)
- CreateCommonButtons(common)
-
- # Widgets belonging only to this page
- a = Tix.Control(nb.hard_disk, value=12, label='Access Time: ')
- w = Tix.Control(nb.hard_disk, value=400, label='Write Throughput: ')
- r = Tix.Control(nb.hard_disk, value=400, label='Read Throughput: ')
- c = Tix.Control(nb.hard_disk, value=1021, label='Capacity: ')
- a.pack(side=Tix.TOP, padx=20, pady=2)
- w.pack(side=Tix.TOP, padx=20, pady=2)
- r.pack(side=Tix.TOP, padx=20, pady=2)
- c.pack(side=Tix.TOP, padx=20, pady=2)
-
- common = Tix.Frame(nb.network)
- common.pack(side=Tix.RIGHT, padx=2, pady=2, fill=Tix.Y)
- CreateCommonButtons(common)
-
- a = Tix.Control(nb.network, value=12, label='Access Time: ')
- w = Tix.Control(nb.network, value=400, label='Write Throughput: ')
- r = Tix.Control(nb.network, value=400, label='Read Throughput: ')
- c = Tix.Control(nb.network, value=1021, label='Capacity: ')
- u = Tix.Control(nb.network, value=10, label='Users: ')
- a.pack(side=Tix.TOP, padx=20, pady=2)
- w.pack(side=Tix.TOP, padx=20, pady=2)
- r.pack(side=Tix.TOP, padx=20, pady=2)
- c.pack(side=Tix.TOP, padx=20, pady=2)
- u.pack(side=Tix.TOP, padx=20, pady=2)
-
- msg.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
- nb.pack(side=Tix.TOP, padx=5, pady=5, fill=Tix.BOTH, expand=1)
-
-def CreateCommonButtons(f):
- ok = Tix.Button(f, text='OK', width = 6)
- cancel = Tix.Button(f, text='Cancel', width = 6)
- ok.pack(side=Tix.TOP, padx=2, pady=2)
- cancel.pack(side=Tix.TOP, padx=2, pady=2)
-
-def MkDirList(nb, name):
- w = nb.page(name)
- options = "label.padX 4"
-
- dir = Tix.LabelFrame(w, label='Tix.DirList', options=options)
- fsbox = Tix.LabelFrame(w, label='Tix.ExFileSelectBox', options=options)
- MkDirListWidget(dir.frame)
- MkExFileWidget(fsbox.frame)
- dir.form(top=0, left=0, right='%40', bottom=-1)
- fsbox.form(top=0, left='%40', right=-1, bottom=-1)
-
-def MkDirListWidget(w):
- """The TixDirList widget gives a graphical representation of the file
- system directory and makes it easy for the user to choose and access
- directories.
- """
- msg = Tix.Message(w,
- relief=Tix.FLAT, width=240, anchor=Tix.N,
- text='The Tix DirList widget gives a graphical representation of the file system directory and makes it easy for the user to choose and access directories.')
- dirlist = Tix.DirList(w, options='hlist.padY 1 hlist.width 25 hlist.height 16')
- msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
- dirlist.pack(side=Tix.TOP, padx=3, pady=3)
-
-def MkExFileWidget(w):
- """The TixExFileSelectBox widget is more user friendly than the Motif
- style FileSelectBox. """
- msg = Tix.Message(w,
- relief=Tix.FLAT, width=240, anchor=Tix.N,
- text='The Tix ExFileSelectBox widget is more user friendly than the Motif style FileSelectBox.')
- # There's a bug in the ComboBoxes - the scrolledlistbox is destroyed
- box = Tix.ExFileSelectBox(w, bd=2, relief=Tix.RAISED)
- msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
- box.pack(side=Tix.TOP, padx=3, pady=3)
-
-###
-### List of all the demos we want to show off
-comments = {'widget' : 'Widget Demos', 'image' : 'Image Demos'}
-samples = {'Balloon' : 'Balloon',
- 'Button Box' : 'BtnBox',
- 'Combo Box' : 'ComboBox',
- 'Compound Image' : 'CmpImg',
- 'Directory List' : 'DirList',
- 'Directory Tree' : 'DirTree',
- 'Control' : 'Control',
- 'Notebook' : 'NoteBook',
- 'Option Menu' : 'OptMenu',
- 'Paned Window' : 'PanedWin',
- 'Popup Menu' : 'PopMenu',
- 'ScrolledHList (1)' : 'SHList1',
- 'ScrolledHList (2)' : 'SHList2',
- 'Tree (dynamic)' : 'Tree'
-}
-
-# There are still a lot of demos to be translated:
-## set root {
-## {d "File Selectors" file }
-## {d "Hierachical ListBox" hlist }
-## {d "Tabular ListBox" tlist {c tixTList}}
-## {d "Grid Widget" grid {c tixGrid}}
-## {d "Manager Widgets" manager }
-## {d "Scrolled Widgets" scroll }
-## {d "Miscellaneous Widgets" misc }
-## {d "Image Types" image }
-## }
-##
-## set image {
-## {d "Compound Image" cmpimg }
-## {d "XPM Image" xpm {i pixmap}}
-## }
-##
-## set cmpimg {
-##done {f "In Buttons" CmpImg.tcl }
-## {f "In NoteBook" CmpImg2.tcl }
-## {f "Notebook Color Tabs" CmpImg4.tcl }
-## {f "Icons" CmpImg3.tcl }
-## }
-##
-## set xpm {
-## {f "In Button" Xpm.tcl {i pixmap}}
-## {f "In Menu" Xpm1.tcl {i pixmap}}
-## }
-##
-## set file {
-##added {f DirList DirList.tcl }
-##added {f DirTree DirTree.tcl }
-## {f DirSelectDialog DirDlg.tcl }
-## {f ExFileSelectDialog EFileDlg.tcl }
-## {f FileSelectDialog FileDlg.tcl }
-## {f FileEntry FileEnt.tcl }
-## }
-##
-## set hlist {
-## {f HList HList1.tcl }
-## {f CheckList ChkList.tcl {c tixCheckList}}
-##done {f "ScrolledHList (1)" SHList.tcl }
-##done {f "ScrolledHList (2)" SHList2.tcl }
-##done {f Tree Tree.tcl }
-##done {f "Tree (Dynamic)" DynTree.tcl {v win}}
-## }
-##
-## set tlist {
-## {f "ScrolledTList (1)" STList1.tcl {c tixTList}}
-## {f "ScrolledTList (2)" STList2.tcl {c tixTList}}
-## }
-## global tcl_platform
-## # This demo hangs windows
-## if {$tcl_platform(platform) != "windows"} {
-##na lappend tlist {f "TList File Viewer" STList3.tcl {c tixTList}}
-## }
-##
-## set grid {
-##na {f "Simple Grid" SGrid0.tcl {c tixGrid}}
-##na {f "ScrolledGrid" SGrid1.tcl {c tixGrid}}
-##na {f "Editable Grid" EditGrid.tcl {c tixGrid}}
-## }
-##
-## set scroll {
-## {f ScrolledListBox SListBox.tcl }
-## {f ScrolledText SText.tcl }
-## {f ScrolledWindow SWindow.tcl }
-##na {f "Canvas Object View" CObjView.tcl {c tixCObjView}}
-## }
-##
-## set manager {
-## {f ListNoteBook ListNBK.tcl }
-##done {f NoteBook NoteBook.tcl }
-##done {f PanedWindow PanedWin.tcl }
-## }
-##
-## set misc {
-##done {f Balloon Balloon.tcl }
-##done {f ButtonBox BtnBox.tcl }
-##done {f ComboBox ComboBox.tcl }
-##done {f Control Control.tcl }
-## {f LabelEntry LabEntry.tcl }
-## {f LabelFrame LabFrame.tcl }
-## {f Meter Meter.tcl {c tixMeter}}
-##done {f OptionMenu OptMenu.tcl }
-##done {f PopupMenu PopMenu.tcl }
-## {f Select Select.tcl }
-## {f StdButtonBox StdBBox.tcl }
-## }
-##
-
-stypes = {}
-stypes['widget'] = ['Balloon', 'Button Box', 'Combo Box', 'Control',
- 'Directory List', 'Directory Tree',
- 'Notebook', 'Option Menu', 'Popup Menu', 'Paned Window',
- 'ScrolledHList (1)', 'ScrolledHList (2)', 'Tree (dynamic)']
-stypes['image'] = ['Compound Image']
-
-def MkSample(nb, name):
- w = nb.page(name)
- options = "label.padX 4"
-
- pane = Tix.PanedWindow(w, orientation='horizontal')
- pane.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH)
- f1 = pane.add('list', expand='1')
- f2 = pane.add('text', expand='5')
- f1['relief'] = 'flat'
- f2['relief'] = 'flat'
-
- lab = Tix.LabelFrame(f1, label='Select a sample program:')
- lab.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=5, pady=5)
- lab1 = Tix.LabelFrame(f2, label='Source:')
- lab1.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=5, pady=5)
-
- slb = Tix.Tree(lab.frame, options='hlist.width 20')
- slb.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=5)
-
- stext = Tix.ScrolledText(lab1.frame, name='stext')
- font = root.tk.eval('tix option get fixed_font')
- stext.text.config(font=font)
-
- frame = Tix.Frame(lab1.frame, name='frame')
-
- run = Tix.Button(frame, text='Run ...', name='run')
- view = Tix.Button(frame, text='View Source ...', name='view')
- run.pack(side=Tix.LEFT, expand=0, fill=Tix.NONE)
- view.pack(side=Tix.LEFT, expand=0, fill=Tix.NONE)
-
- stext.text['bg'] = slb.hlist['bg']
- stext.text['state'] = 'disabled'
- stext.text['wrap'] = 'none'
- stext.text['width'] = 80
-
- frame.pack(side=Tix.BOTTOM, expand=0, fill=Tix.X, padx=7)
- stext.pack(side=Tix.TOP, expand=0, fill=Tix.BOTH, padx=7)
-
- slb.hlist['separator'] = '.'
- slb.hlist['width'] = 25
- slb.hlist['drawbranch'] = 0
- slb.hlist['indent'] = 10
- slb.hlist['wideselect'] = 1
- slb.hlist['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'run')
- slb.hlist['browsecmd'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'browse')
-
- run['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'run')
- view['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'view')
-
- for type in ['widget', 'image']:
- if type != 'widget':
- x = Tix.Frame(slb.hlist, bd=2, height=2, width=150,
- relief=Tix.SUNKEN, bg=slb.hlist['bg'])
- slb.hlist.add_child(itemtype=Tix.WINDOW, window=x, state='disabled')
- x = slb.hlist.add_child(itemtype=Tix.TEXT, state='disabled',
- text=comments[type])
- for key in stypes[type]:
- slb.hlist.add_child(x, itemtype=Tix.TEXT, data=key,
- text=key)
- slb.hlist.selection_clear()
-
- run['state'] = 'disabled'
- view['state'] = 'disabled'
-
-def Sample_Action(w, slb, stext, run, view, action):
- global demo
-
- hlist = slb.hlist
- anchor = hlist.info_anchor()
- if not anchor:
- run['state'] = 'disabled'
- view['state'] = 'disabled'
- elif not hlist.info_parent(anchor):
- # a comment
- return
-
- run['state'] = 'normal'
- view['state'] = 'normal'
- key = hlist.info_data(anchor)
- title = key
- prog = samples[key]
-
- if action == 'run':
- exec('import ' + prog)
- w = Tix.Toplevel()
- w.title(title)
- rtn = eval(prog + '.RunSample')
- rtn(w)
- elif action == 'view':
- w = Tix.Toplevel()
- w.title('Source view: ' + title)
- LoadFile(w, demo.dir + '/samples/' + prog + '.py')
- elif action == 'browse':
- ReadFile(stext.text, demo.dir + '/samples/' + prog + '.py')
-
-def LoadFile(w, fname):
- global root
- b = Tix.Button(w, text='Close', command=w.destroy)
- t = Tix.ScrolledText(w)
- # b.form(left=0, bottom=0, padx=4, pady=4)
- # t.form(left=0, bottom=b, right='-0', top=0)
- t.pack()
- b.pack()
-
- font = root.tk.eval('tix option get fixed_font')
- t.text.config(font=font)
- t.text['bd'] = 2
- t.text['wrap'] = 'none'
-
- ReadFile(t.text, fname)
-
-def ReadFile(w, fname):
- old_state = w['state']
- w['state'] = 'normal'
- w.delete('0.0', Tix.END)
-
- try:
- f = open(fname)
- lines = f.readlines()
- for s in lines:
- w.insert(Tix.END, s)
- f.close()
- finally:
-# w.see('1.0')
- w['state'] = old_state
-
-if __name__ == '__main__':
- root = Tix.Tk()
- RunMain(root)
diff --git a/Demo/tkinter/README b/Demo/tkinter/README
deleted file mode 100644
index c9f18df..0000000
--- a/Demo/tkinter/README
+++ /dev/null
@@ -1,11 +0,0 @@
-Several collections of example code for Tkinter.
-
-See the toplevel README for an explanation of the difference between
-Tkinter and _tkinter, how to enable the Python Tk interface, and where
-to get Matt Conway's lifesaver document.
-
-Subdirectories:
-
-guido my original example set (fairly random collection)
-matt Matt Conway's examples, to go with his lifesaver document
-ttk Examples using the ttk module
diff --git a/Demo/tkinter/guido/AttrDialog.py b/Demo/tkinter/guido/AttrDialog.py
deleted file mode 100644
index 86333ad..0000000
--- a/Demo/tkinter/guido/AttrDialog.py
+++ /dev/null
@@ -1,452 +0,0 @@
-
-# The options of a widget are described by the following attributes
-# of the Pack and Widget dialogs:
-#
-# Dialog.current: {name: value}
-# -- changes during Widget's lifetime
-#
-# Dialog.options: {name: (default, klass)}
-# -- depends on widget class only
-#
-# Dialog.classes: {klass: (v0, v1, v2, ...) | 'boolean' | 'other'}
-# -- totally static, though different between PackDialog and WidgetDialog
-# (but even that could be unified)
-
-from Tkinter import *
-
-class Option:
-
- varclass = StringVar # May be overridden
-
- def __init__(self, dialog, option):
- self.dialog = dialog
- self.option = option
- self.master = dialog.top
- self.default, self.klass = dialog.options[option]
- self.var = self.varclass(self.master)
- self.frame = Frame(self.master)
- self.frame.pack(fill=X)
- self.label = Label(self.frame, text=(option + ":"))
- self.label.pack(side=LEFT)
- self.update()
- self.addoption()
-
- def refresh(self):
- self.dialog.refresh()
- self.update()
-
- def update(self):
- try:
- self.current = self.dialog.current[self.option]
- except KeyError:
- self.current = self.default
- self.var.set(self.current)
-
- def set(self, e=None): # Should be overridden
- pass
-
-class BooleanOption(Option):
-
- varclass = BooleanVar
-
- def addoption(self):
- self.button = Checkbutton(self.frame,
- text='on/off',
- onvalue=1,
- offvalue=0,
- variable=self.var,
- relief=RAISED,
- borderwidth=2,
- command=self.set)
- self.button.pack(side=RIGHT)
-
-class EnumOption(Option):
-
- def addoption(self):
- self.button = Menubutton(self.frame,
- textvariable=self.var,
- relief=RAISED, borderwidth=2)
- self.button.pack(side=RIGHT)
- self.menu = Menu(self.button)
- self.button['menu'] = self.menu
- for v in self.dialog.classes[self.klass]:
- self.menu.add_radiobutton(
- label=v,
- variable=self.var,
- value=v,
- command=self.set)
-
-class StringOption(Option):
-
- def addoption(self):
- self.entry = Entry(self.frame,
- textvariable=self.var,
- width=10,
- relief=SUNKEN,
- borderwidth=2)
- self.entry.pack(side=RIGHT, fill=X, expand=1)
- self.entry.bind('<Return>', self.set)
-
-class ReadonlyOption(Option):
-
- def addoption(self):
- self.label = Label(self.frame, textvariable=self.var,
- anchor=E)
- self.label.pack(side=RIGHT)
-
-class Dialog:
-
- def __init__(self, master):
- self.master = master
- self.fixclasses()
- self.refresh()
- self.top = Toplevel(self.master)
- self.top.title(self.__class__.__name__)
- self.top.minsize(1, 1)
- self.addchoices()
-
- def refresh(self): pass # Must override
-
- def fixclasses(self): pass # May override
-
- def addchoices(self):
- self.choices = {}
- list = []
- for k, dc in self.options.items():
- list.append((k, dc))
- list.sort()
- for k, (d, c) in list:
- try:
- cl = self.classes[c]
- except KeyError:
- cl = 'unknown'
- if type(cl) == TupleType:
- cl = self.enumoption
- elif cl == 'boolean':
- cl = self.booleanoption
- elif cl == 'readonly':
- cl = self.readonlyoption
- else:
- cl = self.stringoption
- self.choices[k] = cl(self, k)
-
- # Must override:
- options = {}
- classes = {}
-
- # May override:
- booleanoption = BooleanOption
- stringoption = StringOption
- enumoption = EnumOption
- readonlyoption = ReadonlyOption
-
-class PackDialog(Dialog):
-
- def __init__(self, widget):
- self.widget = widget
- Dialog.__init__(self, widget)
-
- def refresh(self):
- self.current = self.widget.info()
- self.current['.class'] = self.widget.winfo_class()
- self.current['.name'] = self.widget._w
-
- class packoption: # Mix-in class
- def set(self, e=None):
- self.current = self.var.get()
- try:
- apply(self.dialog.widget.pack, (),
- {self.option: self.current})
- except TclError, msg:
- print msg
- self.refresh()
-
- class booleanoption(packoption, BooleanOption): pass
- class enumoption(packoption, EnumOption): pass
- class stringoption(packoption, StringOption): pass
- class readonlyoption(packoption, ReadonlyOption): pass
-
- options = {
- '.class': (None, 'Class'),
- '.name': (None, 'Name'),
- 'after': (None, 'Widget'),
- 'anchor': ('center', 'Anchor'),
- 'before': (None, 'Widget'),
- 'expand': ('no', 'Boolean'),
- 'fill': ('none', 'Fill'),
- 'in': (None, 'Widget'),
- 'ipadx': (0, 'Pad'),
- 'ipady': (0, 'Pad'),
- 'padx': (0, 'Pad'),
- 'pady': (0, 'Pad'),
- 'side': ('top', 'Side'),
- }
-
- classes = {
- 'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
- 'Boolean': 'boolean',
- 'Class': 'readonly',
- 'Expand': 'boolean',
- 'Fill': (NONE, X, Y, BOTH),
- 'Name': 'readonly',
- 'Pad': 'pixel',
- 'Side': (TOP, RIGHT, BOTTOM, LEFT),
- 'Widget': 'readonly',
- }
-
-class RemotePackDialog(PackDialog):
-
- def __init__(self, master, app, widget):
- self.master = master
- self.app = app
- self.widget = widget
- self.refresh()
- self.top = Toplevel(self.master)
- self.top.title(self.app + ' PackDialog')
- self.top.minsize(1, 1)
- self.addchoices()
-
- def refresh(self):
- try:
- words = self.master.tk.splitlist(
- self.master.send(self.app,
- 'pack',
- 'info',
- self.widget))
- except TclError, msg:
- print msg
- return
- dict = {}
- for i in range(0, len(words), 2):
- key = words[i][1:]
- value = words[i+1]
- dict[key] = value
- dict['.class'] = self.master.send(self.app,
- 'winfo',
- 'class',
- self.widget)
- dict['.name'] = self.widget
- self.current = dict
-
- class remotepackoption: # Mix-in class
- def set(self, e=None):
- self.current = self.var.get()
- try:
- self.dialog.master.send(
- self.dialog.app,
- 'pack',
- 'config',
- self.dialog.widget,
- '-'+self.option,
- self.dialog.master.tk.merge(
- self.current))
- except TclError, msg:
- print msg
- self.refresh()
-
- class booleanoption(remotepackoption, BooleanOption): pass
- class enumoption(remotepackoption, EnumOption): pass
- class stringoption(remotepackoption, StringOption): pass
- class readonlyoption(remotepackoption, ReadonlyOption): pass
-
-class WidgetDialog(Dialog):
-
- def __init__(self, widget):
- self.widget = widget
- self.klass = widget.winfo_class()
- Dialog.__init__(self, widget)
-
- def fixclasses(self):
- if self.addclasses.has_key(self.klass):
- classes = {}
- for c in (self.classes,
- self.addclasses[self.klass]):
- for k in c.keys():
- classes[k] = c[k]
- self.classes = classes
-
- def refresh(self):
- self.configuration = self.widget.config()
- self.update()
- self.current['.class'] = self.widget.winfo_class()
- self.current['.name'] = self.widget._w
-
- def update(self):
- self.current = {}
- self.options = {}
- for k, v in self.configuration.items():
- if len(v) > 4:
- self.current[k] = v[4]
- self.options[k] = v[3], v[2] # default, klass
- self.options['.class'] = (None, 'Class')
- self.options['.name'] = (None, 'Name')
-
- class widgetoption: # Mix-in class
- def set(self, e=None):
- self.current = self.var.get()
- try:
- self.dialog.widget[self.option] = self.current
- except TclError, msg:
- print msg
- self.refresh()
-
- class booleanoption(widgetoption, BooleanOption): pass
- class enumoption(widgetoption, EnumOption): pass
- class stringoption(widgetoption, StringOption): pass
- class readonlyoption(widgetoption, ReadonlyOption): pass
-
- # Universal classes
- classes = {
- 'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
- 'Aspect': 'integer',
- 'Background': 'color',
- 'Bitmap': 'bitmap',
- 'BorderWidth': 'pixel',
- 'Class': 'readonly',
- 'CloseEnough': 'double',
- 'Command': 'command',
- 'Confine': 'boolean',
- 'Cursor': 'cursor',
- 'CursorWidth': 'pixel',
- 'DisabledForeground': 'color',
- 'ExportSelection': 'boolean',
- 'Font': 'font',
- 'Foreground': 'color',
- 'From': 'integer',
- 'Geometry': 'geometry',
- 'Height': 'pixel',
- 'InsertWidth': 'time',
- 'Justify': (LEFT, CENTER, RIGHT),
- 'Label': 'string',
- 'Length': 'pixel',
- 'MenuName': 'widget',
- 'Name': 'readonly',
- 'OffTime': 'time',
- 'OnTime': 'time',
- 'Orient': (HORIZONTAL, VERTICAL),
- 'Pad': 'pixel',
- 'Relief': (RAISED, SUNKEN, FLAT, RIDGE, GROOVE),
- 'RepeatDelay': 'time',
- 'RepeatInterval': 'time',
- 'ScrollCommand': 'command',
- 'ScrollIncrement': 'pixel',
- 'ScrollRegion': 'rectangle',
- 'ShowValue': 'boolean',
- 'SetGrid': 'boolean',
- 'Sliderforeground': 'color',
- 'SliderLength': 'pixel',
- 'Text': 'string',
- 'TickInterval': 'integer',
- 'To': 'integer',
- 'Underline': 'index',
- 'Variable': 'variable',
- 'Value': 'string',
- 'Width': 'pixel',
- 'Wrap': (NONE, CHAR, WORD),
- }
-
- # Classes that (may) differ per widget type
- _tristate = {'State': (NORMAL, ACTIVE, DISABLED)}
- _bistate = {'State': (NORMAL, DISABLED)}
- addclasses = {
- 'Button': _tristate,
- 'Radiobutton': _tristate,
- 'Checkbutton': _tristate,
- 'Entry': _bistate,
- 'Text': _bistate,
- 'Menubutton': _tristate,
- 'Slider': _bistate,
- }
-
-class RemoteWidgetDialog(WidgetDialog):
-
- def __init__(self, master, app, widget):
- self.app = app
- self.widget = widget
- self.klass = master.send(self.app,
- 'winfo',
- 'class',
- self.widget)
- Dialog.__init__(self, master)
-
- def refresh(self):
- try:
- items = self.master.tk.splitlist(
- self.master.send(self.app,
- self.widget,
- 'config'))
- except TclError, msg:
- print msg
- return
- dict = {}
- for item in items:
- words = self.master.tk.splitlist(item)
- key = words[0][1:]
- value = (key,) + words[1:]
- dict[key] = value
- self.configuration = dict
- self.update()
- self.current['.class'] = self.klass
- self.current['.name'] = self.widget
-
- class remotewidgetoption: # Mix-in class
- def set(self, e=None):
- self.current = self.var.get()
- try:
- self.dialog.master.send(
- self.dialog.app,
- self.dialog.widget,
- 'config',
- '-'+self.option,
- self.current)
- except TclError, msg:
- print msg
- self.refresh()
-
- class booleanoption(remotewidgetoption, BooleanOption): pass
- class enumoption(remotewidgetoption, EnumOption): pass
- class stringoption(remotewidgetoption, StringOption): pass
- class readonlyoption(remotewidgetoption, ReadonlyOption): pass
-
-def test():
- import sys
- root = Tk()
- root.minsize(1, 1)
- if sys.argv[1:]:
- remotetest(root, sys.argv[1])
- else:
- frame = Frame(root, name='frame')
- frame.pack(expand=1, fill=BOTH)
- button = Button(frame, name='button', text='button')
- button.pack(expand=1)
- canvas = Canvas(frame, name='canvas')
- canvas.pack()
- fpd = PackDialog(frame)
- fwd = WidgetDialog(frame)
- bpd = PackDialog(button)
- bwd = WidgetDialog(button)
- cpd = PackDialog(canvas)
- cwd = WidgetDialog(canvas)
- root.mainloop()
-
-def remotetest(root, app):
- from listtree import listtree
- list = listtree(root, app)
- list.bind('<Any-Double-1>', opendialogs)
- list.app = app # Pass it on to handler
-
-def opendialogs(e):
- import string
- list = e.widget
- sel = list.curselection()
- for i in sel:
- item = list.get(i)
- widget = string.split(item)[0]
- RemoteWidgetDialog(list, list.app, widget)
- if widget == '.': continue
- try:
- RemotePackDialog(list, list.app, widget)
- except TclError, msg:
- print msg
-
-test()
diff --git a/Demo/tkinter/guido/ManPage.py b/Demo/tkinter/guido/ManPage.py
deleted file mode 100644
index de3117b..0000000
--- a/Demo/tkinter/guido/ManPage.py
+++ /dev/null
@@ -1,220 +0,0 @@
-# Widget to display a man page
-
-import re
-from Tkinter import *
-from Tkinter import _tkinter
-from ScrolledText import ScrolledText
-
-# XXX These fonts may have to be changed to match your system
-BOLDFONT = '*-Courier-Bold-R-Normal-*-120-*'
-ITALICFONT = '*-Courier-Medium-O-Normal-*-120-*'
-
-# XXX Recognizing footers is system dependent
-# (This one works for IRIX 5.2 and Solaris 2.2)
-footerprog = re.compile(
- '^ Page [1-9][0-9]*[ \t]+\|^.*Last change:.*[1-9][0-9]*\n')
-emptyprog = re.compile('^[ \t]*\n')
-ulprog = re.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n')
-
-# Basic Man Page class -- does not disable editing
-class EditableManPage(ScrolledText):
-
- # Initialize instance
- def __init__(self, master=None, **cnf):
- # Initialize base class
- apply(ScrolledText.__init__, (self, master), cnf)
-
- # Define tags for formatting styles
- self.tag_config('X', underline=1)
- self.tag_config('!', font=BOLDFONT)
- self.tag_config('_', font=ITALICFONT)
-
- # Set state to idle
- self.fp = None
- self.lineno = 0
-
- # Test whether we are busy parsing a file
- def busy(self):
- return self.fp != None
-
- # Ensure we're not busy
- def kill(self):
- if self.busy():
- self._endparser()
-
- # Parse a file, in the background
- def asyncparsefile(self, fp):
- self._startparser(fp)
- self.tk.createfilehandler(fp, _tkinter.READABLE,
- self._filehandler)
-
- parsefile = asyncparsefile # Alias
-
- # I/O handler used by background parsing
- def _filehandler(self, fp, mask):
- nextline = self.fp.readline()
- if not nextline:
- self._endparser()
- return
- self._parseline(nextline)
-
- # Parse a file, now (cannot be aborted)
- def syncparsefile(self, fp):
- from select import select
- def avail(fp=fp, tout=0.0, select=select):
- return select([fp], [], [], tout)[0]
- height = self.getint(self['height'])
- self._startparser(fp)
- while 1:
- nextline = fp.readline()
- if not nextline:
- break
- self._parseline(nextline)
- self._endparser()
-
- # Initialize parsing from a particular file -- must not be busy
- def _startparser(self, fp):
- if self.busy():
- raise RuntimeError, 'startparser: still busy'
- fp.fileno() # Test for file-ness
- self.fp = fp
- self.lineno = 0
- self.ok = 0
- self.empty = 0
- self.buffer = None
- savestate = self['state']
- self['state'] = NORMAL
- self.delete('1.0', END)
- self['state'] = savestate
-
- # End parsing -- must be busy, need not be at EOF
- def _endparser(self):
- if not self.busy():
- raise RuntimeError, 'endparser: not busy'
- if self.buffer:
- self._parseline('')
- try:
- self.tk.deletefilehandler(self.fp)
- except TclError, msg:
- pass
- self.fp.close()
- self.fp = None
- del self.ok, self.empty, self.buffer
-
- # Parse a single line
- def _parseline(self, nextline):
- if not self.buffer:
- # Save this line -- we need one line read-ahead
- self.buffer = nextline
- return
- if emptyprog.match(self.buffer) >= 0:
- # Buffered line was empty -- set a flag
- self.empty = 1
- self.buffer = nextline
- return
- textline = self.buffer
- if ulprog.match(nextline) >= 0:
- # Next line is properties for buffered line
- propline = nextline
- self.buffer = None
- else:
- # Next line is read-ahead
- propline = None
- self.buffer = nextline
- if not self.ok:
- # First non blank line after footer must be header
- # -- skip that too
- self.ok = 1
- self.empty = 0
- return
- if footerprog.match(textline) >= 0:
- # Footer -- start skipping until next non-blank line
- self.ok = 0
- self.empty = 0
- return
- savestate = self['state']
- self['state'] = NORMAL
- if TkVersion >= 4.0:
- self.mark_set('insert', 'end-1c')
- else:
- self.mark_set('insert', END)
- if self.empty:
- # One or more previous lines were empty
- # -- insert one blank line in the text
- self._insert_prop('\n')
- self.lineno = self.lineno + 1
- self.empty = 0
- if not propline:
- # No properties
- self._insert_prop(textline)
- else:
- # Search for properties
- p = ''
- j = 0
- for i in range(min(len(propline), len(textline))):
- if propline[i] != p:
- if j < i:
- self._insert_prop(textline[j:i], p)
- j = i
- p = propline[i]
- self._insert_prop(textline[j:])
- self.lineno = self.lineno + 1
- self['state'] = savestate
-
- # Insert a string at the end, with at most one property (tag)
- def _insert_prop(self, str, prop = ' '):
- here = self.index(AtInsert())
- self.insert(AtInsert(), str)
- if TkVersion <= 4.0:
- tags = self.tag_names(here)
- for tag in tags:
- self.tag_remove(tag, here, AtInsert())
- if prop != ' ':
- self.tag_add(prop, here, AtInsert())
-
-# Readonly Man Page class -- disables editing, otherwise the same
-class ReadonlyManPage(EditableManPage):
-
- # Initialize instance
- def __init__(self, master=None, **cnf):
- cnf['state'] = DISABLED
- apply(EditableManPage.__init__, (self, master), cnf)
-
-# Alias
-ManPage = ReadonlyManPage
-
-# Test program.
-# usage: ManPage [manpage]; or ManPage [-f] file
-# -f means that the file is nroff -man output run through ul -i
-def test():
- import os
- import sys
- # XXX This directory may be different on your system
- MANDIR = '/usr/local/man/mann'
- DEFAULTPAGE = 'Tcl'
- formatted = 0
- if sys.argv[1:] and sys.argv[1] == '-f':
- formatted = 1
- del sys.argv[1]
- if sys.argv[1:]:
- name = sys.argv[1]
- else:
- name = DEFAULTPAGE
- if not formatted:
- if name[-2:-1] != '.':
- name = name + '.n'
- name = os.path.join(MANDIR, name)
- root = Tk()
- root.minsize(1, 1)
- manpage = ManPage(root, relief=SUNKEN, borderwidth=2)
- manpage.pack(expand=1, fill=BOTH)
- if formatted:
- fp = open(name, 'r')
- else:
- fp = os.popen('nroff -man %s | ul -i' % name, 'r')
- manpage.parsefile(fp)
- root.mainloop()
-
-# Run the test program when called as a script
-if __name__ == '__main__':
- test()
diff --git a/Demo/tkinter/guido/MimeViewer.py b/Demo/tkinter/guido/MimeViewer.py
deleted file mode 100755
index 7494425..0000000
--- a/Demo/tkinter/guido/MimeViewer.py
+++ /dev/null
@@ -1,143 +0,0 @@
-#! /usr/bin/env python
-
-# View a single MIME multipart message.
-# Display each part as a box.
-
-import string
-from types import *
-from Tkinter import *
-from ScrolledText import ScrolledText
-
-class MimeViewer:
- def __init__(self, parent, title, msg):
- self.title = title
- self.msg = msg
- self.frame = Frame(parent, {'relief': 'raised', 'bd': 2})
- self.frame.packing = {'expand': 0, 'fill': 'both'}
- self.button = Checkbutton(self.frame,
- {'text': title,
- 'command': self.toggle})
- self.button.pack({'anchor': 'w'})
- headertext = msg.getheadertext(
- lambda x: x != 'received' and x[:5] != 'x400-')
- height = countlines(headertext, 4)
- if height:
- self.htext = ScrolledText(self.frame,
- {'height': height,
- 'width': 80,
- 'wrap': 'none',
- 'relief': 'raised',
- 'bd': 2})
- self.htext.packing = {'expand': 1, 'fill': 'both',
- 'after': self.button}
- self.htext.insert('end', headertext)
- else:
- self.htext = Frame(self.frame,
- {'relief': 'raised', 'bd': 2})
- self.htext.packing = {'side': 'top',
- 'ipady': 2,
- 'fill': 'x',
- 'after': self.button}
- body = msg.getbody()
- if type(body) == StringType:
- self.pad = None
- height = countlines(body, 10)
- if height:
- self.btext = ScrolledText(self.frame,
- {'height': height,
- 'width': 80,
- 'wrap': 'none',
- 'relief': 'raised',
- 'bd': 2})
- self.btext.packing = {'expand': 1,
- 'fill': 'both'}
- self.btext.insert('end', body)
- else:
- self.btext = None
- self.parts = None
- else:
- self.pad = Frame(self.frame,
- {'relief': 'flat', 'bd': 2})
- self.pad.packing = {'side': 'left', 'ipadx': 10,
- 'fill': 'y', 'after': self.htext}
- self.parts = []
- for i in range(len(body)):
- p = MimeViewer(self.frame,
- '%s.%d' % (title, i+1),
- body[i])
- self.parts.append(p)
- self.btext = None
- self.collapsed = 1
- def pack(self):
- self.frame.pack(self.frame.packing)
- def destroy(self):
- self.frame.destroy()
- def show(self):
- if self.collapsed:
- self.button.invoke()
- def toggle(self):
- if self.collapsed:
- self.explode()
- else:
- self.collapse()
- def collapse(self):
- self.collapsed = 1
- for comp in self.htext, self.btext, self.pad:
- if comp:
- comp.forget()
- if self.parts:
- for part in self.parts:
- part.frame.forget()
- self.frame.pack({'expand': 0})
- def explode(self):
- self.collapsed = 0
- for comp in self.htext, self.btext, self.pad:
- if comp: comp.pack(comp.packing)
- if self.parts:
- for part in self.parts:
- part.pack()
- self.frame.pack({'expand': 1})
-
-def countlines(str, limit):
- i = 0
- n = 0
- while n < limit:
- i = string.find(str, '\n', i)
- if i < 0: break
- n = n+1
- i = i+1
- return n
-
-def main():
- import sys
- import getopt
- import mhlib
- opts, args = getopt.getopt(sys.argv[1:], '')
- for o, a in opts:
- pass
- message = None
- folder = 'inbox'
- for arg in args:
- if arg[:1] == '+':
- folder = arg[1:]
- else:
- message = string.atoi(arg)
-
- mh = mhlib.MH()
- f = mh.openfolder(folder)
- if not message:
- message = f.getcurrent()
- m = f.openmessage(message)
-
- root = Tk()
- tk = root.tk
-
- top = MimeViewer(root, '+%s/%d' % (folder, message), m)
- top.pack()
- top.show()
-
- root.minsize(1, 1)
-
- tk.mainloop()
-
-if __name__ == '__main__': main()
diff --git a/Demo/tkinter/guido/ShellWindow.py b/Demo/tkinter/guido/ShellWindow.py
deleted file mode 100644
index 0b100f1..0000000
--- a/Demo/tkinter/guido/ShellWindow.py
+++ /dev/null
@@ -1,147 +0,0 @@
-import os
-import sys
-import string
-from Tkinter import *
-from ScrolledText import ScrolledText
-from Dialog import Dialog
-import signal
-
-BUFSIZE = 512
-
-class ShellWindow(ScrolledText):
-
- def __init__(self, master=None, shell=None, **cnf):
- if not shell:
- try:
- shell = os.environ['SHELL']
- except KeyError:
- shell = '/bin/sh'
- shell = shell + ' -i'
- args = string.split(shell)
- shell = args[0]
-
- apply(ScrolledText.__init__, (self, master), cnf)
- self.pos = '1.0'
- self.bind('<Return>', self.inputhandler)
- self.bind('<Control-c>', self.sigint)
- self.bind('<Control-t>', self.sigterm)
- self.bind('<Control-k>', self.sigkill)
- self.bind('<Control-d>', self.sendeof)
-
- self.pid, self.fromchild, self.tochild = spawn(shell, args)
- self.tk.createfilehandler(self.fromchild, READABLE,
- self.outputhandler)
-
- def outputhandler(self, file, mask):
- data = os.read(file, BUFSIZE)
- if not data:
- self.tk.deletefilehandler(file)
- pid, sts = os.waitpid(self.pid, 0)
- print 'pid', pid, 'status', sts
- self.pid = None
- detail = sts>>8
- cause = sts & 0xff
- if cause == 0:
- msg = "exit status %d" % detail
- else:
- msg = "killed by signal %d" % (cause & 0x7f)
- if cause & 0x80:
- msg = msg + " -- core dumped"
- Dialog(self.master,
- text=msg,
- title="Exit status",
- bitmap='warning',
- default=0,
- strings=('OK',))
- return
- self.insert(END, data)
- self.pos = self.index("end - 1 char")
- self.yview_pickplace(END)
-
- def inputhandler(self, *args):
- if not self.pid:
- self.no_process()
- return "break"
- self.insert(END, "\n")
- line = self.get(self.pos, "end - 1 char")
- self.pos = self.index(END)
- os.write(self.tochild, line)
- return "break"
-
- def sendeof(self, *args):
- if not self.pid:
- self.no_process()
- return "break"
- os.close(self.tochild)
- return "break"
-
- def sendsig(self, sig):
- if not self.pid:
- self.no_process()
- return "break"
- os.kill(self.pid, sig)
- return "break"
-
- def sigint(self, *args):
- return self.sendsig(signal.SIGINT)
-
- def sigquit(self, *args):
- return self.sendsig(signal.SIGQUIT)
-
- def sigterm(self, *args):
- return self.sendsig(signal.SIGTERM)
-
- def sigkill(self, *args):
- return self.sendsig(signal.SIGKILL)
-
- def no_process(self):
- Dialog(self.master,
- text="No active process",
- title="No process",
- bitmap='error',
- default=0,
- strings=('OK',))
-
-MAXFD = 100 # Max number of file descriptors (os.getdtablesize()???)
-
-def spawn(prog, args):
- p2cread, p2cwrite = os.pipe()
- c2pread, c2pwrite = os.pipe()
- pid = os.fork()
- if pid == 0:
- # Child
- for i in 0, 1, 2:
- try:
- os.close(i)
- except os.error:
- pass
- if os.dup(p2cread) <> 0:
- sys.stderr.write('popen2: bad read dup\n')
- if os.dup(c2pwrite) <> 1:
- sys.stderr.write('popen2: bad write dup\n')
- if os.dup(c2pwrite) <> 2:
- sys.stderr.write('popen2: bad write dup\n')
- os.closerange(3, MAXFD)
- try:
- os.execvp(prog, args)
- finally:
- sys.stderr.write('execvp failed\n')
- os._exit(1)
- os.close(p2cread)
- os.close(c2pwrite)
- return pid, c2pread, p2cwrite
-
-def test():
- shell = string.join(sys.argv[1:])
- root = Tk()
- root.minsize(1, 1)
- if shell:
- w = ShellWindow(root, shell=shell)
- else:
- w = ShellWindow(root)
- w.pack(expand=1, fill=BOTH)
- w.focus_set()
- w.tk.mainloop()
-
-if __name__ == '__main__':
- test()
diff --git a/Demo/tkinter/guido/brownian.py b/Demo/tkinter/guido/brownian.py
deleted file mode 100644
index 8007f14..0000000
--- a/Demo/tkinter/guido/brownian.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Brownian motion -- an example of a multi-threaded Tkinter program.
-
-from Tkinter import *
-import random
-import threading
-import time
-import sys
-
-WIDTH = 400
-HEIGHT = 300
-SIGMA = 10
-BUZZ = 2
-RADIUS = 2
-LAMBDA = 10
-FILL = 'red'
-
-stop = 0 # Set when main loop exits
-
-def particle(canvas):
- r = RADIUS
- x = random.gauss(WIDTH/2.0, SIGMA)
- y = random.gauss(HEIGHT/2.0, SIGMA)
- p = canvas.create_oval(x-r, y-r, x+r, y+r, fill=FILL)
- while not stop:
- dx = random.gauss(0, BUZZ)
- dy = random.gauss(0, BUZZ)
- dt = random.expovariate(LAMBDA)
- try:
- canvas.move(p, dx, dy)
- except TclError:
- break
- time.sleep(dt)
-
-def main():
- global stop
- root = Tk()
- canvas = Canvas(root, width=WIDTH, height=HEIGHT)
- canvas.pack(fill='both', expand=1)
- np = 30
- if sys.argv[1:]:
- np = int(sys.argv[1])
- for i in range(np):
- t = threading.Thread(target=particle, args=(canvas,))
- t.start()
- try:
- root.mainloop()
- finally:
- stop = 1
-
-main()
diff --git a/Demo/tkinter/guido/brownian2.py b/Demo/tkinter/guido/brownian2.py
deleted file mode 100644
index 281a645..0000000
--- a/Demo/tkinter/guido/brownian2.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Brownian motion -- an example of a NON multi-threaded Tkinter program ;)
-# By Michele Simoniato, inspired by brownian.py
-
-from Tkinter import *
-import random
-import sys
-
-WIDTH = 400
-HEIGHT = 300
-SIGMA = 10
-BUZZ = 2
-RADIUS = 2
-LAMBDA = 10
-FILL = 'red'
-
-stop = 0 # Set when main loop exits
-root = None # main window
-
-def particle(canvas): # particle = iterator over the moves
- r = RADIUS
- x = random.gauss(WIDTH/2.0, SIGMA)
- y = random.gauss(HEIGHT/2.0, SIGMA)
- p = canvas.create_oval(x-r, y-r, x+r, y+r, fill=FILL)
- while not stop:
- dx = random.gauss(0, BUZZ)
- dy = random.gauss(0, BUZZ)
- try:
- canvas.move(p, dx, dy)
- except TclError:
- break
- else:
- yield None
-
-def move(particle): # move the particle at random time
- particle.next()
- dt = random.expovariate(LAMBDA)
- root.after(int(dt*1000), move, particle)
-
-def main():
- global root, stop
- root = Tk()
- canvas = Canvas(root, width=WIDTH, height=HEIGHT)
- canvas.pack(fill='both', expand=1)
- np = 30
- if sys.argv[1:]:
- np = int(sys.argv[1])
- for i in range(np): # start the dance
- move(particle(canvas))
- try:
- root.mainloop()
- finally:
- stop = 1
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/tkinter/guido/canvasevents.py b/Demo/tkinter/guido/canvasevents.py
deleted file mode 100644
index 74ed76f..0000000
--- a/Demo/tkinter/guido/canvasevents.py
+++ /dev/null
@@ -1,244 +0,0 @@
-#! /usr/bin/env python
-
-from Tkinter import *
-from Canvas import Oval, Group, CanvasText
-
-
-# Fix a bug in Canvas.Group as distributed in Python 1.4. The
-# distributed bind() method is broken. This is what should be used:
-
-class Group(Group):
- def bind(self, sequence=None, command=None):
- return self.canvas.tag_bind(self.id, sequence, command)
-
-class Object:
-
- """Base class for composite graphical objects.
-
- Objects belong to a canvas, and can be moved around on the canvas.
- They also belong to at most one ``pile'' of objects, and can be
- transferred between piles (or removed from their pile).
-
- Objects have a canonical ``x, y'' position which is moved when the
- object is moved. Where the object is relative to this position
- depends on the object; for simple objects, it may be their center.
-
- Objects have mouse sensitivity. They can be clicked, dragged and
- double-clicked. The behavior may actually determined by the pile
- they are in.
-
- All instance attributes are public since the derived class may
- need them.
-
- """
-
- def __init__(self, canvas, x=0, y=0, fill='red', text='object'):
- self.canvas = canvas
- self.x = x
- self.y = y
- self.pile = None
- self.group = Group(self.canvas)
- self.createitems(fill, text)
-
- def __str__(self):
- return str(self.group)
-
- def createitems(self, fill, text):
- self.__oval = Oval(self.canvas,
- self.x-20, self.y-10, self.x+20, self.y+10,
- fill=fill, width=3)
- self.group.addtag_withtag(self.__oval)
- self.__text = CanvasText(self.canvas,
- self.x, self.y, text=text)
- self.group.addtag_withtag(self.__text)
-
- def moveby(self, dx, dy):
- if dx == dy == 0:
- return
- self.group.move(dx, dy)
- self.x = self.x + dx
- self.y = self.y + dy
-
- def moveto(self, x, y):
- self.moveby(x - self.x, y - self.y)
-
- def transfer(self, pile):
- if self.pile:
- self.pile.delete(self)
- self.pile = None
- self.pile = pile
- if self.pile:
- self.pile.add(self)
-
- def tkraise(self):
- self.group.tkraise()
-
-
-class Bottom(Object):
-
- """An object to serve as the bottom of a pile."""
-
- def createitems(self, *args):
- self.__oval = Oval(self.canvas,
- self.x-20, self.y-10, self.x+20, self.y+10,
- fill='gray', outline='')
- self.group.addtag_withtag(self.__oval)
-
-
-class Pile:
-
- """A group of graphical objects."""
-
- def __init__(self, canvas, x, y, tag=None):
- self.canvas = canvas
- self.x = x
- self.y = y
- self.objects = []
- self.bottom = Bottom(self.canvas, self.x, self.y)
- self.group = Group(self.canvas, tag=tag)
- self.group.addtag_withtag(self.bottom.group)
- self.bindhandlers()
-
- def bindhandlers(self):
- self.group.bind('<1>', self.clickhandler)
- self.group.bind('<Double-1>', self.doubleclickhandler)
-
- def add(self, object):
- self.objects.append(object)
- self.group.addtag_withtag(object.group)
- self.position(object)
-
- def delete(self, object):
- object.group.dtag(self.group)
- self.objects.remove(object)
-
- def position(self, object):
- object.tkraise()
- i = self.objects.index(object)
- object.moveto(self.x + i*4, self.y + i*8)
-
- def clickhandler(self, event):
- pass
-
- def doubleclickhandler(self, event):
- pass
-
-
-class MovingPile(Pile):
-
- def bindhandlers(self):
- Pile.bindhandlers(self)
- self.group.bind('<B1-Motion>', self.motionhandler)
- self.group.bind('<ButtonRelease-1>', self.releasehandler)
-
- movethis = None
-
- def clickhandler(self, event):
- tags = self.canvas.gettags('current')
- for i in range(len(self.objects)):
- o = self.objects[i]
- if o.group.tag in tags:
- break
- else:
- self.movethis = None
- return
- self.movethis = self.objects[i:]
- for o in self.movethis:
- o.tkraise()
- self.lastx = event.x
- self.lasty = event.y
-
- doubleclickhandler = clickhandler
-
- def motionhandler(self, event):
- if not self.movethis:
- return
- dx = event.x - self.lastx
- dy = event.y - self.lasty
- self.lastx = event.x
- self.lasty = event.y
- for o in self.movethis:
- o.moveby(dx, dy)
-
- def releasehandler(self, event):
- objects = self.movethis
- if not objects:
- return
- self.movethis = None
- self.finishmove(objects)
-
- def finishmove(self, objects):
- for o in objects:
- self.position(o)
-
-
-class Pile1(MovingPile):
-
- x = 50
- y = 50
- tag = 'p1'
-
- def __init__(self, demo):
- self.demo = demo
- MovingPile.__init__(self, self.demo.canvas, self.x, self.y, self.tag)
-
- def doubleclickhandler(self, event):
- try:
- o = self.objects[-1]
- except IndexError:
- return
- o.transfer(self.other())
- MovingPile.doubleclickhandler(self, event)
-
- def other(self):
- return self.demo.p2
-
- def finishmove(self, objects):
- o = objects[0]
- p = self.other()
- x, y = o.x, o.y
- if (x-p.x)**2 + (y-p.y)**2 < (x-self.x)**2 + (y-self.y)**2:
- for o in objects:
- o.transfer(p)
- else:
- MovingPile.finishmove(self, objects)
-
-class Pile2(Pile1):
-
- x = 150
- y = 50
- tag = 'p2'
-
- def other(self):
- return self.demo.p1
-
-
-class Demo:
-
- def __init__(self, master):
- self.master = master
- self.canvas = Canvas(master,
- width=200, height=200,
- background='yellow',
- relief=SUNKEN, borderwidth=2)
- self.canvas.pack(expand=1, fill=BOTH)
- self.p1 = Pile1(self)
- self.p2 = Pile2(self)
- o1 = Object(self.canvas, fill='red', text='o1')
- o2 = Object(self.canvas, fill='green', text='o2')
- o3 = Object(self.canvas, fill='light blue', text='o3')
- o1.transfer(self.p1)
- o2.transfer(self.p1)
- o3.transfer(self.p2)
-
-
-# Main function, run when invoked as a stand-alone Python program.
-
-def main():
- root = Tk()
- demo = Demo(root)
- root.protocol('WM_DELETE_WINDOW', root.quit)
- root.mainloop()
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/tkinter/guido/dialog.py b/Demo/tkinter/guido/dialog.py
deleted file mode 100755
index 50d84b9..0000000
--- a/Demo/tkinter/guido/dialog.py
+++ /dev/null
@@ -1,109 +0,0 @@
-#! /usr/bin/env python
-
-# A Python function that generates dialog boxes with a text message,
-# optional bitmap, and any number of buttons.
-# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.2-3, pp. 269-270.
-
-from Tkinter import *
-import sys
-
-
-def dialog(master, title, text, bitmap, default, *args):
-
- # 1. Create the top-level window and divide it into top
- # and bottom parts.
-
- w = Toplevel(master, class_='Dialog')
- w.title(title)
- w.iconname('Dialog')
-
- top = Frame(w, relief=RAISED, borderwidth=1)
- top.pack(side=TOP, fill=BOTH)
- bot = Frame(w, relief=RAISED, borderwidth=1)
- bot.pack(side=BOTTOM, fill=BOTH)
-
- # 2. Fill the top part with the bitmap and message.
-
- msg = Message(top, width='3i', text=text,
- font='-Adobe-Times-Medium-R-Normal-*-180-*')
- msg.pack(side=RIGHT, expand=1, fill=BOTH, padx='3m', pady='3m')
- if bitmap:
- bm = Label(top, bitmap=bitmap)
- bm.pack(side=LEFT, padx='3m', pady='3m')
-
- # 3. Create a row of buttons at the bottom of the dialog.
-
- var = IntVar()
- buttons = []
- i = 0
- for but in args:
- b = Button(bot, text=but, command=lambda v=var,i=i: v.set(i))
- buttons.append(b)
- if i == default:
- bd = Frame(bot, relief=SUNKEN, borderwidth=1)
- bd.pack(side=LEFT, expand=1, padx='3m', pady='2m')
- b.lift()
- b.pack (in_=bd, side=LEFT,
- padx='2m', pady='2m', ipadx='2m', ipady='1m')
- else:
- b.pack (side=LEFT, expand=1,
- padx='3m', pady='3m', ipadx='2m', ipady='1m')
- i = i+1
-
- # 4. Set up a binding for <Return>, if there's a default,
- # set a grab, and claim the focus too.
-
- if default >= 0:
- w.bind('<Return>',
- lambda e, b=buttons[default], v=var, i=default:
- (b.flash(),
- v.set(i)))
-
- oldFocus = w.focus_get()
- w.grab_set()
- w.focus_set()
-
- # 5. Wait for the user to respond, then restore the focus
- # and return the index of the selected button.
-
- w.waitvar(var)
- w.destroy()
- if oldFocus: oldFocus.focus_set()
- return var.get()
-
-# The rest is the test program.
-
-def go():
- i = dialog(mainWidget,
- 'Not Responding',
- "The file server isn't responding right now; "
- "I'll keep trying.",
- '',
- -1,
- 'OK')
- print 'pressed button', i
- i = dialog(mainWidget,
- 'File Modified',
- 'File "tcl.h" has been modified since '
- 'the last time it was saved. '
- 'Do you want to save it before exiting the application?',
- 'warning',
- 0,
- 'Save File',
- 'Discard Changes',
- 'Return To Editor')
- print 'pressed button', i
-
-def test():
- import sys
- global mainWidget
- mainWidget = Frame()
- Pack.config(mainWidget)
- start = Button(mainWidget, text='Press Here To Start', command=go)
- start.pack()
- endit = Button(mainWidget, text="Exit", command=sys.exit)
- endit.pack(fill=BOTH)
- mainWidget.mainloop()
-
-if __name__ == '__main__':
- test()
diff --git a/Demo/tkinter/guido/electrons.py b/Demo/tkinter/guido/electrons.py
deleted file mode 100755
index fdc558f..0000000
--- a/Demo/tkinter/guido/electrons.py
+++ /dev/null
@@ -1,91 +0,0 @@
-#! /usr/bin/env python
-
-# Simulate "electrons" migrating across the screen.
-# An optional bitmap file in can be in the background.
-#
-# Usage: electrons [n [bitmapfile]]
-#
-# n is the number of electrons to animate; default is 30.
-#
-# The bitmap file can be any X11 bitmap file (look in
-# /usr/include/X11/bitmaps for samples); it is displayed as the
-# background of the animation. Default is no bitmap.
-
-from Tkinter import *
-import random
-
-
-# The graphical interface
-class Electrons:
-
- # Create our objects
- def __init__(self, n, bitmap = None):
- self.n = n
- self.tk = tk = Tk()
- self.canvas = c = Canvas(tk)
- c.pack()
- width, height = tk.getint(c['width']), tk.getint(c['height'])
-
- # Add background bitmap
- if bitmap:
- self.bitmap = c.create_bitmap(width/2, height/2,
- bitmap=bitmap,
- foreground='blue')
-
- self.pieces = []
- x1, y1, x2, y2 = 10,70,14,74
- for i in range(n):
- p = c.create_oval(x1, y1, x2, y2, fill='red')
- self.pieces.append(p)
- y1, y2 = y1 +2, y2 + 2
- self.tk.update()
-
- def random_move(self, n):
- c = self.canvas
- for p in self.pieces:
- x = random.choice(range(-2,4))
- y = random.choice(range(-3,4))
- c.move(p, x, y)
- self.tk.update()
-
- # Run -- allow 500 movemens
- def run(self):
- try:
- for i in range(500):
- self.random_move(self.n)
- except TclError:
- try:
- self.tk.destroy()
- except TclError:
- pass
-
-
-# Main program
-def main():
- import sys, string
-
- # First argument is number of electrons, default 30
- if sys.argv[1:]:
- n = string.atoi(sys.argv[1])
- else:
- n = 30
-
- # Second argument is bitmap file, default none
- if sys.argv[2:]:
- bitmap = sys.argv[2]
- # Reverse meaning of leading '@' compared to Tk
- if bitmap[0] == '@': bitmap = bitmap[1:]
- else: bitmap = '@' + bitmap
- else:
- bitmap = None
-
- # Create the graphical objects...
- h = Electrons(n, bitmap)
-
- # ...and run!
- h.run()
-
-
-# Call main when run as script
-if __name__ == '__main__':
- main()
diff --git a/Demo/tkinter/guido/hanoi.py b/Demo/tkinter/guido/hanoi.py
deleted file mode 100644
index 58ba1d1..0000000
--- a/Demo/tkinter/guido/hanoi.py
+++ /dev/null
@@ -1,154 +0,0 @@
-# Animated Towers of Hanoi using Tk with optional bitmap file in
-# background.
-#
-# Usage: tkhanoi [n [bitmapfile]]
-#
-# n is the number of pieces to animate; default is 4, maximum 15.
-#
-# The bitmap file can be any X11 bitmap file (look in
-# /usr/include/X11/bitmaps for samples); it is displayed as the
-# background of the animation. Default is no bitmap.
-
-# This uses Steen Lumholt's Tk interface
-from Tkinter import *
-
-
-# Basic Towers-of-Hanoi algorithm: move n pieces from a to b, using c
-# as temporary. For each move, call report()
-def hanoi(n, a, b, c, report):
- if n <= 0: return
- hanoi(n-1, a, c, b, report)
- report(n, a, b)
- hanoi(n-1, c, b, a, report)
-
-
-# The graphical interface
-class Tkhanoi:
-
- # Create our objects
- def __init__(self, n, bitmap = None):
- self.n = n
- self.tk = tk = Tk()
- self.canvas = c = Canvas(tk)
- c.pack()
- width, height = tk.getint(c['width']), tk.getint(c['height'])
-
- # Add background bitmap
- if bitmap:
- self.bitmap = c.create_bitmap(width//2, height//2,
- bitmap=bitmap,
- foreground='blue')
-
- # Generate pegs
- pegwidth = 10
- pegheight = height//2
- pegdist = width//3
- x1, y1 = (pegdist-pegwidth)//2, height*1//3
- x2, y2 = x1+pegwidth, y1+pegheight
- self.pegs = []
- p = c.create_rectangle(x1, y1, x2, y2, fill='black')
- self.pegs.append(p)
- x1, x2 = x1+pegdist, x2+pegdist
- p = c.create_rectangle(x1, y1, x2, y2, fill='black')
- self.pegs.append(p)
- x1, x2 = x1+pegdist, x2+pegdist
- p = c.create_rectangle(x1, y1, x2, y2, fill='black')
- self.pegs.append(p)
- self.tk.update()
-
- # Generate pieces
- pieceheight = pegheight//16
- maxpiecewidth = pegdist*2//3
- minpiecewidth = 2*pegwidth
- self.pegstate = [[], [], []]
- self.pieces = {}
- x1, y1 = (pegdist-maxpiecewidth)//2, y2-pieceheight-2
- x2, y2 = x1+maxpiecewidth, y1+pieceheight
- dx = (maxpiecewidth-minpiecewidth) // (2*max(1, n-1))
- for i in range(n, 0, -1):
- p = c.create_rectangle(x1, y1, x2, y2, fill='red')
- self.pieces[i] = p
- self.pegstate[0].append(i)
- x1, x2 = x1 + dx, x2-dx
- y1, y2 = y1 - pieceheight-2, y2-pieceheight-2
- self.tk.update()
- self.tk.after(25)
-
- # Run -- never returns
- def run(self):
- while 1:
- hanoi(self.n, 0, 1, 2, self.report)
- hanoi(self.n, 1, 2, 0, self.report)
- hanoi(self.n, 2, 0, 1, self.report)
- hanoi(self.n, 0, 2, 1, self.report)
- hanoi(self.n, 2, 1, 0, self.report)
- hanoi(self.n, 1, 0, 2, self.report)
-
- # Reporting callback for the actual hanoi function
- def report(self, i, a, b):
- if self.pegstate[a][-1] != i: raise RuntimeError # Assertion
- del self.pegstate[a][-1]
- p = self.pieces[i]
- c = self.canvas
-
- # Lift the piece above peg a
- ax1, ay1, ax2, ay2 = c.bbox(self.pegs[a])
- while 1:
- x1, y1, x2, y2 = c.bbox(p)
- if y2 < ay1: break
- c.move(p, 0, -1)
- self.tk.update()
-
- # Move it towards peg b
- bx1, by1, bx2, by2 = c.bbox(self.pegs[b])
- newcenter = (bx1+bx2)//2
- while 1:
- x1, y1, x2, y2 = c.bbox(p)
- center = (x1+x2)//2
- if center == newcenter: break
- if center > newcenter: c.move(p, -1, 0)
- else: c.move(p, 1, 0)
- self.tk.update()
-
- # Move it down on top of the previous piece
- pieceheight = y2-y1
- newbottom = by2 - pieceheight*len(self.pegstate[b]) - 2
- while 1:
- x1, y1, x2, y2 = c.bbox(p)
- if y2 >= newbottom: break
- c.move(p, 0, 1)
- self.tk.update()
-
- # Update peg state
- self.pegstate[b].append(i)
-
-
-# Main program
-def main():
- import sys, string
-
- # First argument is number of pegs, default 4
- if sys.argv[1:]:
- n = string.atoi(sys.argv[1])
- else:
- n = 4
-
- # Second argument is bitmap file, default none
- if sys.argv[2:]:
- bitmap = sys.argv[2]
- # Reverse meaning of leading '@' compared to Tk
- if bitmap[0] == '@': bitmap = bitmap[1:]
- else: bitmap = '@' + bitmap
- else:
- bitmap = None
-
- # Create the graphical objects...
- h = Tkhanoi(n, bitmap)
-
- # ...and run!
- h.run()
-
-
-# Call main when run as script
-if __name__ == '__main__':
- main()
diff --git a/Demo/tkinter/guido/hello.py b/Demo/tkinter/guido/hello.py
deleted file mode 100644
index 358a7ec..0000000
--- a/Demo/tkinter/guido/hello.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Display hello, world in a button; clicking it quits the program
-
-import sys
-from Tkinter import *
-
-def main():
- root = Tk()
- button = Button(root)
- button['text'] = 'Hello, world'
- button['command'] = quit_callback # See below
- button.pack()
- root.mainloop()
-
-def quit_callback():
- sys.exit(0)
-
-main()
diff --git a/Demo/tkinter/guido/imagedraw.py b/Demo/tkinter/guido/imagedraw.py
deleted file mode 100644
index d3dba45..0000000
--- a/Demo/tkinter/guido/imagedraw.py
+++ /dev/null
@@ -1,23 +0,0 @@
-"""Draw on top of an image"""
-
-from Tkinter import *
-import sys
-
-def main():
- filename = sys.argv[1]
- root = Tk()
- img = PhotoImage(file=filename)
- w, h = img.width(), img.height()
- canv = Canvas(root, width=w, height=h)
- canv.create_image(0, 0, anchor=NW, image=img)
- canv.pack()
- canv.bind('<Button-1>', blob)
- root.mainloop()
-
-def blob(event):
- x, y = event.x, event.y
- canv = event.widget
- r = 5
- canv.create_oval(x-r, y-r, x+r, y+r, fill='red', outline="")
-
-main()
diff --git a/Demo/tkinter/guido/imageview.py b/Demo/tkinter/guido/imageview.py
deleted file mode 100644
index d6efed0..0000000
--- a/Demo/tkinter/guido/imageview.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from Tkinter import *
-import sys
-
-def main():
- filename = sys.argv[1]
- root = Tk()
- img = PhotoImage(file=filename)
- label = Label(root, image=img)
- label.pack()
- root.mainloop()
-
-main()
diff --git a/Demo/tkinter/guido/kill.py b/Demo/tkinter/guido/kill.py
deleted file mode 100755
index e7df261..0000000
--- a/Demo/tkinter/guido/kill.py
+++ /dev/null
@@ -1,98 +0,0 @@
-#! /usr/bin/env python
-# Tkinter interface to Linux `kill' command.
-
-from Tkinter import *
-from string import splitfields
-from string import split
-import commands
-import os
-
-class BarButton(Menubutton):
- def __init__(self, master=None, **cnf):
- apply(Menubutton.__init__, (self, master), cnf)
- self.pack(side=LEFT)
- self.menu = Menu(self, name='menu')
- self['menu'] = self.menu
-
-class Kill(Frame):
- # List of (name, option, pid_column)
- format_list = [('Default', '', 0),
- ('Long', '-l', 2),
- ('User', '-u', 1),
- ('Jobs', '-j', 1),
- ('Signal', '-s', 1),
- ('Memory', '-m', 0),
- ('VM', '-v', 0),
- ('Hex', '-X', 0)]
- def kill(self, selected):
- c = self.format_list[self.format.get()][2]
- pid = split(selected)[c]
- os.system('kill -9 ' + pid)
- self.do_update()
- def do_update(self):
- name, option, column = self.format_list[self.format.get()]
- s = commands.getoutput('ps -w ' + option)
- list = splitfields(s, '\n')
- self.header.set(list[0])
- del list[0]
- y = self.frame.vscroll.get()[0]
- self.frame.list.delete(0, AtEnd())
- for line in list:
- self.frame.list.insert(0, line)
- self.frame.list.yview(int(y))
- def do_motion(self, e):
- e.widget.select_clear(0, END)
- e.widget.select_set(e.widget.nearest(e.y))
- def do_leave(self, e):
- e.widget.select_clear(0, END)
- def do_1(self, e):
- self.kill(e.widget.get(e.widget.nearest(e.y)))
- def __init__(self, master=None, **cnf):
- Frame.__init__(self, master, cnf)
- self.pack(expand=1, fill=BOTH)
- self.bar = Frame(self, name='bar', relief=RAISED,
- borderwidth=2)
- self.bar.pack(fill=X)
- self.bar.file = BarButton(self.bar, text='File')
- self.bar.file.menu.add_command(
- label='Quit', command=self.quit)
- self.bar.view = BarButton(self.bar, text='View')
- self.format = IntVar(self)
- self.format.set(2)
- for num in range(len(self.format_list)):
- self.bar.view.menu.add_radiobutton(
- label=self.format_list[num][0],
- command=self.do_update,
- variable=self.format,
- value=num)
- #self.bar.view.menu.add_separator()
- #XXX ...
- self.bar.tk_menuBar(self.bar.file, self.bar.view)
- self.frame = Frame(self, relief=RAISED, borderwidth=2)
- self.frame.pack(expand=1, fill=BOTH)
- self.header = StringVar(self)
- self.frame.label = Label(self.frame, relief=FLAT, anchor=NW,
- borderwidth=0,
- textvariable=self.header)
- self.frame.label.pack(fill=X)
- self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL)
- self.frame.list = Listbox(self.frame, relief=SUNKEN,
- selectbackground='#eed5b7',
- selectborderwidth=0,
- yscroll=self.frame.vscroll.set)
- self.frame.vscroll['command'] = self.frame.list.yview
- self.frame.vscroll.pack(side=RIGHT, fill=Y)
- self.frame.list.pack(expand=1, fill=BOTH)
- self.update = Button(self, text="Update",
- command=self.do_update)
- self.update.pack(expand=1, fill=X)
- self.frame.list.bind('<Motion>', self.do_motion)
- self.frame.list.bind('<Leave>', self.do_leave)
- self.frame.list.bind('<1>', self.do_1)
- self.do_update()
-
-if __name__ == '__main__':
- kill = Kill(None, borderwidth=5)
- kill.winfo_toplevel().title('Tkinter Process Killer')
- kill.winfo_toplevel().minsize(1, 1)
- kill.mainloop()
diff --git a/Demo/tkinter/guido/listtree.py b/Demo/tkinter/guido/listtree.py
deleted file mode 100644
index d28ce49..0000000
--- a/Demo/tkinter/guido/listtree.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# List a remote app's widget tree (names and classes only)
-
-import sys
-import string
-
-from Tkinter import *
-
-def listtree(master, app):
- list = Listbox(master, name='list')
- list.pack(expand=1, fill=BOTH)
- listnodes(list, app, '.', 0)
- return list
-
-def listnodes(list, app, widget, level):
- klass = list.send(app, 'winfo', 'class', widget)
-## i = string.rindex(widget, '.')
-## list.insert(END, '%s%s (%s)' % ((level-1)*'. ', widget[i:], klass))
- list.insert(END, '%s (%s)' % (widget, klass))
- children = list.tk.splitlist(
- list.send(app, 'winfo', 'children', widget))
- for c in children:
- listnodes(list, app, c, level+1)
-
-def main():
- if not sys.argv[1:]:
- sys.stderr.write('Usage: listtree appname\n')
- sys.exit(2)
- app = sys.argv[1]
- tk = Tk()
- tk.minsize(1, 1)
- f = Frame(tk, name='f')
- f.pack(expand=1, fill=BOTH)
- list = listtree(f, app)
- tk.mainloop()
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/tkinter/guido/mbox.py b/Demo/tkinter/guido/mbox.py
deleted file mode 100755
index 3c36d88..0000000
--- a/Demo/tkinter/guido/mbox.py
+++ /dev/null
@@ -1,285 +0,0 @@
-#! /usr/bin/env python
-
-# Scan MH folder, display results in window
-
-import os
-import sys
-import re
-import getopt
-import string
-import mhlib
-
-from Tkinter import *
-
-from dialog import dialog
-
-mailbox = os.environ['HOME'] + '/Mail'
-
-def main():
- global root, tk, top, mid, bot
- global folderbox, foldermenu, scanbox, scanmenu, viewer
- global folder, seq
- global mh, mhf
-
- # Parse command line options
-
- folder = 'inbox'
- seq = 'all'
- try:
- opts, args = getopt.getopt(sys.argv[1:], '')
- except getopt.error, msg:
- print msg
- sys.exit(2)
- for arg in args:
- if arg[:1] == '+':
- folder = arg[1:]
- else:
- seq = arg
-
- # Initialize MH
-
- mh = mhlib.MH()
- mhf = mh.openfolder(folder)
-
- # Build widget hierarchy
-
- root = Tk()
- tk = root.tk
-
- top = Frame(root)
- top.pack({'expand': 1, 'fill': 'both'})
-
- # Build right part: folder list
-
- right = Frame(top)
- right.pack({'fill': 'y', 'side': 'right'})
-
- folderbar = Scrollbar(right, {'relief': 'sunken', 'bd': 2})
- folderbar.pack({'fill': 'y', 'side': 'right'})
-
- folderbox = Listbox(right, {'exportselection': 0})
- folderbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
-
- foldermenu = Menu(root)
- foldermenu.add('command',
- {'label': 'Open Folder',
- 'command': open_folder})
- foldermenu.add('separator')
- foldermenu.add('command',
- {'label': 'Quit',
- 'command': 'exit'})
- foldermenu.bind('<ButtonRelease-3>', folder_unpost)
-
- folderbox['yscrollcommand'] = (folderbar, 'set')
- folderbar['command'] = (folderbox, 'yview')
- folderbox.bind('<Double-1>', open_folder, 1)
- folderbox.bind('<3>', folder_post)
-
- # Build left part: scan list
-
- left = Frame(top)
- left.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
-
- scanbar = Scrollbar(left, {'relief': 'sunken', 'bd': 2})
- scanbar.pack({'fill': 'y', 'side': 'right'})
-
- scanbox = Listbox(left, {'font': 'fixed'})
- scanbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
-
- scanmenu = Menu(root)
- scanmenu.add('command',
- {'label': 'Open Message',
- 'command': open_message})
- scanmenu.add('command',
- {'label': 'Remove Message',
- 'command': remove_message})
- scanmenu.add('command',
- {'label': 'Refile Message',
- 'command': refile_message})
- scanmenu.add('separator')
- scanmenu.add('command',
- {'label': 'Quit',
- 'command': 'exit'})
- scanmenu.bind('<ButtonRelease-3>', scan_unpost)
-
- scanbox['yscrollcommand'] = (scanbar, 'set')
- scanbar['command'] = (scanbox, 'yview')
- scanbox.bind('<Double-1>', open_message)
- scanbox.bind('<3>', scan_post)
-
- # Separator between middle and bottom part
-
- rule2 = Frame(root, {'bg': 'black'})
- rule2.pack({'fill': 'x'})
-
- # Build bottom part: current message
-
- bot = Frame(root)
- bot.pack({'expand': 1, 'fill': 'both'})
- #
- viewer = None
-
- # Window manager commands
-
- root.minsize(800, 1) # Make window resizable
-
- # Fill folderbox with text
-
- setfolders()
-
- # Fill scanbox with text
-
- rescan()
-
- # Enter mainloop
-
- root.mainloop()
-
-def folder_post(e):
- x, y = e.x_root, e.y_root
- foldermenu.post(x - 10, y - 10)
- foldermenu.grab_set()
-
-def folder_unpost(e):
- tk.call('update', 'idletasks')
- foldermenu.grab_release()
- foldermenu.unpost()
- foldermenu.invoke('active')
-
-def scan_post(e):
- x, y = e.x_root, e.y_root
- scanmenu.post(x - 10, y - 10)
- scanmenu.grab_set()
-
-def scan_unpost(e):
- tk.call('update', 'idletasks')
- scanmenu.grab_release()
- scanmenu.unpost()
- scanmenu.invoke('active')
-
-scanparser = re.compile('^ *([0-9]+)')
-
-def open_folder(e=None):
- global folder, mhf
- sel = folderbox.curselection()
- if len(sel) != 1:
- if len(sel) > 1:
- msg = "Please open one folder at a time"
- else:
- msg = "Please select a folder to open"
- dialog(root, "Can't Open Folder", msg, "", 0, "OK")
- return
- i = sel[0]
- folder = folderbox.get(i)
- mhf = mh.openfolder(folder)
- rescan()
-
-def open_message(e=None):
- global viewer
- sel = scanbox.curselection()
- if len(sel) != 1:
- if len(sel) > 1:
- msg = "Please open one message at a time"
- else:
- msg = "Please select a message to open"
- dialog(root, "Can't Open Message", msg, "", 0, "OK")
- return
- cursor = scanbox['cursor']
- scanbox['cursor'] = 'watch'
- tk.call('update', 'idletasks')
- i = sel[0]
- line = scanbox.get(i)
- if scanparser.match(line) >= 0:
- num = string.atoi(scanparser.group(1))
- m = mhf.openmessage(num)
- if viewer: viewer.destroy()
- from MimeViewer import MimeViewer
- viewer = MimeViewer(bot, '+%s/%d' % (folder, num), m)
- viewer.pack()
- viewer.show()
- scanbox['cursor'] = cursor
-
-def interestingheader(header):
- return header != 'received'
-
-def remove_message(e=None):
- itop = scanbox.nearest(0)
- sel = scanbox.curselection()
- if not sel:
- dialog(root, "No Message To Remove",
- "Please select a message to remove", "", 0, "OK")
- return
- todo = []
- for i in sel:
- line = scanbox.get(i)
- if scanparser.match(line) >= 0:
- todo.append(string.atoi(scanparser.group(1)))
- mhf.removemessages(todo)
- rescan()
- fixfocus(min(todo), itop)
-
-lastrefile = ''
-tofolder = None
-def refile_message(e=None):
- global lastrefile, tofolder
- itop = scanbox.nearest(0)
- sel = scanbox.curselection()
- if not sel:
- dialog(root, "No Message To Refile",
- "Please select a message to refile", "", 0, "OK")
- return
- foldersel = folderbox.curselection()
- if len(foldersel) != 1:
- if not foldersel:
- msg = "Please select a folder to refile to"
- else:
- msg = "Please select exactly one folder to refile to"
- dialog(root, "No Folder To Refile", msg, "", 0, "OK")
- return
- refileto = folderbox.get(foldersel[0])
- todo = []
- for i in sel:
- line = scanbox.get(i)
- if scanparser.match(line) >= 0:
- todo.append(string.atoi(scanparser.group(1)))
- if lastrefile != refileto or not tofolder:
- lastrefile = refileto
- tofolder = None
- tofolder = mh.openfolder(lastrefile)
- mhf.refilemessages(todo, tofolder)
- rescan()
- fixfocus(min(todo), itop)
-
-def fixfocus(near, itop):
- n = scanbox.size()
- for i in range(n):
- line = scanbox.get(repr(i))
- if scanparser.match(line) >= 0:
- num = string.atoi(scanparser.group(1))
- if num >= near:
- break
- else:
- i = 'end'
- scanbox.select_from(i)
- scanbox.yview(itop)
-
-def setfolders():
- folderbox.delete(0, 'end')
- for fn in mh.listallfolders():
- folderbox.insert('end', fn)
-
-def rescan():
- global viewer
- if viewer:
- viewer.destroy()
- viewer = None
- scanbox.delete(0, 'end')
- for line in scanfolder(folder, seq):
- scanbox.insert('end', line)
-
-def scanfolder(folder = 'inbox', sequence = 'all'):
- return map(
- lambda line: line[:-1],
- os.popen('scan +%s %s' % (folder, sequence), 'r').readlines())
-
-main()
diff --git a/Demo/tkinter/guido/newmenubardemo.py b/Demo/tkinter/guido/newmenubardemo.py
deleted file mode 100644
index 57bf13c..0000000
--- a/Demo/tkinter/guido/newmenubardemo.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#! /usr/bin/env python
-
-"""Play with the new Tk 8.0 toplevel menu option."""
-
-from Tkinter import *
-
-class App:
-
- def __init__(self, master):
- self.master = master
-
- self.menubar = Menu(self.master)
-
- self.filemenu = Menu(self.menubar)
-
- self.filemenu.add_command(label="New")
- self.filemenu.add_command(label="Open...")
- self.filemenu.add_command(label="Close")
- self.filemenu.add_separator()
- self.filemenu.add_command(label="Quit", command=self.master.quit)
-
- self.editmenu = Menu(self.menubar)
-
- self.editmenu.add_command(label="Cut")
- self.editmenu.add_command(label="Copy")
- self.editmenu.add_command(label="Paste")
-
- self.helpmenu = Menu(self.menubar, name='help')
-
- self.helpmenu.add_command(label="About...")
-
- self.menubar.add_cascade(label="File", menu=self.filemenu)
- self.menubar.add_cascade(label="Edit", menu=self.editmenu)
- self.menubar.add_cascade(label="Help", menu=self.helpmenu)
-
- self.top = Toplevel(menu=self.menubar)
-
- # Rest of app goes here...
-
-def main():
- root = Tk()
- root.withdraw()
- app = App(root)
- root.mainloop()
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/tkinter/guido/optionmenu.py b/Demo/tkinter/guido/optionmenu.py
deleted file mode 100644
index be9d3ac..0000000
--- a/Demo/tkinter/guido/optionmenu.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# option menu sample (Fredrik Lundh, September 1997)
-
-from Tkinter import *
-
-root = Tk()
-
-#
-# standard usage
-
-var1 = StringVar()
-var1.set("One") # default selection
-
-menu1 = OptionMenu(root, var1, "One", "Two", "Three")
-menu1.pack()
-
-#
-# initialize from a sequence
-
-CHOICES = "Aah", "Bee", "Cee", "Dee", "Eff"
-
-var2 = StringVar()
-var2.set(CHOICES[0])
-
-menu2 = apply(OptionMenu, (root, var2) + tuple(CHOICES))
-menu2.pack()
-
-root.mainloop()
diff --git a/Demo/tkinter/guido/paint.py b/Demo/tkinter/guido/paint.py
deleted file mode 100644
index 7b2e814..0000000
--- a/Demo/tkinter/guido/paint.py
+++ /dev/null
@@ -1,60 +0,0 @@
-""""Paint program by Dave Michell.
-
-Subject: tkinter "paint" example
-From: Dave Mitchell <davem@magnet.com>
-To: python-list@cwi.nl
-Date: Fri, 23 Jan 1998 12:18:05 -0500 (EST)
-
- Not too long ago (last week maybe?) someone posted a request
-for an example of a paint program using Tkinter. Try as I might
-I can't seem to find it in the archive, so i'll just post mine
-here and hope that the person who requested it sees this!
-
- All this does is put up a canvas and draw a smooth black line
-whenever you have the mouse button down, but hopefully it will
-be enough to start with.. It would be easy enough to add some
-options like other shapes or colors...
-
- yours,
- dave mitchell
- davem@magnet.com
-"""
-
-from Tkinter import *
-
-"""paint.py: not exactly a paint program.. just a smooth line drawing demo."""
-
-b1 = "up"
-xold, yold = None, None
-
-def main():
- root = Tk()
- drawing_area = Canvas(root)
- drawing_area.pack()
- drawing_area.bind("<Motion>", motion)
- drawing_area.bind("<ButtonPress-1>", b1down)
- drawing_area.bind("<ButtonRelease-1>", b1up)
- root.mainloop()
-
-def b1down(event):
- global b1
- b1 = "down" # you only want to draw when the button is down
- # because "Motion" events happen -all the time-
-
-def b1up(event):
- global b1, xold, yold
- b1 = "up"
- xold = None # reset the line when you let go of the button
- yold = None
-
-def motion(event):
- if b1 == "down":
- global xold, yold
- if xold is not None and yold is not None:
- event.widget.create_line(xold,yold,event.x,event.y,smooth=TRUE)
- # here's where you draw it. smooth. neat.
- xold = event.x
- yold = event.y
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/tkinter/guido/rmt.py b/Demo/tkinter/guido/rmt.py
deleted file mode 100755
index bfea195..0000000
--- a/Demo/tkinter/guido/rmt.py
+++ /dev/null
@@ -1,159 +0,0 @@
-#! /usr/bin/env python
-
-# A Python program implementing rmt, an application for remotely
-# controlling other Tk applications.
-# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.5-8, pp. 273-276.
-
-# Note that because of forward references in the original, we
-# sometimes delay bindings until after the corresponding procedure is
-# defined. We also introduce names for some unnamed code blocks in
-# the original because of restrictions on lambda forms in Python.
-
-# XXX This should be written in a more Python-like style!!!
-
-from Tkinter import *
-import sys
-
-# 1. Create basic application structure: menu bar on top of
-# text widget, scrollbar on right.
-
-root = Tk()
-tk = root.tk
-mBar = Frame(root, relief=RAISED, borderwidth=2)
-mBar.pack(fill=X)
-
-f = Frame(root)
-f.pack(expand=1, fill=BOTH)
-s = Scrollbar(f, relief=FLAT)
-s.pack(side=RIGHT, fill=Y)
-t = Text(f, relief=RAISED, borderwidth=2, yscrollcommand=s.set, setgrid=1)
-t.pack(side=LEFT, fill=BOTH, expand=1)
-t.tag_config('bold', font='-Adobe-Courier-Bold-R-Normal-*-120-*')
-s['command'] = t.yview
-
-root.title('Tk Remote Controller')
-root.iconname('Tk Remote')
-
-# 2. Create menu button and menus.
-
-file = Menubutton(mBar, text='File', underline=0)
-file.pack(side=LEFT)
-file_m = Menu(file)
-file['menu'] = file_m
-file_m_apps = Menu(file_m, tearoff=0)
-file_m.add_cascade(label='Select Application', underline=0,
- menu=file_m_apps)
-file_m.add_command(label='Quit', underline=0, command=sys.exit)
-
-# 3. Create bindings for text widget to allow commands to be
-# entered and information to be selected. New characters
-# can only be added at the end of the text (can't ever move
-# insertion point).
-
-def single1(e):
- x = e.x
- y = e.y
- t.setvar('tk_priv(selectMode)', 'char')
- t.mark_set('anchor', At(x, y))
- # Should focus W
-t.bind('<1>', single1)
-
-def double1(e):
- x = e.x
- y = e.y
- t.setvar('tk_priv(selectMode)', 'word')
- t.tk_textSelectTo(At(x, y))
-t.bind('<Double-1>', double1)
-
-def triple1(e):
- x = e.x
- y = e.y
- t.setvar('tk_priv(selectMode)', 'line')
- t.tk_textSelectTo(At(x, y))
-t.bind('<Triple-1>', triple1)
-
-def returnkey(e):
- t.insert(AtInsert(), '\n')
- invoke()
-t.bind('<Return>', returnkey)
-
-def controlv(e):
- t.insert(AtInsert(), t.selection_get())
- t.yview_pickplace(AtInsert())
- if t.index(AtInsert())[-2:] == '.0':
- invoke()
-t.bind('<Control-v>', controlv)
-
-# 4. Procedure to backspace over one character, as long as
-# the character isn't part of the prompt.
-
-def backspace(e):
- if t.index('promptEnd') != t.index('insert - 1 char'):
- t.delete('insert - 1 char', AtInsert())
- t.yview_pickplace(AtInsert())
-t.bind('<BackSpace>', backspace)
-t.bind('<Control-h>', backspace)
-t.bind('<Delete>', backspace)
-
-
-# 5. Procedure that's invoked when return is typed: if
-# there's not yet a complete command (e.g. braces are open)
-# then do nothing. Otherwise, execute command (locally or
-# remotely), output the result or error message, and issue
-# a new prompt.
-
-def invoke():
- cmd = t.get('promptEnd + 1 char', AtInsert())
- if t.getboolean(tk.call('info', 'complete', cmd)): # XXX
- if app == root.winfo_name():
- msg = tk.call('eval', cmd) # XXX
- else:
- msg = t.send(app, cmd)
- if msg:
- t.insert(AtInsert(), msg + '\n')
- prompt()
- t.yview_pickplace(AtInsert())
-
-def prompt():
- t.insert(AtInsert(), app + ': ')
- t.mark_set('promptEnd', 'insert - 1 char')
- t.tag_add('bold', 'insert linestart', 'promptEnd')
-
-# 6. Procedure to select a new application. Also changes
-# the prompt on the current command line to reflect the new
-# name.
-
-def newApp(appName):
- global app
- app = appName
- t.delete('promptEnd linestart', 'promptEnd')
- t.insert('promptEnd', appName + ':')
- t.tag_add('bold', 'promptEnd linestart', 'promptEnd')
-
-def fillAppsMenu():
- file_m_apps.add('command')
- file_m_apps.delete(0, 'last')
- names = root.winfo_interps()
- names = list(names)
- names.sort()
- for name in names:
- try:
- root.send(name, 'winfo name .')
- except TclError:
- # Inoperative window -- ignore it
- pass
- else:
- file_m_apps.add_command(
- label=name,
- command=lambda name=name: newApp(name))
-
-file_m_apps['postcommand'] = fillAppsMenu
-mBar.tk_menuBar(file)
-
-# 7. Miscellaneous initialization.
-
-app = root.winfo_name()
-prompt()
-t.focus()
-
-root.mainloop()
diff --git a/Demo/tkinter/guido/solitaire.py b/Demo/tkinter/guido/solitaire.py
deleted file mode 100755
index 1c1105c..0000000
--- a/Demo/tkinter/guido/solitaire.py
+++ /dev/null
@@ -1,637 +0,0 @@
-#! /usr/bin/env python
-
-"""Solitaire game, much like the one that comes with MS Windows.
-
-Limitations:
-
-- No cute graphical images for the playing cards faces or backs.
-- No scoring or timer.
-- No undo.
-- No option to turn 3 cards at a time.
-- No keyboard shortcuts.
-- Less fancy animation when you win.
-- The determination of which stack you drag to is more relaxed.
-
-Apology:
-
-I'm not much of a card player, so my terminology in these comments may
-at times be a little unusual. If you have suggestions, please let me
-know!
-
-"""
-
-# Imports
-
-import math
-import random
-
-from Tkinter import *
-from Canvas import Rectangle, CanvasText, Group, Window
-
-
-# Fix a bug in Canvas.Group as distributed in Python 1.4. The
-# distributed bind() method is broken. Rather than asking you to fix
-# the source, we fix it here by deriving a subclass:
-
-class Group(Group):
- def bind(self, sequence=None, command=None):
- return self.canvas.tag_bind(self.id, sequence, command)
-
-
-# Constants determining the size and lay-out of cards and stacks. We
-# work in a "grid" where each card/stack is surrounded by MARGIN
-# pixels of space on each side, so adjacent stacks are separated by
-# 2*MARGIN pixels. OFFSET is the offset used for displaying the
-# face down cards in the row stacks.
-
-CARDWIDTH = 100
-CARDHEIGHT = 150
-MARGIN = 10
-XSPACING = CARDWIDTH + 2*MARGIN
-YSPACING = CARDHEIGHT + 4*MARGIN
-OFFSET = 5
-
-# The background color, green to look like a playing table. The
-# standard green is way too bright, and dark green is way to dark, so
-# we use something in between. (There are a few more colors that
-# could be customized, but they are less controversial.)
-
-BACKGROUND = '#070'
-
-
-# Suits and colors. The values of the symbolic suit names are the
-# strings used to display them (you change these and VALNAMES to
-# internationalize the game). The COLOR dictionary maps suit names to
-# colors (red and black) which must be Tk color names. The keys() of
-# the COLOR dictionary conveniently provides us with a list of all
-# suits (in arbitrary order).
-
-HEARTS = 'Heart'
-DIAMONDS = 'Diamond'
-CLUBS = 'Club'
-SPADES = 'Spade'
-
-RED = 'red'
-BLACK = 'black'
-
-COLOR = {}
-for s in (HEARTS, DIAMONDS):
- COLOR[s] = RED
-for s in (CLUBS, SPADES):
- COLOR[s] = BLACK
-
-ALLSUITS = COLOR.keys()
-NSUITS = len(ALLSUITS)
-
-
-# Card values are 1-13. We also define symbolic names for the picture
-# cards. ALLVALUES is a list of all card values.
-
-ACE = 1
-JACK = 11
-QUEEN = 12
-KING = 13
-ALLVALUES = range(1, 14) # (one more than the highest value)
-NVALUES = len(ALLVALUES)
-
-
-# VALNAMES is a list that maps a card value to string. It contains a
-# dummy element at index 0 so it can be indexed directly with the card
-# value.
-
-VALNAMES = ["", "A"] + map(str, range(2, 11)) + ["J", "Q", "K"]
-
-
-# Solitaire constants. The only one I can think of is the number of
-# row stacks.
-
-NROWS = 7
-
-
-# The rest of the program consists of class definitions. These are
-# further described in their documentation strings.
-
-
-class Card:
-
- """A playing card.
-
- A card doesn't record to which stack it belongs; only the stack
- records this (it turns out that we always know this from the
- context, and this saves a ``double update'' with potential for
- inconsistencies).
-
- Public methods:
-
- moveto(x, y) -- move the card to an absolute position
- moveby(dx, dy) -- move the card by a relative offset
- tkraise() -- raise the card to the top of its stack
- showface(), showback() -- turn the card face up or down & raise it
-
- Public read-only instance variables:
-
- suit, value, color -- the card's suit, value and color
- face_shown -- true when the card is shown face up, else false
-
- Semi-public read-only instance variables (XXX should be made
- private):
-
- group -- the Canvas.Group representing the card
- x, y -- the position of the card's top left corner
-
- Private instance variables:
-
- __back, __rect, __text -- the canvas items making up the card
-
- (To show the card face up, the text item is placed in front of
- rect and the back is placed behind it. To show it face down, this
- is reversed. The card is created face down.)
-
- """
-
- def __init__(self, suit, value, canvas):
- """Card constructor.
-
- Arguments are the card's suit and value, and the canvas widget.
-
- The card is created at position (0, 0), with its face down
- (adding it to a stack will position it according to that
- stack's rules).
-
- """
- self.suit = suit
- self.value = value
- self.color = COLOR[suit]
- self.face_shown = 0
-
- self.x = self.y = 0
- self.group = Group(canvas)
-
- text = "%s %s" % (VALNAMES[value], suit)
- self.__text = CanvasText(canvas, CARDWIDTH//2, 0,
- anchor=N, fill=self.color, text=text)
- self.group.addtag_withtag(self.__text)
-
- self.__rect = Rectangle(canvas, 0, 0, CARDWIDTH, CARDHEIGHT,
- outline='black', fill='white')
- self.group.addtag_withtag(self.__rect)
-
- self.__back = Rectangle(canvas, MARGIN, MARGIN,
- CARDWIDTH-MARGIN, CARDHEIGHT-MARGIN,
- outline='black', fill='blue')
- self.group.addtag_withtag(self.__back)
-
- def __repr__(self):
- """Return a string for debug print statements."""
- return "Card(%r, %r)" % (self.suit, self.value)
-
- def moveto(self, x, y):
- """Move the card to absolute position (x, y)."""
- self.moveby(x - self.x, y - self.y)
-
- def moveby(self, dx, dy):
- """Move the card by (dx, dy)."""
- self.x = self.x + dx
- self.y = self.y + dy
- self.group.move(dx, dy)
-
- def tkraise(self):
- """Raise the card above all other objects in its canvas."""
- self.group.tkraise()
-
- def showface(self):
- """Turn the card's face up."""
- self.tkraise()
- self.__rect.tkraise()
- self.__text.tkraise()
- self.face_shown = 1
-
- def showback(self):
- """Turn the card's face down."""
- self.tkraise()
- self.__rect.tkraise()
- self.__back.tkraise()
- self.face_shown = 0
-
-
-class Stack:
-
- """A generic stack of cards.
-
- This is used as a base class for all other stacks (e.g. the deck,
- the suit stacks, and the row stacks).
-
- Public methods:
-
- add(card) -- add a card to the stack
- delete(card) -- delete a card from the stack
- showtop() -- show the top card (if any) face up
- deal() -- delete and return the top card, or None if empty
-
- Method that subclasses may override:
-
- position(card) -- move the card to its proper (x, y) position
-
- The default position() method places all cards at the stack's
- own (x, y) position.
-
- userclickhandler(), userdoubleclickhandler() -- called to do
- subclass specific things on single and double clicks
-
- The default user (single) click handler shows the top card
- face up. The default user double click handler calls the user
- single click handler.
-
- usermovehandler(cards) -- called to complete a subpile move
-
- The default user move handler moves all moved cards back to
- their original position (by calling the position() method).
-
- Private methods:
-
- clickhandler(event), doubleclickhandler(event),
- motionhandler(event), releasehandler(event) -- event handlers
-
- The default event handlers turn the top card of the stack with
- its face up on a (single or double) click, and also support
- moving a subpile around.
-
- startmoving(event) -- begin a move operation
- finishmoving() -- finish a move operation
-
- """
-
- def __init__(self, x, y, game=None):
- """Stack constructor.
-
- Arguments are the stack's nominal x and y position (the top
- left corner of the first card placed in the stack), and the
- game object (which is used to get the canvas; subclasses use
- the game object to find other stacks).
-
- """
- self.x = x
- self.y = y
- self.game = game
- self.cards = []
- self.group = Group(self.game.canvas)
- self.group.bind('<1>', self.clickhandler)
- self.group.bind('<Double-1>', self.doubleclickhandler)
- self.group.bind('<B1-Motion>', self.motionhandler)
- self.group.bind('<ButtonRelease-1>', self.releasehandler)
- self.makebottom()
-
- def makebottom(self):
- pass
-
- def __repr__(self):
- """Return a string for debug print statements."""
- return "%s(%d, %d)" % (self.__class__.__name__, self.x, self.y)
-
- # Public methods
-
- def add(self, card):
- self.cards.append(card)
- card.tkraise()
- self.position(card)
- self.group.addtag_withtag(card.group)
-
- def delete(self, card):
- self.cards.remove(card)
- card.group.dtag(self.group)
-
- def showtop(self):
- if self.cards:
- self.cards[-1].showface()
-
- def deal(self):
- if not self.cards:
- return None
- card = self.cards[-1]
- self.delete(card)
- return card
-
- # Subclass overridable methods
-
- def position(self, card):
- card.moveto(self.x, self.y)
-
- def userclickhandler(self):
- self.showtop()
-
- def userdoubleclickhandler(self):
- self.userclickhandler()
-
- def usermovehandler(self, cards):
- for card in cards:
- self.position(card)
-
- # Event handlers
-
- def clickhandler(self, event):
- self.finishmoving() # In case we lost an event
- self.userclickhandler()
- self.startmoving(event)
-
- def motionhandler(self, event):
- self.keepmoving(event)
-
- def releasehandler(self, event):
- self.keepmoving(event)
- self.finishmoving()
-
- def doubleclickhandler(self, event):
- self.finishmoving() # In case we lost an event
- self.userdoubleclickhandler()
- self.startmoving(event)
-
- # Move internals
-
- moving = None
-
- def startmoving(self, event):
- self.moving = None
- tags = self.game.canvas.gettags('current')
- for i in range(len(self.cards)):
- card = self.cards[i]
- if card.group.tag in tags:
- break
- else:
- return
- if not card.face_shown:
- return
- self.moving = self.cards[i:]
- self.lastx = event.x
- self.lasty = event.y
- for card in self.moving:
- card.tkraise()
-
- def keepmoving(self, event):
- if not self.moving:
- return
- dx = event.x - self.lastx
- dy = event.y - self.lasty
- self.lastx = event.x
- self.lasty = event.y
- if dx or dy:
- for card in self.moving:
- card.moveby(dx, dy)
-
- def finishmoving(self):
- cards = self.moving
- self.moving = None
- if cards:
- self.usermovehandler(cards)
-
-
-class Deck(Stack):
-
- """The deck is a stack with support for shuffling.
-
- New methods:
-
- fill() -- create the playing cards
- shuffle() -- shuffle the playing cards
-
- A single click moves the top card to the game's open deck and
- moves it face up; if we're out of cards, it moves the open deck
- back to the deck.
-
- """
-
- def makebottom(self):
- bottom = Rectangle(self.game.canvas,
- self.x, self.y,
- self.x+CARDWIDTH, self.y+CARDHEIGHT,
- outline='black', fill=BACKGROUND)
- self.group.addtag_withtag(bottom)
-
- def fill(self):
- for suit in ALLSUITS:
- for value in ALLVALUES:
- self.add(Card(suit, value, self.game.canvas))
-
- def shuffle(self):
- n = len(self.cards)
- newcards = []
- for i in randperm(n):
- newcards.append(self.cards[i])
- self.cards = newcards
-
- def userclickhandler(self):
- opendeck = self.game.opendeck
- card = self.deal()
- if not card:
- while 1:
- card = opendeck.deal()
- if not card:
- break
- self.add(card)
- card.showback()
- else:
- self.game.opendeck.add(card)
- card.showface()
-
-
-def randperm(n):
- """Function returning a random permutation of range(n)."""
- r = range(n)
- x = []
- while r:
- i = random.choice(r)
- x.append(i)
- r.remove(i)
- return x
-
-
-class OpenStack(Stack):
-
- def acceptable(self, cards):
- return 0
-
- def usermovehandler(self, cards):
- card = cards[0]
- stack = self.game.closeststack(card)
- if not stack or stack is self or not stack.acceptable(cards):
- Stack.usermovehandler(self, cards)
- else:
- for card in cards:
- self.delete(card)
- stack.add(card)
- self.game.wincheck()
-
- def userdoubleclickhandler(self):
- if not self.cards:
- return
- card = self.cards[-1]
- if not card.face_shown:
- self.userclickhandler()
- return
- for s in self.game.suits:
- if s.acceptable([card]):
- self.delete(card)
- s.add(card)
- self.game.wincheck()
- break
-
-
-class SuitStack(OpenStack):
-
- def makebottom(self):
- bottom = Rectangle(self.game.canvas,
- self.x, self.y,
- self.x+CARDWIDTH, self.y+CARDHEIGHT,
- outline='black', fill='')
-
- def userclickhandler(self):
- pass
-
- def userdoubleclickhandler(self):
- pass
-
- def acceptable(self, cards):
- if len(cards) != 1:
- return 0
- card = cards[0]
- if not self.cards:
- return card.value == ACE
- topcard = self.cards[-1]
- return card.suit == topcard.suit and card.value == topcard.value + 1
-
-
-class RowStack(OpenStack):
-
- def acceptable(self, cards):
- card = cards[0]
- if not self.cards:
- return card.value == KING
- topcard = self.cards[-1]
- if not topcard.face_shown:
- return 0
- return card.color != topcard.color and card.value == topcard.value - 1
-
- def position(self, card):
- y = self.y
- for c in self.cards:
- if c == card:
- break
- if c.face_shown:
- y = y + 2*MARGIN
- else:
- y = y + OFFSET
- card.moveto(self.x, y)
-
-
-class Solitaire:
-
- def __init__(self, master):
- self.master = master
-
- self.canvas = Canvas(self.master,
- background=BACKGROUND,
- highlightthickness=0,
- width=NROWS*XSPACING,
- height=3*YSPACING + 20 + MARGIN)
- self.canvas.pack(fill=BOTH, expand=TRUE)
-
- self.dealbutton = Button(self.canvas,
- text="Deal",
- highlightthickness=0,
- background=BACKGROUND,
- activebackground="green",
- command=self.deal)
- Window(self.canvas, MARGIN, 3*YSPACING + 20,
- window=self.dealbutton, anchor=SW)
-
- x = MARGIN
- y = MARGIN
-
- self.deck = Deck(x, y, self)
-
- x = x + XSPACING
- self.opendeck = OpenStack(x, y, self)
-
- x = x + XSPACING
- self.suits = []
- for i in range(NSUITS):
- x = x + XSPACING
- self.suits.append(SuitStack(x, y, self))
-
- x = MARGIN
- y = y + YSPACING
-
- self.rows = []
- for i in range(NROWS):
- self.rows.append(RowStack(x, y, self))
- x = x + XSPACING
-
- self.openstacks = [self.opendeck] + self.suits + self.rows
-
- self.deck.fill()
- self.deal()
-
- def wincheck(self):
- for s in self.suits:
- if len(s.cards) != NVALUES:
- return
- self.win()
- self.deal()
-
- def win(self):
- """Stupid animation when you win."""
- cards = []
- for s in self.openstacks:
- cards = cards + s.cards
- while cards:
- card = random.choice(cards)
- cards.remove(card)
- self.animatedmoveto(card, self.deck)
-
- def animatedmoveto(self, card, dest):
- for i in range(10, 0, -1):
- dx, dy = (dest.x-card.x)//i, (dest.y-card.y)//i
- card.moveby(dx, dy)
- self.master.update_idletasks()
-
- def closeststack(self, card):
- closest = None
- cdist = 999999999
- # Since we only compare distances,
- # we don't bother to take the square root.
- for stack in self.openstacks:
- dist = (stack.x - card.x)**2 + (stack.y - card.y)**2
- if dist < cdist:
- closest = stack
- cdist = dist
- return closest
-
- def deal(self):
- self.reset()
- self.deck.shuffle()
- for i in range(NROWS):
- for r in self.rows[i:]:
- card = self.deck.deal()
- r.add(card)
- for r in self.rows:
- r.showtop()
-
- def reset(self):
- for stack in self.openstacks:
- while 1:
- card = stack.deal()
- if not card:
- break
- self.deck.add(card)
- card.showback()
-
-
-# Main function, run when invoked as a stand-alone Python program.
-
-def main():
- root = Tk()
- game = Solitaire(root)
- root.protocol('WM_DELETE_WINDOW', root.quit)
- root.mainloop()
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/tkinter/guido/sortvisu.py b/Demo/tkinter/guido/sortvisu.py
deleted file mode 100644
index 9148b73..0000000
--- a/Demo/tkinter/guido/sortvisu.py
+++ /dev/null
@@ -1,634 +0,0 @@
-#! /usr/bin/env python
-
-"""Sorting algorithms visualizer using Tkinter.
-
-This module is comprised of three ``components'':
-
-- an array visualizer with methods that implement basic sorting
-operations (compare, swap) as well as methods for ``annotating'' the
-sorting algorithm (e.g. to show the pivot element);
-
-- a number of sorting algorithms (currently quicksort, insertion sort,
-selection sort and bubble sort, as well as a randomization function),
-all using the array visualizer for its basic operations and with calls
-to its annotation methods;
-
-- and a ``driver'' class which can be used as a Grail applet or as a
-stand-alone application.
-
-"""
-
-
-from Tkinter import *
-from Canvas import Line, Rectangle
-import random
-
-
-XGRID = 10
-YGRID = 10
-WIDTH = 6
-
-
-class Array:
-
- def __init__(self, master, data=None):
- self.master = master
- self.frame = Frame(self.master)
- self.frame.pack(fill=X)
- self.label = Label(self.frame)
- self.label.pack()
- self.canvas = Canvas(self.frame)
- self.canvas.pack()
- self.report = Label(self.frame)
- self.report.pack()
- self.left = Line(self.canvas, 0, 0, 0, 0)
- self.right = Line(self.canvas, 0, 0, 0, 0)
- self.pivot = Line(self.canvas, 0, 0, 0, 0)
- self.items = []
- self.size = self.maxvalue = 0
- if data:
- self.setdata(data)
-
- def setdata(self, data):
- olditems = self.items
- self.items = []
- for item in olditems:
- item.delete()
- self.size = len(data)
- self.maxvalue = max(data)
- self.canvas.config(width=(self.size+1)*XGRID,
- height=(self.maxvalue+1)*YGRID)
- for i in range(self.size):
- self.items.append(ArrayItem(self, i, data[i]))
- self.reset("Sort demo, size %d" % self.size)
-
- speed = "normal"
-
- def setspeed(self, speed):
- self.speed = speed
-
- def destroy(self):
- self.frame.destroy()
-
- in_mainloop = 0
- stop_mainloop = 0
-
- def cancel(self):
- self.stop_mainloop = 1
- if self.in_mainloop:
- self.master.quit()
-
- def step(self):
- if self.in_mainloop:
- self.master.quit()
-
- Cancelled = "Array.Cancelled" # Exception
-
- def wait(self, msecs):
- if self.speed == "fastest":
- msecs = 0
- elif self.speed == "fast":
- msecs = msecs//10
- elif self.speed == "single-step":
- msecs = 1000000000
- if not self.stop_mainloop:
- self.master.update()
- id = self.master.after(msecs, self.master.quit)
- self.in_mainloop = 1
- self.master.mainloop()
- self.master.after_cancel(id)
- self.in_mainloop = 0
- if self.stop_mainloop:
- self.stop_mainloop = 0
- self.message("Cancelled")
- raise Array.Cancelled
-
- def getsize(self):
- return self.size
-
- def show_partition(self, first, last):
- for i in range(self.size):
- item = self.items[i]
- if first <= i < last:
- item.item.config(fill='red')
- else:
- item.item.config(fill='orange')
- self.hide_left_right_pivot()
-
- def hide_partition(self):
- for i in range(self.size):
- item = self.items[i]
- item.item.config(fill='red')
- self.hide_left_right_pivot()
-
- def show_left(self, left):
- if not 0 <= left < self.size:
- self.hide_left()
- return
- x1, y1, x2, y2 = self.items[left].position()
-## top, bot = HIRO
- self.left.coords([(x1-2, 0), (x1-2, 9999)])
- self.master.update()
-
- def show_right(self, right):
- if not 0 <= right < self.size:
- self.hide_right()
- return
- x1, y1, x2, y2 = self.items[right].position()
- self.right.coords(((x2+2, 0), (x2+2, 9999)))
- self.master.update()
-
- def hide_left_right_pivot(self):
- self.hide_left()
- self.hide_right()
- self.hide_pivot()
-
- def hide_left(self):
- self.left.coords(((0, 0), (0, 0)))
-
- def hide_right(self):
- self.right.coords(((0, 0), (0, 0)))
-
- def show_pivot(self, pivot):
- x1, y1, x2, y2 = self.items[pivot].position()
- self.pivot.coords(((0, y1-2), (9999, y1-2)))
-
- def hide_pivot(self):
- self.pivot.coords(((0, 0), (0, 0)))
-
- def swap(self, i, j):
- if i == j: return
- self.countswap()
- item = self.items[i]
- other = self.items[j]
- self.items[i], self.items[j] = other, item
- item.swapwith(other)
-
- def compare(self, i, j):
- self.countcompare()
- item = self.items[i]
- other = self.items[j]
- return item.compareto(other)
-
- def reset(self, msg):
- self.ncompares = 0
- self.nswaps = 0
- self.message(msg)
- self.updatereport()
- self.hide_partition()
-
- def message(self, msg):
- self.label.config(text=msg)
-
- def countswap(self):
- self.nswaps = self.nswaps + 1
- self.updatereport()
-
- def countcompare(self):
- self.ncompares = self.ncompares + 1
- self.updatereport()
-
- def updatereport(self):
- text = "%d cmps, %d swaps" % (self.ncompares, self.nswaps)
- self.report.config(text=text)
-
-
-class ArrayItem:
-
- def __init__(self, array, index, value):
- self.array = array
- self.index = index
- self.value = value
- x1, y1, x2, y2 = self.position()
- self.item = Rectangle(array.canvas, x1, y1, x2, y2,
- fill='red', outline='black', width=1)
- self.item.bind('<Button-1>', self.mouse_down)
- self.item.bind('<Button1-Motion>', self.mouse_move)
- self.item.bind('<ButtonRelease-1>', self.mouse_up)
-
- def delete(self):
- item = self.item
- self.array = None
- self.item = None
- item.delete()
-
- def mouse_down(self, event):
- self.lastx = event.x
- self.lasty = event.y
- self.origx = event.x
- self.origy = event.y
- self.item.tkraise()
-
- def mouse_move(self, event):
- self.item.move(event.x - self.lastx, event.y - self.lasty)
- self.lastx = event.x
- self.lasty = event.y
-
- def mouse_up(self, event):
- i = self.nearestindex(event.x)
- if i >= self.array.getsize():
- i = self.array.getsize() - 1
- if i < 0:
- i = 0
- other = self.array.items[i]
- here = self.index
- self.array.items[here], self.array.items[i] = other, self
- self.index = i
- x1, y1, x2, y2 = self.position()
- self.item.coords(((x1, y1), (x2, y2)))
- other.setindex(here)
-
- def setindex(self, index):
- nsteps = steps(self.index, index)
- if not nsteps: return
- if self.array.speed == "fastest":
- nsteps = 0
- oldpts = self.position()
- self.index = index
- newpts = self.position()
- trajectory = interpolate(oldpts, newpts, nsteps)
- self.item.tkraise()
- for pts in trajectory:
- self.item.coords((pts[:2], pts[2:]))
- self.array.wait(50)
-
- def swapwith(self, other):
- nsteps = steps(self.index, other.index)
- if not nsteps: return
- if self.array.speed == "fastest":
- nsteps = 0
- myoldpts = self.position()
- otheroldpts = other.position()
- self.index, other.index = other.index, self.index
- mynewpts = self.position()
- othernewpts = other.position()
- myfill = self.item['fill']
- otherfill = other.item['fill']
- self.item.config(fill='green')
- other.item.config(fill='yellow')
- self.array.master.update()
- if self.array.speed == "single-step":
- self.item.coords((mynewpts[:2], mynewpts[2:]))
- other.item.coords((othernewpts[:2], othernewpts[2:]))
- self.array.master.update()
- self.item.config(fill=myfill)
- other.item.config(fill=otherfill)
- self.array.wait(0)
- return
- mytrajectory = interpolate(myoldpts, mynewpts, nsteps)
- othertrajectory = interpolate(otheroldpts, othernewpts, nsteps)
- if self.value > other.value:
- self.item.tkraise()
- other.item.tkraise()
- else:
- other.item.tkraise()
- self.item.tkraise()
- try:
- for i in range(len(mytrajectory)):
- mypts = mytrajectory[i]
- otherpts = othertrajectory[i]
- self.item.coords((mypts[:2], mypts[2:]))
- other.item.coords((otherpts[:2], otherpts[2:]))
- self.array.wait(50)
- finally:
- mypts = mytrajectory[-1]
- otherpts = othertrajectory[-1]
- self.item.coords((mypts[:2], mypts[2:]))
- other.item.coords((otherpts[:2], otherpts[2:]))
- self.item.config(fill=myfill)
- other.item.config(fill=otherfill)
-
- def compareto(self, other):
- myfill = self.item['fill']
- otherfill = other.item['fill']
- outcome = cmp(self.value, other.value)
- if outcome < 0:
- myflash = 'white'
- otherflash = 'black'
- elif outcome > 0:
- myflash = 'black'
- otherflash = 'white'
- else:
- myflash = otherflash = 'grey'
- try:
- self.item.config(fill=myflash)
- other.item.config(fill=otherflash)
- self.array.wait(500)
- finally:
- self.item.config(fill=myfill)
- other.item.config(fill=otherfill)
- return outcome
-
- def position(self):
- x1 = (self.index+1)*XGRID - WIDTH//2
- x2 = x1+WIDTH
- y2 = (self.array.maxvalue+1)*YGRID
- y1 = y2 - (self.value)*YGRID
- return x1, y1, x2, y2
-
- def nearestindex(self, x):
- return int(round(float(x)/XGRID)) - 1
-
-
-# Subroutines that don't need an object
-
-def steps(here, there):
- nsteps = abs(here - there)
- if nsteps <= 3:
- nsteps = nsteps * 3
- elif nsteps <= 5:
- nsteps = nsteps * 2
- elif nsteps > 10:
- nsteps = 10
- return nsteps
-
-def interpolate(oldpts, newpts, n):
- if len(oldpts) != len(newpts):
- raise ValueError, "can't interpolate arrays of different length"
- pts = [0]*len(oldpts)
- res = [tuple(oldpts)]
- for i in range(1, n):
- for k in range(len(pts)):
- pts[k] = oldpts[k] + (newpts[k] - oldpts[k])*i//n
- res.append(tuple(pts))
- res.append(tuple(newpts))
- return res
-
-
-# Various (un)sorting algorithms
-
-def uniform(array):
- size = array.getsize()
- array.setdata([(size+1)//2] * size)
- array.reset("Uniform data, size %d" % size)
-
-def distinct(array):
- size = array.getsize()
- array.setdata(range(1, size+1))
- array.reset("Distinct data, size %d" % size)
-
-def randomize(array):
- array.reset("Randomizing")
- n = array.getsize()
- for i in range(n):
- j = random.randint(0, n-1)
- array.swap(i, j)
- array.message("Randomized")
-
-def insertionsort(array):
- size = array.getsize()
- array.reset("Insertion sort")
- for i in range(1, size):
- j = i-1
- while j >= 0:
- if array.compare(j, j+1) <= 0:
- break
- array.swap(j, j+1)
- j = j-1
- array.message("Sorted")
-
-def selectionsort(array):
- size = array.getsize()
- array.reset("Selection sort")
- try:
- for i in range(size):
- array.show_partition(i, size)
- for j in range(i+1, size):
- if array.compare(i, j) > 0:
- array.swap(i, j)
- array.message("Sorted")
- finally:
- array.hide_partition()
-
-def bubblesort(array):
- size = array.getsize()
- array.reset("Bubble sort")
- for i in range(size):
- for j in range(1, size):
- if array.compare(j-1, j) > 0:
- array.swap(j-1, j)
- array.message("Sorted")
-
-def quicksort(array):
- size = array.getsize()
- array.reset("Quicksort")
- try:
- stack = [(0, size)]
- while stack:
- first, last = stack[-1]
- del stack[-1]
- array.show_partition(first, last)
- if last-first < 5:
- array.message("Insertion sort")
- for i in range(first+1, last):
- j = i-1
- while j >= first:
- if array.compare(j, j+1) <= 0:
- break
- array.swap(j, j+1)
- j = j-1
- continue
- array.message("Choosing pivot")
- j, i, k = first, (first+last)//2, last-1
- if array.compare(k, i) < 0:
- array.swap(k, i)
- if array.compare(k, j) < 0:
- array.swap(k, j)
- if array.compare(j, i) < 0:
- array.swap(j, i)
- pivot = j
- array.show_pivot(pivot)
- array.message("Pivot at left of partition")
- array.wait(1000)
- left = first
- right = last
- while 1:
- array.message("Sweep right pointer")
- right = right-1
- array.show_right(right)
- while right > first and array.compare(right, pivot) >= 0:
- right = right-1
- array.show_right(right)
- array.message("Sweep left pointer")
- left = left+1
- array.show_left(left)
- while left < last and array.compare(left, pivot) <= 0:
- left = left+1
- array.show_left(left)
- if left > right:
- array.message("End of partition")
- break
- array.message("Swap items")
- array.swap(left, right)
- array.message("Swap pivot back")
- array.swap(pivot, right)
- n1 = right-first
- n2 = last-left
- if n1 > 1: stack.append((first, right))
- if n2 > 1: stack.append((left, last))
- array.message("Sorted")
- finally:
- array.hide_partition()
-
-def demosort(array):
- while 1:
- for alg in [quicksort, insertionsort, selectionsort, bubblesort]:
- randomize(array)
- alg(array)
-
-
-# Sort demo class -- usable as a Grail applet
-
-class SortDemo:
-
- def __init__(self, master, size=15):
- self.master = master
- self.size = size
- self.busy = 0
- self.array = Array(self.master)
-
- self.botframe = Frame(master)
- self.botframe.pack(side=BOTTOM)
- self.botleftframe = Frame(self.botframe)
- self.botleftframe.pack(side=LEFT, fill=Y)
- self.botrightframe = Frame(self.botframe)
- self.botrightframe.pack(side=RIGHT, fill=Y)
-
- self.b_qsort = Button(self.botleftframe,
- text="Quicksort", command=self.c_qsort)
- self.b_qsort.pack(fill=X)
- self.b_isort = Button(self.botleftframe,
- text="Insertion sort", command=self.c_isort)
- self.b_isort.pack(fill=X)
- self.b_ssort = Button(self.botleftframe,
- text="Selection sort", command=self.c_ssort)
- self.b_ssort.pack(fill=X)
- self.b_bsort = Button(self.botleftframe,
- text="Bubble sort", command=self.c_bsort)
- self.b_bsort.pack(fill=X)
-
- # Terrible hack to overcome limitation of OptionMenu...
- class MyIntVar(IntVar):
- def __init__(self, master, demo):
- self.demo = demo
- IntVar.__init__(self, master)
- def set(self, value):
- IntVar.set(self, value)
- if str(value) != '0':
- self.demo.resize(value)
-
- self.v_size = MyIntVar(self.master, self)
- self.v_size.set(size)
- sizes = [1, 2, 3, 4] + range(5, 55, 5)
- if self.size not in sizes:
- sizes.append(self.size)
- sizes.sort()
- self.m_size = apply(OptionMenu,
- (self.botleftframe, self.v_size) + tuple(sizes))
- self.m_size.pack(fill=X)
-
- self.v_speed = StringVar(self.master)
- self.v_speed.set("normal")
- self.m_speed = OptionMenu(self.botleftframe, self.v_speed,
- "single-step", "normal", "fast", "fastest")
- self.m_speed.pack(fill=X)
-
- self.b_step = Button(self.botleftframe,
- text="Step", command=self.c_step)
- self.b_step.pack(fill=X)
-
- self.b_randomize = Button(self.botrightframe,
- text="Randomize", command=self.c_randomize)
- self.b_randomize.pack(fill=X)
- self.b_uniform = Button(self.botrightframe,
- text="Uniform", command=self.c_uniform)
- self.b_uniform.pack(fill=X)
- self.b_distinct = Button(self.botrightframe,
- text="Distinct", command=self.c_distinct)
- self.b_distinct.pack(fill=X)
- self.b_demo = Button(self.botrightframe,
- text="Demo", command=self.c_demo)
- self.b_demo.pack(fill=X)
- self.b_cancel = Button(self.botrightframe,
- text="Cancel", command=self.c_cancel)
- self.b_cancel.pack(fill=X)
- self.b_cancel.config(state=DISABLED)
- self.b_quit = Button(self.botrightframe,
- text="Quit", command=self.c_quit)
- self.b_quit.pack(fill=X)
-
- def resize(self, newsize):
- if self.busy:
- self.master.bell()
- return
- self.size = newsize
- self.array.setdata(range(1, self.size+1))
-
- def c_qsort(self):
- self.run(quicksort)
-
- def c_isort(self):
- self.run(insertionsort)
-
- def c_ssort(self):
- self.run(selectionsort)
-
- def c_bsort(self):
- self.run(bubblesort)
-
- def c_demo(self):
- self.run(demosort)
-
- def c_randomize(self):
- self.run(randomize)
-
- def c_uniform(self):
- self.run(uniform)
-
- def c_distinct(self):
- self.run(distinct)
-
- def run(self, func):
- if self.busy:
- self.master.bell()
- return
- self.busy = 1
- self.array.setspeed(self.v_speed.get())
- self.b_cancel.config(state=NORMAL)
- try:
- func(self.array)
- except Array.Cancelled:
- pass
- self.b_cancel.config(state=DISABLED)
- self.busy = 0
-
- def c_cancel(self):
- if not self.busy:
- self.master.bell()
- return
- self.array.cancel()
-
- def c_step(self):
- if not self.busy:
- self.master.bell()
- return
- self.v_speed.set("single-step")
- self.array.setspeed("single-step")
- self.array.step()
-
- def c_quit(self):
- if self.busy:
- self.array.cancel()
- self.master.after_idle(self.master.quit)
-
-
-# Main program -- for stand-alone operation outside Grail
-
-def main():
- root = Tk()
- demo = SortDemo(root)
- root.protocol('WM_DELETE_WINDOW', demo.c_quit)
- root.mainloop()
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/tkinter/guido/ss1.py b/Demo/tkinter/guido/ss1.py
deleted file mode 100644
index 8935475..0000000
--- a/Demo/tkinter/guido/ss1.py
+++ /dev/null
@@ -1,845 +0,0 @@
-"""SS1 -- a spreadsheet."""
-
-import os
-import re
-import sys
-import cgi
-import rexec
-from xml.parsers import expat
-
-LEFT, CENTER, RIGHT = "LEFT", "CENTER", "RIGHT"
-
-def ljust(x, n):
- return x.ljust(n)
-def center(x, n):
- return x.center(n)
-def rjust(x, n):
- return x.rjust(n)
-align2action = {LEFT: ljust, CENTER: center, RIGHT: rjust}
-
-align2xml = {LEFT: "left", CENTER: "center", RIGHT: "right"}
-xml2align = {"left": LEFT, "center": CENTER, "right": RIGHT}
-
-align2anchor = {LEFT: "w", CENTER: "center", RIGHT: "e"}
-
-def sum(seq):
- total = 0
- for x in seq:
- if x is not None:
- total += x
- return total
-
-class Sheet:
-
- def __init__(self):
- self.cells = {} # {(x, y): cell, ...}
- self.rexec = rexec.RExec()
- m = self.rexec.add_module('__main__')
- m.cell = self.cellvalue
- m.cells = self.multicellvalue
- m.sum = sum
-
- def cellvalue(self, x, y):
- cell = self.getcell(x, y)
- if hasattr(cell, 'recalc'):
- return cell.recalc(self.rexec)
- else:
- return cell
-
- def multicellvalue(self, x1, y1, x2, y2):
- if x1 > x2:
- x1, x2 = x2, x1
- if y1 > y2:
- y1, y2 = y2, y1
- seq = []
- for y in range(y1, y2+1):
- for x in range(x1, x2+1):
- seq.append(self.cellvalue(x, y))
- return seq
-
- def getcell(self, x, y):
- return self.cells.get((x, y))
-
- def setcell(self, x, y, cell):
- assert x > 0 and y > 0
- assert isinstance(cell, BaseCell)
- self.cells[x, y] = cell
-
- def clearcell(self, x, y):
- try:
- del self.cells[x, y]
- except KeyError:
- pass
-
- def clearcells(self, x1, y1, x2, y2):
- for xy in self.selectcells(x1, y1, x2, y2):
- del self.cells[xy]
-
- def clearrows(self, y1, y2):
- self.clearcells(0, y1, sys.maxint, y2)
-
- def clearcolumns(self, x1, x2):
- self.clearcells(x1, 0, x2, sys.maxint)
-
- def selectcells(self, x1, y1, x2, y2):
- if x1 > x2:
- x1, x2 = x2, x1
- if y1 > y2:
- y1, y2 = y2, y1
- return [(x, y) for x, y in self.cells
- if x1 <= x <= x2 and y1 <= y <= y2]
-
- def movecells(self, x1, y1, x2, y2, dx, dy):
- if dx == 0 and dy == 0:
- return
- if x1 > x2:
- x1, x2 = x2, x1
- if y1 > y2:
- y1, y2 = y2, y1
- assert x1+dx > 0 and y1+dy > 0
- new = {}
- for x, y in self.cells:
- cell = self.cells[x, y]
- if hasattr(cell, 'renumber'):
- cell = cell.renumber(x1, y1, x2, y2, dx, dy)
- if x1 <= x <= x2 and y1 <= y <= y2:
- x += dx
- y += dy
- new[x, y] = cell
- self.cells = new
-
- def insertrows(self, y, n):
- assert n > 0
- self.movecells(0, y, sys.maxint, sys.maxint, 0, n)
-
- def deleterows(self, y1, y2):
- if y1 > y2:
- y1, y2 = y2, y1
- self.clearrows(y1, y2)
- self.movecells(0, y2+1, sys.maxint, sys.maxint, 0, y1-y2-1)
-
- def insertcolumns(self, x, n):
- assert n > 0
- self.movecells(x, 0, sys.maxint, sys.maxint, n, 0)
-
- def deletecolumns(self, x1, x2):
- if x1 > x2:
- x1, x2 = x2, x1
- self.clearcells(x1, x2)
- self.movecells(x2+1, 0, sys.maxint, sys.maxint, x1-x2-1, 0)
-
- def getsize(self):
- maxx = maxy = 0
- for x, y in self.cells:
- maxx = max(maxx, x)
- maxy = max(maxy, y)
- return maxx, maxy
-
- def reset(self):
- for cell in self.cells.itervalues():
- if hasattr(cell, 'reset'):
- cell.reset()
-
- def recalc(self):
- self.reset()
- for cell in self.cells.itervalues():
- if hasattr(cell, 'recalc'):
- cell.recalc(self.rexec)
-
- def display(self):
- maxx, maxy = self.getsize()
- width, height = maxx+1, maxy+1
- colwidth = [1] * width
- full = {}
- # Add column heading labels in row 0
- for x in range(1, width):
- full[x, 0] = text, alignment = colnum2name(x), RIGHT
- colwidth[x] = max(colwidth[x], len(text))
- # Add row labels in column 0
- for y in range(1, height):
- full[0, y] = text, alignment = str(y), RIGHT
- colwidth[0] = max(colwidth[0], len(text))
- # Add sheet cells in columns with x>0 and y>0
- for (x, y), cell in self.cells.iteritems():
- if x <= 0 or y <= 0:
- continue
- if hasattr(cell, 'recalc'):
- cell.recalc(self.rexec)
- if hasattr(cell, 'format'):
- text, alignment = cell.format()
- assert isinstance(text, str)
- assert alignment in (LEFT, CENTER, RIGHT)
- else:
- text = str(cell)
- if isinstance(cell, str):
- alignment = LEFT
- else:
- alignment = RIGHT
- full[x, y] = (text, alignment)
- colwidth[x] = max(colwidth[x], len(text))
- # Calculate the horizontal separator line (dashes and dots)
- sep = ""
- for x in range(width):
- if sep:
- sep += "+"
- sep += "-"*colwidth[x]
- # Now print The full grid
- for y in range(height):
- line = ""
- for x in range(width):
- text, alignment = full.get((x, y)) or ("", LEFT)
- text = align2action[alignment](text, colwidth[x])
- if line:
- line += '|'
- line += text
- print line
- if y == 0:
- print sep
-
- def xml(self):
- out = ['<spreadsheet>']
- for (x, y), cell in self.cells.iteritems():
- if hasattr(cell, 'xml'):
- cellxml = cell.xml()
- else:
- cellxml = '<value>%s</value>' % cgi.escape(cell)
- out.append('<cell row="%s" col="%s">\n %s\n</cell>' %
- (y, x, cellxml))
- out.append('</spreadsheet>')
- return '\n'.join(out)
-
- def save(self, filename):
- text = self.xml()
- f = open(filename, "w")
- f.write(text)
- if text and not text.endswith('\n'):
- f.write('\n')
- f.close()
-
- def load(self, filename):
- f = open(filename, 'r')
- SheetParser(self).parsefile(f)
- f.close()
-
-class SheetParser:
-
- def __init__(self, sheet):
- self.sheet = sheet
-
- def parsefile(self, f):
- parser = expat.ParserCreate()
- parser.StartElementHandler = self.startelement
- parser.EndElementHandler = self.endelement
- parser.CharacterDataHandler = self.data
- parser.ParseFile(f)
-
- def startelement(self, tag, attrs):
- method = getattr(self, 'start_'+tag, None)
- if method:
- for key, value in attrs.iteritems():
- attrs[key] = str(value) # XXX Convert Unicode to 8-bit
- method(attrs)
- self.texts = []
-
- def data(self, text):
- text = str(text) # XXX Convert Unicode to 8-bit
- self.texts.append(text)
-
- def endelement(self, tag):
- method = getattr(self, 'end_'+tag, None)
- if method:
- method("".join(self.texts))
-
- def start_cell(self, attrs):
- self.y = int(attrs.get("row"))
- self.x = int(attrs.get("col"))
-
- def start_value(self, attrs):
- self.fmt = attrs.get('format')
- self.alignment = xml2align.get(attrs.get('align'))
-
- start_formula = start_value
-
- def end_int(self, text):
- try:
- self.value = int(text)
- except:
- self.value = None
-
- def end_long(self, text):
- try:
- self.value = long(text)
- except:
- self.value = None
-
- def end_double(self, text):
- try:
- self.value = float(text)
- except:
- self.value = None
-
- def end_complex(self, text):
- try:
- self.value = complex(text)
- except:
- self.value = None
-
- def end_string(self, text):
- try:
- self.value = text
- except:
- self.value = None
-
- def end_value(self, text):
- if isinstance(self.value, BaseCell):
- self.cell = self.value
- elif isinstance(self.value, str):
- self.cell = StringCell(self.value,
- self.fmt or "%s",
- self.alignment or LEFT)
- else:
- self.cell = NumericCell(self.value,
- self.fmt or "%s",
- self.alignment or RIGHT)
-
- def end_formula(self, text):
- self.cell = FormulaCell(text,
- self.fmt or "%s",
- self.alignment or RIGHT)
-
- def end_cell(self, text):
- self.sheet.setcell(self.x, self.y, self.cell)
-
-class BaseCell:
- __init__ = None # Must provide
- """Abstract base class for sheet cells.
-
- Subclasses may but needn't provide the following APIs:
-
- cell.reset() -- prepare for recalculation
- cell.recalc(rexec) -> value -- recalculate formula
- cell.format() -> (value, alignment) -- return formatted value
- cell.xml() -> string -- return XML
- """
-
-class NumericCell(BaseCell):
-
- def __init__(self, value, fmt="%s", alignment=RIGHT):
- assert isinstance(value, (int, long, float, complex))
- assert alignment in (LEFT, CENTER, RIGHT)
- self.value = value
- self.fmt = fmt
- self.alignment = alignment
-
- def recalc(self, rexec):
- return self.value
-
- def format(self):
- try:
- text = self.fmt % self.value
- except:
- text = str(self.value)
- return text, self.alignment
-
- def xml(self):
- method = getattr(self, '_xml_' + type(self.value).__name__)
- return '<value align="%s" format="%s">%s</value>' % (
- align2xml[self.alignment],
- self.fmt,
- method())
-
- def _xml_int(self):
- if -2**31 <= self.value < 2**31:
- return '<int>%s</int>' % self.value
- else:
- return self._xml_long()
-
- def _xml_long(self):
- return '<long>%s</long>' % self.value
-
- def _xml_float(self):
- return '<double>%s</double>' % repr(self.value)
-
- def _xml_complex(self):
- return '<complex>%s</double>' % repr(self.value)
-
-class StringCell(BaseCell):
-
- def __init__(self, text, fmt="%s", alignment=LEFT):
- assert isinstance(text, (str, unicode))
- assert alignment in (LEFT, CENTER, RIGHT)
- self.text = text
- self.fmt = fmt
- self.alignment = alignment
-
- def recalc(self, rexec):
- return self.text
-
- def format(self):
- return self.text, self.alignment
-
- def xml(self):
- s = '<value align="%s" format="%s"><string>%s</string></value>'
- return s % (
- align2xml[self.alignment],
- self.fmt,
- cgi.escape(self.text))
-
-class FormulaCell(BaseCell):
-
- def __init__(self, formula, fmt="%s", alignment=RIGHT):
- assert alignment in (LEFT, CENTER, RIGHT)
- self.formula = formula
- self.translated = translate(self.formula)
- self.fmt = fmt
- self.alignment = alignment
- self.reset()
-
- def reset(self):
- self.value = None
-
- def recalc(self, rexec):
- if self.value is None:
- try:
- # A hack to evaluate expressions using true division
- rexec.r_exec("from __future__ import division\n" +
- "__value__ = eval(%s)" % repr(self.translated))
- self.value = rexec.r_eval("__value__")
- except:
- exc = sys.exc_info()[0]
- if hasattr(exc, "__name__"):
- self.value = exc.__name__
- else:
- self.value = str(exc)
- return self.value
-
- def format(self):
- try:
- text = self.fmt % self.value
- except:
- text = str(self.value)
- return text, self.alignment
-
- def xml(self):
- return '<formula align="%s" format="%s">%s</formula>' % (
- align2xml[self.alignment],
- self.fmt,
- self.formula)
-
- def renumber(self, x1, y1, x2, y2, dx, dy):
- out = []
- for part in re.split('(\w+)', self.formula):
- m = re.match('^([A-Z]+)([1-9][0-9]*)$', part)
- if m is not None:
- sx, sy = m.groups()
- x = colname2num(sx)
- y = int(sy)
- if x1 <= x <= x2 and y1 <= y <= y2:
- part = cellname(x+dx, y+dy)
- out.append(part)
- return FormulaCell("".join(out), self.fmt, self.alignment)
-
-def translate(formula):
- """Translate a formula containing fancy cell names to valid Python code.
-
- Examples:
- B4 -> cell(2, 4)
- B4:Z100 -> cells(2, 4, 26, 100)
- """
- out = []
- for part in re.split(r"(\w+(?::\w+)?)", formula):
- m = re.match(r"^([A-Z]+)([1-9][0-9]*)(?::([A-Z]+)([1-9][0-9]*))?$", part)
- if m is None:
- out.append(part)
- else:
- x1, y1, x2, y2 = m.groups()
- x1 = colname2num(x1)
- if x2 is None:
- s = "cell(%s, %s)" % (x1, y1)
- else:
- x2 = colname2num(x2)
- s = "cells(%s, %s, %s, %s)" % (x1, y1, x2, y2)
- out.append(s)
- return "".join(out)
-
-def cellname(x, y):
- "Translate a cell coordinate to a fancy cell name (e.g. (1, 1)->'A1')."
- assert x > 0 # Column 0 has an empty name, so can't use that
- return colnum2name(x) + str(y)
-
-def colname2num(s):
- "Translate a column name to number (e.g. 'A'->1, 'Z'->26, 'AA'->27)."
- s = s.upper()
- n = 0
- for c in s:
- assert 'A' <= c <= 'Z'
- n = n*26 + ord(c) - ord('A') + 1
- return n
-
-def colnum2name(n):
- "Translate a column number to name (e.g. 1->'A', etc.)."
- assert n > 0
- s = ""
- while n:
- n, m = divmod(n-1, 26)
- s = chr(m+ord('A')) + s
- return s
-
-import Tkinter as Tk
-
-class SheetGUI:
-
- """Beginnings of a GUI for a spreadsheet.
-
- TO DO:
- - clear multiple cells
- - Insert, clear, remove rows or columns
- - Show new contents while typing
- - Scroll bars
- - Grow grid when window is grown
- - Proper menus
- - Undo, redo
- - Cut, copy and paste
- - Formatting and alignment
- """
-
- def __init__(self, filename="sheet1.xml", rows=10, columns=5):
- """Constructor.
-
- Load the sheet from the filename argument.
- Set up the Tk widget tree.
- """
- # Create and load the sheet
- self.filename = filename
- self.sheet = Sheet()
- if os.path.isfile(filename):
- self.sheet.load(filename)
- # Calculate the needed grid size
- maxx, maxy = self.sheet.getsize()
- rows = max(rows, maxy)
- columns = max(columns, maxx)
- # Create the widgets
- self.root = Tk.Tk()
- self.root.wm_title("Spreadsheet: %s" % self.filename)
- self.beacon = Tk.Label(self.root, text="A1",
- font=('helvetica', 16, 'bold'))
- self.entry = Tk.Entry(self.root)
- self.savebutton = Tk.Button(self.root, text="Save",
- command=self.save)
- self.cellgrid = Tk.Frame(self.root)
- # Configure the widget lay-out
- self.cellgrid.pack(side="bottom", expand=1, fill="both")
- self.beacon.pack(side="left")
- self.savebutton.pack(side="right")
- self.entry.pack(side="left", expand=1, fill="x")
- # Bind some events
- self.entry.bind("<Return>", self.return_event)
- self.entry.bind("<Shift-Return>", self.shift_return_event)
- self.entry.bind("<Tab>", self.tab_event)
- self.entry.bind("<Shift-Tab>", self.shift_tab_event)
- self.entry.bind("<Delete>", self.delete_event)
- self.entry.bind("<Escape>", self.escape_event)
- # Now create the cell grid
- self.makegrid(rows, columns)
- # Select the top-left cell
- self.currentxy = None
- self.cornerxy = None
- self.setcurrent(1, 1)
- # Copy the sheet cells to the GUI cells
- self.sync()
-
- def delete_event(self, event):
- if self.cornerxy != self.currentxy and self.cornerxy is not None:
- self.sheet.clearcells(*(self.currentxy + self.cornerxy))
- else:
- self.sheet.clearcell(*self.currentxy)
- self.sync()
- self.entry.delete(0, 'end')
- return "break"
-
- def escape_event(self, event):
- x, y = self.currentxy
- self.load_entry(x, y)
-
- def load_entry(self, x, y):
- cell = self.sheet.getcell(x, y)
- if cell is None:
- text = ""
- elif isinstance(cell, FormulaCell):
- text = '=' + cell.formula
- else:
- text, alignment = cell.format()
- self.entry.delete(0, 'end')
- self.entry.insert(0, text)
- self.entry.selection_range(0, 'end')
-
- def makegrid(self, rows, columns):
- """Helper to create the grid of GUI cells.
-
- The edge (x==0 or y==0) is filled with labels; the rest is real cells.
- """
- self.rows = rows
- self.columns = columns
- self.gridcells = {}
- # Create the top left corner cell (which selects all)
- cell = Tk.Label(self.cellgrid, relief='raised')
- cell.grid_configure(column=0, row=0, sticky='NSWE')
- cell.bind("<ButtonPress-1>", self.selectall)
- # Create the top row of labels, and confiure the grid columns
- for x in range(1, columns+1):
- self.cellgrid.grid_columnconfigure(x, minsize=64)
- cell = Tk.Label(self.cellgrid, text=colnum2name(x), relief='raised')
- cell.grid_configure(column=x, row=0, sticky='WE')
- self.gridcells[x, 0] = cell
- cell.__x = x
- cell.__y = 0
- cell.bind("<ButtonPress-1>", self.selectcolumn)
- cell.bind("<B1-Motion>", self.extendcolumn)
- cell.bind("<ButtonRelease-1>", self.extendcolumn)
- cell.bind("<Shift-Button-1>", self.extendcolumn)
- # Create the leftmost column of labels
- for y in range(1, rows+1):
- cell = Tk.Label(self.cellgrid, text=str(y), relief='raised')
- cell.grid_configure(column=0, row=y, sticky='WE')
- self.gridcells[0, y] = cell
- cell.__x = 0
- cell.__y = y
- cell.bind("<ButtonPress-1>", self.selectrow)
- cell.bind("<B1-Motion>", self.extendrow)
- cell.bind("<ButtonRelease-1>", self.extendrow)
- cell.bind("<Shift-Button-1>", self.extendrow)
- # Create the real cells
- for x in range(1, columns+1):
- for y in range(1, rows+1):
- cell = Tk.Label(self.cellgrid, relief='sunken',
- bg='white', fg='black')
- cell.grid_configure(column=x, row=y, sticky='NSWE')
- self.gridcells[x, y] = cell
- cell.__x = x
- cell.__y = y
- # Bind mouse events
- cell.bind("<ButtonPress-1>", self.press)
- cell.bind("<B1-Motion>", self.motion)
- cell.bind("<ButtonRelease-1>", self.release)
- cell.bind("<Shift-Button-1>", self.release)
-
- def selectall(self, event):
- self.setcurrent(1, 1)
- self.setcorner(sys.maxint, sys.maxint)
-
- def selectcolumn(self, event):
- x, y = self.whichxy(event)
- self.setcurrent(x, 1)
- self.setcorner(x, sys.maxint)
-
- def extendcolumn(self, event):
- x, y = self.whichxy(event)
- if x > 0:
- self.setcurrent(self.currentxy[0], 1)
- self.setcorner(x, sys.maxint)
-
- def selectrow(self, event):
- x, y = self.whichxy(event)
- self.setcurrent(1, y)
- self.setcorner(sys.maxint, y)
-
- def extendrow(self, event):
- x, y = self.whichxy(event)
- if y > 0:
- self.setcurrent(1, self.currentxy[1])
- self.setcorner(sys.maxint, y)
-
- def press(self, event):
- x, y = self.whichxy(event)
- if x > 0 and y > 0:
- self.setcurrent(x, y)
-
- def motion(self, event):
- x, y = self.whichxy(event)
- if x > 0 and y > 0:
- self.setcorner(x, y)
-
- release = motion
-
- def whichxy(self, event):
- w = self.cellgrid.winfo_containing(event.x_root, event.y_root)
- if w is not None and isinstance(w, Tk.Label):
- try:
- return w.__x, w.__y
- except AttributeError:
- pass
- return 0, 0
-
- def save(self):
- self.sheet.save(self.filename)
-
- def setcurrent(self, x, y):
- "Make (x, y) the current cell."
- if self.currentxy is not None:
- self.change_cell()
- self.clearfocus()
- self.beacon['text'] = cellname(x, y)
- self.load_entry(x, y)
- self.entry.focus_set()
- self.currentxy = x, y
- self.cornerxy = None
- gridcell = self.gridcells.get(self.currentxy)
- if gridcell is not None:
- gridcell['bg'] = 'yellow'
-
- def setcorner(self, x, y):
- if self.currentxy is None or self.currentxy == (x, y):
- self.setcurrent(x, y)
- return
- self.clearfocus()
- self.cornerxy = x, y
- x1, y1 = self.currentxy
- x2, y2 = self.cornerxy or self.currentxy
- if x1 > x2:
- x1, x2 = x2, x1
- if y1 > y2:
- y1, y2 = y2, y1
- for (x, y), cell in self.gridcells.iteritems():
- if x1 <= x <= x2 and y1 <= y <= y2:
- cell['bg'] = 'lightBlue'
- gridcell = self.gridcells.get(self.currentxy)
- if gridcell is not None:
- gridcell['bg'] = 'yellow'
- self.setbeacon(x1, y1, x2, y2)
-
- def setbeacon(self, x1, y1, x2, y2):
- if x1 == y1 == 1 and x2 == y2 == sys.maxint:
- name = ":"
- elif (x1, x2) == (1, sys.maxint):
- if y1 == y2:
- name = "%d" % y1
- else:
- name = "%d:%d" % (y1, y2)
- elif (y1, y2) == (1, sys.maxint):
- if x1 == x2:
- name = "%s" % colnum2name(x1)
- else:
- name = "%s:%s" % (colnum2name(x1), colnum2name(x2))
- else:
- name1 = cellname(*self.currentxy)
- name2 = cellname(*self.cornerxy)
- name = "%s:%s" % (name1, name2)
- self.beacon['text'] = name
-
-
- def clearfocus(self):
- if self.currentxy is not None:
- x1, y1 = self.currentxy
- x2, y2 = self.cornerxy or self.currentxy
- if x1 > x2:
- x1, x2 = x2, x1
- if y1 > y2:
- y1, y2 = y2, y1
- for (x, y), cell in self.gridcells.iteritems():
- if x1 <= x <= x2 and y1 <= y <= y2:
- cell['bg'] = 'white'
-
- def return_event(self, event):
- "Callback for the Return key."
- self.change_cell()
- x, y = self.currentxy
- self.setcurrent(x, y+1)
- return "break"
-
- def shift_return_event(self, event):
- "Callback for the Return key with Shift modifier."
- self.change_cell()
- x, y = self.currentxy
- self.setcurrent(x, max(1, y-1))
- return "break"
-
- def tab_event(self, event):
- "Callback for the Tab key."
- self.change_cell()
- x, y = self.currentxy
- self.setcurrent(x+1, y)
- return "break"
-
- def shift_tab_event(self, event):
- "Callback for the Tab key with Shift modifier."
- self.change_cell()
- x, y = self.currentxy
- self.setcurrent(max(1, x-1), y)
- return "break"
-
- def change_cell(self):
- "Set the current cell from the entry widget."
- x, y = self.currentxy
- text = self.entry.get()
- cell = None
- if text.startswith('='):
- cell = FormulaCell(text[1:])
- else:
- for cls in int, long, float, complex:
- try:
- value = cls(text)
- except:
- continue
- else:
- cell = NumericCell(value)
- break
- if cell is None and text:
- cell = StringCell(text)
- if cell is None:
- self.sheet.clearcell(x, y)
- else:
- self.sheet.setcell(x, y, cell)
- self.sync()
-
- def sync(self):
- "Fill the GUI cells from the sheet cells."
- self.sheet.recalc()
- for (x, y), gridcell in self.gridcells.iteritems():
- if x == 0 or y == 0:
- continue
- cell = self.sheet.getcell(x, y)
- if cell is None:
- gridcell['text'] = ""
- else:
- if hasattr(cell, 'format'):
- text, alignment = cell.format()
- else:
- text, alignment = str(cell), LEFT
- gridcell['text'] = text
- gridcell['anchor'] = align2anchor[alignment]
-
-
-def test_basic():
- "Basic non-gui self-test."
- import os
- a = Sheet()
- for x in range(1, 11):
- for y in range(1, 11):
- if x == 1:
- cell = NumericCell(y)
- elif y == 1:
- cell = NumericCell(x)
- else:
- c1 = cellname(x, 1)
- c2 = cellname(1, y)
- formula = "%s*%s" % (c1, c2)
- cell = FormulaCell(formula)
- a.setcell(x, y, cell)
-## if os.path.isfile("sheet1.xml"):
-## print "Loading from sheet1.xml"
-## a.load("sheet1.xml")
- a.display()
- a.save("sheet1.xml")
-
-def test_gui():
- "GUI test."
- if sys.argv[1:]:
- filename = sys.argv[1]
- else:
- filename = "sheet1.xml"
- g = SheetGUI(filename)
- g.root.mainloop()
-
-if __name__ == '__main__':
- #test_basic()
- test_gui()
diff --git a/Demo/tkinter/guido/svkill.py b/Demo/tkinter/guido/svkill.py
deleted file mode 100755
index 69f7f3b..0000000
--- a/Demo/tkinter/guido/svkill.py
+++ /dev/null
@@ -1,128 +0,0 @@
-#! /usr/bin/env python
-
-# Tkinter interface to SYSV `ps' and `kill' commands.
-
-from Tkinter import *
-
-if TkVersion < 4.0:
- raise ImportError, "This version of svkill requires Tk 4.0 or later"
-
-from string import splitfields
-from string import split
-import commands
-import os
-
-user = os.environ['LOGNAME']
-
-class BarButton(Menubutton):
- def __init__(self, master=None, **cnf):
- apply(Menubutton.__init__, (self, master), cnf)
- self.pack(side=LEFT)
- self.menu = Menu(self, name='menu')
- self['menu'] = self.menu
-
-class Kill(Frame):
- # List of (name, option, pid_column)
- view_list = [
- ('Default', ''),
- ('Every (-e)', '-e'),
- ('Non process group leaders (-d)', '-d'),
- ('Non leaders with tty (-a)', '-a'),
- ('For this user (-u %s)' % user, '-u %s' % user),
- ]
- format_list = [
- ('Default', '', 0),
- ('Long (-l)', '-l', 3),
- ('Full (-f)', '-f', 1),
- ('Full Long (-f -l)', '-l -f', 3),
- ('Session and group ID (-j)', '-j', 0),
- ('Scheduler properties (-c)', '-c', 0),
- ]
- def kill(self, selected):
- c = self.format_list[self.format.get()][2]
- pid = split(selected)[c]
- os.system('kill -9 ' + pid)
- self.do_update()
- def do_update(self):
- format = self.format_list[self.format.get()][1]
- view = self.view_list[self.view.get()][1]
- s = commands.getoutput('ps %s %s' % (view, format))
- list = splitfields(s, '\n')
- self.header.set(list[0] + ' ')
- del list[0]
- self.frame.list.delete(0, AtEnd())
- for line in list:
- self.frame.list.insert(0, line)
- def do_motion(self, e):
- e.widget.select_clear('0', 'end')
- e.widget.select_set(e.widget.nearest(e.y))
- def do_leave(self, e):
- e.widget.select_clear('0', 'end')
- def do_1(self, e):
- self.kill(e.widget.get(e.widget.nearest(e.y)))
- def __init__(self, master=None, **cnf):
- apply(Frame.__init__, (self, master), cnf)
- self.pack(expand=1, fill=BOTH)
- self.bar = Frame(self, name='bar', relief=RAISED,
- borderwidth=2)
- self.bar.pack(fill=X)
- self.bar.file = BarButton(self.bar, text='File')
- self.bar.file.menu.add_command(
- label='Quit', command=self.quit)
- self.bar.view = BarButton(self.bar, text='View')
- self.bar.format = BarButton(self.bar, text='Format')
- self.view = IntVar(self)
- self.view.set(0)
- self.format = IntVar(self)
- self.format.set(0)
- for num in range(len(self.view_list)):
- label, option = self.view_list[num]
- self.bar.view.menu.add_radiobutton(
- label=label,
- command=self.do_update,
- variable=self.view,
- value=num)
- for num in range(len(self.format_list)):
- label, option, col = self.format_list[num]
- self.bar.format.menu.add_radiobutton(
- label=label,
- command=self.do_update,
- variable=self.format,
- value=num)
- self.bar.tk_menuBar(self.bar.file,
- self.bar.view,
- self.bar.format)
- self.frame = Frame(self, relief=RAISED, borderwidth=2)
- self.frame.pack(expand=1, fill=BOTH)
- self.header = StringVar(self)
- self.frame.label = Label(
- self.frame, relief=FLAT, anchor=NW, borderwidth=0,
- font='*-Courier-Bold-R-Normal-*-120-*',
- textvariable=self.header)
- self.frame.label.pack(fill=Y, anchor=W)
- self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL)
- self.frame.list = Listbox(
- self.frame,
- relief=SUNKEN,
- font='*-Courier-Medium-R-Normal-*-120-*',
- width=40, height=10,
- selectbackground='#eed5b7',
- selectborderwidth=0,
- selectmode=BROWSE,
- yscroll=self.frame.vscroll.set)
- self.frame.vscroll['command'] = self.frame.list.yview
- self.frame.vscroll.pack(side=RIGHT, fill=Y)
- self.frame.list.pack(expand=1, fill=BOTH)
- self.update = Button(self, text='Update',
- command=self.do_update)
- self.update.pack(fill=X)
- self.frame.list.bind('<Motion>', self.do_motion)
- self.frame.list.bind('<Leave>', self.do_leave)
- self.frame.list.bind('<1>', self.do_1)
- self.do_update()
-
-if __name__ == '__main__':
- kill = Kill(None, borderwidth=5)
- kill.winfo_toplevel().title('Tkinter Process Killer (SYSV)')
- kill.winfo_toplevel().minsize(1, 1)
- kill.mainloop()
diff --git a/Demo/tkinter/guido/switch.py b/Demo/tkinter/guido/switch.py
deleted file mode 100644
index 3b58f7c..0000000
--- a/Demo/tkinter/guido/switch.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Show how to do switchable panels.
-
-from Tkinter import *
-
-class App:
-
- def __init__(self, top=None, master=None):
- if top is None:
- if master is None:
- top = Tk()
- else:
- top = Toplevel(master)
- self.top = top
- self.buttonframe = Frame(top)
- self.buttonframe.pack()
- self.panelframe = Frame(top, borderwidth=2, relief=GROOVE)
- self.panelframe.pack(expand=1, fill=BOTH)
- self.panels = {}
- self.curpanel = None
-
- def addpanel(self, name, klass):
- button = Button(self.buttonframe, text=name,
- command=lambda self=self, name=name: self.show(name))
- button.pack(side=LEFT)
- frame = Frame(self.panelframe)
- instance = klass(frame)
- self.panels[name] = (button, frame, instance)
- if self.curpanel is None:
- self.show(name)
-
- def show(self, name):
- (button, frame, instance) = self.panels[name]
- if self.curpanel:
- self.curpanel.pack_forget()
- self.curpanel = frame
- frame.pack(expand=1, fill="both")
-
-class LabelPanel:
- def __init__(self, frame):
- self.label = Label(frame, text="Hello world")
- self.label.pack()
-
-class ButtonPanel:
- def __init__(self, frame):
- self.button = Button(frame, text="Press me")
- self.button.pack()
-
-def main():
- app = App()
- app.addpanel("label", LabelPanel)
- app.addpanel("button", ButtonPanel)
- app.top.mainloop()
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/tkinter/guido/tkman.py b/Demo/tkinter/guido/tkman.py
deleted file mode 100755
index 6b0b641..0000000
--- a/Demo/tkinter/guido/tkman.py
+++ /dev/null
@@ -1,267 +0,0 @@
-#! /usr/bin/env python
-
-# Tk man page browser -- currently only shows the Tcl/Tk man pages
-
-import sys
-import os
-import string
-import re
-from Tkinter import *
-from ManPage import ManPage
-
-MANNDIRLIST = ['/depot/sundry/man/mann','/usr/local/man/mann']
-MAN3DIRLIST = ['/depot/sundry/man/man3','/usr/local/man/man3']
-
-foundmanndir = 0
-for dir in MANNDIRLIST:
- if os.path.exists(dir):
- MANNDIR = dir
- foundmanndir = 1
-
-foundman3dir = 0
-for dir in MAN3DIRLIST:
- if os.path.exists(dir):
- MAN3DIR = dir
- foundman3dir = 1
-
-if not foundmanndir or not foundman3dir:
- sys.stderr.write('\n')
- if not foundmanndir:
- msg = """\
-Failed to find mann directory.
-Please add the correct entry to the MANNDIRLIST
-at the top of %s script.""" % \
-sys.argv[0]
- sys.stderr.write("%s\n\n" % msg)
- if not foundman3dir:
- msg = """\
-Failed to find man3 directory.
-Please add the correct entry to the MAN3DIRLIST
-at the top of %s script.""" % \
-sys.argv[0]
- sys.stderr.write("%s\n\n" % msg)
- sys.exit(1)
-
-del foundmanndir
-del foundman3dir
-
-def listmanpages(mandir):
- files = os.listdir(mandir)
- names = []
- for file in files:
- if file[-2:-1] == '.' and (file[-1] in 'ln123456789'):
- names.append(file[:-2])
- names.sort()
- return names
-
-class SelectionBox:
-
- def __init__(self, master=None):
- self.choices = []
-
- self.frame = Frame(master, name="frame")
- self.frame.pack(expand=1, fill=BOTH)
- self.master = self.frame.master
- self.subframe = Frame(self.frame, name="subframe")
- self.subframe.pack(expand=0, fill=BOTH)
- self.leftsubframe = Frame(self.subframe, name='leftsubframe')
- self.leftsubframe.pack(side=LEFT, expand=1, fill=BOTH)
- self.rightsubframe = Frame(self.subframe, name='rightsubframe')
- self.rightsubframe.pack(side=RIGHT, expand=1, fill=BOTH)
- self.chaptervar = StringVar(master)
- self.chapter = Menubutton(self.rightsubframe, name='chapter',
- text='Directory', relief=RAISED,
- borderwidth=2)
- self.chapter.pack(side=TOP)
- self.chaptermenu = Menu(self.chapter, name='chaptermenu')
- self.chaptermenu.add_radiobutton(label='C functions',
- value=MAN3DIR,
- variable=self.chaptervar,
- command=self.newchapter)
- self.chaptermenu.add_radiobutton(label='Tcl/Tk functions',
- value=MANNDIR,
- variable=self.chaptervar,
- command=self.newchapter)
- self.chapter['menu'] = self.chaptermenu
- self.listbox = Listbox(self.rightsubframe, name='listbox',
- relief=SUNKEN, borderwidth=2,
- width=20, height=5)
- self.listbox.pack(expand=1, fill=BOTH)
- self.l1 = Button(self.leftsubframe, name='l1',
- text='Display manual page named:',
- command=self.entry_cb)
- self.l1.pack(side=TOP)
- self.entry = Entry(self.leftsubframe, name='entry',
- relief=SUNKEN, borderwidth=2,
- width=20)
- self.entry.pack(expand=0, fill=X)
- self.l2frame = Frame(self.leftsubframe, name='l2frame')
- self.l2frame.pack(expand=0, fill=NONE)
- self.l2 = Button(self.l2frame, name='l2',
- text='Search regexp:',
- command=self.search_cb)
- self.l2.pack(side=LEFT)
- self.casevar = BooleanVar()
- self.casesense = Checkbutton(self.l2frame, name='casesense',
- text='Case sensitive',
- variable=self.casevar,
- relief=FLAT)
- self.casesense.pack(side=LEFT)
- self.search = Entry(self.leftsubframe, name='search',
- relief=SUNKEN, borderwidth=2,
- width=20)
- self.search.pack(expand=0, fill=X)
- self.title = Label(self.leftsubframe, name='title',
- text='(none)')
- self.title.pack(side=BOTTOM)
- self.text = ManPage(self.frame, name='text',
- relief=SUNKEN, borderwidth=2,
- wrap=NONE, width=72,
- selectbackground='pink')
- self.text.pack(expand=1, fill=BOTH)
-
- self.entry.bind('<Return>', self.entry_cb)
- self.search.bind('<Return>', self.search_cb)
- self.listbox.bind('<Double-1>', self.listbox_cb)
-
- self.entry.bind('<Tab>', self.entry_tab)
- self.search.bind('<Tab>', self.search_tab)
- self.text.bind('<Tab>', self.text_tab)
-
- self.entry.focus_set()
-
- self.chaptervar.set(MANNDIR)
- self.newchapter()
-
- def newchapter(self):
- mandir = self.chaptervar.get()
- self.choices = []
- self.addlist(listmanpages(mandir))
-
- def addchoice(self, choice):
- if choice not in self.choices:
- self.choices.append(choice)
- self.choices.sort()
- self.update()
-
- def addlist(self, list):
- self.choices[len(self.choices):] = list
- self.choices.sort()
- self.update()
-
- def entry_cb(self, *e):
- self.update()
-
- def listbox_cb(self, e):
- selection = self.listbox.curselection()
- if selection and len(selection) == 1:
- name = self.listbox.get(selection[0])
- self.show_page(name)
-
- def search_cb(self, *e):
- self.search_string(self.search.get())
-
- def entry_tab(self, e):
- self.search.focus_set()
-
- def search_tab(self, e):
- self.entry.focus_set()
-
- def text_tab(self, e):
- self.entry.focus_set()
-
- def updatelist(self):
- key = self.entry.get()
- ok = filter(lambda name, key=key, n=len(key): name[:n]==key,
- self.choices)
- if not ok:
- self.frame.bell()
- self.listbox.delete(0, AtEnd())
- exactmatch = 0
- for item in ok:
- if item == key: exactmatch = 1
- self.listbox.insert(AtEnd(), item)
- if exactmatch:
- return key
- n = self.listbox.size()
- if n == 1:
- return self.listbox.get(0)
- # Else return None, meaning not a unique selection
-
- def update(self):
- name = self.updatelist()
- if name:
- self.show_page(name)
- self.entry.delete(0, AtEnd())
- self.updatelist()
-
- def show_page(self, name):
- file = '%s/%s.?' % (self.chaptervar.get(), name)
- fp = os.popen('nroff -man %s | ul -i' % file, 'r')
- self.text.kill()
- self.title['text'] = name
- self.text.parsefile(fp)
-
- def search_string(self, search):
- if not search:
- self.frame.bell()
- print 'Empty search string'
- return
- if not self.casevar.get():
- map = re.IGNORECASE
- else:
- map = None
- try:
- if map:
- prog = re.compile(search, map)
- else:
- prog = re.compile(search)
- except re.error, msg:
- self.frame.bell()
- print 'Regex error:', msg
- return
- here = self.text.index(AtInsert())
- lineno = string.atoi(here[:string.find(here, '.')])
- end = self.text.index(AtEnd())
- endlineno = string.atoi(end[:string.find(end, '.')])
- wraplineno = lineno
- found = 0
- while 1:
- lineno = lineno + 1
- if lineno > endlineno:
- if wraplineno <= 0:
- break
- endlineno = wraplineno
- lineno = 0
- wraplineno = 0
- line = self.text.get('%d.0 linestart' % lineno,
- '%d.0 lineend' % lineno)
- i = prog.search(line)
- if i >= 0:
- found = 1
- n = max(1, len(prog.group(0)))
- try:
- self.text.tag_remove('sel',
- AtSelFirst(),
- AtSelLast())
- except TclError:
- pass
- self.text.tag_add('sel',
- '%d.%d' % (lineno, i),
- '%d.%d' % (lineno, i+n))
- self.text.mark_set(AtInsert(),
- '%d.%d' % (lineno, i))
- self.text.yview_pickplace(AtInsert())
- break
- if not found:
- self.frame.bell()
-
-def main():
- root = Tk()
- sb = SelectionBox(root)
- if sys.argv[1:]:
- sb.show_page(sys.argv[1])
- root.minsize(1, 1)
- root.mainloop()
-
-main()
diff --git a/Demo/tkinter/guido/wish.py b/Demo/tkinter/guido/wish.py
deleted file mode 100644
index 0a61ad8..0000000
--- a/Demo/tkinter/guido/wish.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# This is about all it requires to write a wish shell in Python!
-
-import _tkinter
-import os
-
-tk = _tkinter.create(os.environ['DISPLAY'], 'wish', 'Tk', 1)
-tk.call('update')
-
-cmd = ''
-
-while 1:
- if cmd: prompt = ''
- else: prompt = '% '
- try:
- line = raw_input(prompt)
- except EOFError:
- break
- cmd = cmd + (line + '\n')
- if tk.getboolean(tk.call('info', 'complete', cmd)):
- tk.record(line)
- try:
- result = tk.call('eval', cmd)
- except _tkinter.TclError, msg:
- print 'TclError:', msg
- else:
- if result: print result
- cmd = ''
diff --git a/Demo/tkinter/matt/00-HELLO-WORLD.py b/Demo/tkinter/matt/00-HELLO-WORLD.py
deleted file mode 100644
index 1c3151b..0000000
--- a/Demo/tkinter/matt/00-HELLO-WORLD.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from Tkinter import *
-
-# note that there is no explicit call to start Tk.
-# Tkinter is smart enough to start the system if it's not already going.
-
-class Test(Frame):
- def printit(self):
- print "hi"
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
-
- self.QUIT.pack(side=LEFT, fill=BOTH)
-
- # a hello button
- self.hi_there = Button(self, text='Hello',
- command=self.printit)
- self.hi_there.pack(side=LEFT)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-test.mainloop()
diff --git a/Demo/tkinter/matt/README b/Demo/tkinter/matt/README
deleted file mode 100644
index eb9d302..0000000
--- a/Demo/tkinter/matt/README
+++ /dev/null
@@ -1,30 +0,0 @@
-This directory contains some ad-hoc examples of Tkinter widget
-creation. The files named
-
- *-simple.py
-
-are the ones to start with if you're looking for a bare-bones usage of
-a widget. The other files are meant to show common usage patters that
-are a tad more involved.
-
-If you have a suggestion for an example program, please send mail to
-
- conway@virginia.edu
-
-and I'll include it.
-
-
-matt
-
-TODO
--------
-The X selection
-Dialog Boxes
-More canvas examples
-Message widgets
-Text Editors
-Scrollbars
-Listboxes
-
-
-
diff --git a/Demo/tkinter/matt/animation-simple.py b/Demo/tkinter/matt/animation-simple.py
deleted file mode 100644
index b52e1dc..0000000
--- a/Demo/tkinter/matt/animation-simple.py
+++ /dev/null
@@ -1,35 +0,0 @@
-from Tkinter import *
-
-# This program shows how to use the "after" function to make animation.
-
-class Test(Frame):
- def printit(self):
- print "hi"
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
- self.QUIT.pack(side=LEFT, fill=BOTH)
-
- self.draw = Canvas(self, width="5i", height="5i")
-
- # all of these work..
- self.draw.create_rectangle(0, 0, 10, 10, tags="thing", fill="blue")
- self.draw.pack(side=LEFT)
-
- def moveThing(self, *args):
- # move 1/10 of an inch every 1/10 sec (1" per second, smoothly)
- self.draw.move("thing", "0.01i", "0.01i")
- self.after(10, self.moveThing)
-
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
- self.after(10, self.moveThing)
-
-
-test = Test()
-
-test.mainloop()
diff --git a/Demo/tkinter/matt/animation-w-velocity-ctrl.py b/Demo/tkinter/matt/animation-w-velocity-ctrl.py
deleted file mode 100644
index e676338..0000000
--- a/Demo/tkinter/matt/animation-w-velocity-ctrl.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from Tkinter import *
-
-# this is the same as simple-demo-1.py, but uses
-# subclassing.
-# note that there is no explicit call to start Tk.
-# Tkinter is smart enough to start the system if it's not already going.
-
-
-class Test(Frame):
- def printit(self):
- print "hi"
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
- self.QUIT.pack(side=BOTTOM, fill=BOTH)
-
- self.draw = Canvas(self, width="5i", height="5i")
-
- self.speed = Scale(self, orient=HORIZONTAL, from_=-100, to=100)
-
- self.speed.pack(side=BOTTOM, fill=X)
-
- # all of these work..
- self.draw.create_rectangle(0, 0, 10, 10, tags="thing", fill="blue")
- self.draw.pack(side=LEFT)
-
- def moveThing(self, *args):
- velocity = self.speed.get()
- str = float(velocity) / 1000.0
- str = "%ri" % (str,)
- self.draw.move("thing", str, str)
- self.after(10, self.moveThing)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
- self.after(10, self.moveThing)
-
-
-test = Test()
-
-test.mainloop()
diff --git a/Demo/tkinter/matt/bind-w-mult-calls-p-type.py b/Demo/tkinter/matt/bind-w-mult-calls-p-type.py
deleted file mode 100644
index f3220da..0000000
--- a/Demo/tkinter/matt/bind-w-mult-calls-p-type.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from Tkinter import *
-import string
-
-# This program shows how to use a simple type-in box
-
-class App(Frame):
- def __init__(self, master=None):
- Frame.__init__(self, master)
- self.pack()
-
- self.entrythingy = Entry()
- self.entrythingy.pack()
-
- # and here we get a callback when the user hits return. we could
- # make the key that triggers the callback anything we wanted to.
- # other typical options might be <Key-Tab> or <Key> (for anything)
- self.entrythingy.bind('<Key-Return>', self.print_contents)
-
- # Note that here is where we bind a completely different callback to
- # the same event. We pass "+" here to indicate that we wish to ADD
- # this callback to the list associated with this event type.
- # Not specifying "+" would simply override whatever callback was
- # defined on this event.
- self.entrythingy.bind('<Key-Return>', self.print_something_else, "+")
-
- def print_contents(self, event):
- print "hi. contents of entry is now ---->", self.entrythingy.get()
-
-
- def print_something_else(self, event):
- print "hi. Now doing something completely different"
-
-
-root = App()
-root.master.title("Foo")
-root.mainloop()
-
-
-
-# secret tip for experts: if you pass *any* non-false value as
-# the third parameter to bind(), Tkinter.py will accumulate
-# callbacks instead of overwriting. I use "+" here because that's
-# the Tk notation for getting this sort of behavior. The perfect GUI
-# interface would use a less obscure notation.
diff --git a/Demo/tkinter/matt/canvas-demo-simple.py b/Demo/tkinter/matt/canvas-demo-simple.py
deleted file mode 100644
index a01679a..0000000
--- a/Demo/tkinter/matt/canvas-demo-simple.py
+++ /dev/null
@@ -1,28 +0,0 @@
-from Tkinter import *
-
-# this program creates a canvas and puts a single polygon on the canvas
-
-class Test(Frame):
- def printit(self):
- print "hi"
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
- self.QUIT.pack(side=BOTTOM, fill=BOTH)
-
- self.draw = Canvas(self, width="5i", height="5i")
-
- # see the other demos for other ways of specifying coords for a polygon
- self.draw.create_rectangle(0, 0, "3i", "3i", fill="black")
-
- self.draw.pack(side=LEFT)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-
-test.mainloop()
diff --git a/Demo/tkinter/matt/canvas-gridding.py b/Demo/tkinter/matt/canvas-gridding.py
deleted file mode 100644
index 3c52b91..0000000
--- a/Demo/tkinter/matt/canvas-gridding.py
+++ /dev/null
@@ -1,61 +0,0 @@
-from Tkinter import *
-
-# this is the same as simple-demo-1.py, but uses
-# subclassing.
-# note that there is no explicit call to start Tk.
-# Tkinter is smart enough to start the system if it's not already going.
-
-class Test(Frame):
- def printit(self):
- print "hi"
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT',
- background='red',
- foreground='white',
- height=3,
- command=self.quit)
- self.QUIT.pack(side=BOTTOM, fill=BOTH)
-
- self.canvasObject = Canvas(self, width="5i", height="5i")
- self.canvasObject.pack(side=LEFT)
-
- def mouseDown(self, event):
- # canvas x and y take the screen coords from the event and translate
- # them into the coordinate system of the canvas object
- self.startx = self.canvasObject.canvasx(event.x, self.griddingSize)
- self.starty = self.canvasObject.canvasy(event.y, self.griddingSize)
-
- def mouseMotion(self, event):
- # canvas x and y take the screen coords from the event and translate
- # them into the coordinate system of the canvas object
- x = self.canvasObject.canvasx(event.x, self.griddingSize)
- y = self.canvasObject.canvasy(event.y, self.griddingSize)
-
- if (self.startx != event.x) and (self.starty != event.y) :
- self.canvasObject.delete(self.rubberbandBox)
- self.rubberbandBox = self.canvasObject.create_rectangle(
- self.startx, self.starty, x, y)
- # this flushes the output, making sure that
- # the rectangle makes it to the screen
- # before the next event is handled
- self.update_idletasks()
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
- # this is a "tagOrId" for the rectangle we draw on the canvas
- self.rubberbandBox = None
-
- # this is the size of the gridding squares
- self.griddingSize = 50
-
- Widget.bind(self.canvasObject, "<Button-1>", self.mouseDown)
- Widget.bind(self.canvasObject, "<Button1-Motion>", self.mouseMotion)
-
-
-test = Test()
-
-test.mainloop()
diff --git a/Demo/tkinter/matt/canvas-moving-or-creating.py b/Demo/tkinter/matt/canvas-moving-or-creating.py
deleted file mode 100644
index 5327c08..0000000
--- a/Demo/tkinter/matt/canvas-moving-or-creating.py
+++ /dev/null
@@ -1,62 +0,0 @@
-from Tkinter import *
-
-# this file demonstrates a more sophisticated movement --
-# move dots or create new ones if you click outside the dots
-
-class Test(Frame):
- ###################################################################
- ###### Event callbacks for THE CANVAS (not the stuff drawn on it)
- ###################################################################
- def mouseDown(self, event):
- # see if we're inside a dot. If we are, it
- # gets tagged as CURRENT for free by tk.
- if not event.widget.find_withtag(CURRENT):
- # there is no dot here, so we can make one,
- # and bind some interesting behavior to it.
- # ------
- # create a dot, and mark it as CURRENT
- fred = self.draw.create_oval(
- event.x - 10, event.y -10, event.x +10, event.y + 10,
- fill="green", tags=CURRENT)
-
- self.draw.tag_bind(fred, "<Any-Enter>", self.mouseEnter)
- self.draw.tag_bind(fred, "<Any-Leave>", self.mouseLeave)
-
- self.lastx = event.x
- self.lasty = event.y
-
- def mouseMove(self, event):
- self.draw.move(CURRENT, event.x - self.lastx, event.y - self.lasty)
- self.lastx = event.x
- self.lasty = event.y
-
- ###################################################################
- ###### Event callbacks for canvas ITEMS (stuff drawn on the canvas)
- ###################################################################
- def mouseEnter(self, event):
- # the CURRENT tag is applied to the object the cursor is over.
- # this happens automatically.
- self.draw.itemconfig(CURRENT, fill="red")
-
- def mouseLeave(self, event):
- # the CURRENT tag is applied to the object the cursor is over.
- # this happens automatically.
- self.draw.itemconfig(CURRENT, fill="blue")
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
- self.QUIT.pack(side=LEFT, fill=BOTH)
- self.draw = Canvas(self, width="5i", height="5i")
- self.draw.pack(side=LEFT)
-
- Widget.bind(self.draw, "<1>", self.mouseDown)
- Widget.bind(self.draw, "<B1-Motion>", self.mouseMove)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-test.mainloop()
diff --git a/Demo/tkinter/matt/canvas-moving-w-mouse.py b/Demo/tkinter/matt/canvas-moving-w-mouse.py
deleted file mode 100644
index 81785d8..0000000
--- a/Demo/tkinter/matt/canvas-moving-w-mouse.py
+++ /dev/null
@@ -1,55 +0,0 @@
-from Tkinter import *
-
-# this file demonstrates the movement of a single canvas item under mouse control
-
-class Test(Frame):
- ###################################################################
- ###### Event callbacks for THE CANVAS (not the stuff drawn on it)
- ###################################################################
- def mouseDown(self, event):
- # remember where the mouse went down
- self.lastx = event.x
- self.lasty = event.y
-
- def mouseMove(self, event):
- # whatever the mouse is over gets tagged as CURRENT for free by tk.
- self.draw.move(CURRENT, event.x - self.lastx, event.y - self.lasty)
- self.lastx = event.x
- self.lasty = event.y
-
- ###################################################################
- ###### Event callbacks for canvas ITEMS (stuff drawn on the canvas)
- ###################################################################
- def mouseEnter(self, event):
- # the CURRENT tag is applied to the object the cursor is over.
- # this happens automatically.
- self.draw.itemconfig(CURRENT, fill="red")
-
- def mouseLeave(self, event):
- # the CURRENT tag is applied to the object the cursor is over.
- # this happens automatically.
- self.draw.itemconfig(CURRENT, fill="blue")
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
- self.QUIT.pack(side=LEFT, fill=BOTH)
- self.draw = Canvas(self, width="5i", height="5i")
- self.draw.pack(side=LEFT)
-
- fred = self.draw.create_oval(0, 0, 20, 20,
- fill="green", tags="selected")
-
- self.draw.tag_bind(fred, "<Any-Enter>", self.mouseEnter)
- self.draw.tag_bind(fred, "<Any-Leave>", self.mouseLeave)
-
- Widget.bind(self.draw, "<1>", self.mouseDown)
- Widget.bind(self.draw, "<B1-Motion>", self.mouseMove)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-test.mainloop()
diff --git a/Demo/tkinter/matt/canvas-mult-item-sel.py b/Demo/tkinter/matt/canvas-mult-item-sel.py
deleted file mode 100644
index a4f267c..0000000
--- a/Demo/tkinter/matt/canvas-mult-item-sel.py
+++ /dev/null
@@ -1,78 +0,0 @@
-from Tkinter import *
-
-# allows moving dots with multiple selection.
-
-SELECTED_COLOR = "red"
-UNSELECTED_COLOR = "blue"
-
-class Test(Frame):
- ###################################################################
- ###### Event callbacks for THE CANVAS (not the stuff drawn on it)
- ###################################################################
- def mouseDown(self, event):
- # see if we're inside a dot. If we are, it
- # gets tagged as CURRENT for free by tk.
-
- if not event.widget.find_withtag(CURRENT):
- # we clicked outside of all dots on the canvas. unselect all.
-
- # re-color everything back to an unselected color
- self.draw.itemconfig("selected", fill=UNSELECTED_COLOR)
- # unselect everything
- self.draw.dtag("selected")
- else:
- # mark as "selected" the thing the cursor is under
- self.draw.addtag("selected", "withtag", CURRENT)
- # color it as selected
- self.draw.itemconfig("selected", fill=SELECTED_COLOR)
-
- self.lastx = event.x
- self.lasty = event.y
-
-
- def mouseMove(self, event):
- self.draw.move("selected", event.x - self.lastx, event.y - self.lasty)
- self.lastx = event.x
- self.lasty = event.y
-
- def makeNewDot(self):
- # create a dot, and mark it as current
- fred = self.draw.create_oval(0, 0, 20, 20,
- fill=SELECTED_COLOR, tags=CURRENT)
- # and make it selected
- self.draw.addtag("selected", "withtag", CURRENT)
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
-
- ################
- # make the canvas and bind some behavior to it
- ################
- self.draw = Canvas(self, width="5i", height="5i")
- Widget.bind(self.draw, "<1>", self.mouseDown)
- Widget.bind(self.draw, "<B1-Motion>", self.mouseMove)
-
- # and other things.....
- self.button = Button(self, text="make a new dot", foreground="blue",
- command=self.makeNewDot)
-
- message = ("%s dots are selected and can be dragged.\n"
- "%s are not selected.\n"
- "Click in a dot to select it.\n"
- "Click on empty space to deselect all dots."
- ) % (SELECTED_COLOR, UNSELECTED_COLOR)
- self.label = Message(self, width="5i", text=message)
-
- self.QUIT.pack(side=BOTTOM, fill=BOTH)
- self.label.pack(side=BOTTOM, fill=X, expand=1)
- self.button.pack(side=BOTTOM, fill=X)
- self.draw.pack(side=LEFT)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-test.mainloop()
diff --git a/Demo/tkinter/matt/canvas-reading-tag-info.py b/Demo/tkinter/matt/canvas-reading-tag-info.py
deleted file mode 100644
index f57ea18..0000000
--- a/Demo/tkinter/matt/canvas-reading-tag-info.py
+++ /dev/null
@@ -1,49 +0,0 @@
-from Tkinter import *
-
-
-class Test(Frame):
- def printit(self):
- print "hi"
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
- self.QUIT.pack(side=BOTTOM, fill=BOTH)
-
- self.drawing = Canvas(self, width="5i", height="5i")
-
- # make a shape
- pgon = self.drawing.create_polygon(
- 10, 10, 110, 10, 110, 110, 10 , 110,
- fill="red", tags=("weee", "foo", "groo"))
-
- # this is how you query an object for its attributes
- # config options FOR CANVAS ITEMS always come back in tuples of length 5.
- # 0 attribute name
- # 1 BLANK
- # 2 BLANK
- # 3 default value
- # 4 current value
- # the blank spots are for consistency with the config command that
- # is used for widgets. (remember, this is for ITEMS drawn
- # on a canvas widget, not widgets)
- option_value = self.drawing.itemconfig(pgon, "stipple")
- print "pgon's current stipple value is -->", option_value[4], "<--"
- option_value = self.drawing.itemconfig(pgon, "fill")
- print "pgon's current fill value is -->", option_value[4], "<--"
- print " when he is usually colored -->", option_value[3], "<--"
-
- ## here we print out all the tags associated with this object
- option_value = self.drawing.itemconfig(pgon, "tags")
- print "pgon's tags are", option_value[4]
-
- self.drawing.pack(side=LEFT)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-
-test.mainloop()
diff --git a/Demo/tkinter/matt/canvas-w-widget-draw-el.py b/Demo/tkinter/matt/canvas-w-widget-draw-el.py
deleted file mode 100644
index 5b26210..0000000
--- a/Demo/tkinter/matt/canvas-w-widget-draw-el.py
+++ /dev/null
@@ -1,36 +0,0 @@
-from Tkinter import *
-
-# this file demonstrates the creation of widgets as part of a canvas object
-
-class Test(Frame):
- def printhi(self):
- print "hi"
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
- self.QUIT.pack(side=BOTTOM, fill=BOTH)
-
- self.draw = Canvas(self, width="5i", height="5i")
-
- self.button = Button(self, text="this is a button",
- command=self.printhi)
-
- # note here the coords are given in pixels (form the
- # upper right and corner of the window, as usual for X)
- # but might just have well been given in inches or points or
- # whatever...use the "anchor" option to control what point of the
- # widget (in this case the button) gets mapped to the given x, y.
- # you can specify corners, edges, center, etc...
- self.draw.create_window(300, 300, window=self.button)
-
- self.draw.pack(side=LEFT)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-
-test.mainloop()
diff --git a/Demo/tkinter/matt/canvas-with-scrollbars.py b/Demo/tkinter/matt/canvas-with-scrollbars.py
deleted file mode 100644
index 81ef25a..0000000
--- a/Demo/tkinter/matt/canvas-with-scrollbars.py
+++ /dev/null
@@ -1,60 +0,0 @@
-from Tkinter import *
-
-# This example program creates a scroling canvas, and demonstrates
-# how to tie scrollbars and canvses together. The mechanism
-# is analogus for listboxes and other widgets with
-# "xscroll" and "yscroll" configuration options.
-
-class Test(Frame):
- def printit(self):
- print "hi"
-
- def createWidgets(self):
- self.question = Label(self, text="Can Find The BLUE Square??????")
- self.question.pack()
-
- self.QUIT = Button(self, text='QUIT', background='red',
- height=3, command=self.quit)
- self.QUIT.pack(side=BOTTOM, fill=BOTH)
- spacer = Frame(self, height="0.25i")
- spacer.pack(side=BOTTOM)
-
- # notice that the scroll region (20" x 20") is larger than
- # displayed size of the widget (5" x 5")
- self.draw = Canvas(self, width="5i", height="5i",
- background="white",
- scrollregion=(0, 0, "20i", "20i"))
-
- self.draw.scrollX = Scrollbar(self, orient=HORIZONTAL)
- self.draw.scrollY = Scrollbar(self, orient=VERTICAL)
-
- # now tie the three together. This is standard boilerplate text
- self.draw['xscrollcommand'] = self.draw.scrollX.set
- self.draw['yscrollcommand'] = self.draw.scrollY.set
- self.draw.scrollX['command'] = self.draw.xview
- self.draw.scrollY['command'] = self.draw.yview
-
- # draw something. Note that the first square
- # is visible, but you need to scroll to see the second one.
- self.draw.create_rectangle(0, 0, "3.5i", "3.5i", fill="black")
- self.draw.create_rectangle("10i", "10i", "13.5i", "13.5i", fill="blue")
-
- # pack 'em up
- self.draw.scrollX.pack(side=BOTTOM, fill=X)
- self.draw.scrollY.pack(side=RIGHT, fill=Y)
- self.draw.pack(side=LEFT)
-
-
- def scrollCanvasX(self, *args):
- print "scrolling", args
- print self.draw.scrollX.get()
-
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-
-test.mainloop()
diff --git a/Demo/tkinter/matt/dialog-box.py b/Demo/tkinter/matt/dialog-box.py
deleted file mode 100644
index dea8f39..0000000
--- a/Demo/tkinter/matt/dialog-box.py
+++ /dev/null
@@ -1,64 +0,0 @@
-from Tkinter import *
-from Dialog import Dialog
-
-# this shows how to create a new window with a button in it
-# that can create new windows
-
-class Test(Frame):
- def printit(self):
- print "hi"
-
- def makeWindow(self):
- """Create a top-level dialog with some buttons.
-
- This uses the Dialog class, which is a wrapper around the Tcl/Tk
- tk_dialog script. The function returns 0 if the user clicks 'yes'
- or 1 if the user clicks 'no'.
- """
- # the parameters to this call are as follows:
- d = Dialog(
- self, ## name of a toplevel window
- title="fred the dialog box",## title on the window
- text="click on a choice", ## message to appear in window
- bitmap="info", ## bitmap (if any) to appear;
- ## if none, use ""
- # legal values here are:
- # string what it looks like
- # ----------------------------------------------
- # error a circle with a slash through it
- # grey25 grey square
- # grey50 darker grey square
- # hourglass use for "wait.."
- # info a large, lower case "i"
- # questhead a human head with a "?" in it
- # question a large "?"
- # warning a large "!"
- # @fname X bitmap where fname is the path to the file
- #
- default=0, # the index of the default button choice.
- # hitting return selects this
- strings=("yes", "no"))
- # values of the 'strings' key are the labels for the
- # buttons that appear left to right in the dialog box
- return d.num
-
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
- self.QUIT.pack(side=LEFT, fill=BOTH)
-
- # a hello button
- self.hi_there = Button(self, text='Make a New Window',
- command=self.makeWindow)
- self.hi_there.pack(side=LEFT)
-
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.windownum = 0
- self.createWidgets()
-
-test = Test()
-test.mainloop()
diff --git a/Demo/tkinter/matt/entry-simple.py b/Demo/tkinter/matt/entry-simple.py
deleted file mode 100644
index 5146e6f..0000000
--- a/Demo/tkinter/matt/entry-simple.py
+++ /dev/null
@@ -1,24 +0,0 @@
-from Tkinter import *
-import string
-
-# This program shows how to use a simple type-in box
-
-class App(Frame):
- def __init__(self, master=None):
- Frame.__init__(self, master)
- self.pack()
-
- self.entrythingy = Entry()
- self.entrythingy.pack()
-
- # and here we get a callback when the user hits return. we could
- # make the key that triggers the callback anything we wanted to.
- # other typical options might be <Key-Tab> or <Key> (for anything)
- self.entrythingy.bind('<Key-Return>', self.print_contents)
-
- def print_contents(self, event):
- print "hi. contents of entry is now ---->", self.entrythingy.get()
-
-root = App()
-root.master.title("Foo")
-root.mainloop()
diff --git a/Demo/tkinter/matt/entry-with-shared-variable.py b/Demo/tkinter/matt/entry-with-shared-variable.py
deleted file mode 100644
index 2b76162..0000000
--- a/Demo/tkinter/matt/entry-with-shared-variable.py
+++ /dev/null
@@ -1,46 +0,0 @@
-from Tkinter import *
-import string
-
-# This program shows how to make a typein box shadow a program variable.
-
-class App(Frame):
- def __init__(self, master=None):
- Frame.__init__(self, master)
- self.pack()
-
- self.entrythingy = Entry(self)
- self.entrythingy.pack()
-
- self.button = Button(self, text="Uppercase The Entry",
- command=self.upper)
- self.button.pack()
-
- # here we have the text in the entry widget tied to a variable.
- # changes in the variable are echoed in the widget and vice versa.
- # Very handy.
- # there are other Variable types. See Tkinter.py for all
- # the other variable types that can be shadowed
- self.contents = StringVar()
- self.contents.set("this is a variable")
- self.entrythingy.config(textvariable=self.contents)
-
- # and here we get a callback when the user hits return. we could
- # make the key that triggers the callback anything we wanted to.
- # other typical options might be <Key-Tab> or <Key> (for anything)
- self.entrythingy.bind('<Key-Return>', self.print_contents)
-
- def upper(self):
- # notice here, we don't actually refer to the entry box.
- # we just operate on the string variable and we
- # because it's being looked at by the entry widget, changing
- # the variable changes the entry widget display automatically.
- # the strange get/set operators are clunky, true...
- str = string.upper(self.contents.get())
- self.contents.set(str)
-
- def print_contents(self, event):
- print "hi. contents of entry is now ---->", self.contents.get()
-
-root = App()
-root.master.title("Foo")
-root.mainloop()
diff --git a/Demo/tkinter/matt/killing-window-w-wm.py b/Demo/tkinter/matt/killing-window-w-wm.py
deleted file mode 100644
index 6a0e2fe..0000000
--- a/Demo/tkinter/matt/killing-window-w-wm.py
+++ /dev/null
@@ -1,42 +0,0 @@
-from Tkinter import *
-
-# This file shows how to trap the killing of a window
-# when the user uses window manager menus (typ. upper left hand corner
-# menu in the decoration border).
-
-
-### ******* this isn't really called -- read the comments
-def my_delete_callback():
- print "whoops -- tried to delete me!"
-
-class Test(Frame):
- def deathHandler(self, event):
- print self, "is now getting nuked. performing some save here...."
-
- def createWidgets(self):
- # a hello button
- self.hi_there = Button(self, text='Hello')
- self.hi_there.pack(side=LEFT)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
- ###
- ### PREVENT WM kills from happening
- ###
-
- # the docs would have you do this:
-
-# self.master.protocol("WM_DELETE_WINDOW", my_delete_callback)
-
- # unfortunately, some window managers will not send this request to a window.
- # the "protocol" function seems incapable of trapping these "aggressive" window kills.
- # this line of code catches everything, tho. The window is deleted, but you have a chance
- # of cleaning up first.
- self.bind_all("<Destroy>", self.deathHandler)
-
-
-test = Test()
-test.mainloop()
diff --git a/Demo/tkinter/matt/menu-all-types-of-entries.py b/Demo/tkinter/matt/menu-all-types-of-entries.py
deleted file mode 100644
index 69a21ca..0000000
--- a/Demo/tkinter/matt/menu-all-types-of-entries.py
+++ /dev/null
@@ -1,244 +0,0 @@
-from Tkinter import *
-
-# some vocabulary to keep from getting confused. This terminology
-# is something I cooked up for this file, but follows the man pages
-# pretty closely
-#
-#
-#
-# This is a MENUBUTTON
-# V
-# +-------------+
-# | |
-#
-# +------------++------------++------------+
-# | || || |
-# | File || Edit || Options | <-------- the MENUBAR
-# | || || |
-# +------------++------------++------------+
-# | New... |
-# | Open... |
-# | Print |
-# | | <-------- This is a MENU. The lines of text in the menu are
-# | | MENU ENTRIES
-# | +---------------+
-# | Open Files > | file1 |
-# | | file2 |
-# | | another file | <------ this cascading part is also a MENU
-# +----------------| |
-# | |
-# | |
-# | |
-# +---------------+
-
-
-
-# some miscellaneous callbacks
-def new_file():
- print "opening new file"
-
-def open_file():
- print "opening OLD file"
-
-def print_something():
- print "picked a menu item"
-
-
-
-anchovies = 0
-
-def print_anchovies():
- global anchovies
- anchovies = not anchovies
- print "anchovies?", anchovies
-
-def makeCommandMenu():
- # make menu button
- Command_button = Menubutton(mBar, text='Simple Button Commands',
- underline=0)
- Command_button.pack(side=LEFT, padx="2m")
-
- # make the pulldown part of the File menu. The parameter passed is the master.
- # we attach it to the button as a python attribute called "menu" by convention.
- # hopefully this isn't too confusing...
- Command_button.menu = Menu(Command_button)
-
- # just to be cute, let's disable the undo option:
- Command_button.menu.add_command(label="Undo")
- # undo is the 0th entry...
- Command_button.menu.entryconfig(0, state=DISABLED)
-
- Command_button.menu.add_command(label='New...', underline=0,
- command=new_file)
- Command_button.menu.add_command(label='Open...', underline=0,
- command=open_file)
- Command_button.menu.add_command(label='Different Font', underline=0,
- font='-*-helvetica-*-r-*-*-*-180-*-*-*-*-*-*',
- command=print_something)
-
- # we can make bitmaps be menu entries too. File format is X11 bitmap.
- # if you use XV, save it under X11 bitmap format. duh-uh.,..
- Command_button.menu.add_command(
- bitmap="info")
- #bitmap='@/home/mjc4y/dilbert/project.status.is.doomed.last.panel.bm')
-
- # this is just a line
- Command_button.menu.add('separator')
-
- # change the color
- Command_button.menu.add_command(label='Quit', underline=0,
- background='red',
- activebackground='green',
- command=Command_button.quit)
-
- # set up a pointer from the file menubutton back to the file menu
- Command_button['menu'] = Command_button.menu
-
- return Command_button
-
-
-
-def makeCascadeMenu():
- # make menu button
- Cascade_button = Menubutton(mBar, text='Cascading Menus', underline=0)
- Cascade_button.pack(side=LEFT, padx="2m")
-
- # the primary pulldown
- Cascade_button.menu = Menu(Cascade_button)
-
- # this is the menu that cascades from the primary pulldown....
- Cascade_button.menu.choices = Menu(Cascade_button.menu)
-
- # ...and this is a menu that cascades from that.
- Cascade_button.menu.choices.weirdones = Menu(Cascade_button.menu.choices)
-
- # then you define the menus from the deepest level on up.
- Cascade_button.menu.choices.weirdones.add_command(label='avacado')
- Cascade_button.menu.choices.weirdones.add_command(label='belgian endive')
- Cascade_button.menu.choices.weirdones.add_command(label='beefaroni')
-
- # definition of the menu one level up...
- Cascade_button.menu.choices.add_command(label='Chocolate')
- Cascade_button.menu.choices.add_command(label='Vanilla')
- Cascade_button.menu.choices.add_command(label='TuttiFruiti')
- Cascade_button.menu.choices.add_command(label='WopBopaLoopBapABopBamBoom')
- Cascade_button.menu.choices.add_command(label='Rocky Road')
- Cascade_button.menu.choices.add_command(label='BubbleGum')
- Cascade_button.menu.choices.add_cascade(
- label='Weird Flavors',
- menu=Cascade_button.menu.choices.weirdones)
-
- # and finally, the definition for the top level
- Cascade_button.menu.add_cascade(label='more choices',
- menu=Cascade_button.menu.choices)
-
- Cascade_button['menu'] = Cascade_button.menu
-
- return Cascade_button
-
-def makeCheckbuttonMenu():
- global fred
- # make menu button
- Checkbutton_button = Menubutton(mBar, text='Checkbutton Menus',
- underline=0)
- Checkbutton_button.pack(side=LEFT, padx='2m')
-
- # the primary pulldown
- Checkbutton_button.menu = Menu(Checkbutton_button)
-
- # and all the check buttons. Note that the "variable" "onvalue" and "offvalue" options
- # are not supported correctly at present. You have to do all your application
- # work through the calback.
- Checkbutton_button.menu.add_checkbutton(label='Pepperoni')
- Checkbutton_button.menu.add_checkbutton(label='Sausage')
- Checkbutton_button.menu.add_checkbutton(label='Extra Cheese')
-
- # so here's a callback
- Checkbutton_button.menu.add_checkbutton(label='Anchovy',
- command=print_anchovies)
-
- # and start with anchovies selected to be on. Do this by
- # calling invoke on this menu option. To refer to the "anchovy" menu
- # entry we need to know it's index. To do this, we use the index method
- # which takes arguments of several forms:
- #
- # argument what it does
- # -----------------------------------
- # a number -- this is useless.
- # "last" -- last option in the menu
- # "none" -- used with the activate command. see the man page on menus
- # "active" -- the currently active menu option. A menu option is made active
- # with the 'activate' method
- # "@number" -- where 'number' is an integer and is treated like a y coordinate in pixels
- # string pattern -- this is the option used below, and attempts to match "labels" using the
- # rules of Tcl_StringMatch
- Checkbutton_button.menu.invoke(Checkbutton_button.menu.index('Anchovy'))
-
- # set up a pointer from the file menubutton back to the file menu
- Checkbutton_button['menu'] = Checkbutton_button.menu
-
- return Checkbutton_button
-
-
-def makeRadiobuttonMenu():
- # make menu button
- Radiobutton_button = Menubutton(mBar, text='Radiobutton Menus',
- underline=0)
- Radiobutton_button.pack(side=LEFT, padx='2m')
-
- # the primary pulldown
- Radiobutton_button.menu = Menu(Radiobutton_button)
-
- # and all the Radio buttons. Note that the "variable" "onvalue" and "offvalue" options
- # are not supported correctly at present. You have to do all your application
- # work through the calback.
- Radiobutton_button.menu.add_radiobutton(label='Republican')
- Radiobutton_button.menu.add_radiobutton(label='Democrat')
- Radiobutton_button.menu.add_radiobutton(label='Libertarian')
- Radiobutton_button.menu.add_radiobutton(label='Commie')
- Radiobutton_button.menu.add_radiobutton(label='Facist')
- Radiobutton_button.menu.add_radiobutton(label='Labor Party')
- Radiobutton_button.menu.add_radiobutton(label='Torie')
- Radiobutton_button.menu.add_radiobutton(label='Independent')
- Radiobutton_button.menu.add_radiobutton(label='Anarchist')
- Radiobutton_button.menu.add_radiobutton(label='No Opinion')
-
- # set up a pointer from the file menubutton back to the file menu
- Radiobutton_button['menu'] = Radiobutton_button.menu
-
- return Radiobutton_button
-
-
-def makeDisabledMenu():
- Dummy_button = Menubutton(mBar, text='Dead Menu', underline=0)
- Dummy_button.pack(side=LEFT, padx='2m')
-
- # this is the standard way of turning off a whole menu
- Dummy_button["state"] = DISABLED
- return Dummy_button
-
-
-#################################################
-#### Main starts here ...
-root = Tk()
-
-
-# make a menu bar
-mBar = Frame(root, relief=RAISED, borderwidth=2)
-mBar.pack(fill=X)
-
-Command_button = makeCommandMenu()
-Cascade_button = makeCascadeMenu()
-Checkbutton_button = makeCheckbuttonMenu()
-Radiobutton_button = makeRadiobuttonMenu()
-NoMenu = makeDisabledMenu()
-
-# finally, install the buttons in the menu bar.
-# This allows for scanning from one menubutton to the next.
-mBar.tk_menuBar(Command_button, Cascade_button, Checkbutton_button, Radiobutton_button, NoMenu)
-
-
-root.title('menu demo')
-root.iconname('menu demo')
-
-root.mainloop()
diff --git a/Demo/tkinter/matt/menu-simple.py b/Demo/tkinter/matt/menu-simple.py
deleted file mode 100644
index b71c514..0000000
--- a/Demo/tkinter/matt/menu-simple.py
+++ /dev/null
@@ -1,112 +0,0 @@
-from Tkinter import *
-
-# some vocabulary to keep from getting confused. This terminology
-# is something I cooked up for this file, but follows the man pages
-# pretty closely
-#
-#
-#
-# This is a MENUBUTTON
-# V
-# +-------------+
-# | |
-#
-# +------------++------------++------------+
-# | || || |
-# | File || Edit || Options | <-------- the MENUBAR
-# | || || |
-# +------------++------------++------------+
-# | New... |
-# | Open... |
-# | Print |
-# | | <------ This is a MENU. The lines of text in the menu are
-# | | MENU ENTRIES
-# | +---------------+
-# | Open Files > | file1 |
-# | | file2 |
-# | | another file | <------ this cascading part is also a MENU
-# +----------------| |
-# | |
-# | |
-# | |
-# +---------------+
-
-
-
-def new_file():
- print "opening new file"
-
-
-def open_file():
- print "opening OLD file"
-
-
-def makeFileMenu():
- # make menu button : "File"
- File_button = Menubutton(mBar, text='File', underline=0)
- File_button.pack(side=LEFT, padx="1m")
- File_button.menu = Menu(File_button)
-
- # add an item. The first param is a menu entry type,
- # must be one of: "cascade", "checkbutton", "command", "radiobutton", "separator"
- # see menu-demo-2.py for examples of use
- File_button.menu.add_command(label='New...', underline=0,
- command=new_file)
-
-
- File_button.menu.add_command(label='Open...', underline=0,
- command=open_file)
-
- File_button.menu.add_command(label='Quit', underline=0,
- command='exit')
-
- # set up a pointer from the file menubutton back to the file menu
- File_button['menu'] = File_button.menu
-
- return File_button
-
-
-
-def makeEditMenu():
- Edit_button = Menubutton(mBar, text='Edit', underline=0)
- Edit_button.pack(side=LEFT, padx="1m")
- Edit_button.menu = Menu(Edit_button)
-
- # just to be cute, let's disable the undo option:
- Edit_button.menu.add('command', label="Undo")
- # Since the tear-off bar is the 0th entry,
- # undo is the 1st entry...
- Edit_button.menu.entryconfig(1, state=DISABLED)
-
- # and these are just for show. No "command" callbacks attached.
- Edit_button.menu.add_command(label="Cut")
- Edit_button.menu.add_command(label="Copy")
- Edit_button.menu.add_command(label="Paste")
-
- # set up a pointer from the file menubutton back to the file menu
- Edit_button['menu'] = Edit_button.menu
-
- return Edit_button
-
-
-#################################################
-
-#### Main starts here ...
-root = Tk()
-
-
-# make a menu bar
-mBar = Frame(root, relief=RAISED, borderwidth=2)
-mBar.pack(fill=X)
-
-File_button = makeFileMenu()
-Edit_button = makeEditMenu()
-
-# finally, install the buttons in the menu bar.
-# This allows for scanning from one menubutton to the next.
-mBar.tk_menuBar(File_button, Edit_button)
-
-root.title('menu demo')
-root.iconname('packer')
-
-root.mainloop()
diff --git a/Demo/tkinter/matt/not-what-you-might-think-1.py b/Demo/tkinter/matt/not-what-you-might-think-1.py
deleted file mode 100644
index 7b20f02..0000000
--- a/Demo/tkinter/matt/not-what-you-might-think-1.py
+++ /dev/null
@@ -1,28 +0,0 @@
-from Tkinter import *
-
-
-class Test(Frame):
- def createWidgets(self):
-
- self.Gpanel = Frame(self, width='1i', height='1i',
- background='green')
- self.Gpanel.pack(side=LEFT)
-
- # a QUIT button
- self.Gpanel.QUIT = Button(self.Gpanel, text='QUIT',
- foreground='red',
- command=self.quit)
- self.Gpanel.QUIT.pack(side=LEFT)
-
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-
-test.master.title('packer demo')
-test.master.iconname('packer')
-
-test.mainloop()
diff --git a/Demo/tkinter/matt/not-what-you-might-think-2.py b/Demo/tkinter/matt/not-what-you-might-think-2.py
deleted file mode 100644
index 9ee197c..0000000
--- a/Demo/tkinter/matt/not-what-you-might-think-2.py
+++ /dev/null
@@ -1,30 +0,0 @@
-from Tkinter import *
-
-
-class Test(Frame):
- def createWidgets(self):
-
- self.Gpanel = Frame(self, width='1i', height='1i',
- background='green')
-
- # this line turns off the recalculation of geometry by masters.
- self.Gpanel.propagate(0)
-
- self.Gpanel.pack(side=LEFT)
-
- # a QUIT button
- self.Gpanel.QUIT = Button(self.Gpanel, text='QUIT', foreground='red',
- command=self.quit)
- self.Gpanel.QUIT.pack(side=LEFT)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-
-test.master.title('packer demo')
-test.master.iconname('packer')
-
-test.mainloop()
diff --git a/Demo/tkinter/matt/packer-and-placer-together.py b/Demo/tkinter/matt/packer-and-placer-together.py
deleted file mode 100644
index 184d56b..0000000
--- a/Demo/tkinter/matt/packer-and-placer-together.py
+++ /dev/null
@@ -1,41 +0,0 @@
-from Tkinter import *
-
-# This is a program that tests the placer geom manager in conjunction with
-# the packer. The background (green) is packed, while the widget inside is placed
-
-
-def do_motion(event):
- app.button.place(x=event.x, y=event.y)
-
-def dothis():
- print 'calling me!'
-
-def createWidgets(top):
- # make a frame. Note that the widget is 200 x 200
- # and the window containing is 400x400. We do this
- # simply to show that this is possible. The rest of the
- # area is inaccesssible.
- f = Frame(top, width=200, height=200, background='green')
-
- # note that we use a different manager here.
- # This way, the top level frame widget resizes when the
- # application window does.
- f.pack(fill=BOTH, expand=1)
-
- # now make a button
- f.button = Button(f, foreground='red', text='amazing', command=dothis)
-
- # and place it so that the nw corner is
- # 1/2 way along the top X edge of its' parent
- f.button.place(relx=0.5, rely=0.0, anchor=NW)
-
- # allow the user to move the button SUIT-style.
- f.bind('<Control-Shift-Motion>', do_motion)
-
- return f
-
-root = Tk()
-app = createWidgets(root)
-root.geometry("400x400")
-root.maxsize(1000, 1000)
-root.mainloop()
diff --git a/Demo/tkinter/matt/packer-simple.py b/Demo/tkinter/matt/packer-simple.py
deleted file mode 100644
index f55f1be..0000000
--- a/Demo/tkinter/matt/packer-simple.py
+++ /dev/null
@@ -1,32 +0,0 @@
-from Tkinter import *
-
-
-class Test(Frame):
- def printit(self):
- print self.hi_there["command"]
-
- def createWidgets(self):
- # a hello button
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
- self.QUIT.pack(side=LEFT, fill=BOTH)
-
- self.hi_there = Button(self, text='Hello',
- command=self.printit)
- self.hi_there.pack(side=LEFT)
-
- # note how Packer defaults to side=TOP
-
- self.guy2 = Button(self, text='button 2')
- self.guy2.pack()
-
- self.guy3 = Button(self, text='button 3')
- self.guy3.pack()
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-test.mainloop()
diff --git a/Demo/tkinter/matt/placer-simple.py b/Demo/tkinter/matt/placer-simple.py
deleted file mode 100644
index 30d9e9e..0000000
--- a/Demo/tkinter/matt/placer-simple.py
+++ /dev/null
@@ -1,39 +0,0 @@
-from Tkinter import *
-
-# This is a program that tests the placer geom manager
-
-def do_motion(event):
- app.button.place(x=event.x, y=event.y)
-
-def dothis():
- print 'calling me!'
-
-def createWidgets(top):
- # make a frame. Note that the widget is 200 x 200
- # and the window containing is 400x400. We do this
- # simply to show that this is possible. The rest of the
- # area is inaccesssible.
- f = Frame(top, width=200, height=200, background='green')
-
- # place it so the upper left hand corner of
- # the frame is in the upper left corner of
- # the parent
- f.place(relx=0.0, rely=0.0)
-
- # now make a button
- f.button = Button(f, foreground='red', text='amazing', command=dothis)
-
- # and place it so that the nw corner is
- # 1/2 way along the top X edge of its' parent
- f.button.place(relx=0.5, rely=0.0, anchor=NW)
-
- # allow the user to move the button SUIT-style.
- f.bind('<Control-Shift-Motion>', do_motion)
-
- return f
-
-root = Tk()
-app = createWidgets(root)
-root.geometry("400x400")
-root.maxsize(1000, 1000)
-root.mainloop()
diff --git a/Demo/tkinter/matt/pong-demo-1.py b/Demo/tkinter/matt/pong-demo-1.py
deleted file mode 100644
index 7fcf800..0000000
--- a/Demo/tkinter/matt/pong-demo-1.py
+++ /dev/null
@@ -1,54 +0,0 @@
-from Tkinter import *
-
-import string
-
-
-class Pong(Frame):
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
- self.QUIT.pack(side=LEFT, fill=BOTH)
-
- ## The playing field
- self.draw = Canvas(self, width="5i", height="5i")
-
- ## The speed control for the ball
- self.speed = Scale(self, orient=HORIZONTAL, label="ball speed",
- from_=-100, to=100)
-
- self.speed.pack(side=BOTTOM, fill=X)
-
- # The ball
- self.ball = self.draw.create_oval("0i", "0i", "0.10i", "0.10i",
- fill="red")
- self.x = 0.05
- self.y = 0.05
- self.velocity_x = 0.3
- self.velocity_y = 0.5
-
- self.draw.pack(side=LEFT)
-
- def moveBall(self, *args):
- if (self.x > 5.0) or (self.x < 0.0):
- self.velocity_x = -1.0 * self.velocity_x
- if (self.y > 5.0) or (self.y < 0.0):
- self.velocity_y = -1.0 * self.velocity_y
-
- deltax = (self.velocity_x * self.speed.get() / 100.0)
- deltay = (self.velocity_y * self.speed.get() / 100.0)
- self.x = self.x + deltax
- self.y = self.y + deltay
-
- self.draw.move(self.ball, "%ri" % deltax, "%ri" % deltay)
- self.after(10, self.moveBall)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
- self.after(10, self.moveBall)
-
-
-game = Pong()
-
-game.mainloop()
diff --git a/Demo/tkinter/matt/printing-coords-of-items.py b/Demo/tkinter/matt/printing-coords-of-items.py
deleted file mode 100644
index a37733d..0000000
--- a/Demo/tkinter/matt/printing-coords-of-items.py
+++ /dev/null
@@ -1,61 +0,0 @@
-from Tkinter import *
-
-# this file demonstrates the creation of widgets as part of a canvas object
-
-class Test(Frame):
- ###################################################################
- ###### Event callbacks for THE CANVAS (not the stuff drawn on it)
- ###################################################################
- def mouseDown(self, event):
- # see if we're inside a dot. If we are, it
- # gets tagged as CURRENT for free by tk.
-
- if not event.widget.find_withtag(CURRENT):
- # there is no dot here, so we can make one,
- # and bind some interesting behavior to it.
- # ------
- # create a dot, and mark it as current
- fred = self.draw.create_oval(
- event.x - 10, event.y -10, event.x +10, event.y + 10,
- fill="green")
- self.draw.tag_bind(fred, "<Enter>", self.mouseEnter)
- self.draw.tag_bind(fred, "<Leave>", self.mouseLeave)
- self.lastx = event.x
- self.lasty = event.y
-
- def mouseMove(self, event):
- self.draw.move(CURRENT, event.x - self.lastx, event.y - self.lasty)
- self.lastx = event.x
- self.lasty = event.y
-
- ###################################################################
- ###### Event callbacks for canvas ITEMS (stuff drawn on the canvas)
- ###################################################################
- def mouseEnter(self, event):
- # the "current" tag is applied to the object the cursor is over.
- # this happens automatically.
- self.draw.itemconfig(CURRENT, fill="red")
- print self.draw.coords(CURRENT)
-
- def mouseLeave(self, event):
- # the "current" tag is applied to the object the cursor is over.
- # this happens automatically.
- self.draw.itemconfig(CURRENT, fill="blue")
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
- self.QUIT.pack(side=LEFT, fill=BOTH)
- self.draw = Canvas(self, width="5i", height="5i")
- self.draw.pack(side=LEFT)
-
- Widget.bind(self.draw, "<1>", self.mouseDown)
- Widget.bind(self.draw, "<B1-Motion>", self.mouseMove)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-test.mainloop()
diff --git a/Demo/tkinter/matt/radiobutton-simple.py b/Demo/tkinter/matt/radiobutton-simple.py
deleted file mode 100644
index e9d6afe..0000000
--- a/Demo/tkinter/matt/radiobutton-simple.py
+++ /dev/null
@@ -1,62 +0,0 @@
-from Tkinter import *
-
-# This is a demo program that shows how to
-# create radio buttons and how to get other widgets to
-# share the information in a radio button.
-#
-# There are other ways of doing this too, but
-# the "variable" option of radiobuttons seems to be the easiest.
-#
-# note how each button has a value it sets the variable to as it gets hit.
-
-
-class Test(Frame):
- def printit(self):
- print "hi"
-
- def createWidgets(self):
-
- self.flavor = StringVar()
- self.flavor.set("chocolate")
-
- self.radioframe = Frame(self)
- self.radioframe.pack()
-
- # 'text' is the label
- # 'variable' is the name of the variable that all these radio buttons share
- # 'value' is the value this variable takes on when the radio button is selected
- # 'anchor' makes the text appear left justified (default is centered. ick)
- self.radioframe.choc = Radiobutton(
- self.radioframe, text="Chocolate Flavor",
- variable=self.flavor, value="chocolate",
- anchor=W)
- self.radioframe.choc.pack(fill=X)
-
- self.radioframe.straw = Radiobutton(
- self.radioframe, text="Strawberry Flavor",
- variable=self.flavor, value="strawberry",
- anchor=W)
- self.radioframe.straw.pack(fill=X)
-
- self.radioframe.lemon = Radiobutton(
- self.radioframe, text="Lemon Flavor",
- variable=self.flavor, value="lemon",
- anchor=W)
- self.radioframe.lemon.pack(fill=X)
-
- # this is a text entry that lets you type in the name of a flavor too.
- self.entry = Entry(self, textvariable=self.flavor)
- self.entry.pack(fill=X)
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
- self.QUIT.pack(side=BOTTOM, fill=BOTH)
-
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-
-test.mainloop()
diff --git a/Demo/tkinter/matt/rubber-band-box-demo-1.py b/Demo/tkinter/matt/rubber-band-box-demo-1.py
deleted file mode 100644
index b00518e..0000000
--- a/Demo/tkinter/matt/rubber-band-box-demo-1.py
+++ /dev/null
@@ -1,58 +0,0 @@
-from Tkinter import *
-
-class Test(Frame):
- def printit(self):
- print "hi"
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT',
- background='red',
- foreground='white',
- height=3,
- command=self.quit)
- self.QUIT.pack(side=BOTTOM, fill=BOTH)
-
- self.canvasObject = Canvas(self, width="5i", height="5i")
- self.canvasObject.pack(side=LEFT)
-
- def mouseDown(self, event):
- # canvas x and y take the screen coords from the event and translate
- # them into the coordinate system of the canvas object
- self.startx = self.canvasObject.canvasx(event.x)
- self.starty = self.canvasObject.canvasy(event.y)
-
- def mouseMotion(self, event):
- # canvas x and y take the screen coords from the event and translate
- # them into the coordinate system of the canvas object
- x = self.canvasObject.canvasx(event.x)
- y = self.canvasObject.canvasy(event.y)
-
- if (self.startx != event.x) and (self.starty != event.y) :
- self.canvasObject.delete(self.rubberbandBox)
- self.rubberbandBox = self.canvasObject.create_rectangle(
- self.startx, self.starty, x, y)
- # this flushes the output, making sure that
- # the rectangle makes it to the screen
- # before the next event is handled
- self.update_idletasks()
-
- def mouseUp(self, event):
- self.canvasObject.delete(self.rubberbandBox)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
- # this is a "tagOrId" for the rectangle we draw on the canvas
- self.rubberbandBox = None
-
- # and the bindings that make it work..
- Widget.bind(self.canvasObject, "<Button-1>", self.mouseDown)
- Widget.bind(self.canvasObject, "<Button1-Motion>", self.mouseMotion)
- Widget.bind(self.canvasObject, "<Button1-ButtonRelease>", self.mouseUp)
-
-
-test = Test()
-
-test.mainloop()
diff --git a/Demo/tkinter/matt/rubber-line-demo-1.py b/Demo/tkinter/matt/rubber-line-demo-1.py
deleted file mode 100644
index 59b8bd9..0000000
--- a/Demo/tkinter/matt/rubber-line-demo-1.py
+++ /dev/null
@@ -1,51 +0,0 @@
-from Tkinter import *
-
-class Test(Frame):
- def printit(self):
- print "hi"
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT',
- background='red',
- foreground='white',
- height=3,
- command=self.quit)
- self.QUIT.pack(side=BOTTOM, fill=BOTH)
-
- self.canvasObject = Canvas(self, width="5i", height="5i")
- self.canvasObject.pack(side=LEFT)
-
- def mouseDown(self, event):
- # canvas x and y take the screen coords from the event and translate
- # them into the coordinate system of the canvas object
- self.startx = self.canvasObject.canvasx(event.x)
- self.starty = self.canvasObject.canvasy(event.y)
-
- def mouseMotion(self, event):
- # canvas x and y take the screen coords from the event and translate
- # them into the coordinate system of the canvas object
- x = self.canvasObject.canvasx(event.x)
- y = self.canvasObject.canvasy(event.y)
-
- if (self.startx != event.x) and (self.starty != event.y) :
- self.canvasObject.delete(self.rubberbandLine)
- self.rubberbandLine = self.canvasObject.create_line(
- self.startx, self.starty, x, y)
- # this flushes the output, making sure that
- # the rectangle makes it to the screen
- # before the next event is handled
- self.update_idletasks()
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
- # this is a "tagOrId" for the rectangle we draw on the canvas
- self.rubberbandLine = None
- Widget.bind(self.canvasObject, "<Button-1>", self.mouseDown)
- Widget.bind(self.canvasObject, "<Button1-Motion>", self.mouseMotion)
-
-
-test = Test()
-
-test.mainloop()
diff --git a/Demo/tkinter/matt/slider-demo-1.py b/Demo/tkinter/matt/slider-demo-1.py
deleted file mode 100644
index db6114b..0000000
--- a/Demo/tkinter/matt/slider-demo-1.py
+++ /dev/null
@@ -1,36 +0,0 @@
-from Tkinter import *
-
-# shows how to make a slider, set and get its value under program control
-
-
-class Test(Frame):
- def print_value(self, val):
- print "slider now at", val
-
- def reset(self):
- self.slider.set(0)
-
- def createWidgets(self):
- self.slider = Scale(self, from_=0, to=100,
- orient=HORIZONTAL,
- length="3i",
- label="happy slider",
- command=self.print_value)
-
- self.reset = Button(self, text='reset slider',
- command=self.reset)
-
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
-
- self.slider.pack(side=LEFT)
- self.reset.pack(side=LEFT)
- self.QUIT.pack(side=LEFT, fill=BOTH)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-test.mainloop()
diff --git a/Demo/tkinter/matt/subclass-existing-widgets.py b/Demo/tkinter/matt/subclass-existing-widgets.py
deleted file mode 100644
index 0e08f92..0000000
--- a/Demo/tkinter/matt/subclass-existing-widgets.py
+++ /dev/null
@@ -1,28 +0,0 @@
-from Tkinter import *
-
-# This is a program that makes a simple two button application
-
-
-class New_Button(Button):
- def callback(self):
- print self.counter
- self.counter = self.counter + 1
-
-def createWidgets(top):
- f = Frame(top)
- f.pack()
- f.QUIT = Button(f, text='QUIT', foreground='red', command=top.quit)
-
- f.QUIT.pack(side=LEFT, fill=BOTH)
-
- # a hello button
- f.hi_there = New_Button(f, text='Hello')
- # we do this on a different line because we need to reference f.hi_there
- f.hi_there.config(command=f.hi_there.callback)
- f.hi_there.pack(side=LEFT)
- f.hi_there.counter = 43
-
-
-root = Tk()
-createWidgets(root)
-root.mainloop()
diff --git a/Demo/tkinter/matt/two-radio-groups.py b/Demo/tkinter/matt/two-radio-groups.py
deleted file mode 100644
index 9fd8f4f..0000000
--- a/Demo/tkinter/matt/two-radio-groups.py
+++ /dev/null
@@ -1,110 +0,0 @@
-from Tkinter import *
-
-# The way to think about this is that each radio button menu
-# controls a different variable -- clicking on one of the
-# mutually exclusive choices in a radiobutton assigns some value
-# to an application variable you provide. When you define a
-# radiobutton menu choice, you have the option of specifying the
-# name of a varaible and value to assign to that variable when
-# that choice is selected. This clever mechanism relieves you,
-# the programmer, from having to write a dumb callback that
-# probably wouldn't have done anything more than an assignment
-# anyway. The Tkinter options for this follow their Tk
-# counterparts:
-# {"variable" : my_flavor_variable, "value" : "strawberry"}
-# where my_flavor_variable is an instance of one of the
-# subclasses of Variable, provided in Tkinter.py (there is
-# StringVar(), IntVar(), DoubleVar() and BooleanVar() to choose
-# from)
-
-
-
-def makePoliticalParties(var):
- # make menu button
- Radiobutton_button = Menubutton(mBar, text='Political Party',
- underline=0)
- Radiobutton_button.pack(side=LEFT, padx='2m')
-
- # the primary pulldown
- Radiobutton_button.menu = Menu(Radiobutton_button)
-
- Radiobutton_button.menu.add_radiobutton(label='Republican',
- variable=var, value=1)
-
- Radiobutton_button.menu.add('radiobutton', {'label': 'Democrat',
- 'variable' : var,
- 'value' : 2})
-
- Radiobutton_button.menu.add('radiobutton', {'label': 'Libertarian',
- 'variable' : var,
- 'value' : 3})
-
- var.set(2)
-
- # set up a pointer from the file menubutton back to the file menu
- Radiobutton_button['menu'] = Radiobutton_button.menu
-
- return Radiobutton_button
-
-
-def makeFlavors(var):
- # make menu button
- Radiobutton_button = Menubutton(mBar, text='Flavors',
- underline=0)
- Radiobutton_button.pack(side=LEFT, padx='2m')
-
- # the primary pulldown
- Radiobutton_button.menu = Menu(Radiobutton_button)
-
- Radiobutton_button.menu.add_radiobutton(label='Strawberry',
- variable=var, value='Strawberry')
-
- Radiobutton_button.menu.add_radiobutton(label='Chocolate',
- variable=var, value='Chocolate')
-
- Radiobutton_button.menu.add_radiobutton(label='Rocky Road',
- variable=var, value='Rocky Road')
-
- # choose a default
- var.set("Chocolate")
-
- # set up a pointer from the file menubutton back to the file menu
- Radiobutton_button['menu'] = Radiobutton_button.menu
-
- return Radiobutton_button
-
-
-def printStuff():
- print "party is", party.get()
- print "flavor is", flavor.get()
- print
-
-#################################################
-#### Main starts here ...
-root = Tk()
-
-
-# make a menu bar
-mBar = Frame(root, relief=RAISED, borderwidth=2)
-mBar.pack(fill=X)
-
-# make two application variables,
-# one to control each radio button set
-party = IntVar()
-flavor = StringVar()
-
-Radiobutton_button = makePoliticalParties(party)
-Radiobutton_button2 = makeFlavors(flavor)
-
-# finally, install the buttons in the menu bar.
-# This allows for scanning from one menubutton to the next.
-mBar.tk_menuBar(Radiobutton_button, Radiobutton_button2)
-
-b = Button(root, text="print party and flavor", foreground="red",
- command=printStuff)
-b.pack(side=TOP)
-
-root.title('menu demo')
-root.iconname('menu demo')
-
-root.mainloop()
diff --git a/Demo/tkinter/matt/window-creation-more.py b/Demo/tkinter/matt/window-creation-more.py
deleted file mode 100644
index eb0eb6f..0000000
--- a/Demo/tkinter/matt/window-creation-more.py
+++ /dev/null
@@ -1,35 +0,0 @@
-from Tkinter import *
-
-# this shows how to create a new window with a button in it
-# that can create new windows
-
-class Test(Frame):
- def printit(self):
- print "hi"
-
- def makeWindow(self):
- fred = Toplevel()
- fred.label = Button(fred,
- text="This is window number %d." % self.windownum,
- command=self.makeWindow)
- fred.label.pack()
- self.windownum = self.windownum + 1
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
- self.QUIT.pack(side=LEFT, fill=BOTH)
-
- # a hello button
- self.hi_there = Button(self, text='Make a New Window',
- command=self.makeWindow)
- self.hi_there.pack(side=LEFT)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.windownum = 0
- self.createWidgets()
-
-test = Test()
-test.mainloop()
diff --git a/Demo/tkinter/matt/window-creation-simple.py b/Demo/tkinter/matt/window-creation-simple.py
deleted file mode 100644
index c990ed9..0000000
--- a/Demo/tkinter/matt/window-creation-simple.py
+++ /dev/null
@@ -1,31 +0,0 @@
-from Tkinter import *
-
-# this shows how to spawn off new windows at a button press
-
-class Test(Frame):
- def printit(self):
- print "hi"
-
- def makeWindow(self):
- fred = Toplevel()
- fred.label = Label(fred, text="Here's a new window")
- fred.label.pack()
-
- def createWidgets(self):
- self.QUIT = Button(self, text='QUIT', foreground='red',
- command=self.quit)
-
- self.QUIT.pack(side=LEFT, fill=BOTH)
-
- # a hello button
- self.hi_there = Button(self, text='Make a New Window',
- command=self.makeWindow)
- self.hi_there.pack(side=LEFT)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-test.mainloop()
diff --git a/Demo/tkinter/matt/window-creation-w-location.py b/Demo/tkinter/matt/window-creation-w-location.py
deleted file mode 100644
index 3f2b5b0..0000000
--- a/Demo/tkinter/matt/window-creation-w-location.py
+++ /dev/null
@@ -1,45 +0,0 @@
-from Tkinter import *
-
-import sys
-##sys.path.append("/users/mjc4y/projects/python/tkinter/utils")
-##from TkinterUtils import *
-
-# this shows how to create a new window with a button in it that
-# can create new windows
-
-class QuitButton(Button):
- def __init__(self, master, *args, **kwargs):
- if not kwargs.has_key("text"):
- kwargs["text"] = "QUIT"
- if not kwargs.has_key("command"):
- kwargs["command"] = master.quit
- apply(Button.__init__, (self, master) + args, kwargs)
-
-class Test(Frame):
- def makeWindow(self, *args):
- fred = Toplevel()
-
- fred.label = Canvas (fred, width="2i", height="2i")
-
- fred.label.create_line("0", "0", "2i", "2i")
- fred.label.create_line("0", "2i", "2i", "0")
- fred.label.pack()
-
- ##centerWindow(fred, self.master)
-
- def createWidgets(self):
- self.QUIT = QuitButton(self)
- self.QUIT.pack(side=LEFT, fill=BOTH)
-
- self.makeWindow = Button(self, text='Make a New Window',
- width=50, height=20,
- command=self.makeWindow)
- self.makeWindow.pack(side=LEFT)
-
- def __init__(self, master=None):
- Frame.__init__(self, master)
- Pack.config(self)
- self.createWidgets()
-
-test = Test()
-test.mainloop()
diff --git a/Demo/tkinter/ttk/combo_themes.py b/Demo/tkinter/ttk/combo_themes.py
deleted file mode 100644
index 98b3164..0000000
--- a/Demo/tkinter/ttk/combo_themes.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""Ttk Theme Selector.
-
-Although it is a theme selector, you won't notice many changes since
-there is only a combobox and a frame around.
-"""
-import ttk
-
-class App(ttk.Frame):
- def __init__(self):
- ttk.Frame.__init__(self)
-
- self.style = ttk.Style()
- self._setup_widgets()
-
- def _change_theme(self, event):
- if event.widget.current(): # value #0 is not a theme
- newtheme = event.widget.get()
- # change to the new theme and refresh all the widgets
- self.style.theme_use(newtheme)
-
- def _setup_widgets(self):
- themes = list(self.style.theme_names())
- themes.insert(0, "Pick a theme")
- # Create a readonly Combobox which will display 4 values at max,
- # which will cause it to create a scrollbar if there are more
- # than 4 values in total.
- themes_combo = ttk.Combobox(self, values=themes, state="readonly",
- height=4)
- themes_combo.set(themes[0]) # sets the combobox value to "Pick a theme"
- # Combobox widget generates a <<ComboboxSelected>> virtual event
- # when the user selects an element. This event is generated after
- # the listbox is unposted (after you select an item, the combobox's
- # listbox disappears, then it is said that listbox is now unposted).
- themes_combo.bind("<<ComboboxSelected>>", self._change_theme)
- themes_combo.pack(fill='x')
-
- self.pack(fill='both', expand=1)
-
-
-def main():
- app = App()
- app.master.title("Ttk Combobox")
- app.mainloop()
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/tkinter/ttk/dirbrowser.py b/Demo/tkinter/ttk/dirbrowser.py
deleted file mode 100644
index b4f79bd..0000000
--- a/Demo/tkinter/ttk/dirbrowser.py
+++ /dev/null
@@ -1,93 +0,0 @@
-"""A directory browser using Ttk Treeview.
-
-Based on the demo found in Tk 8.5 library/demos/browse
-"""
-import os
-import glob
-import Tkinter
-import ttk
-
-def populate_tree(tree, node):
- if tree.set(node, "type") != 'directory':
- return
-
- path = tree.set(node, "fullpath")
- tree.delete(*tree.get_children(node))
-
- parent = tree.parent(node)
- special_dirs = [] if parent else glob.glob('.') + glob.glob('..')
-
- for p in special_dirs + os.listdir(path):
- ptype = None
- p = os.path.join(path, p).replace('\\', '/')
- if os.path.isdir(p): ptype = "directory"
- elif os.path.isfile(p): ptype = "file"
-
- fname = os.path.split(p)[1]
- id = tree.insert(node, "end", text=fname, values=[p, ptype])
-
- if ptype == 'directory':
- if fname not in ('.', '..'):
- tree.insert(id, 0, text="dummy")
- tree.item(id, text=fname)
- elif ptype == 'file':
- size = os.stat(p).st_size
- tree.set(id, "size", "%d bytes" % size)
-
-
-def populate_roots(tree):
- dir = os.path.abspath('.').replace('\\', '/')
- node = tree.insert('', 'end', text=dir, values=[dir, "directory"])
- populate_tree(tree, node)
-
-def update_tree(event):
- tree = event.widget
- populate_tree(tree, tree.focus())
-
-def change_dir(event):
- tree = event.widget
- node = tree.focus()
- if tree.parent(node):
- path = os.path.abspath(tree.set(node, "fullpath"))
- if os.path.isdir(path):
- os.chdir(path)
- tree.delete(tree.get_children(''))
- populate_roots(tree)
-
-def autoscroll(sbar, first, last):
- """Hide and show scrollbar as needed."""
- first, last = float(first), float(last)
- if first <= 0 and last >= 1:
- sbar.grid_remove()
- else:
- sbar.grid()
- sbar.set(first, last)
-
-root = Tkinter.Tk()
-
-vsb = ttk.Scrollbar(orient="vertical")
-hsb = ttk.Scrollbar(orient="horizontal")
-
-tree = ttk.Treeview(columns=("fullpath", "type", "size"),
- displaycolumns="size", yscrollcommand=lambda f, l: autoscroll(vsb, f, l),
- xscrollcommand=lambda f, l:autoscroll(hsb, f, l))
-
-vsb['command'] = tree.yview
-hsb['command'] = tree.xview
-
-tree.heading("#0", text="Directory Structure", anchor='w')
-tree.heading("size", text="File Size", anchor='w')
-tree.column("size", stretch=0, width=100)
-
-populate_roots(tree)
-tree.bind('<<TreeviewOpen>>', update_tree)
-tree.bind('<Double-Button-1>', change_dir)
-
-# Arrange the tree and its scrollbars in the toplevel
-tree.grid(column=0, row=0, sticky='nswe')
-vsb.grid(column=1, row=0, sticky='ns')
-hsb.grid(column=0, row=1, sticky='ew')
-root.grid_columnconfigure(0, weight=1)
-root.grid_rowconfigure(0, weight=1)
-
-root.mainloop()
diff --git a/Demo/tkinter/ttk/img/close.gif b/Demo/tkinter/ttk/img/close.gif
deleted file mode 100644
index 18cf6c7..0000000
--- a/Demo/tkinter/ttk/img/close.gif
+++ /dev/null
Binary files differ
diff --git a/Demo/tkinter/ttk/img/close_active.gif b/Demo/tkinter/ttk/img/close_active.gif
deleted file mode 100644
index db7f392..0000000
--- a/Demo/tkinter/ttk/img/close_active.gif
+++ /dev/null
Binary files differ
diff --git a/Demo/tkinter/ttk/img/close_pressed.gif b/Demo/tkinter/ttk/img/close_pressed.gif
deleted file mode 100644
index 5616954..0000000
--- a/Demo/tkinter/ttk/img/close_pressed.gif
+++ /dev/null
Binary files differ
diff --git a/Demo/tkinter/ttk/listbox_scrollcmd.py b/Demo/tkinter/ttk/listbox_scrollcmd.py
deleted file mode 100644
index f2a56a4..0000000
--- a/Demo/tkinter/ttk/listbox_scrollcmd.py
+++ /dev/null
@@ -1,37 +0,0 @@
-"""Sample taken from: http://www.tkdocs.com/tutorial/morewidgets.html and
-converted to Python, mainly to demonstrate xscrollcommand option.
-
-grid [tk::listbox .l -yscrollcommand ".s set" -height 5] -column 0 -row 0 -sticky nwes
-grid [ttk::scrollbar .s -command ".l yview" -orient vertical] -column 1 -row 0 -sticky ns
-grid [ttk::label .stat -text "Status message here" -anchor w] -column 0 -row 1 -sticky we
-grid [ttk::sizegrip .sz] -column 1 -row 1 -sticky se
-grid columnconfigure . 0 -weight 1; grid rowconfigure . 0 -weight 1
-for {set i 0} {$i<100} {incr i} {
- .l insert end "Line $i of 100"
- }
-"""
-import Tkinter
-import ttk
-
-root = Tkinter.Tk()
-
-l = Tkinter.Listbox(height=5)
-l.grid(column=0, row=0, sticky='nwes')
-
-s = ttk.Scrollbar(command=l.yview, orient='vertical')
-l['yscrollcommand'] = s.set
-s.grid(column=1, row=0, sticky="ns")
-
-stat = ttk.Label(text="Status message here", anchor='w')
-stat.grid(column=0, row=1, sticky='we')
-
-sz = ttk.Sizegrip()
-sz.grid(column=1, row=1, sticky='se')
-
-root.grid_columnconfigure(0, weight=1)
-root.grid_rowconfigure(0, weight=1)
-
-for i in range(100):
- l.insert('end', "Line %d of 100" % i)
-
-root.mainloop()
diff --git a/Demo/tkinter/ttk/mac_searchentry.py b/Demo/tkinter/ttk/mac_searchentry.py
deleted file mode 100644
index 48d5aa9..0000000
--- a/Demo/tkinter/ttk/mac_searchentry.py
+++ /dev/null
@@ -1,78 +0,0 @@
-"""Mac style search widget
-
-Translated from Tcl code by Schelte Bron, http://wiki.tcl.tk/18188
-"""
-import Tkinter
-import ttk
-
-root = Tkinter.Tk()
-
-data = """
-R0lGODlhKgAaAOfnAFdZVllbWFpcWVtdWlxeW11fXF9hXmBiX2ZnZWhpZ2lraGxua25wbXJ0
-cXR2c3V3dHZ4dXh6d3x+e31/fH6AfYSGg4eJhoiKh4qMiYuNio2PjHmUqnqVq3yXrZGTkJKU
-kX+asJSWk32cuJWXlIGcs5aYlX6euZeZloOetZial4SftpqbmIWgt4GhvYahuIKivpudmYei
-uYOjv5yem4ijuoSkwIWlwYmlu56gnYamwp+hnoenw4unvaCin4ioxJCnuZykrImpxZmlsoaq
-zI2pv6KkoZGouoqqxpqms4erzaOloo6qwYurx5Kqu5untIiszqSmo5CrwoysyJeqtpOrvJyo
-tZGsw42typSsvaaopZKtxJWtvp6qt4+uy6epppOuxZCvzKiqp5quuZSvxoyx06mrqJWwx42y
-1JKxzpmwwaqsqZaxyI6z1ZqxwqutqpOzz4+01qyuq56yvpizypS00Jm0y5W10Zq1zJa20rCy
-rpu3zqizwbGzr6C3yZy4z7K0saG4yp250LO1sqK5y5660Z+70qO7zKy4xaC806S8zba4taG9
-1KW9zq66x6+7yLi6t6S/1rC8yrm7uLO8xLG9y7q8ubS9xabB2anB07K+zLW+xrO/za7CzrTA
-zrjAyLXBz77BvbbC0K/G2LjD0bnE0rLK28TGw8bIxcLL07vP28HN28rMycvOyr/T38DU4cnR
-2s/RztHT0NLU0cTY5MrW5MvX5dHX2c3Z59bY1dPb5Nbb3dLe7Nvd2t3f3NXh797g3d3j5dnl
-9OPl4eTm4+Ln6tzo9uXn5Obo5eDp8efp5uHq8uXq7ejq5+nr6OPs9Ovu6unu8O3v6+vw8+7w
-7ezx9O/x7vDy7/Hz8O/19/P18vT38/L3+fb49Pf59vX6/fj69/b7/vn7+Pr8+ff9//v9+vz/
-+/7//P//////////////////////////////////////////////////////////////////
-/////////////////////////////////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJZAD/ACwC
-AAIAKAAWAAAI/gD/CRz4bwUGCg8eQFjIsGHDBw4iTLAQgqBFgisuePCiyJOpUyBDihRpypMi
-Lx8qaLhIMIyGFZ5sAUsmjZrNmzhzWpO2DJgtTysqfGDpxoMbW8ekeQsXzty4p1CjRjUXrps3
-asJsuclQ4uKKSbamMR3n1JzZs2jRkh1HzuxVXX8y4CDYAwqua+DInVrRwMGJU2kDp31KThy1
-XGWGDlxhi1rTPAUICBBAoEAesoIzn6Vm68MKgVAUHftmzhOCBCtQwQKSoABgzZnJdSMmyIPA
-FbCotdUQAIhNa9B6DPCAGbZac+SowVIMRVe4pwkA4GpqDlwuAAmMZx4nTtfnf1mO5JEDNy46
-MHJkxQEDgKC49rPjwC0bqGaZuOoZAKjBPE4NgAzUvYcWOc0QZF91imAnCDHJ5JFAAJN0I2Ba
-4iRDUC/gOEVNDwIUcEABCAgAAATUTIgWOMBYRFp80ghiAQIIVAAEAwJIYI2JZnUji0XSYAYO
-NcsQA8wy0hCTwAASXGOiONFcxAtpTokTHznfiLMNMAkcAMuE43jDC0vLeGOWe2R5o4sn1LgH
-GzkWsvTPMgEOaA433Ag4TjjMuDkQMNi0tZ12sqWoJ0HATMPNffAZZ6U0wLAyqJ62RGoLLrhI
-aqmlpzwaEAAh+QQJZAD/ACwAAAAAKgAaAAAI/gD/CRw40JEhQoEC+fGjcOHCMRAjRkxDsKLF
-f5YcAcID582ZjyBDJhmZZIjJIUySEDHiBMhFghrtdNnRAgSHmzhz6sTZQcSLITx+CHn5bxSk
-Nz5MCMGy55CjTVCjbuJEtSrVQ3uwqDBRQwrFi476SHHxow8qXcemVbPGtm21t3CnTaP27Jgu
-VHtuiIjBsuImQkRiiEEFTNo2cOTMKV7MuLE5cN68QUOGSgwKG1EqJqJDY8+rZt8UjxtNunTj
-cY3DgZOWS46KIFgGjiI0ZIsqaqNNjWjgYMUpx8Adc3v2aosNMAI1DbqyI9WycOb4IAggQEAB
-A3lQBxet/TG4cMpI/tHwYeSfIzxM0uTKNs7UgAQrYL1akaDA7+3bueVqY4NJlUhIcQLNYx8E
-AIQ01mwjTQ8DeNAdfouNA8440GBCQxJY3MEGD6p4Y844CQCAizcSgpMLAAlAuJ03qOyQRBR3
-nEHEK+BMGKIui4kDDAAIPKiiYuSYSMQQRCDCxhiziPMYBgDkEaEaAGQA3Y+MjUPOLFoMoUUh
-cKxRC4ngeILiH8Qkk0cCAUzSDZWpzbLEE1EwggcYqWCj2DNADFDAAQUgIAAAEFDDJmPYqNJF
-F1s4cscTmCDjDTjdSPOHBQggUAEQDAgggTWDPoYMJkFoUdRmddyyjWLeULMMMcAsIw0x4wkM
-IME1g25zyxpHxFYUHmyIggw4H4ojITnfiLMNMAkcAAub4BQjihRdDGTJHmvc4Qo1wD6Imje6
-eILbj+BQ4wqu5Q3ECSJ0FOKKMtv4mBg33Pw4zjbKuBIIE1xYpIkhdQQiyi7OtAucj6dt48wu
-otQhBRa6VvSJIRwhIkotvgRTzMUYZ6xxMcj4QkspeKDxxRhEmUfIHWjAgQcijEDissuXvCyz
-zH7Q8YQURxDhUsn/bCInR3AELfTQZBRt9BBJkCGFFVhMwTNBlnBCSCGEIJQQIAklZMXWRBAR
-RRRWENHwRQEBADs="""
-
-
-s1 = Tkinter.PhotoImage("search1", data=data, format="gif -index 0")
-s2 = Tkinter.PhotoImage("search2", data=data, format="gif -index 1")
-
-style = ttk.Style()
-
-style.element_create("Search.field", "image", "search1",
- ("focus", "search2"), border=[22, 7, 14], sticky="ew")
-
-style.layout("Search.entry", [
- ("Search.field", {"sticky": "nswe", "border": 1, "children":
- [("Entry.padding", {"sticky": "nswe", "children":
- [("Entry.textarea", {"sticky": "nswe"})]
- })]
- })]
-)
-
-style.configure("Search.entry", background="#b2b2b2")
-
-root.configure(background="#b2b2b2")
-
-e1 = ttk.Entry(style="Search.entry", width=20)
-e2 = ttk.Entry(style="Search.entry", width=20)
-
-e1.grid(padx=10, pady=10)
-e2.grid(padx=10, pady=10)
-
-root.mainloop()
diff --git a/Demo/tkinter/ttk/notebook_closebtn.py b/Demo/tkinter/ttk/notebook_closebtn.py
deleted file mode 100644
index 244168d..0000000
--- a/Demo/tkinter/ttk/notebook_closebtn.py
+++ /dev/null
@@ -1,78 +0,0 @@
-"""A Ttk Notebook with close buttons.
-
-Based on an example by patthoyts, http://paste.tclers.tk/896
-"""
-import os
-import Tkinter
-import ttk
-
-root = Tkinter.Tk()
-
-imgdir = os.path.join(os.path.dirname(__file__), 'img')
-i1 = Tkinter.PhotoImage("img_close", file=os.path.join(imgdir, 'close.gif'))
-i2 = Tkinter.PhotoImage("img_closeactive",
- file=os.path.join(imgdir, 'close_active.gif'))
-i3 = Tkinter.PhotoImage("img_closepressed",
- file=os.path.join(imgdir, 'close_pressed.gif'))
-
-style = ttk.Style()
-
-style.element_create("close", "image", "img_close",
- ("active", "pressed", "!disabled", "img_closepressed"),
- ("active", "!disabled", "img_closeactive"), border=8, sticky='')
-
-style.layout("ButtonNotebook", [("ButtonNotebook.client", {"sticky": "nswe"})])
-style.layout("ButtonNotebook.Tab", [
- ("ButtonNotebook.tab", {"sticky": "nswe", "children":
- [("ButtonNotebook.padding", {"side": "top", "sticky": "nswe",
- "children":
- [("ButtonNotebook.focus", {"side": "top", "sticky": "nswe",
- "children":
- [("ButtonNotebook.label", {"side": "left", "sticky": ''}),
- ("ButtonNotebook.close", {"side": "left", "sticky": ''})]
- })]
- })]
- })]
-)
-
-def btn_press(event):
- x, y, widget = event.x, event.y, event.widget
- elem = widget.identify(x, y)
- index = widget.index("@%d,%d" % (x, y))
-
- if "close" in elem:
- widget.state(['pressed'])
- widget.pressed_index = index
-
-def btn_release(event):
- x, y, widget = event.x, event.y, event.widget
-
- if not widget.instate(['pressed']):
- return
-
- elem = widget.identify(x, y)
- index = widget.index("@%d,%d" % (x, y))
-
- if "close" in elem and widget.pressed_index == index:
- widget.forget(index)
- widget.event_generate("<<NotebookClosedTab>>")
-
- widget.state(["!pressed"])
- widget.pressed_index = None
-
-
-root.bind_class("TNotebook", "<ButtonPress-1>", btn_press, True)
-root.bind_class("TNotebook", "<ButtonRelease-1>", btn_release)
-
-# create a ttk notebook with our custom style, and add some tabs to it
-nb = ttk.Notebook(width=200, height=200, style="ButtonNotebook")
-nb.pressed_index = None
-f1 = Tkinter.Frame(nb, background="red")
-f2 = Tkinter.Frame(nb, background="green")
-f3 = Tkinter.Frame(nb, background="blue")
-nb.add(f1, text='Red', padding=3)
-nb.add(f2, text='Green', padding=3)
-nb.add(f3, text='Blue', padding=3)
-nb.pack(expand=1, fill='both')
-
-root.mainloop()
diff --git a/Demo/tkinter/ttk/plastik_theme.py b/Demo/tkinter/ttk/plastik_theme.py
deleted file mode 100644
index 4922d90..0000000
--- a/Demo/tkinter/ttk/plastik_theme.py
+++ /dev/null
@@ -1,269 +0,0 @@
-"""This demonstrates good part of the syntax accepted by theme_create.
-
-This is a translation of plastik.tcl to python.
-You will need the images used by the plastik theme to test this. The
-images (and other tile themes) can be retrived by doing:
-
-$ cvs -z3 -d:pserver:anonymous@tktable.cvs.sourceforge.net:/cvsroot/tktable \
- co tile-themes
-
-To test this module you should do, for example:
-
-import Tkinter
-import plastik_theme
-
-root = Tkinter.Tk()
-plastik_theme.install(plastik_image_dir)
-...
-
-Where plastik_image_dir contains the path to the images directory used by
-the plastik theme, something like: tile-themes/plastik/plastik
-"""
-import os
-import glob
-import ttk
-from Tkinter import PhotoImage
-
-__all__ = ['install']
-
-colors = {
- "frame": "#efefef",
- "disabledfg": "#aaaaaa",
- "selectbg": "#657a9e",
- "selectfg": "#ffffff"
- }
-
-imgs = {}
-def _load_imgs(imgdir):
- imgdir = os.path.expanduser(imgdir)
- if not os.path.isdir(imgdir):
- raise Exception("%r is not a directory, can't load images" % imgdir)
- for f in glob.glob("%s/*.gif" % imgdir):
- img = os.path.split(f)[1]
- name = img[:-4]
- imgs[name] = PhotoImage(name, file=f, format="gif89")
-
-def install(imgdir):
- _load_imgs(imgdir)
- style = ttk.Style()
- style.theme_create("plastik", "default", settings={
- ".": {
- "configure":
- {"background": colors['frame'],
- "troughcolor": colors['frame'],
- "selectbackground": colors['selectbg'],
- "selectforeground": colors['selectfg'],
- "fieldbackground": colors['frame'],
- "font": "TkDefaultFont",
- "borderwidth": 1},
- "map": {"foreground": [("disabled", colors['disabledfg'])]}
- },
-
- "Vertical.TScrollbar": {"layout": [
- ("Vertical.Scrollbar.uparrow", {"side": "top", "sticky": ''}),
- ("Vertical.Scrollbar.downarrow", {"side": "bottom", "sticky": ''}),
- ("Vertical.Scrollbar.uparrow", {"side": "bottom", "sticky": ''}),
- ("Vertical.Scrollbar.trough", {"sticky": "ns", "children":
- [("Vertical.Scrollbar.thumb", {"expand": 1, "unit": 1,
- "children": [("Vertical.Scrollbar.grip", {"sticky": ''})]
- })]
- })]
- },
-
- "Horizontal.TScrollbar": {"layout": [
- ("Horizontal.Scrollbar.leftarrow", {"side": "left", "sticky": ''}),
- ("Horizontal.Scrollbar.rightarrow",
- {"side": "right", "sticky": ''}),
- ("Horizontal.Scrollbar.leftarrow",
- {"side": "right", "sticky": ''}),
- ("Horizontal.Scrollbar.trough", {"sticky": "ew", "children":
- [("Horizontal.Scrollbar.thumb", {"expand": 1, "unit": 1,
- "children": [("Horizontal.Scrollbar.grip", {"sticky": ''})]
- })]
- })]
- },
-
- "TButton": {
- "configure": {"width": 10, "anchor": "center"},
- "layout": [
- ("Button.button", {"children":
- [("Button.focus", {"children":
- [("Button.padding", {"children":
- [("Button.label", {"side": "left", "expand": 1})]
- })]
- })]
- })
- ]
- },
-
- "Toolbutton": {
- "configure": {"anchor": "center"},
- "layout": [
- ("Toolbutton.border", {"children":
- [("Toolbutton.button", {"children":
- [("Toolbutton.padding", {"children":
- [("Toolbutton.label", {"side":"left", "expand":1})]
- })]
- })]
- })
- ]
- },
-
- "TMenubutton": {"layout": [
- ("Menubutton.button", {"children":
- [("Menubutton.indicator", {"side": "right"}),
- ("Menubutton.focus", {"children":
- [("Menubutton.padding", {"children":
- [("Menubutton.label", {"side": "left", "expand": 1})]
- })]
- })]
- })]
- },
-
- "TNotebook": {"configure": {"tabmargins": [0, 2, 0, 0]}},
- "TNotebook.tab": {
- "configure": {"padding": [6, 2, 6, 2], "expand": [0, 0, 2]},
- "map": {"expand": [("selected", [1, 2, 4, 2])]}
- },
- "Treeview": {"configure": {"padding": 0}},
-
- # elements
- "Button.button": {"element create":
- ("image", 'button-n',
- ("pressed", 'button-p'), ("active", 'button-h'),
- {"border": [4, 10], "padding": 4, "sticky":"ewns"}
- )
- },
-
- "Toolbutton.button": {"element create":
- ("image", 'tbutton-n',
- ("selected", 'tbutton-p'), ("pressed", 'tbutton-p'),
- ("active", 'tbutton-h'),
- {"border": [4, 9], "padding": 3, "sticky": "news"}
- )
- },
-
- "Checkbutton.indicator": {"element create":
- ("image", 'check-nu',
- ('active', 'selected', 'check-hc'),
- ('pressed', 'selected', 'check-pc'),
- ('active', 'check-hu'),
- ("selected", 'check-nc'),
- {"sticky": ''}
- )
- },
-
- "Radiobutton.indicator": {"element create":
- ("image", 'radio-nu',
- ('active', 'selected', 'radio-hc'),
- ('pressed', 'selected', 'radio-pc'),
- ('active', 'radio-hu'), ('selected', 'radio-nc'),
- {"sticky": ''}
- )
- },
-
- "Horizontal.Scrollbar.thumb": {"element create":
- ("image", 'hsb-n', {"border": 3, "sticky": "ew"})
- },
-
- "Horizontal.Scrollbar.grip": {"element create": ("image", 'hsb-g')},
- "Horizontal.Scrollbar.trough": {"element create": ("image", 'hsb-t')},
- "Vertical.Scrollbar.thumb": {"element create":
- ("image", 'vsb-n', {"border": 3, "sticky": "ns"})
- },
- "Vertical.Scrollbar.grip": {"element create": ("image", 'vsb-g')},
- "Vertical.Scrollbar.trough": {"element create": ("image", 'vsb-t')},
- "Scrollbar.uparrow": {"element create":
- ("image", 'arrowup-n', ("pressed", 'arrowup-p'), {"sticky": ''})
- },
- "Scrollbar.downarrow": {"element create":
- ("image", 'arrowdown-n',
- ("pressed", 'arrowdown-p'), {'sticky': ''})
- },
- "Scrollbar.leftarrow": {"element create":
- ("image", 'arrowleft-n',
- ("pressed", 'arrowleft-p'), {'sticky': ''})
- },
- "Scrollbar.rightarrow": {"element create":
- ("image", 'arrowright-n', ("pressed", 'arrowright-p'),
- {'sticky': ''})
- },
-
- "Horizontal.Scale.slider": {"element create":
- ("image", 'hslider-n', {'sticky': ''})
- },
- "Horizontal.Scale.trough": {"element create":
- ("image", 'hslider-t', {'border': 1, 'padding': 0})
- },
- "Vertical.Scale.slider": {"element create":
- ("image", 'vslider-n', {'sticky': ''})
- },
- "Vertical.Scale.trough": {"element create":
- ("image", 'vslider-t', {'border': 1, 'padding': 0})
- },
-
- "Entry.field": {"element create":
- ("image", 'entry-n',
- ("focus", 'entry-f'),
- {'border': 2, 'padding': [3, 4], 'sticky': 'news'}
- )
- },
-
- "Labelframe.border": {"element create":
- ("image", 'border', {'border': 4, 'padding': 4, 'sticky': 'news'})
- },
-
- "Menubutton.button": {"element create":
- ("image", 'combo-r',
- ('active', 'combo-ra'),
- {'sticky': 'news', 'border': [4, 6, 24, 15],
- 'padding': [4, 4, 5]}
- )
- },
- "Menubutton.indicator": {"element create":
- ("image", 'arrow-d', {"sticky": "e", "border": [15, 0, 0, 0]})
- },
-
- "Combobox.field": {"element create":
- ("image", 'combo-n',
- ('readonly', 'active', 'combo-ra'),
- ('focus', 'active', 'combo-fa'),
- ('active', 'combo-a'), ('!readonly', 'focus', 'combo-f'),
- ('readonly', 'combo-r'),
- {'border': [4, 6, 24, 15], 'padding': [4, 4, 5],
- 'sticky': 'news'}
- )
- },
- "Combobox.downarrow": {"element create":
- ("image", 'arrow-d', {'sticky': 'e', 'border': [15, 0, 0, 0]})
- },
-
- "Notebook.client": {"element create":
- ("image", 'notebook-c', {'border': 4})
- },
- "Notebook.tab": {"element create":
- ("image", 'notebook-tn',
- ("selected", 'notebook-ts'), ("active", 'notebook-ta'),
- {'padding': [0, 2, 0, 0], 'border': [4, 10, 4, 10]}
- )
- },
-
- "Progressbar.trough": {"element create":
- ("image", 'hprogress-t', {'border': 2})
- },
- "Horizontal.Progressbar.pbar": {"element create":
- ("image", 'hprogress-b', {'border': [2, 9]})
- },
- "Vertical.Progressbar.pbar": {"element create":
- ("image", 'vprogress-b', {'border': [9, 2]})
- },
-
- "Treeheading.cell": {"element create":
- ("image", 'tree-n',
- ("pressed", 'tree-p'),
- {'border': [4, 10], 'padding': 4, 'sticky': 'news'}
- )
- }
-
- })
- style.theme_use("plastik")
diff --git a/Demo/tkinter/ttk/roundframe.py b/Demo/tkinter/ttk/roundframe.py
deleted file mode 100644
index ed2147a..0000000
--- a/Demo/tkinter/ttk/roundframe.py
+++ /dev/null
@@ -1,111 +0,0 @@
-"""Ttk Frame with rounded corners.
-
-Based on an example by Bryan Oakley, found at: http://wiki.tcl.tk/20152"""
-import Tkinter
-import ttk
-
-root = Tkinter.Tk()
-
-img1 = Tkinter.PhotoImage("frameFocusBorder", data="""
-R0lGODlhQABAAPcAAHx+fMTCxKSipOTi5JSSlNTS1LSytPTy9IyKjMzKzKyq
-rOzq7JyanNza3Ly6vPz6/ISChMTGxKSmpOTm5JSWlNTW1LS2tPT29IyOjMzO
-zKyurOzu7JyenNze3Ly+vPz+/OkAKOUA5IEAEnwAAACuQACUAAFBAAB+AFYd
-QAC0AABBAAB+AIjMAuEEABINAAAAAHMgAQAAAAAAAAAAAKjSxOIEJBIIpQAA
-sRgBMO4AAJAAAHwCAHAAAAUAAJEAAHwAAP+eEP8CZ/8Aif8AAG0BDAUAAJEA
-AHwAAIXYAOfxAIESAHwAAABAMQAbMBZGMAAAIEggJQMAIAAAAAAAfqgaXESI
-5BdBEgB+AGgALGEAABYAAAAAAACsNwAEAAAMLwAAAH61MQBIAABCM8B+AAAU
-AAAAAAAApQAAsf8Brv8AlP8AQf8Afv8AzP8A1P8AQf8AfgAArAAABAAADAAA
-AACQDADjAAASAAAAAACAAADVABZBAAB+ALjMwOIEhxINUAAAANIgAOYAAIEA
-AHwAAGjSAGEEABYIAAAAAEoBB+MAAIEAAHwCACABAJsAAFAAAAAAAGjJAGGL
-AAFBFgB+AGmIAAAQAABHAAB+APQoAOE/ABIAAAAAAADQAADjAAASAAAAAPiF
-APcrABKDAAB8ABgAGO4AAJAAqXwAAHAAAAUAAJEAAHwAAP8AAP8AAP8AAP8A
-AG0pIwW3AJGSAHx8AEocI/QAAICpAHwAAAA0SABk6xaDEgB8AAD//wD//wD/
-/wD//2gAAGEAABYAAAAAAAC0/AHj5AASEgAAAAA01gBkWACDTAB8AFf43PT3
-5IASEnwAAOAYd+PuMBKQTwB8AGgAEGG35RaSEgB8AOj/NOL/ZBL/gwD/fMkc
-q4sA5UGpEn4AAIg02xBk/0eD/358fx/4iADk5QASEgAAAALnHABkAACDqQB8
-AMyINARkZA2DgwB8fBABHL0AAEUAqQAAAIAxKOMAPxIwAAAAAIScAOPxABIS
-AAAAAIIAnQwA/0IAR3cAACwAAAAAQABAAAAI/wA/CBxIsKDBgwgTKlzIsKFD
-gxceNnxAsaLFixgzUrzAsWPFCw8kDgy5EeQDkBxPolypsmXKlx1hXnS48UEH
-CwooMCDAgIJOCjx99gz6k+jQnkWR9lRgYYDJkAk/DlAgIMICZlizat3KtatX
-rAsiCNDgtCJClQkoFMgqsu3ArBkoZDgA8uDJAwk4bGDmtm9BZgcYzK078m4D
-Cgf4+l0skNkGCg3oUhR4d4GCDIoZM2ZWQMECyZQvLMggIbPmzQIyfCZ5YcME
-AwFMn/bLLIKBCRtMHljQQcDV2ZqZTRDQYfWFAwMqUJANvC8zBhUWbDi5YUAB
-Bsybt2VGoUKH3AcmdP+Im127xOcJih+oXsEDdvOLuQfIMGBD9QwBlsOnzcBD
-hfrsuVfefgzJR599A+CnH4Hb9fcfgu29x6BIBgKYYH4DTojQc/5ZGGGGGhpU
-IYIKghgiQRw+GKCEJxZIwXwWlthiQyl6KOCMLsJIIoY4LlQjhDf2mNCI9/Eo
-5IYO2sjikX+9eGCRCzL5V5JALillY07GaOSVb1G5ookzEnlhlFx+8OOXZb6V
-5Y5kcnlmckGmKaaMaZrpJZxWXjnnlmW++WGdZq5ZXQEetKmnlxPgl6eUYhJq
-KKOI0imnoNbF2ScFHQJJwW99TsBAAAVYWEAAHEQAZoi1cQDqAAeEV0EACpT/
-JqcACgRQAW6uNWCbYKcyyEwGDBgQwa2tTlBBAhYIQMFejC5AgQAWJNDABK3y
-loEDEjCgV6/aOcYBAwp4kIF6rVkXgAEc8IQZVifCBRQHGqya23HGIpsTBgSU
-OsFX/PbrVVjpYsCABA4kQCxHu11ogAQUIOAwATpBLDFQFE9sccUYS0wAxD5h
-4DACFEggbAHk3jVBA/gtTIHHEADg8sswxyzzzDQDAAEECGAQsgHiTisZResN
-gLIHBijwLQEYePzx0kw37fTSSjuMr7ZMzfcgYZUZi58DGsTKwbdgayt22GSP
-bXbYY3MggQIaONDzAJ8R9kFlQheQQAAOWGCAARrwdt23Bn8H7vfggBMueOEG
-WOBBAAkU0EB9oBGUdXIFZJBABAEEsPjmmnfO+eeeh/55BBEk0Ph/E8Q9meQq
-bbDABAN00EADFRRQ++2254777rr3jrvjFTTQwQCpz7u6QRut5/oEzA/g/PPQ
-Ry/99NIz//oGrZpUUEAAOw==""")
-
-img2 = Tkinter.PhotoImage("frameBorder", data="""
-R0lGODlhQABAAPcAAHx+fMTCxKSipOTi5JSSlNTS1LSytPTy9IyKjMzKzKyq
-rOzq7JyanNza3Ly6vPz6/ISChMTGxKSmpOTm5JSWlNTW1LS2tPT29IyOjMzO
-zKyurOzu7JyenNze3Ly+vPz+/OkAKOUA5IEAEnwAAACuQACUAAFBAAB+AFYd
-QAC0AABBAAB+AIjMAuEEABINAAAAAHMgAQAAAAAAAAAAAKjSxOIEJBIIpQAA
-sRgBMO4AAJAAAHwCAHAAAAUAAJEAAHwAAP+eEP8CZ/8Aif8AAG0BDAUAAJEA
-AHwAAIXYAOfxAIESAHwAAABAMQAbMBZGMAAAIEggJQMAIAAAAAAAfqgaXESI
-5BdBEgB+AGgALGEAABYAAAAAAACsNwAEAAAMLwAAAH61MQBIAABCM8B+AAAU
-AAAAAAAApQAAsf8Brv8AlP8AQf8Afv8AzP8A1P8AQf8AfgAArAAABAAADAAA
-AACQDADjAAASAAAAAACAAADVABZBAAB+ALjMwOIEhxINUAAAANIgAOYAAIEA
-AHwAAGjSAGEEABYIAAAAAEoBB+MAAIEAAHwCACABAJsAAFAAAAAAAGjJAGGL
-AAFBFgB+AGmIAAAQAABHAAB+APQoAOE/ABIAAAAAAADQAADjAAASAAAAAPiF
-APcrABKDAAB8ABgAGO4AAJAAqXwAAHAAAAUAAJEAAHwAAP8AAP8AAP8AAP8A
-AG0pIwW3AJGSAHx8AEocI/QAAICpAHwAAAA0SABk6xaDEgB8AAD//wD//wD/
-/wD//2gAAGEAABYAAAAAAAC0/AHj5AASEgAAAAA01gBkWACDTAB8AFf43PT3
-5IASEnwAAOAYd+PuMBKQTwB8AGgAEGG35RaSEgB8AOj/NOL/ZBL/gwD/fMkc
-q4sA5UGpEn4AAIg02xBk/0eD/358fx/4iADk5QASEgAAAALnHABkAACDqQB8
-AMyINARkZA2DgwB8fBABHL0AAEUAqQAAAIAxKOMAPxIwAAAAAIScAOPxABIS
-AAAAAIIAnQwA/0IAR3cAACwAAAAAQABAAAAI/wA/CBxIsKDBgwgTKlzIsKFD
-gxceNnxAsaLFixgzUrzAsWPFCw8kDgy5EeQDkBxPolypsmXKlx1hXnS48UEH
-CwooMCDAgIJOCjx99gz6k+jQnkWR9lRgYYDJkAk/DlAgIMICkVgHLoggQIPT
-ighVJqBQIKvZghkoZDgA8uDJAwk4bDhLd+ABBmvbjnzbgMKBuoA/bKDQgC1F
-gW8XKMgQOHABBQsMI76wIIOExo0FZIhM8sKGCQYCYA4cwcCEDSYPLOgg4Oro
-uhMEdOB84cCAChReB2ZQYcGGkxsGFGCgGzCFCh1QH5jQIW3xugwSzD4QvIIH
-4s/PUgiQYcCG4BkC5P/ObpaBhwreq18nb3Z79+8Dwo9nL9I8evjWsdOX6D59
-fPH71Xeef/kFyB93/sln4EP2Ebjegg31B5+CEDLUIH4PVqiQhOABqKFCF6qn
-34cHcfjffCQaFOJtGaZYkIkUuljQigXK+CKCE3po40A0trgjjDru+EGPI/6I
-Y4co7kikkAMBmaSNSzL5gZNSDjkghkXaaGIBHjwpY4gThJeljFt2WSWYMQpZ
-5pguUnClehS4tuMEDARQgH8FBMBBBExGwIGdAxywXAUBKHCZkAIoEEAFp33W
-QGl47ZgBAwZEwKigE1SQgAUCUDCXiwtQIIAFCTQwgaCrZeCABAzIleIGHDD/
-oIAHGUznmXABGMABT4xpmBYBHGgAKGq1ZbppThgAG8EEAW61KwYMSOBAApdy
-pNp/BkhAAQLcEqCTt+ACJW645I5rLrgEeOsTBtwiQIEElRZg61sTNBBethSw
-CwEA/Pbr778ABywwABBAgAAG7xpAq6mGUUTdAPZ6YIACsRKAAbvtZqzxxhxn
-jDG3ybbKFHf36ZVYpuE5oIGhHMTqcqswvyxzzDS/HDMHEiiggQMLDxCZXh8k
-BnEBCQTggAUGGKCB0ktr0PTTTEfttNRQT22ABR4EkEABDXgnGUEn31ZABglE
-EEAAWaeN9tpqt832221HEEECW6M3wc+Hga3SBgtMODBABw00UEEBgxdO+OGG
-J4744oZzXUEDHQxwN7F5G7QRdXxPoPkAnHfu+eeghw665n1vIKhJBQUEADs=""")
-
-style = ttk.Style()
-
-style.element_create("RoundedFrame", "image", "frameBorder",
- ("focus", "frameFocusBorder"), border=16, sticky="nsew")
-
-style.layout("RoundedFrame", [("RoundedFrame", {"sticky": "nsew"})])
-style.configure("TEntry", borderwidth=0)
-
-frame = ttk.Frame(style="RoundedFrame", padding=10)
-frame.pack(fill='x')
-
-frame2 = ttk.Frame(style="RoundedFrame", padding=10)
-frame2.pack(fill='both', expand=1)
-
-entry = ttk.Entry(frame, text='Test')
-entry.pack(fill='x')
-entry.bind("<FocusIn>", lambda evt: frame.state(["focus"]))
-entry.bind("<FocusOut>", lambda evt: frame.state(["!focus"]))
-
-text = Tkinter.Text(frame2, borderwidth=0, bg="white", highlightthickness=0)
-text.pack(fill='both', expand=1)
-text.bind("<FocusIn>", lambda evt: frame2.state(["focus"]))
-text.bind("<FocusOut>", lambda evt: frame2.state(["!focus"]))
-
-root.mainloop()
diff --git a/Demo/tkinter/ttk/theme_selector.py b/Demo/tkinter/ttk/theme_selector.py
deleted file mode 100644
index adb8472..0000000
--- a/Demo/tkinter/ttk/theme_selector.py
+++ /dev/null
@@ -1,61 +0,0 @@
-"""Ttk Theme Selector v2.
-
-This is an improvement from the other theme selector (themes_combo.py)
-since now you can notice theme changes in Ttk Combobox, Ttk Frame,
-Ttk Label and Ttk Button.
-"""
-import Tkinter
-import ttk
-
-class App(ttk.Frame):
- def __init__(self):
- ttk.Frame.__init__(self, borderwidth=3)
-
- self.style = ttk.Style()
-
- # XXX Ideally I wouldn't want to create a Tkinter.IntVar to make
- # it works with Checkbutton variable option.
- self.theme_autochange = Tkinter.IntVar(self, 0)
- self._setup_widgets()
-
- def _change_theme(self):
- self.style.theme_use(self.themes_combo.get())
-
- def _theme_sel_changed(self, widget):
- if self.theme_autochange.get():
- self._change_theme()
-
- def _setup_widgets(self):
- themes_lbl = ttk.Label(self, text="Themes")
-
- themes = self.style.theme_names()
- self.themes_combo = ttk.Combobox(self, values=themes, state="readonly")
- self.themes_combo.set(themes[0])
- self.themes_combo.bind("<<ComboboxSelected>>", self._theme_sel_changed)
-
- change_btn = ttk.Button(self, text='Change Theme',
- command=self._change_theme)
-
- theme_change_checkbtn = ttk.Checkbutton(self,
- text="Change themes when combobox item is activated",
- variable=self.theme_autochange)
-
- themes_lbl.grid(ipadx=6, sticky="w")
- self.themes_combo.grid(row=0, column=1, padx=6, sticky="ew")
- change_btn.grid(row=0, column=2, padx=6, sticky="e")
- theme_change_checkbtn.grid(row=1, columnspan=3, sticky="w", pady=6)
-
- top = self.winfo_toplevel()
- top.rowconfigure(0, weight=1)
- top.columnconfigure(0, weight=1)
- self.columnconfigure(1, weight=1)
- self.grid(row=0, column=0, sticky="nsew", columnspan=3, rowspan=2)
-
-
-def main():
- app = App()
- app.master.title("Theme Selector")
- app.mainloop()
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/tkinter/ttk/treeview_multicolumn.py b/Demo/tkinter/ttk/treeview_multicolumn.py
deleted file mode 100644
index e0edc4f..0000000
--- a/Demo/tkinter/ttk/treeview_multicolumn.py
+++ /dev/null
@@ -1,107 +0,0 @@
-"""Demo based on the demo mclist included with tk source distribution."""
-import Tkinter
-import tkFont
-import ttk
-
-tree_columns = ("country", "capital", "currency")
-tree_data = [
- ("Argentina", "Buenos Aires", "ARS"),
- ("Australia", "Canberra", "AUD"),
- ("Brazil", "Brazilia", "BRL"),
- ("Canada", "Ottawa", "CAD"),
- ("China", "Beijing", "CNY"),
- ("France", "Paris", "EUR"),
- ("Germany", "Berlin", "EUR"),
- ("India", "New Delhi", "INR"),
- ("Italy", "Rome", "EUR"),
- ("Japan", "Tokyo", "JPY"),
- ("Mexico", "Mexico City", "MXN"),
- ("Russia", "Moscow", "RUB"),
- ("South Africa", "Pretoria", "ZAR"),
- ("United Kingdom", "London", "GBP"),
- ("United States", "Washington, D.C.", "USD")
- ]
-
-def sortby(tree, col, descending):
- """Sort tree contents when a column is clicked on."""
- # grab values to sort
- data = [(tree.set(child, col), child) for child in tree.get_children('')]
-
- # reorder data
- data.sort(reverse=descending)
- for indx, item in enumerate(data):
- tree.move(item[1], '', indx)
-
- # switch the heading so that it will sort in the opposite direction
- tree.heading(col,
- command=lambda col=col: sortby(tree, col, int(not descending)))
-
-class App(object):
- def __init__(self):
- self.tree = None
- self._setup_widgets()
- self._build_tree()
-
- def _setup_widgets(self):
- msg = ttk.Label(wraplength="4i", justify="left", anchor="n",
- padding=(10, 2, 10, 6),
- text=("Ttk is the new Tk themed widget set. One of the widgets it "
- "includes is a tree widget, which can be configured to "
- "display multiple columns of informational data without "
- "displaying the tree itself. This is a simple way to build "
- "a listbox that has multiple columns. Clicking on the "
- "heading for a column will sort the data by that column. "
- "You can also change the width of the columns by dragging "
- "the boundary between them."))
- msg.pack(fill='x')
-
- container = ttk.Frame()
- container.pack(fill='both', expand=True)
-
- # XXX Sounds like a good support class would be one for constructing
- # a treeview with scrollbars.
- self.tree = ttk.Treeview(columns=tree_columns, show="headings")
- vsb = ttk.Scrollbar(orient="vertical", command=self.tree.yview)
- hsb = ttk.Scrollbar(orient="horizontal", command=self.tree.xview)
- self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)
- self.tree.grid(column=0, row=0, sticky='nsew', in_=container)
- vsb.grid(column=1, row=0, sticky='ns', in_=container)
- hsb.grid(column=0, row=1, sticky='ew', in_=container)
-
- container.grid_columnconfigure(0, weight=1)
- container.grid_rowconfigure(0, weight=1)
-
- def _build_tree(self):
- for col in tree_columns:
- self.tree.heading(col, text=col.title(),
- command=lambda c=col: sortby(self.tree, c, 0))
- # XXX tkFont.Font().measure expected args are incorrect according
- # to the Tk docs
- self.tree.column(col, width=tkFont.Font().measure(col.title()))
-
- for item in tree_data:
- self.tree.insert('', 'end', values=item)
-
- # adjust columns lenghts if necessary
- for indx, val in enumerate(item):
- ilen = tkFont.Font().measure(val)
- if self.tree.column(tree_columns[indx], width=None) < ilen:
- self.tree.column(tree_columns[indx], width=ilen)
-
-def main():
- root = Tkinter.Tk()
- root.wm_title("Multi-Column List")
- root.wm_iconname("mclist")
-
- import plastik_theme
- try:
- plastik_theme.install('~/tile-themes/plastik/plastik')
- except Exception:
- import warnings
- warnings.warn("plastik theme being used without images")
-
- app = App()
- root.mainloop()
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/tkinter/ttk/ttkcalendar.py b/Demo/tkinter/ttk/ttkcalendar.py
deleted file mode 100644
index faa45c5..0000000
--- a/Demo/tkinter/ttk/ttkcalendar.py
+++ /dev/null
@@ -1,231 +0,0 @@
-"""
-Simple calendar using ttk Treeview together with calendar and datetime
-classes.
-"""
-import calendar
-import Tkinter
-import tkFont
-import ttk
-
-def get_calendar(locale, fwday):
- # instantiate proper calendar class
- if locale is None:
- return calendar.TextCalendar(fwday)
- else:
- return calendar.LocaleTextCalendar(fwday, locale)
-
-class Calendar(ttk.Frame):
- # XXX ToDo: cget and configure
-
- datetime = calendar.datetime.datetime
- timedelta = calendar.datetime.timedelta
-
- def __init__(self, master=None, **kw):
- """
- WIDGET-SPECIFIC OPTIONS
-
- locale, firstweekday, year, month, selectbackground,
- selectforeground
- """
- # remove custom options from kw before initializating ttk.Frame
- fwday = kw.pop('firstweekday', calendar.MONDAY)
- year = kw.pop('year', self.datetime.now().year)
- month = kw.pop('month', self.datetime.now().month)
- locale = kw.pop('locale', None)
- sel_bg = kw.pop('selectbackground', '#ecffc4')
- sel_fg = kw.pop('selectforeground', '#05640e')
-
- self._date = self.datetime(year, month, 1)
- self._selection = None # no date selected
-
- ttk.Frame.__init__(self, master, **kw)
-
- self._cal = get_calendar(locale, fwday)
-
- self.__setup_styles() # creates custom styles
- self.__place_widgets() # pack/grid used widgets
- self.__config_calendar() # adjust calendar columns and setup tags
- # configure a canvas, and proper bindings, for selecting dates
- self.__setup_selection(sel_bg, sel_fg)
-
- # store items ids, used for insertion later
- self._items = [self._calendar.insert('', 'end', values='')
- for _ in range(6)]
- # insert dates in the currently empty calendar
- self._build_calendar()
-
- # set the minimal size for the widget
- self._calendar.bind('<Map>', self.__minsize)
-
- def __setitem__(self, item, value):
- if item in ('year', 'month'):
- raise AttributeError("attribute '%s' is not writeable" % item)
- elif item == 'selectbackground':
- self._canvas['background'] = value
- elif item == 'selectforeground':
- self._canvas.itemconfigure(self._canvas.text, item=value)
- else:
- ttk.Frame.__setitem__(self, item, value)
-
- def __getitem__(self, item):
- if item in ('year', 'month'):
- return getattr(self._date, item)
- elif item == 'selectbackground':
- return self._canvas['background']
- elif item == 'selectforeground':
- return self._canvas.itemcget(self._canvas.text, 'fill')
- else:
- r = ttk.tclobjs_to_py({item: ttk.Frame.__getitem__(self, item)})
- return r[item]
-
- def __setup_styles(self):
- # custom ttk styles
- style = ttk.Style(self.master)
- arrow_layout = lambda dir: (
- [('Button.focus', {'children': [('Button.%sarrow' % dir, None)]})]
- )
- style.layout('L.TButton', arrow_layout('left'))
- style.layout('R.TButton', arrow_layout('right'))
-
- def __place_widgets(self):
- # header frame and its widgets
- hframe = ttk.Frame(self)
- lbtn = ttk.Button(hframe, style='L.TButton', command=self._prev_month)
- rbtn = ttk.Button(hframe, style='R.TButton', command=self._next_month)
- self._header = ttk.Label(hframe, width=15, anchor='center')
- # the calendar
- self._calendar = ttk.Treeview(show='', selectmode='none', height=7)
-
- # pack the widgets
- hframe.pack(in_=self, side='top', pady=4, anchor='center')
- lbtn.grid(in_=hframe)
- self._header.grid(in_=hframe, column=1, row=0, padx=12)
- rbtn.grid(in_=hframe, column=2, row=0)
- self._calendar.pack(in_=self, expand=1, fill='both', side='bottom')
-
- def __config_calendar(self):
- cols = self._cal.formatweekheader(3).split()
- self._calendar['columns'] = cols
- self._calendar.tag_configure('header', background='grey90')
- self._calendar.insert('', 'end', values=cols, tag='header')
- # adjust its columns width
- font = tkFont.Font()
- maxwidth = max(font.measure(col) for col in cols)
- for col in cols:
- self._calendar.column(col, width=maxwidth, minwidth=maxwidth,
- anchor='e')
-
- def __setup_selection(self, sel_bg, sel_fg):
- self._font = tkFont.Font()
- self._canvas = canvas = Tkinter.Canvas(self._calendar,
- background=sel_bg, borderwidth=0, highlightthickness=0)
- canvas.text = canvas.create_text(0, 0, fill=sel_fg, anchor='w')
-
- canvas.bind('<ButtonPress-1>', lambda evt: canvas.place_forget())
- self._calendar.bind('<Configure>', lambda evt: canvas.place_forget())
- self._calendar.bind('<ButtonPress-1>', self._pressed)
-
- def __minsize(self, evt):
- width, height = self._calendar.master.geometry().split('x')
- height = height[:height.index('+')]
- self._calendar.master.minsize(width, height)
-
- def _build_calendar(self):
- year, month = self._date.year, self._date.month
-
- # update header text (Month, YEAR)
- header = self._cal.formatmonthname(year, month, 0)
- self._header['text'] = header.title()
-
- # update calendar shown dates
- cal = self._cal.monthdayscalendar(year, month)
- for indx, item in enumerate(self._items):
- week = cal[indx] if indx < len(cal) else []
- fmt_week = [('%02d' % day) if day else '' for day in week]
- self._calendar.item(item, values=fmt_week)
-
- def _show_selection(self, text, bbox):
- """Configure canvas for a new selection."""
- x, y, width, height = bbox
-
- textw = self._font.measure(text)
-
- canvas = self._canvas
- canvas.configure(width=width, height=height)
- canvas.coords(canvas.text, width - textw, height / 2 - 1)
- canvas.itemconfigure(canvas.text, text=text)
- canvas.place(in_=self._calendar, x=x, y=y)
-
- # Callbacks
-
- def _pressed(self, evt):
- """Clicked somewhere in the calendar."""
- x, y, widget = evt.x, evt.y, evt.widget
- item = widget.identify_row(y)
- column = widget.identify_column(x)
-
- if not column or not item in self._items:
- # clicked in the weekdays row or just outside the columns
- return
-
- item_values = widget.item(item)['values']
- if not len(item_values): # row is empty for this month
- return
-
- text = item_values[int(column[1]) - 1]
- if not text: # date is empty
- return
-
- bbox = widget.bbox(item, column)
- if not bbox: # calendar not visible yet
- return
-
- # update and then show selection
- text = '%02d' % text
- self._selection = (text, item, column)
- self._show_selection(text, bbox)
-
- def _prev_month(self):
- """Updated calendar to show the previous month."""
- self._canvas.place_forget()
-
- self._date = self._date - self.timedelta(days=1)
- self._date = self.datetime(self._date.year, self._date.month, 1)
- self._build_calendar() # reconstuct calendar
-
- def _next_month(self):
- """Update calendar to show the next month."""
- self._canvas.place_forget()
-
- year, month = self._date.year, self._date.month
- self._date = self._date + self.timedelta(
- days=calendar.monthrange(year, month)[1] + 1)
- self._date = self.datetime(self._date.year, self._date.month, 1)
- self._build_calendar() # reconstruct calendar
-
- # Properties
-
- @property
- def selection(self):
- """Return a datetime representing the current selected date."""
- if not self._selection:
- return None
-
- year, month = self._date.year, self._date.month
- return self.datetime(year, month, int(self._selection[0]))
-
-def test():
- import sys
- root = Tkinter.Tk()
- root.title('Ttk Calendar')
- ttkcal = Calendar(firstweekday=calendar.SUNDAY)
- ttkcal.pack(expand=1, fill='both')
-
- if 'win' not in sys.platform:
- style = ttk.Style()
- style.theme_use('clam')
-
- root.mainloop()
-
-if __name__ == '__main__':
- test()
diff --git a/Demo/tkinter/ttk/widget_state.py b/Demo/tkinter/ttk/widget_state.py
deleted file mode 100644
index c92c28b..0000000
--- a/Demo/tkinter/ttk/widget_state.py
+++ /dev/null
@@ -1,83 +0,0 @@
-"""Sample demo showing widget states and some font styling."""
-import ttk
-
-states = ['active', 'disabled', 'focus', 'pressed', 'selected',
- 'background', 'readonly', 'alternate', 'invalid']
-
-for state in states[:]:
- states.append("!" + state)
-
-def reset_state(widget):
- nostate = states[len(states) // 2:]
- widget.state(nostate)
-
-class App(ttk.Frame):
- def __init__(self, title=None):
- ttk.Frame.__init__(self, borderwidth=6)
- self.master.title(title)
-
- self.style = ttk.Style()
-
- # get default font size and family
- btn_font = self.style.lookup("TButton", "font")
- fsize = str(self.tk.eval("font configure %s -size" % btn_font))
- self.font_family = self.tk.eval("font configure %s -family" % btn_font)
- if ' ' in self.font_family:
- self.font_family = '{%s}' % self.font_family
- self.fsize_prefix = fsize[0] if fsize[0] == '-' else ''
- self.base_fsize = int(fsize[1 if fsize[0] == '-' else 0:])
-
- # a list to hold all the widgets that will have their states changed
- self.update_widgets = []
-
- self._setup_widgets()
-
- def _set_font(self, extra=0):
- self.style.configure("TButton", font="%s %s%d" % (self.font_family,
- self.fsize_prefix, self.base_fsize + extra))
-
- def _new_state(self, widget, newtext):
- widget = self.nametowidget(widget)
-
- if not newtext:
- goodstates = ["disabled"]
- font_extra = 0
- else:
- # set widget state according to what has been entered in the entry
- newstates = set(newtext.split()) # eliminate duplicates
-
- # keep only the valid states
- goodstates = [state for state in newstates if state in states]
- # define a new font size based on amount of states
- font_extra = 2 * len(goodstates)
-
- # set new widget state
- for widget in self.update_widgets:
- reset_state(widget) # remove any previous state from the widget
- widget.state(goodstates)
-
- # update Ttk Button font size
- self._set_font(font_extra)
- return 1
-
- def _setup_widgets(self):
- btn = ttk.Button(self, text='Enter states and watch')
-
- entry = ttk.Entry(self, cursor='xterm', validate="key")
- entry['validatecommand'] = (self.register(self._new_state), '%W', '%P')
- entry.focus()
-
- self.update_widgets.append(btn)
- entry.validate()
-
- entry.pack(fill='x', padx=6)
- btn.pack(side='left', pady=6, padx=6, anchor='n')
- self.pack(fill='both', expand=1)
-
-
-def main():
- app = App("Widget State Tester")
- app.mainloop()
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/turtle/about_turtle.txt b/Demo/turtle/about_turtle.txt
deleted file mode 100644
index 4d290be..0000000
--- a/Demo/turtle/about_turtle.txt
+++ /dev/null
@@ -1,77 +0,0 @@
-
-========================================================
- A new turtle module for Python
-========================================================
-
-Turtle graphics is a popular way for introducing programming to
-kids. It was part of the original Logo programming language developed
-by Wally Feurzig and Seymour Papert in 1966.
-
-Imagine a robotic turtle starting at (0, 0) in the x-y plane. After an ``import turtle``, give it
-the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
-the direction it is facing, drawing a line as it moves. Give it the
-command turtle.right(25), and it rotates in-place 25 degrees clockwise.
-
-By combining together these and similar commands, intricate shapes and
-pictures can easily be drawn.
-
------ turtle.py
-
-This module is an extended reimplementation of turtle.py from the
-Python standard distribution up to Python 2.5. (See: http:\\www.python.org)
-
-It tries to keep the merits of turtle.py and to be (nearly) 100%
-compatible with it. This means in the first place to enable the
-learning programmer to use all the commands, classes and methods
-interactively when using the module from within IDLE run with
-the -n switch.
-
-Roughly it has the following features added:
-
-- Better animation of the turtle movements, especially of turning the
- turtle. So the turtles can more easily be used as a visual feedback
- instrument by the (beginning) programmer.
-
-- Different turtle shapes, gif-images as turtle shapes, user defined
- and user controllable turtle shapes, among them compound
- (multicolored) shapes. Turtle shapes can be stgretched and tilted, which
- makes turtles zu very versatile geometrical objects.
-
-- Fine control over turtle movement and screen updates via delay(),
- and enhanced tracer() and speed() methods.
-
-- Aliases for the most commonly used commands, like fd for forward etc.,
- following the early Logo traditions. This reduces the boring work of
- typing long sequences of commands, which often occur in a natural way
- when kids try to program fancy pictures on their first encounter with
- turtle graphcis.
-
-- Turtles now have an undo()-method with configurable undo-buffer.
-
-- Some simple commands/methods for creating event driven programs
- (mouse-, key-, timer-events). Especially useful for programming games.
-
-- A scrollable Canvas class. The default scrollable Canvas can be
- extended interactively as needed while playing around with the turtle(s).
-
-- A TurtleScreen class with methods controlling background color or
- background image, window and canvas size and other properties of the
- TurtleScreen.
-
-- There is a method, setworldcoordinates(), to install a user defined
- coordinate-system for the TurtleScreen.
-
-- The implementation uses a 2-vector class named Vec2D, derived from tuple.
- This class is public, so it can be imported by the application programmer,
- which makes certain types of computations very natural and compact.
-
-- Appearance of the TurtleScreen and the Turtles at startup/import can be
- configured by means of a turtle.cfg configuration file.
- The default configuration mimics the appearance of the old turtle module.
-
-- If configured appropriately the module reads in docstrings from a docstring
- dictionary in some different language, supplied separately and replaces
- the english ones by those read in. There is a utility function
- write_docstringdict() to write a dictionary with the original (english)
- docstrings to disc, so it can serve as a template for translations.
-
diff --git a/Demo/turtle/about_turtledemo.txt b/Demo/turtle/about_turtledemo.txt
deleted file mode 100644
index c1afec2..0000000
--- a/Demo/turtle/about_turtledemo.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-
- --------------------------------------
- About xturtleDemo.py
- --------------------------------------
-
- Tiny demo Viewer to view turtle graphics example scripts.
-
- Quickly and dirtyly assembled by Gregor Lingl.
- June, 2006
-
- For more information see: xturtleDemo - Help
-
- Have fun!
-
diff --git a/Demo/turtle/demohelp.txt b/Demo/turtle/demohelp.txt
deleted file mode 100644
index d565691..0000000
--- a/Demo/turtle/demohelp.txt
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
- ----------------------------------------------
-
- xturtleDemo - Help
-
- ----------------------------------------------
-
- This document has two sections:
-
- (1) How to use the demo viewer
- (2) How to add your own demos to the demo repository
-
-
- (1) How to use the demo viewer.
-
- Select a demoscript from the example menu.
- The (syntax coloured) source code appears in the left
- source code window. IT CANNOT BE EDITED, but ONLY VIEWED!
-
- - Press START button to start the demo.
- - Stop execution by pressing the STOP button.
- - Clear screen by pressing the CLEAR button.
- - Restart by pressing the START button again.
-
- SPECIAL demos are those which run EVENTDRIVEN.
- (For example clock.py - or oldTurtleDemo.py which
- in the end expects a mouse click.):
-
- Press START button to start the demo.
-
- - Until the EVENTLOOP is entered everything works
- as in an ordinary demo script.
-
- - When the EVENTLOOP is entered, you control the
- application by using the mouse and/or keys (or it's
- controlled by some timer events)
- To stop it you can and must press the STOP button.
-
- While the EVENTLOOP is running, the examples menu is disabled.
-
- - Only after having pressed the STOP button, you may
- restart it or choose another example script.
-
- * * * * * * * *
- In some rare situations there may occur interferences/conflicts
- between events concerning the demo script and those concerning the
- demo-viewer. (They run in the same process.) Strange behaviour may be
- the consequence and in the worst case you must close and restart the
- viewer.
- * * * * * * * *
-
-
- (2) How to add your own demos to the demo repository
-
- - scriptname: must begin with tdemo_ ,
- so it must have the form tdemo_<your-script-name>.py
-
- - place: same directory as xturtleDemo.py or some
- subdirectory, the name of which must also begin with
- tdemo_.....
-
- - requirements on source code:
- code must contain a main() function which will
- be executed by the viewer (see provided example scripts)
- main() may return a string which will be displayed
- in the Label below the source code window (when execution
- has finished.)
-
- !! For programs, which are EVENT DRIVEN, main must return
- !! the string "EVENTLOOP". This informs the viewer, that the
- !! script is still running and must be stopped by the user!
-
-
-
diff --git a/Demo/turtle/tdemo_I_dontlike_tiltdemo.py b/Demo/turtle/tdemo_I_dontlike_tiltdemo.py
deleted file mode 100644
index c9e6e65..0000000
--- a/Demo/turtle/tdemo_I_dontlike_tiltdemo.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python
-""" turtle-example-suite:
-
- tdemo-I_dont_like_tiltdemo.py
-
-Demostrates
- (a) use of a tilted ellipse as
- turtle shape
- (b) stamping that shape
-
-We can remove it, if you don't like it.
- Without using reset() ;-)
- ---------------------------------------
-"""
-from turtle import *
-import time
-
-def main():
- reset()
- shape("circle")
- resizemode("user")
-
- pu(); bk(24*18/6.283); rt(90); pd()
- tilt(45)
-
- pu()
-
- turtlesize(16,10,5)
- color("red", "violet")
- for i in range(18):
- fd(24)
- lt(20)
- stamp()
- color("red", "")
- for i in range(18):
- fd(24)
- lt(20)
- stamp()
-
- tilt(-15)
- turtlesize(3, 1, 4)
- color("blue", "yellow")
- for i in range(17):
- fd(24)
- lt(20)
- if i%2 == 0:
- stamp()
- time.sleep(1)
- while undobufferentries():
- undo()
- ht()
- write("OK, OVER!", align="center", font=("Courier", 18, "bold"))
- return "Done!"
-
-if __name__=="__main__":
- msg = main()
- print msg
- mainloop()
diff --git a/Demo/turtle/tdemo_bytedesign.py b/Demo/turtle/tdemo_bytedesign.py
deleted file mode 100644
index bed671d..0000000
--- a/Demo/turtle/tdemo_bytedesign.py
+++ /dev/null
@@ -1,162 +0,0 @@
-#!/usr/bin/env python
-""" turtle-example-suite:
-
- tdemo_bytedesign.py
-
-An example adapted from the example-suite
-of PythonCard's turtle graphcis.
-
-It's based on an article in BYTE magazine
-Problem Solving with Logo: Using Turtle
-Graphics to Redraw a Design
-November 1982, p. 118 - 134
-
--------------------------------------------
-
-Due to the statement
-
-t.delay(0)
-
-in line 152, which sets the animation delay
-to 0, this animation runs in "line per line"
-mode as fast as possible.
-"""
-
-import math
-from turtle import Turtle, mainloop
-from time import clock
-
-# wrapper for any additional drawing routines
-# that need to know about each other
-class Designer(Turtle):
-
- def design(self, homePos, scale):
- self.up()
- for i in range(5):
- self.forward(64.65 * scale)
- self.down()
- self.wheel(self.position(), scale)
- self.up()
- self.backward(64.65 * scale)
- self.right(72)
- self.up()
- self.goto(homePos)
- self.right(36)
- self.forward(24.5 * scale)
- self.right(198)
- self.down()
- self.centerpiece(46 * scale, 143.4, scale)
- self.tracer(True)
-
- def wheel(self, initpos, scale):
- self.right(54)
- for i in range(4):
- self.pentpiece(initpos, scale)
- self.down()
- self.left(36)
- for i in range(5):
- self.tripiece(initpos, scale)
- self.left(36)
- for i in range(5):
- self.down()
- self.right(72)
- self.forward(28 * scale)
- self.up()
- self.backward(28 * scale)
- self.left(54)
- self.getscreen().update()
-
- def tripiece(self, initpos, scale):
- oldh = self.heading()
- self.down()
- self.backward(2.5 * scale)
- self.tripolyr(31.5 * scale, scale)
- self.up()
- self.goto(initpos)
- self.setheading(oldh)
- self.down()
- self.backward(2.5 * scale)
- self.tripolyl(31.5 * scale, scale)
- self.up()
- self.goto(initpos)
- self.setheading(oldh)
- self.left(72)
- self.getscreen().update()
-
- def pentpiece(self, initpos, scale):
- oldh = self.heading()
- self.up()
- self.forward(29 * scale)
- self.down()
- for i in range(5):
- self.forward(18 * scale)
- self.right(72)
- self.pentr(18 * scale, 75, scale)
- self.up()
- self.goto(initpos)
- self.setheading(oldh)
- self.forward(29 * scale)
- self.down()
- for i in range(5):
- self.forward(18 * scale)
- self.right(72)
- self.pentl(18 * scale, 75, scale)
- self.up()
- self.goto(initpos)
- self.setheading(oldh)
- self.left(72)
- self.getscreen().update()
-
- def pentl(self, side, ang, scale):
- if side < (2 * scale): return
- self.forward(side)
- self.left(ang)
- self.pentl(side - (.38 * scale), ang, scale)
-
- def pentr(self, side, ang, scale):
- if side < (2 * scale): return
- self.forward(side)
- self.right(ang)
- self.pentr(side - (.38 * scale), ang, scale)
-
- def tripolyr(self, side, scale):
- if side < (4 * scale): return
- self.forward(side)
- self.right(111)
- self.forward(side / 1.78)
- self.right(111)
- self.forward(side / 1.3)
- self.right(146)
- self.tripolyr(side * .75, scale)
-
- def tripolyl(self, side, scale):
- if side < (4 * scale): return
- self.forward(side)
- self.left(111)
- self.forward(side / 1.78)
- self.left(111)
- self.forward(side / 1.3)
- self.left(146)
- self.tripolyl(side * .75, scale)
-
- def centerpiece(self, s, a, scale):
- self.forward(s); self.left(a)
- if s < (7.5 * scale):
- return
- self.centerpiece(s - (1.2 * scale), a, scale)
-
-def main():
- t = Designer()
- t.speed(0)
- t.hideturtle()
- t.getscreen().delay(0)
- t.tracer(0)
- at = clock()
- t.design(t.position(), 2)
- et = clock()
- return "runtime: %.2f sec." % (et-at)
-
-if __name__ == '__main__':
- msg = main()
- print msg
- mainloop()
diff --git a/Demo/turtle/tdemo_clock.py b/Demo/turtle/tdemo_clock.py
deleted file mode 100644
index b6280bb..0000000
--- a/Demo/turtle/tdemo_clock.py
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: cp1252 -*-
-""" turtle-example-suite:
-
- tdemo_clock.py
-
-Enhanced clock-program, showing date
-and time
- ------------------------------------
- Press STOP to exit the program!
- ------------------------------------
-"""
-from turtle import *
-from datetime import datetime
-
-mode("logo")
-
-def jump(distanz, winkel=0):
- penup()
- right(winkel)
- forward(distanz)
- left(winkel)
- pendown()
-
-def hand(laenge, spitze):
- fd(laenge*1.15)
- rt(90)
- fd(spitze/2.0)
- lt(120)
- fd(spitze)
- lt(120)
- fd(spitze)
- lt(120)
- fd(spitze/2.0)
-
-def make_hand_shape(name, laenge, spitze):
- reset()
- jump(-laenge*0.15)
- begin_poly()
- hand(laenge, spitze)
- end_poly()
- hand_form = get_poly()
- register_shape(name, hand_form)
-
-
-def clockface(radius):
- reset()
- pensize(7)
- for i in range(60):
- jump(radius)
- if i % 5 == 0:
- fd(25)
- jump(-radius-25)
- else:
- dot(3)
- jump(-radius)
- rt(6)
-
-def setup():
- global second_hand, minute_hand, hour_hand, writer
- mode("logo")
- make_hand_shape("second_hand", 125, 25)
- make_hand_shape("minute_hand", 130, 25)
- make_hand_shape("hour_hand", 90, 25)
- clockface(160)
- second_hand = Turtle()
- second_hand.shape("second_hand")
- second_hand.color("gray20", "gray80")
- minute_hand = Turtle()
- minute_hand.shape("minute_hand")
- minute_hand.color("blue1", "red1")
- hour_hand = Turtle()
- hour_hand.shape("hour_hand")
- hour_hand.color("blue3", "red3")
- for hand in second_hand, minute_hand, hour_hand:
- hand.resizemode("user")
- hand.shapesize(1, 1, 3)
- hand.speed(0)
- ht()
- writer = Turtle()
- #writer.mode("logo")
- writer.ht()
- writer.pu()
- writer.bk(85)
-
-
-def wochentag(t):
- wochentag = ["Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday", "Sunday"]
- return wochentag[t.weekday()]
-
-def datum(z):
- monat = ["Jan.", "Feb.", "Mar.", "Apr.", "May", "June",
- "July", "Aug.", "Sep.", "Oct.", "Nov.", "Dec."]
- j = z.year
- m = monat[z.month - 1]
- t = z.day
- return "%s %d %d" % (m, t, j)
-
-def tick():
- t = datetime.today()
- sekunde = t.second + t.microsecond*0.000001
- minute = t.minute + sekunde/60.0
- stunde = t.hour + minute/60.0
- tracer(False)
- writer.clear()
- writer.home()
- writer.forward(65)
- writer.write(wochentag(t),
- align="center", font=("Courier", 14, "bold"))
- writer.back(150)
- writer.write(datum(t),
- align="center", font=("Courier", 14, "bold"))
- writer.forward(85)
- tracer(True)
- second_hand.setheading(6*sekunde)
- minute_hand.setheading(6*minute)
- hour_hand.setheading(30*stunde)
- tracer(True)
- ontimer(tick, 100)
-
-def main():
- tracer(False)
- setup()
- tracer(True)
- tick()
- return "EVENTLOOP"
-
-if __name__ == "__main__":
- msg = main()
- print msg
- mainloop()
diff --git a/Demo/turtle/tdemo_colormixer.py b/Demo/turtle/tdemo_colormixer.py
deleted file mode 100644
index 07d7ee2..0000000
--- a/Demo/turtle/tdemo_colormixer.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# colormixer
-
-from turtle import Screen, Turtle, mainloop
-
-class ColorTurtle(Turtle):
-
- def __init__(self, x, y):
- Turtle.__init__(self)
- self.shape("turtle")
- self.resizemode("user")
- self.shapesize(3,3,5)
- self.pensize(10)
- self._color = [0,0,0]
- self.x = x
- self._color[x] = y
- self.color(self._color)
- self.speed(0)
- self.left(90)
- self.pu()
- self.goto(x,0)
- self.pd()
- self.sety(1)
- self.pu()
- self.sety(y)
- self.pencolor("gray25")
- self.ondrag(self.shift)
-
- def shift(self, x, y):
- self.sety(max(0,min(y,1)))
- self._color[self.x] = self.ycor()
- self.fillcolor(self._color)
- setbgcolor()
-
-def setbgcolor():
- screen.bgcolor(red.ycor(), green.ycor(), blue.ycor())
-
-def main():
- global screen, red, green, blue
- screen = Screen()
- screen.delay(0)
- screen.setworldcoordinates(-1, -0.3, 3, 1.3)
-
- red = ColorTurtle(0, .5)
- green = ColorTurtle(1, .5)
- blue = ColorTurtle(2, .5)
- setbgcolor()
-
- writer = Turtle()
- writer.ht()
- writer.pu()
- writer.goto(1,1.15)
- writer.write("DRAG!",align="center",font=("Arial",30,("bold","italic")))
- return "EVENTLOOP"
-
-if __name__ == "__main__":
- msg = main()
- print msg
- mainloop()
diff --git a/Demo/turtle/tdemo_fractalcurves.py b/Demo/turtle/tdemo_fractalcurves.py
deleted file mode 100644
index 2ac8ecd..0000000
--- a/Demo/turtle/tdemo_fractalcurves.py
+++ /dev/null
@@ -1,137 +0,0 @@
-#!/usr/bin/env python
-""" turtle-example-suite:
-
- tdemo_fractalCurves.py
-
-This program draws two fractal-curve-designs:
-(1) A hilbert curve (in a box)
-(2) A combination of Koch-curves.
-
-The CurvesTurtle class and the fractal-curve-
-methods are taken from the PythonCard example
-scripts for turtle-graphics.
-"""
-from turtle import *
-from time import sleep, clock
-
-class CurvesTurtle(Pen):
- # example derived from
- # Turtle Geometry: The Computer as a Medium for Exploring Mathematics
- # by Harold Abelson and Andrea diSessa
- # p. 96-98
- def hilbert(self, size, level, parity):
- if level == 0:
- return
- # rotate and draw first subcurve with opposite parity to big curve
- self.left(parity * 90)
- self.hilbert(size, level - 1, -parity)
- # interface to and draw second subcurve with same parity as big curve
- self.forward(size)
- self.right(parity * 90)
- self.hilbert(size, level - 1, parity)
- # third subcurve
- self.forward(size)
- self.hilbert(size, level - 1, parity)
- # fourth subcurve
- self.right(parity * 90)
- self.forward(size)
- self.hilbert(size, level - 1, -parity)
- # a final turn is needed to make the turtle
- # end up facing outward from the large square
- self.left(parity * 90)
-
- # Visual Modeling with Logo: A Structural Approach to Seeing
- # by James Clayson
- # Koch curve, after Helge von Koch who introduced this geometric figure in 1904
- # p. 146
- def fractalgon(self, n, rad, lev, dir):
- import math
-
- # if dir = 1 turn outward
- # if dir = -1 turn inward
- edge = 2 * rad * math.sin(math.pi / n)
- self.pu()
- self.fd(rad)
- self.pd()
- self.rt(180 - (90 * (n - 2) / n))
- for i in range(n):
- self.fractal(edge, lev, dir)
- self.rt(360 / n)
- self.lt(180 - (90 * (n - 2) / n))
- self.pu()
- self.bk(rad)
- self.pd()
-
- # p. 146
- def fractal(self, dist, depth, dir):
- if depth < 1:
- self.fd(dist)
- return
- self.fractal(dist / 3, depth - 1, dir)
- self.lt(60 * dir)
- self.fractal(dist / 3, depth - 1, dir)
- self.rt(120 * dir)
- self.fractal(dist / 3, depth - 1, dir)
- self.lt(60 * dir)
- self.fractal(dist / 3, depth - 1, dir)
-
-def main():
- ft = CurvesTurtle()
-
- ft.reset()
- ft.speed(0)
- ft.ht()
- ft.tracer(1,0)
- ft.pu()
-
- size = 6
- ft.setpos(-33*size, -32*size)
- ft.pd()
-
- ta=clock()
- ft.fillcolor("red")
- ft.fill(True)
- ft.fd(size)
-
- ft.hilbert(size, 6, 1)
-
- # frame
- ft.fd(size)
- for i in range(3):
- ft.lt(90)
- ft.fd(size*(64+i%2))
- ft.pu()
- for i in range(2):
- ft.fd(size)
- ft.rt(90)
- ft.pd()
- for i in range(4):
- ft.fd(size*(66+i%2))
- ft.rt(90)
- ft.fill(False)
- tb=clock()
- res = "Hilbert: %.2fsec. " % (tb-ta)
-
- sleep(3)
-
- ft.reset()
- ft.speed(0)
- ft.ht()
- ft.tracer(1,0)
-
- ta=clock()
- ft.color("black", "blue")
- ft.fill(True)
- ft.fractalgon(3, 250, 4, 1)
- ft.fill(True)
- ft.color("red")
- ft.fractalgon(3, 200, 4, -1)
- ft.fill(False)
- tb=clock()
- res += "Koch: %.2fsec." % (tb-ta)
- return res
-
-if __name__ == '__main__':
- msg = main()
- print msg
- mainloop()
diff --git a/Demo/turtle/tdemo_lindenmayer_indian.py b/Demo/turtle/tdemo_lindenmayer_indian.py
deleted file mode 100644
index 92c8cff..0000000
--- a/Demo/turtle/tdemo_lindenmayer_indian.py
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/usr/bin/env python
-""" turtle-example-suite:
-
- xtx_lindenmayer_indian.py
-
-Each morning women in Tamil Nadu, in southern
-India, place designs, created by using rice
-flour and known as kolam on the thresholds of
-their homes.
-
-These can be described by Lindenmayer systems,
-which can easily be implemented with turtle
-graphics and Python.
-
-Two examples are shown here:
-(1) the snake kolam
-(2) anklets of Krishna
-
-Taken from Marcia Ascher: Mathematics
-Elsewhere, An Exploration of Ideas Across
-Cultures
-
-"""
-################################
-# Mini Lindenmayer tool
-###############################
-
-from turtle import *
-
-def replace( seq, replacementRules, n ):
- for i in range(n):
- newseq = ""
- for element in seq:
- newseq = newseq + replacementRules.get(element,element)
- seq = newseq
- return seq
-
-def draw( commands, rules ):
- for b in commands:
- try:
- rules[b]()
- except TypeError:
- try:
- draw(rules[b], rules)
- except:
- pass
-
-
-def main():
- ################################
- # Example 1: Snake kolam
- ################################
-
-
- def r():
- right(45)
-
- def l():
- left(45)
-
- def f():
- forward(7.5)
-
- snake_rules = {"-":r, "+":l, "f":f, "b":"f+f+f--f--f+f+f"}
- snake_replacementRules = {"b": "b+f+b--f--b+f+b"}
- snake_start = "b--f--b--f"
-
- drawing = replace(snake_start, snake_replacementRules, 3)
-
- reset()
- speed(3)
- tracer(1,0)
- ht()
- up()
- backward(195)
- down()
- draw(drawing, snake_rules)
-
- from time import sleep
- sleep(3)
-
- ################################
- # Example 2: Anklets of Krishna
- ################################
-
- def A():
- color("red")
- circle(10,90)
-
- def B():
- from math import sqrt
- color("black")
- l = 5/sqrt(2)
- forward(l)
- circle(l, 270)
- forward(l)
-
- def F():
- color("green")
- forward(10)
-
- krishna_rules = {"a":A, "b":B, "f":F}
- krishna_replacementRules = {"a" : "afbfa", "b" : "afbfbfbfa" }
- krishna_start = "fbfbfbfb"
-
- reset()
- speed(0)
- tracer(3,0)
- ht()
- left(45)
- drawing = replace(krishna_start, krishna_replacementRules, 3)
- draw(drawing, krishna_rules)
- tracer(1)
- return "Done!"
-
-if __name__=='__main__':
- msg = main()
- print msg
- mainloop()
diff --git a/Demo/turtle/tdemo_minimal_hanoi.py b/Demo/turtle/tdemo_minimal_hanoi.py
deleted file mode 100644
index 8a1caa8..0000000
--- a/Demo/turtle/tdemo_minimal_hanoi.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/env python
-""" turtle-example-suite:
-
- tdemo_minimal_hanoi.py
-
-A minimal 'Towers of Hanoi' animation:
-A tower of 6 discs is transferred from the
-left to the right peg.
-
-An imho quite elegant and concise
-implementation using a tower class, which
-is derived from the built-in type list.
-
-Discs are turtles with shape "square", but
-stretched to rectangles by shapesize()
- ---------------------------------------
- To exit press STOP button
- ---------------------------------------
-"""
-from turtle import *
-
-class Disc(Turtle):
- def __init__(self, n):
- Turtle.__init__(self, shape="square", visible=False)
- self.pu()
- self.shapesize(1.5, n*1.5, 2) # square-->rectangle
- self.fillcolor(n/6., 0, 1-n/6.)
- self.st()
-
-class Tower(list):
- "Hanoi tower, a subclass of built-in type list"
- def __init__(self, x):
- "create an empty tower. x is x-position of peg"
- self.x = x
- def push(self, d):
- d.setx(self.x)
- d.sety(-150+34*len(self))
- self.append(d)
- def pop(self):
- d = list.pop(self)
- d.sety(150)
- return d
-
-def hanoi(n, from_, with_, to_):
- if n > 0:
- hanoi(n-1, from_, to_, with_)
- to_.push(from_.pop())
- hanoi(n-1, with_, from_, to_)
-
-def play():
- onkey(None,"space")
- clear()
- hanoi(6, t1, t2, t3)
- write("press STOP button to exit",
- align="center", font=("Courier", 16, "bold"))
-
-def main():
- global t1, t2, t3
- ht(); penup(); goto(0, -225) # writer turtle
- t1 = Tower(-250)
- t2 = Tower(0)
- t3 = Tower(250)
- # make tower of 6 discs
- for i in range(6,0,-1):
- t1.push(Disc(i))
- # prepare spartanic user interface ;-)
- write("press spacebar to start game",
- align="center", font=("Courier", 16, "bold"))
- onkey(play, "space")
- listen()
- return "EVENTLOOP"
-
-if __name__=="__main__":
- msg = main()
- print msg
- mainloop()
diff --git a/Demo/turtle/tdemo_nim.py b/Demo/turtle/tdemo_nim.py
deleted file mode 100644
index 8e66d7e..0000000
--- a/Demo/turtle/tdemo_nim.py
+++ /dev/null
@@ -1,227 +0,0 @@
-""" turtle-example-suite:
-
- tdemo_nim.py
-
-Play nim against the computer. The player
-who takes the last stick is the winner.
-
-Implements the model-view-controller
-design pattern.
-"""
-
-
-import turtle
-import random
-import time
-
-SCREENWIDTH = 640
-SCREENHEIGHT = 480
-
-MINSTICKS = 7
-MAXSTICKS = 31
-
-HUNIT = SCREENHEIGHT // 12
-WUNIT = SCREENWIDTH // ((MAXSTICKS // 5) * 11 + (MAXSTICKS % 5) * 2)
-
-SCOLOR = (63, 63, 31)
-HCOLOR = (255, 204, 204)
-COLOR = (204, 204, 255)
-
-def randomrow():
- return random.randint(MINSTICKS, MAXSTICKS)
-
-def computerzug(state):
- xored = state[0] ^ state[1] ^ state[2]
- if xored == 0:
- return randommove(state)
- for z in range(3):
- s = state[z] ^ xored
- if s <= state[z]:
- move = (z, s)
- return move
-
-def randommove(state):
- m = max(state)
- while True:
- z = random.randint(0,2)
- if state[z] > (m > 1):
- break
- rand = random.randint(m > 1, state[z]-1)
- return z, rand
-
-
-class NimModel(object):
- def __init__(self, game):
- self.game = game
-
- def setup(self):
- if self.game.state not in [Nim.CREATED, Nim.OVER]:
- return
- self.sticks = [randomrow(), randomrow(), randomrow()]
- self.player = 0
- self.winner = None
- self.game.view.setup()
- self.game.state = Nim.RUNNING
-
- def move(self, row, col):
- maxspalte = self.sticks[row]
- self.sticks[row] = col
- self.game.view.notify_move(row, col, maxspalte, self.player)
- if self.game_over():
- self.game.state = Nim.OVER
- self.winner = self.player
- self.game.view.notify_over()
- elif self.player == 0:
- self.player = 1
- row, col = computerzug(self.sticks)
- self.move(row, col)
- self.player = 0
-
- def game_over(self):
- return self.sticks == [0, 0, 0]
-
- def notify_move(self, row, col):
- if self.sticks[row] <= col:
- return
- self.move(row, col)
-
-
-class Stick(turtle.Turtle):
- def __init__(self, row, col, game):
- turtle.Turtle.__init__(self, visible=False)
- self.row = row
- self.col = col
- self.game = game
- x, y = self.coords(row, col)
- self.shape("square")
- self.shapesize(HUNIT/10.0, WUNIT/20.0)
- self.speed(0)
- self.pu()
- self.goto(x,y)
- self.color("white")
- self.showturtle()
-
- def coords(self, row, col):
- packet, remainder = divmod(col, 5)
- x = (3 + 11 * packet + 2 * remainder) * WUNIT
- y = (2 + 3 * row) * HUNIT
- return x - SCREENWIDTH // 2 + WUNIT // 2, SCREENHEIGHT // 2 - y - HUNIT // 2
-
- def makemove(self, x, y):
- if self.game.state != Nim.RUNNING:
- return
- self.game.controller.notify_move(self.row, self.col)
-
-
-class NimView(object):
- def __init__(self, game):
- self.game = game
- self.screen = game.screen
- self.model = game.model
- self.screen.colormode(255)
- self.screen.tracer(False)
- self.screen.bgcolor((240, 240, 255))
- self.writer = turtle.Turtle(visible=False)
- self.writer.pu()
- self.writer.speed(0)
- self.sticks = {}
- for row in range(3):
- for col in range(MAXSTICKS):
- self.sticks[(row, col)] = Stick(row, col, game)
- self.display("... a moment please ...")
- self.screen.tracer(True)
-
- def display(self, msg1, msg2=None):
- self.screen.tracer(False)
- self.writer.clear()
- if msg2 is not None:
- self.writer.goto(0, - SCREENHEIGHT // 2 + 48)
- self.writer.pencolor("red")
- self.writer.write(msg2, align="center", font=("Courier",18,"bold"))
- self.writer.goto(0, - SCREENHEIGHT // 2 + 20)
- self.writer.pencolor("black")
- self.writer.write(msg1, align="center", font=("Courier",14,"bold"))
- self.screen.tracer(True)
-
-
- def setup(self):
- self.screen.tracer(False)
- for row in range(3):
- for col in range(self.model.sticks[row]):
- self.sticks[(row, col)].color(SCOLOR)
- for row in range(3):
- for col in range(self.model.sticks[row], MAXSTICKS):
- self.sticks[(row, col)].color("white")
- self.display("Your turn! Click leftmost stick to remove.")
- self.screen.tracer(True)
-
- def notify_move(self, row, col, maxspalte, player):
- if player == 0:
- farbe = HCOLOR
- for s in range(col, maxspalte):
- self.sticks[(row, s)].color(farbe)
- else:
- self.display(" ... thinking ... ")
- time.sleep(0.5)
- self.display(" ... thinking ... aaah ...")
- farbe = COLOR
- for s in range(maxspalte-1, col-1, -1):
- time.sleep(0.2)
- self.sticks[(row, s)].color(farbe)
- self.display("Your turn! Click leftmost stick to remove.")
-
- def notify_over(self):
- if self.game.model.winner == 0:
- msg2 = "Congrats. You're the winner!!!"
- else:
- msg2 = "Sorry, the computer is the winner."
- self.display("To play again press space bar. To leave press ESC.", msg2)
-
- def clear(self):
- if self.game.state == Nim.OVER:
- self.screen.clear()
-
-class NimController(object):
-
- def __init__(self, game):
- self.game = game
- self.sticks = game.view.sticks
- self.BUSY = False
- for stick in self.sticks.values():
- stick.onclick(stick.makemove)
- self.game.screen.onkey(self.game.model.setup, "space")
- self.game.screen.onkey(self.game.view.clear, "Escape")
- self.game.view.display("Press space bar to start game")
- self.game.screen.listen()
-
- def notify_move(self, row, col):
- if self.BUSY:
- return
- self.BUSY = True
- self.game.model.notify_move(row, col)
- self.BUSY = False
-
-class Nim(object):
- CREATED = 0
- RUNNING = 1
- OVER = 2
- def __init__(self, screen):
- self.state = Nim.CREATED
- self.screen = screen
- self.model = NimModel(self)
- self.view = NimView(self)
- self.controller = NimController(self)
-
-
-mainscreen = turtle.Screen()
-mainscreen.mode("standard")
-mainscreen.setup(SCREENWIDTH, SCREENHEIGHT)
-
-def main():
- nim = Nim(mainscreen)
- return "EVENTLOOP!"
-
-if __name__ == "__main__":
- main()
- turtle.mainloop()
-
diff --git a/Demo/turtle/tdemo_paint.py b/Demo/turtle/tdemo_paint.py
deleted file mode 100644
index e1d6303..0000000
--- a/Demo/turtle/tdemo_paint.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-""" turtle-example-suite:
-
- tdemo_paint.py
-
-A simple eventdriven paint program
-
-- use left mouse button to move turtle
-- middle mouse button to change color
-- right mouse button do turn filling on/off
- -------------------------------------------
- Play around by clicking into the canvas
- using all three mouse buttons.
- -------------------------------------------
- To exit press STOP button
- -------------------------------------------
-"""
-from turtle import *
-
-def switchupdown(x=0, y=0):
- if pen()["pendown"]:
- end_fill()
- up()
- else:
- down()
- begin_fill()
-
-def changecolor(x=0, y=0):
- global colors
- colors = colors[1:]+colors[:1]
- color(colors[0])
-
-def main():
- global colors
- shape("circle")
- resizemode("user")
- shapesize(.5)
- width(3)
- colors=["red", "green", "blue", "yellow"]
- color(colors[0])
- switchupdown()
- onscreenclick(goto,1)
- onscreenclick(changecolor,2)
- onscreenclick(switchupdown,3)
- return "EVENTLOOP"
-
-if __name__ == "__main__":
- msg = main()
- print msg
- mainloop()
diff --git a/Demo/turtle/tdemo_peace.py b/Demo/turtle/tdemo_peace.py
deleted file mode 100644
index 13044c9..0000000
--- a/Demo/turtle/tdemo_peace.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python
-""" turtle-example-suite:
-
- tdemo_peace.py
-
-A very simple drawing suitable as a beginner's
-programming example.
-
-Uses only commands, which are also available in
-old turtle.py.
-
-Intentionally no variables are used except for the
-colorloop:
-"""
-
-from turtle import *
-
-def main():
- peacecolors = ("red3", "orange", "yellow",
- "seagreen4", "orchid4",
- "royalblue1", "dodgerblue4")
-
- reset()
- s = Screen()
- up()
- goto(-320,-195)
- width(70)
-
- for pcolor in peacecolors:
- color(pcolor)
- down()
- forward(640)
- up()
- backward(640)
- left(90)
- forward(66)
- right(90)
-
- width(25)
- color("white")
- goto(0,-170)
- down()
-
- circle(170)
- left(90)
- forward(340)
- up()
- left(180)
- forward(170)
- right(45)
- down()
- forward(170)
- up()
- backward(170)
- left(90)
- down()
- forward(170)
- up()
-
- goto(0,300) # vanish if hideturtle() is not available ;-)
- return "Done!!"
-
-if __name__ == "__main__":
- main()
- mainloop()
diff --git a/Demo/turtle/tdemo_penrose.py b/Demo/turtle/tdemo_penrose.py
deleted file mode 100644
index f5824d7..0000000
--- a/Demo/turtle/tdemo_penrose.py
+++ /dev/null
@@ -1,181 +0,0 @@
-#!/usr/bin/env python
-""" xturtle-example-suite:
-
- xtx_kites_and_darts.py
-
-Constructs two aperiodic penrose-tilings,
-consisting of kites and darts, by the method
-of inflation in six steps.
-
-Starting points are the patterns "sun"
-consisting of five kites and "star"
-consisting of five darts.
-
-For more information see:
- http://en.wikipedia.org/wiki/Penrose_tiling
- -------------------------------------------
-"""
-from turtle import *
-from math import cos, pi
-from time import clock, sleep
-
-f = (5**0.5-1)/2.0 # (sqrt(5)-1)/2 -- golden ratio
-d = 2 * cos(3*pi/10)
-
-def kite(l):
- fl = f * l
- lt(36)
- fd(l)
- rt(108)
- fd(fl)
- rt(36)
- fd(fl)
- rt(108)
- fd(l)
- rt(144)
-
-def dart(l):
- fl = f * l
- lt(36)
- fd(l)
- rt(144)
- fd(fl)
- lt(36)
- fd(fl)
- rt(144)
- fd(l)
- rt(144)
-
-def inflatekite(l, n):
- if n == 0:
- px, py = pos()
- h, x, y = int(heading()), round(px,3), round(py,3)
- tiledict[(h,x,y)] = True
- return
- fl = f * l
- lt(36)
- inflatedart(fl, n-1)
- fd(l)
- rt(144)
- inflatekite(fl, n-1)
- lt(18)
- fd(l*d)
- rt(162)
- inflatekite(fl, n-1)
- lt(36)
- fd(l)
- rt(180)
- inflatedart(fl, n-1)
- lt(36)
-
-def inflatedart(l, n):
- if n == 0:
- px, py = pos()
- h, x, y = int(heading()), round(px,3), round(py,3)
- tiledict[(h,x,y)] = False
- return
- fl = f * l
- inflatekite(fl, n-1)
- lt(36)
- fd(l)
- rt(180)
- inflatedart(fl, n-1)
- lt(54)
- fd(l*d)
- rt(126)
- inflatedart(fl, n-1)
- fd(l)
- rt(144)
-
-def draw(l, n, th=2):
- clear()
- l = l * f**n
- shapesize(l/100.0, l/100.0, th)
- for k in tiledict:
- h, x, y = k
- setpos(x, y)
- setheading(h)
- if tiledict[k]:
- shape("kite")
- color("black", (0, 0.75, 0))
- else:
- shape("dart")
- color("black", (0.75, 0, 0))
- stamp()
-
-def sun(l, n):
- for i in range(5):
- inflatekite(l, n)
- lt(72)
-
-def star(l,n):
- for i in range(5):
- inflatedart(l, n)
- lt(72)
-
-def makeshapes():
- tracer(0)
- begin_poly()
- kite(100)
- end_poly()
- register_shape("kite", get_poly())
- begin_poly()
- dart(100)
- end_poly()
- register_shape("dart", get_poly())
- tracer(1)
-
-def start():
- reset()
- ht()
- pu()
- makeshapes()
- resizemode("user")
-
-def test(l=200, n=4, fun=sun, startpos=(0,0), th=2):
- global tiledict
- goto(startpos)
- setheading(0)
- tiledict = {}
- a = clock()
- tracer(0)
- fun(l, n)
- b = clock()
- draw(l, n, th)
- tracer(1)
- c = clock()
- print "Calculation: %7.4f s" % (b - a)
- print "Drawing: %7.4f s" % (c - b)
- print "Together: %7.4f s" % (c - a)
- nk = len([x for x in tiledict if tiledict[x]])
- nd = len([x for x in tiledict if not tiledict[x]])
- print "%d kites and %d darts = %d pieces." % (nk, nd, nk+nd)
-
-def demo(fun=sun):
- start()
- for i in range(8):
- a = clock()
- test(300, i, fun)
- b = clock()
- t = b - a
- if t < 2:
- sleep(2 - t)
-
-def main():
- #title("Penrose-tiling with kites and darts.")
- mode("logo")
- bgcolor(0.3, 0.3, 0)
- demo(sun)
- sleep(2)
- demo(star)
- pencolor("black")
- goto(0,-200)
- pencolor(0.7,0.7,1)
- write("Please wait...",
- align="center", font=('Arial Black', 36, 'bold'))
- test(600, 8, startpos=(70, 117))
- return "Done"
-
-if __name__ == "__main__":
- msg = main()
- mainloop()
diff --git a/Demo/turtle/tdemo_planet_and_moon.py b/Demo/turtle/tdemo_planet_and_moon.py
deleted file mode 100644
index 223d87b..0000000
--- a/Demo/turtle/tdemo_planet_and_moon.py
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/usr/bin/env python
-""" turtle-example-suite:
-
- tdemo_planets_and_moon.py
-
-Gravitational system simulation using the
-approximation method from Feynman-lectures,
-p.9-8, using turtlegraphics.
-
-Example: heavy central body, light planet,
-very light moon!
-Planet has a circular orbit, moon a stable
-orbit around the planet.
-
-You can hold the movement temporarily by pressing
-the left mouse button with mouse over the
-scrollbar of the canvas.
-
-"""
-from turtle import Shape, Turtle, mainloop, Vec2D as Vec
-from time import sleep
-
-G = 8
-
-class GravSys(object):
- def __init__(self):
- self.planets = []
- self.t = 0
- self.dt = 0.01
- def init(self):
- for p in self.planets:
- p.init()
- def start(self):
- for i in range(10000):
- self.t += self.dt
- for p in self.planets:
- p.step()
-
-class Star(Turtle):
- def __init__(self, m, x, v, gravSys, shape):
- Turtle.__init__(self, shape=shape)
- self.penup()
- self.m = m
- self.setpos(x)
- self.v = v
- gravSys.planets.append(self)
- self.gravSys = gravSys
- self.resizemode("user")
- self.pendown()
- def init(self):
- dt = self.gravSys.dt
- self.a = self.acc()
- self.v = self.v + 0.5*dt*self.a
- def acc(self):
- a = Vec(0,0)
- for planet in self.gravSys.planets:
- if planet != self:
- v = planet.pos()-self.pos()
- a += (G*planet.m/abs(v)**3)*v
- return a
- def step(self):
- dt = self.gravSys.dt
- self.setpos(self.pos() + dt*self.v)
- if self.gravSys.planets.index(self) != 0:
- self.setheading(self.towards(self.gravSys.planets[0]))
- self.a = self.acc()
- self.v = self.v + dt*self.a
-
-## create compound yellow/blue turtleshape for planets
-
-def main():
- s = Turtle()
- s.reset()
- s.tracer(0,0)
- s.ht()
- s.pu()
- s.fd(6)
- s.lt(90)
- s.begin_poly()
- s.circle(6, 180)
- s.end_poly()
- m1 = s.get_poly()
- s.begin_poly()
- s.circle(6,180)
- s.end_poly()
- m2 = s.get_poly()
-
- planetshape = Shape("compound")
- planetshape.addcomponent(m1,"orange")
- planetshape.addcomponent(m2,"blue")
- s.getscreen().register_shape("planet", planetshape)
- s.tracer(1,0)
-
- ## setup gravitational system
- gs = GravSys()
- sun = Star(1000000, Vec(0,0), Vec(0,-2.5), gs, "circle")
- sun.color("yellow")
- sun.shapesize(1.8)
- sun.pu()
- earth = Star(12500, Vec(210,0), Vec(0,195), gs, "planet")
- earth.pencolor("green")
- earth.shapesize(0.8)
- moon = Star(1, Vec(220,0), Vec(0,295), gs, "planet")
- moon.pencolor("blue")
- moon.shapesize(0.5)
- gs.init()
- gs.start()
- return "Done!"
-
-if __name__ == '__main__':
- msg = main()
- print msg
- mainloop()
diff --git a/Demo/turtle/tdemo_tree.py b/Demo/turtle/tdemo_tree.py
deleted file mode 100644
index 6fc8735..0000000
--- a/Demo/turtle/tdemo_tree.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env python
-""" turtle-example-suite:
-
- tdemo_tree.py
-
-Displays a 'breadth-first-tree' - in contrast
-to the classical Logo tree drawing programs,
-which use a depth-first-algorithm.
-
-Uses:
-(1) a tree-generator, where the drawing is
-quasi the side-effect, whereas the generator
-always yields None.
-(2) Turtle-cloning: At each branching point the
-current pen is cloned. So in the end there
-are 1024 turtles.
-"""
-from turtle import Turtle, mainloop
-from time import clock
-
-def tree(plist, l, a, f):
- """ plist is list of pens
- l is length of branch
- a is half of the angle between 2 branches
- f is factor by which branch is shortened
- from level to level."""
- if l > 3:
- lst = []
- for p in plist:
- p.forward(l)
- q = p.clone()
- p.left(a)
- q.right(a)
- lst.append(p)
- lst.append(q)
- for x in tree(lst, l*f, a, f):
- yield None
-
-def maketree():
- p = Turtle()
- p.setundobuffer(None)
- p.hideturtle()
- p.speed(0)
- p.tracer(30,0)
- p.left(90)
- p.penup()
- p.forward(-210)
- p.pendown()
- t = tree([p], 200, 65, 0.6375)
- for x in t:
- pass
- print len(p.getscreen().turtles())
-
-def main():
- a=clock()
- maketree()
- b=clock()
- return "done: %.2f sec." % (b-a)
-
-if __name__ == "__main__":
- msg = main()
- print msg
- mainloop()
diff --git a/Demo/turtle/tdemo_wikipedia.py b/Demo/turtle/tdemo_wikipedia.py
deleted file mode 100644
index 89e6995..0000000
--- a/Demo/turtle/tdemo_wikipedia.py
+++ /dev/null
@@ -1,65 +0,0 @@
-""" turtle-example-suite:
-
- tdemo_wikipedia3.py
-
-This example is
-inspired by the Wikipedia article on turtle
-graphics. (See example wikipedia1 for URLs)
-
-First we create (ne-1) (i.e. 35 in this
-example) copies of our first turtle p.
-Then we let them perform their steps in
-parallel.
-
-Followed by a complete undo().
-"""
-from turtle import Screen, Turtle, mainloop
-from time import clock, sleep
-
-def mn_eck(p, ne,sz):
- turtlelist = [p]
- #create ne-1 additional turtles
- for i in range(1,ne):
- q = p.clone()
- q.rt(360.0/ne)
- turtlelist.append(q)
- p = q
- for i in range(ne):
- c = abs(ne/2.0-i)/(ne*.7)
- # let those ne turtles make a step
- # in parallel:
- for t in turtlelist:
- t.rt(360./ne)
- t.pencolor(1-c,0,c)
- t.fd(sz)
-
-def main():
- s = Screen()
- s.bgcolor("black")
- p=Turtle()
- p.speed(0)
- p.hideturtle()
- p.pencolor("red")
- p.pensize(3)
-
- s.tracer(36,0)
-
- at = clock()
- mn_eck(p, 36, 19)
- et = clock()
- z1 = et-at
-
- sleep(1)
-
- at = clock()
- while any([t.undobufferentries() for t in s.turtles()]):
- for t in s.turtles():
- t.undo()
- et = clock()
- return "Laufzeit: %.3f sec" % (z1+et-at)
-
-
-if __name__ == '__main__':
- msg = main()
- print msg
- mainloop()
diff --git a/Demo/turtle/tdemo_yinyang.py b/Demo/turtle/tdemo_yinyang.py
deleted file mode 100644
index 04dd758..0000000
--- a/Demo/turtle/tdemo_yinyang.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-""" turtle-example-suite:
-
- tdemo_yinyang.py
-
-Another drawing suitable as a beginner's
-programming example.
-
-The small circles are drawn by the circle
-command.
-
-"""
-
-from turtle import *
-
-def yin(radius, color1, color2):
- width(3)
- color("black")
- fill(True)
- circle(radius/2., 180)
- circle(radius, 180)
- left(180)
- circle(-radius/2., 180)
- color(color1)
- fill(True)
- color(color2)
- left(90)
- up()
- forward(radius*0.375)
- right(90)
- down()
- circle(radius*0.125)
- left(90)
- fill(False)
- up()
- backward(radius*0.375)
- down()
- left(90)
-
-def main():
- reset()
- yin(200, "white", "black")
- yin(200, "black", "white")
- ht()
- return "Done!"
-
-if __name__ == '__main__':
- main()
- mainloop()
diff --git a/Demo/turtle/turtleDemo.py b/Demo/turtle/turtleDemo.py
deleted file mode 100644
index 30b5e5b..0000000
--- a/Demo/turtle/turtleDemo.py
+++ /dev/null
@@ -1,280 +0,0 @@
-#!/usr/bin/env python
-import sys
-import os
-
-from Tkinter import *
-from idlelib.Percolator import Percolator
-from idlelib.ColorDelegator import ColorDelegator
-from idlelib.textView import TextViewer
-
-import turtle
-import time
-
-STARTUP = 1
-READY = 2
-RUNNING = 3
-DONE = 4
-EVENTDRIVEN = 5
-
-menufont = ("Arial", 12, NORMAL)
-btnfont = ("Arial", 12, 'bold')
-txtfont = ('Lucida Console', 8, 'normal')
-
-def getExampleEntries():
- cwd = os.getcwd()
- if "turtleDemo.py" not in os.listdir(cwd):
- print "Directory of turtleDemo must be current working directory!"
- print "But in your case this is", cwd
- sys.exit()
- entries1 = [entry for entry in os.listdir(cwd) if
- entry.startswith("tdemo_") and
- not entry.endswith(".pyc")]
- entries2 = []
- for entry in entries1:
- if entry.endswith(".py"):
- entries2.append(entry)
- else:
- path = os.path.join(cwd,entry)
- sys.path.append(path)
- subdir = [entry]
- scripts = [script for script in os.listdir(path) if
- script.startswith("tdemo_") and
- script.endswith(".py")]
- entries2.append(subdir+scripts)
- return entries2
-
-def showDemoHelp():
- TextViewer(demo.root, "Help on turtleDemo", "demohelp.txt")
-
-def showAboutDemo():
- TextViewer(demo.root, "About turtleDemo", "about_turtledemo.txt")
-
-def showAboutTurtle():
- TextViewer(demo.root, "About the new turtle module", "about_turtle.txt")
-
-class DemoWindow(object):
-
- def __init__(self, filename=None): #, root=None):
- self.root = root = turtle._root = Tk()
- root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
-
- #################
- self.mBar = Frame(root, relief=RAISED, borderwidth=2)
- self.mBar.pack(fill=X)
-
- self.ExamplesBtn = self.makeLoadDemoMenu()
- self.OptionsBtn = self.makeHelpMenu()
- self.mBar.tk_menuBar(self.ExamplesBtn, self.OptionsBtn) #, QuitBtn)
-
- root.title('Python turtle-graphics examples')
- #################
- self.left_frame = left_frame = Frame(root)
- self.text_frame = text_frame = Frame(left_frame)
- self.vbar = vbar =Scrollbar(text_frame, name='vbar')
- self.text = text = Text(text_frame,
- name='text', padx=5, wrap='none',
- width=45)
- vbar['command'] = text.yview
- vbar.pack(side=LEFT, fill=Y)
- #####################
- self.hbar = hbar =Scrollbar(text_frame, name='hbar', orient=HORIZONTAL)
- hbar['command'] = text.xview
- hbar.pack(side=BOTTOM, fill=X)
- #####################
- text['yscrollcommand'] = vbar.set
- text.config(font=txtfont)
- text.config(xscrollcommand=hbar.set)
- text.pack(side=LEFT, fill=Y, expand=1)
- #####################
- self.output_lbl = Label(left_frame, height= 1,text=" --- ", bg = "#ddf",
- font = ("Arial", 16, 'normal'))
- self.output_lbl.pack(side=BOTTOM, expand=0, fill=X)
- #####################
- text_frame.pack(side=LEFT, fill=BOTH, expand=0)
- left_frame.pack(side=LEFT, fill=BOTH, expand=0)
- self.graph_frame = g_frame = Frame(root)
-
- turtle._Screen._root = g_frame
- turtle._Screen._canvas = turtle.ScrolledCanvas(g_frame, 800, 600, 1000, 800)
- #xturtle.Screen._canvas.pack(expand=1, fill="both")
- self.screen = _s_ = turtle.Screen()
- turtle.TurtleScreen.__init__(_s_, _s_._canvas)
- self.scanvas = _s_._canvas
- #xturtle.RawTurtle.canvases = [self.scanvas]
- turtle.RawTurtle.screens = [_s_]
-
- self.scanvas.pack(side=TOP, fill=BOTH, expand=1)
-
- self.btn_frame = btn_frame = Frame(g_frame, height=100)
- self.start_btn = Button(btn_frame, text=" START ", font=btnfont, fg = "white",
- disabledforeground = "#fed", command=self.startDemo)
- self.start_btn.pack(side=LEFT, fill=X, expand=1)
- self.stop_btn = Button(btn_frame, text=" STOP ", font=btnfont, fg = "white",
- disabledforeground = "#fed", command = self.stopIt)
- self.stop_btn.pack(side=LEFT, fill=X, expand=1)
- self.clear_btn = Button(btn_frame, text=" CLEAR ", font=btnfont, fg = "white",
- disabledforeground = "#fed", command = self.clearCanvas)
- self.clear_btn.pack(side=LEFT, fill=X, expand=1)
-
- self.btn_frame.pack(side=TOP, fill=BOTH, expand=0)
- self.graph_frame.pack(side=TOP, fill=BOTH, expand=1)
-
- Percolator(text).insertfilter(ColorDelegator())
- self.dirty = False
- self.exitflag = False
- if filename:
- self.loadfile(filename)
- self.configGUI(NORMAL, DISABLED, DISABLED, DISABLED,
- "Choose example from menu", "black")
- self.state = STARTUP
-
- def _destroy(self):
- self.root.destroy()
- sys.exit()
-
- def configGUI(self, menu, start, stop, clear, txt="", color="blue"):
- self.ExamplesBtn.config(state=menu)
-
- self.start_btn.config(state=start)
- if start==NORMAL:
- self.start_btn.config(bg="#d00")
- else:
- self.start_btn.config(bg="#fca")
-
- self.stop_btn.config(state=stop)
- if stop==NORMAL:
- self.stop_btn.config(bg="#d00")
- else:
- self.stop_btn.config(bg="#fca")
- self.clear_btn.config(state=clear)
-
- self.clear_btn.config(state=clear)
- if clear==NORMAL:
- self.clear_btn.config(bg="#d00")
- else:
- self.clear_btn.config(bg="#fca")
-
- self.output_lbl.config(text=txt, fg=color)
-
-
- def makeLoadDemoMenu(self):
- CmdBtn = Menubutton(self.mBar, text='Examples', underline=0, font=menufont)
- CmdBtn.pack(side=LEFT, padx="2m")
- CmdBtn.menu = Menu(CmdBtn)
-
- for entry in getExampleEntries():
- def loadexample(x):
- def emit():
- self.loadfile(x)
- return emit
- if isinstance(entry,str):
- CmdBtn.menu.add_command(label=entry[6:-3], underline=0, font=menufont,
- command=loadexample(entry))
- else:
- _dir, entries = entry[0], entry[1:]
- CmdBtn.menu.choices = Menu(CmdBtn.menu)
- for e in entries:
- CmdBtn.menu.choices.add_command(label=e[6:-3], underline=0, font=menufont,
- command = loadexample(os.path.join(_dir,e)))
-
- CmdBtn.menu.add_cascade(label=_dir[6:],
- menu = CmdBtn.menu.choices, font=menufont )
-
- CmdBtn['menu'] = CmdBtn.menu
- return CmdBtn
-
-
- def makeHelpMenu(self):
- CmdBtn = Menubutton(self.mBar, text='Help', underline=0, font = menufont)
- CmdBtn.pack(side=LEFT, padx='2m')
- CmdBtn.menu = Menu(CmdBtn)
-
- CmdBtn.menu.add_command(label='About turtle.py', font=menufont, command=showAboutTurtle)
- CmdBtn.menu.add_command(label='turtleDemo - Help', font=menufont, command=showDemoHelp)
- CmdBtn.menu.add_command(label='About turtleDemo', font=menufont, command=showAboutDemo)
-
- CmdBtn['menu'] = CmdBtn.menu
- return CmdBtn
-
- def refreshCanvas(self):
- if not self.dirty: return
- self.screen.clear()
- #self.screen.mode("standard")
- self.dirty=False
-
- def loadfile(self,filename):
- self.refreshCanvas()
- if os.path.exists(filename) and not os.path.isdir(filename):
- # load and display file text
- f = open(filename,'r')
- chars = f.read()
- f.close()
- self.text.delete("1.0", "end")
- self.text.insert("1.0",chars)
- direc, fname = os.path.split(filename)
- self.root.title(fname[6:-3]+" - a Python turtle graphics example")
- self.module = __import__(fname[:-3])
- reload(self.module)
- self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED,
- "Press start button", "red")
- self.state = READY
-
- def startDemo(self):
- self.refreshCanvas()
- self.dirty = True
- turtle.TurtleScreen._RUNNING = True
- self.configGUI(DISABLED, DISABLED, NORMAL, DISABLED,
- "demo running...", "black")
- self.screen.clear()
- self.screen.mode("standard")
- self.state = RUNNING
-
- try:
- result = self.module.main()
- if result == "EVENTLOOP":
- self.state = EVENTDRIVEN
- else:
- self.state = DONE
- except turtle.Terminator:
- self.state = DONE
- result = "stopped!"
- if self.state == DONE:
- self.configGUI(NORMAL, NORMAL, DISABLED, NORMAL,
- result)
- elif self.state == EVENTDRIVEN:
- self.exitflag = True
- self.configGUI(DISABLED, DISABLED, NORMAL, DISABLED,
- "use mouse/keys or STOP", "red")
-
- def clearCanvas(self):
- self.refreshCanvas()
- self.scanvas.config(cursor="")
- self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED)
-
- def stopIt(self):
- if self.exitflag:
- self.clearCanvas()
- self.exitflag = False
- self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED,
- "STOPPED!", "red")
- turtle.TurtleScreen._RUNNING = False
- #print "stopIT: exitflag = True"
- else:
- turtle.TurtleScreen._RUNNING = False
- #print "stopIt: exitflag = False"
-
-if __name__ == '__main__':
- demo = DemoWindow()
- RUN = True
- while RUN:
- try:
- print "ENTERING mainloop"
- demo.root.mainloop()
- except AttributeError:
- print "CRASH!!!- WAIT A MOMENT!"
- time.sleep(0.3)
- print "GOING ON .."
- demo.refreshCanvas()
-## time.sleep(1)
- except:
- RUN = FALSE
diff --git a/Demo/turtle/turtledemo_two_canvases.py b/Demo/turtle/turtledemo_two_canvases.py
deleted file mode 100644
index 5a9831d..0000000
--- a/Demo/turtle/turtledemo_two_canvases.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-## DEMONSTRATES USE OF 2 CANVASES, SO CANNOT BE RUN IN DEMOVIEWER!
-"""turtle example: Using TurtleScreen and RawTurtle
-for drawing on two distinct canvases.
-"""
-from turtle import TurtleScreen, RawTurtle, TK
-
-root = TK.Tk()
-cv1 = TK.Canvas(root, width=300, height=200, bg="#ddffff")
-cv2 = TK.Canvas(root, width=300, height=200, bg="#ffeeee")
-cv1.pack()
-cv2.pack()
-
-s1 = TurtleScreen(cv1)
-s1.bgcolor(0.85, 0.85, 1)
-s2 = TurtleScreen(cv2)
-s2.bgcolor(1, 0.85, 0.85)
-
-p = RawTurtle(s1)
-q = RawTurtle(s2)
-
-p.color("red", "white")
-p.width(3)
-q.color("blue", "black")
-q.width(3)
-
-for t in p,q:
- t.shape("turtle")
- t.lt(36)
-
-q.lt(180)
-
-for i in range(5):
- for t in p, q:
- t.fd(50)
- t.lt(72)
-for t in p,q:
- t.lt(54)
- t.pu()
- t.bk(50)
-
-## Want to get some info?
-
-print s1, s2
-print p, q
-print s1.turtles()
-print s2.turtles()
-
-TK.mainloop()
diff --git a/Demo/xml/elem_count.py b/Demo/xml/elem_count.py
deleted file mode 100644
index f4e6ef5..0000000
--- a/Demo/xml/elem_count.py
+++ /dev/null
@@ -1,42 +0,0 @@
-"""
-A simple demo that reads in an XML document and displays the number of
-elements and attributes as well as a tally of elements and attributes by name.
-"""
-
-import sys
-from collections import defaultdict
-
-from xml.sax import make_parser, handler
-
-class FancyCounter(handler.ContentHandler):
-
- def __init__(self):
- self._elems = 0
- self._attrs = 0
- self._elem_types = defaultdict(int)
- self._attr_types = defaultdict(int)
-
- def startElement(self, name, attrs):
- self._elems += 1
- self._attrs += len(attrs)
- self._elem_types[name] += 1
-
- for name in attrs.keys():
- self._attr_types[name] += 1
-
- def endDocument(self):
- print "There were", self._elems, "elements."
- print "There were", self._attrs, "attributes."
-
- print "---ELEMENT TYPES"
- for pair in self._elem_types.items():
- print "%20s %d" % pair
-
- print "---ATTRIBUTE TYPES"
- for pair in self._attr_types.items():
- print "%20s %d" % pair
-
-if __name__ == '__main__':
- parser = make_parser()
- parser.setContentHandler(FancyCounter())
- parser.parse(sys.argv[1])
diff --git a/Demo/xml/roundtrip.py b/Demo/xml/roundtrip.py
deleted file mode 100644
index 801c009..0000000
--- a/Demo/xml/roundtrip.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""
-A simple demo that reads in an XML document and spits out an equivalent,
-but not necessarily identical, document.
-"""
-
-import sys
-
-from xml.sax import saxutils, handler, make_parser
-
-# --- The ContentHandler
-
-class ContentGenerator(handler.ContentHandler):
-
- def __init__(self, out=sys.stdout):
- handler.ContentHandler.__init__(self)
- self._out = out
-
- # ContentHandler methods
-
- def startDocument(self):
- self._out.write('<?xml version="1.0" encoding="iso-8859-1"?>\n')
-
- def startElement(self, name, attrs):
- self._out.write('<' + name)
- for (name, value) in attrs.items():
- self._out.write(' %s="%s"' % (name, saxutils.escape(value)))
- self._out.write('>')
-
- def endElement(self, name):
- self._out.write('</%s>' % name)
-
- def characters(self, content):
- self._out.write(saxutils.escape(content))
-
- def ignorableWhitespace(self, content):
- self._out.write(content)
-
- def processingInstruction(self, target, data):
- self._out.write('<?%s %s?>' % (target, data))
-
-# --- The main program
-
-if __name__ == '__main__':
- parser = make_parser()
- parser.setContentHandler(ContentGenerator())
- parser.parse(sys.argv[1])
diff --git a/Demo/xml/rss2html.py b/Demo/xml/rss2html.py
deleted file mode 100644
index f2067a9..0000000
--- a/Demo/xml/rss2html.py
+++ /dev/null
@@ -1,97 +0,0 @@
-"""
-A demo that reads in an RSS XML document and emits an HTML file containing
-a list of the individual items in the feed.
-"""
-
-import sys
-import codecs
-
-from xml.sax import make_parser, handler
-
-# --- Templates
-
-top = """\
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
- <title>%s</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-</head>
-
-<body>
-<h1>%s</h1>
-"""
-
-bottom = """
-</ul>
-
-<hr>
-<address>
-Converted to HTML by rss2html.py.
-</address>
-
-</body>
-</html>
-"""
-
-# --- The ContentHandler
-
-class RSSHandler(handler.ContentHandler):
-
- def __init__(self, out=sys.stdout):
- handler.ContentHandler.__init__(self)
- self._out = codecs.getwriter('utf-8')(out)
-
- self._text = ""
- self._parent = None
- self._list_started = False
- self._title = None
- self._link = None
- self._descr = ""
-
- # ContentHandler methods
-
- def startElement(self, name, attrs):
- if name == "channel" or name == "image" or name == "item":
- self._parent = name
-
- self._text = ""
-
- def endElement(self, name):
- if self._parent == "channel":
- if name == "title":
- self._out.write(top % (self._text, self._text))
- elif name == "description":
- self._out.write("<p>%s</p>\n" % self._text)
-
- elif self._parent == "item":
- if name == "title":
- self._title = self._text
- elif name == "link":
- self._link = self._text
- elif name == "description":
- self._descr = self._text
- elif name == "item":
- if not self._list_started:
- self._out.write("<ul>\n")
- self._list_started = True
-
- self._out.write(' <li><a href="%s">%s</a> %s\n' %
- (self._link, self._title, self._descr))
-
- self._title = None
- self._link = None
- self._descr = ""
-
- if name == "rss":
- self._out.write(bottom)
-
- def characters(self, content):
- self._text = self._text + content
-
-# --- Main program
-
-if __name__ == '__main__':
- parser = make_parser()
- parser.setContentHandler(RSSHandler())
- parser.parse(sys.argv[1])
diff --git a/Demo/zlib/minigzip.py b/Demo/zlib/minigzip.py
deleted file mode 100755
index 87fed4a..0000000
--- a/Demo/zlib/minigzip.py
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/usr/bin/env python
-# Demo program for zlib; it compresses or decompresses files, but *doesn't*
-# delete the original. This doesn't support all of gzip's options.
-#
-# The 'gzip' module in the standard library provides a more complete
-# implementation of gzip-format files.
-
-import zlib, sys, os
-
-FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
-
-def write32(output, value):
- output.write(chr(value & 255)) ; value=value // 256
- output.write(chr(value & 255)) ; value=value // 256
- output.write(chr(value & 255)) ; value=value // 256
- output.write(chr(value & 255))
-
-def read32(input):
- v = ord(input.read(1))
- v += (ord(input.read(1)) << 8 )
- v += (ord(input.read(1)) << 16)
- v += (ord(input.read(1)) << 24)
- return v
-
-def compress (filename, input, output):
- output.write('\037\213\010') # Write the header, ...
- output.write(chr(FNAME)) # ... flag byte ...
-
- statval = os.stat(filename) # ... modification time ...
- mtime = statval[8]
- write32(output, mtime)
- output.write('\002') # ... slowest compression alg. ...
- output.write('\377') # ... OS (=unknown) ...
- output.write(filename+'\000') # ... original filename ...
-
- crcval = zlib.crc32("")
- compobj = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS,
- zlib.DEF_MEM_LEVEL, 0)
- while True:
- data = input.read(1024)
- if data == "":
- break
- crcval = zlib.crc32(data, crcval)
- output.write(compobj.compress(data))
- output.write(compobj.flush())
- write32(output, crcval) # ... the CRC ...
- write32(output, statval[6]) # and the file size.
-
-def decompress (input, output):
- magic = input.read(2)
- if magic != '\037\213':
- print 'Not a gzipped file'
- sys.exit(0)
- if ord(input.read(1)) != 8:
- print 'Unknown compression method'
- sys.exit(0)
- flag = ord(input.read(1))
- input.read(4+1+1) # Discard modification time,
- # extra flags, and OS byte.
- if flag & FEXTRA:
- # Read & discard the extra field, if present
- xlen = ord(input.read(1))
- xlen += 256*ord(input.read(1))
- input.read(xlen)
- if flag & FNAME:
- # Read and discard a null-terminated string containing the filename
- while True:
- s = input.read(1)
- if s == '\0': break
- if flag & FCOMMENT:
- # Read and discard a null-terminated string containing a comment
- while True:
- s=input.read(1)
- if s=='\0': break
- if flag & FHCRC:
- input.read(2) # Read & discard the 16-bit header CRC
-
- decompobj = zlib.decompressobj(-zlib.MAX_WBITS)
- crcval = zlib.crc32("")
- length = 0
- while True:
- data=input.read(1024)
- if data == "":
- break
- decompdata = decompobj.decompress(data)
- output.write(decompdata)
- length += len(decompdata)
- crcval = zlib.crc32(decompdata, crcval)
-
- decompdata = decompobj.flush()
- output.write(decompdata)
- length += len(decompdata)
- crcval = zlib.crc32(decompdata, crcval)
-
- # We've read to the end of the file, so we have to rewind in order
- # to reread the 8 bytes containing the CRC and the file size. The
- # decompressor is smart and knows when to stop, so feeding it
- # extra data is harmless.
- input.seek(-8, 2)
- crc32 = read32(input)
- isize = read32(input)
- if crc32 != crcval:
- print 'CRC check failed.'
- if isize != length:
- print 'Incorrect length of data produced'
-
-def main():
- if len(sys.argv)!=2:
- print 'Usage: minigzip.py <filename>'
- print ' The file will be compressed or decompressed.'
- sys.exit(0)
-
- filename = sys.argv[1]
- if filename.endswith('.gz'):
- compressing = False
- outputname = filename[:-3]
- else:
- compressing = True
- outputname = filename + '.gz'
-
- input = open(filename, 'rb')
- output = open(outputname, 'wb')
-
- if compressing:
- compress(filename, input, output)
- else:
- decompress(input, output)
-
- input.close()
- output.close()
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/zlib/zlibdemo.py b/Demo/zlib/zlibdemo.py
deleted file mode 100755
index b449c19..0000000
--- a/Demo/zlib/zlibdemo.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python
-
-# Takes an optional filename, defaulting to this file itself.
-# Reads the file and compresses the content using level 1 and level 9
-# compression, printing a summary of the results.
-
-import zlib, sys
-
-def main():
- if len(sys.argv) > 1:
- filename = sys.argv[1]
- else:
- filename = sys.argv[0]
- print 'Reading', filename
-
- f = open(filename, 'rb') # Get the data to compress
- s = f.read()
- f.close()
-
- # First, we'll compress the string in one step
- comptext = zlib.compress(s, 1)
- decomp = zlib.decompress(comptext)
-
- print '1-step compression: (level 1)'
- print ' Original:', len(s), 'Compressed:', len(comptext),
- print 'Uncompressed:', len(decomp)
-
- # Now, let's compress the string in stages; set chunk to work in smaller steps
-
- chunk = 256
- compressor = zlib.compressobj(9)
- decompressor = zlib.decompressobj()
- comptext = decomp = ''
- for i in range(0, len(s), chunk):
- comptext = comptext+compressor.compress(s[i:i+chunk])
- # Don't forget to call flush()!!
- comptext = comptext + compressor.flush()
-
- for i in range(0, len(comptext), chunk):
- decomp = decomp + decompressor.decompress(comptext[i:i+chunk])
- decomp=decomp+decompressor.flush()
-
- print 'Progressive compression (level 9):'
- print ' Original:', len(s), 'Compressed:', len(comptext),
- print 'Uncompressed:', len(decomp)
-
-if __name__ == '__main__':
- main()
diff --git a/Doc/Makefile b/Doc/Makefile
index 4052bab..13411f2 100644
--- a/Doc/Makefile
+++ b/Doc/Makefile
@@ -26,6 +26,7 @@ help:
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " text to make plain text files"
+ @echo " epub to make EPUB files"
@echo " changes to make an overview over all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " coverage to check documentation coverage for library and C API"
@@ -81,6 +82,10 @@ text: BUILDER = text
text: build
@echo "Build finished; the text files are in build/text."
+epub: BUILDER = epub
+epub: build
+ @echo "Build finished; the epub files are in build/epub."
+
changes: BUILDER = changes
changes: build
@echo "The overview file is in build/changes."
@@ -108,7 +113,7 @@ doctest: build
pydoc-topics: BUILDER = pydoc-topics
pydoc-topics: build
@echo "Building finished; now copy build/pydoc-topics/topics.py" \
- "to Lib/pydoc_data/topics.py"
+ "to ../Lib/pydoc_data/topics.py"
htmlview: html
$(PYTHON) -c "import webbrowser; webbrowser.open('build/html/index.html')"
@@ -158,6 +163,17 @@ dist:
cp build/latex/docs-pdf.zip dist/python-$(DISTVERSION)-docs-pdf-letter.zip
cp build/latex/docs-pdf.tar.bz2 dist/python-$(DISTVERSION)-docs-pdf-letter.tar.bz2
+ # archive the epub build
+ rm -rf build/epub
+ make epub
+ mkdir -p dist/python-$(DISTVERSION)-docs-epub
+ cp -pPR build/epub/*.epub dist/python-$(DISTVERSION)-docs-epub/
+ tar -C dist -cf dist/python-$(DISTVERSION)-docs-epub.tar python-$(DISTVERSION)-docs-epub
+ bzip2 -9 -k dist/python-$(DISTVERSION)-docs-epub.tar
+ (cd dist; zip -q -r -9 python-$(DISTVERSION)-docs-epub.zip python-$(DISTVERSION)-docs-epub)
+ rm -r dist/python-$(DISTVERSION)-docs-epub
+ rm dist/python-$(DISTVERSION)-docs-epub.tar
+
check:
$(PYTHON) tools/rstlint.py -i tools
@@ -171,10 +187,6 @@ autobuild-dev:
make update
make dist SPHINXOPTS='-A daily=1 -A versionswitcher=1'
-# for quick rebuilds (HTML only)
-autobuild-html:
- make html SPHINXOPTS='-A daily=1 -A versionswitcher=1'
-
# for stable releases: only build if not in pre-release stage (alpha, beta, rc)
autobuild-stable:
@case $(DISTVERSION) in *[abc]*) \
@@ -182,4 +194,3 @@ autobuild-stable:
exit 1;; \
esac
@make autobuild-dev
-
diff --git a/Doc/README.txt b/Doc/README.txt
index f03da76..f296423 100644
--- a/Doc/README.txt
+++ b/Doc/README.txt
@@ -33,6 +33,11 @@ to check out the necessary toolset in the `tools/` subdirectory and build the
HTML output files. To view the generated HTML, point your favorite browser at
the top-level index `build/html/index.html` after running "make".
+To use a Python interpreter that's not called ``python``, use the standard
+way to set Makefile variables, using e.g. ::
+
+ make html PYTHON=/usr/bin/python2.5
+
Available make targets are:
* "html", which builds standalone HTML files for offline viewing.
@@ -49,6 +54,9 @@ Available make targets are:
* "text", which builds a plain text file for each source file.
+ * "epub", which builds an EPUB document, suitable to be viewed on e-book
+ readers.
+
* "linkcheck", which checks all external references to see whether they are
broken, redirected or malformed, and outputs this information to stdout as
well as a plain-text (.txt) file.
@@ -73,7 +81,7 @@ Without make
You'll need to install the Sphinx package, either by checking it out via ::
- svn co http://svn.python.org/projects/external/Sphinx-0.6.7/sphinx tools/sphinx
+ svn co http://svn.python.org/projects/external/Sphinx-1.0.7/sphinx tools/sphinx
or by installing it from PyPI.
diff --git a/Doc/c-api/abstract.rst b/Doc/c-api/abstract.rst
index bc9001c..ad53881 100644
--- a/Doc/c-api/abstract.rst
+++ b/Doc/c-api/abstract.rst
@@ -1,6 +1,5 @@
.. highlightlang:: c
-
.. _abstract:
**********************
@@ -23,4 +22,5 @@ but whose items have not been set to some non-\ ``NULL`` value yet.
sequence.rst
mapping.rst
iter.rst
+ buffer.rst
objbuffer.rst
diff --git a/Doc/c-api/allocation.rst b/Doc/c-api/allocation.rst
index cb43cbf..e8f60bf 100644
--- a/Doc/c-api/allocation.rst
+++ b/Doc/c-api/allocation.rst
@@ -11,13 +11,6 @@ Allocating Objects on the Heap
.. c:function:: PyVarObject* _PyObject_NewVar(PyTypeObject *type, Py_ssize_t size)
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
-
-.. c:function:: void _PyObject_Del(PyObject *op)
-
.. c:function:: PyObject* PyObject_Init(PyObject *op, PyTypeObject *type)
@@ -33,10 +26,6 @@ Allocating Objects on the Heap
This does everything :c:func:`PyObject_Init` does, and also initializes the
length information for a variable-size object.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: TYPE* PyObject_New(TYPE, PyTypeObject *type)
@@ -58,10 +47,6 @@ Allocating Objects on the Heap
fields into the same allocation decreases the number of allocations,
improving the memory management efficiency.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: void PyObject_Del(PyObject *op)
@@ -72,51 +57,15 @@ Allocating Objects on the Heap
longer a valid Python object.
-.. c:function:: PyObject* Py_InitModule(char *name, PyMethodDef *methods)
-
- Create a new module object based on a name and table of functions,
- returning the new module object.
-
- .. versionchanged:: 2.3
- Older versions of Python did not support *NULL* as the value for the
- *methods* argument.
-
-
-.. c:function:: PyObject* Py_InitModule3(char *name, PyMethodDef *methods, char *doc)
-
- Create a new module object based on a name and table of functions,
- returning the new module object. If *doc* is non-*NULL*, it will be used
- to define the docstring for the module.
-
- .. versionchanged:: 2.3
- Older versions of Python did not support *NULL* as the value for the
- *methods* argument.
-
-
-.. c:function:: PyObject* Py_InitModule4(char *name, PyMethodDef *methods, char *doc, PyObject *self, int apiver)
-
- Create a new module object based on a name and table of functions,
- returning the new module object. If *doc* is non-*NULL*, it will be used
- to define the docstring for the module. If *self* is non-*NULL*, it will
- passed to the functions of the module as their (otherwise *NULL*) first
- parameter. (This was added as an experimental feature, and there are no
- known uses in the current version of Python.) For *apiver*, the only value
- which should be passed is defined by the constant
- :const:`PYTHON_API_VERSION`.
-
- .. note::
+.. c:var:: PyObject _Py_NoneStruct
- Most uses of this function should probably be using the
- :c:func:`Py_InitModule3` instead; only use this if you are sure you need
- it.
+ Object which is visible in Python as ``None``. This should only be accessed
+ using the :c:macro:`Py_None` macro, which evaluates to a pointer to this
+ object.
- .. versionchanged:: 2.3
- Older versions of Python did not support *NULL* as the value for the
- *methods* argument.
+.. seealso::
-.. c:var:: PyObject _Py_NoneStruct
+ :c:func:`PyModule_Create`
+ To allocate and create extension modules.
- Object which is visible in Python as ``None``. This should only be
- accessed using the ``Py_None`` macro, which evaluates to a pointer to this
- object.
diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
index 8fbdc50..d4dda7c 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -10,339 +10,373 @@ methods. Additional information and examples are available in
:ref:`extending-index`.
The first three of these functions described, :c:func:`PyArg_ParseTuple`,
-:c:func:`PyArg_ParseTupleAndKeywords`, and :c:func:`PyArg_Parse`, all use
-*format strings* which are used to tell the function about the expected
-arguments. The format strings use the same syntax for each of these
-functions.
+:c:func:`PyArg_ParseTupleAndKeywords`, and :c:func:`PyArg_Parse`, all use *format
+strings* which are used to tell the function about the expected arguments. The
+format strings use the same syntax for each of these functions.
+
+-----------------
+Parsing arguments
+-----------------
A format string consists of zero or more "format units." A format unit
-describes one Python object; it is usually a single character or a
-parenthesized sequence of format units. With a few exceptions, a format unit
-that is not a parenthesized sequence normally corresponds to a single address
-argument to these functions. In the following description, the quoted form is
-the format unit; the entry in (round) parentheses is the Python object type
-that matches the format unit; and the entry in [square] brackets is the type
-of the C variable(s) whose address should be passed.
+describes one Python object; it is usually a single character or a parenthesized
+sequence of format units. With a few exceptions, a format unit that is not a
+parenthesized sequence normally corresponds to a single address argument to
+these functions. In the following description, the quoted form is the format
+unit; the entry in (round) parentheses is the Python object type that matches
+the format unit; and the entry in [square] brackets is the type of the C
+variable(s) whose address should be passed.
+
+Strings and buffers
+-------------------
These formats allow to access an object as a contiguous chunk of memory.
You don't have to provide raw storage for the returned unicode or bytes
area. Also, you won't have to release any memory yourself, except with the
``es``, ``es#``, ``et`` and ``et#`` formats.
-``s`` (string or Unicode) [const char \*]
- Convert a Python string or Unicode object to a C pointer to a character
- string. You must not provide storage for the string itself; a pointer to
- an existing string is stored into the character pointer variable whose
- address you pass. The C string is NUL-terminated. The Python string must
- not contain embedded NUL bytes; if it does, a :exc:`TypeError` exception is
- raised. Unicode objects are converted to C strings using the default
- encoding. If this conversion fails, a :exc:`UnicodeError` is raised.
-
-``s#`` (string, Unicode or any read buffer compatible object) [const char \*, int (or :c:type:`Py_ssize_t`, see below)]
- This variant on ``s`` stores into two C variables, the first one a pointer
- to a character string, the second one its length. In this case the Python
- string may contain embedded null bytes. Unicode objects pass back a
- pointer to the default encoded string version of the object if such a
- conversion is possible. All other read-buffer compatible objects pass back
- a reference to the raw internal data representation.
-
- Starting with Python 2.5 the type of the length argument can be controlled
- by defining the macro :c:macro:`PY_SSIZE_T_CLEAN` before including
- :file:`Python.h`. If the macro is defined, length is a :c:type:`Py_ssize_t`
- rather than an int.
-
-``s*`` (string, Unicode, or any buffer compatible object) [Py_buffer]
- Similar to ``s#``, this code fills a Py_buffer structure provided by the
- caller. The buffer gets locked, so that the caller can subsequently use
- the buffer even inside a ``Py_BEGIN_ALLOW_THREADS`` block; the caller is
- responsible for calling ``PyBuffer_Release`` with the structure after it
- has processed the data.
-
- .. versionadded:: 2.6
-
-``z`` (string, Unicode or ``None``) [const char \*]
+However, when a :c:type:`Py_buffer` structure gets filled, the underlying
+buffer is locked so that the caller can subsequently use the buffer even
+inside a :c:type:`Py_BEGIN_ALLOW_THREADS` block without the risk of mutable data
+being resized or destroyed. As a result, **you have to call**
+:c:func:`PyBuffer_Release` after you have finished processing the data (or
+in any early abort case).
+
+Unless otherwise stated, buffers are not NUL-terminated.
+
+.. note::
+ For all ``#`` variants of formats (``s#``, ``y#``, etc.), the type of
+ the length argument (int or :c:type:`Py_ssize_t`) is controlled by
+ defining the macro :c:macro:`PY_SSIZE_T_CLEAN` before including
+ :file:`Python.h`. If the macro was defined, length is a
+ :c:type:`Py_ssize_t` rather than an :c:type:`int`. This behavior will change
+ in a future Python version to only support :c:type:`Py_ssize_t` and
+ drop :c:type:`int` support. It is best to always define :c:macro:`PY_SSIZE_T_CLEAN`.
+
+
+``s`` (:class:`str`) [const char \*]
+ Convert a Unicode object to a C pointer to a character string.
+ A pointer to an existing string is stored in the character pointer
+ variable whose address you pass. The C string is NUL-terminated.
+ The Python string must not contain embedded NUL bytes; if it does,
+ a :exc:`TypeError` exception is raised. Unicode objects are converted
+ to C strings using ``'utf-8'`` encoding. If this conversion fails, a
+ :exc:`UnicodeError` is raised.
+
+ .. note::
+ This format does not accept bytes-like objects. If you want to accept
+ filesystem paths and convert them to C character strings, it is
+ preferable to use the ``O&`` format with :c:func:`PyUnicode_FSConverter`
+ as *converter*.
+
+``s*`` (:class:`str`, :class:`bytes`, :class:`bytearray` or buffer compatible object) [Py_buffer]
+ This format accepts Unicode objects as well as objects supporting the
+ buffer protocol.
+ It fills a :c:type:`Py_buffer` structure provided by the caller.
+ In this case the resulting C string may contain embedded NUL bytes.
+ Unicode objects are converted to C strings using ``'utf-8'`` encoding.
+
+``s#`` (:class:`str`, :class:`bytes` or read-only buffer compatible object) [const char \*, int or :c:type:`Py_ssize_t`]
+ Like ``s*``, except that it doesn't accept mutable buffer-like objects
+ such as :class:`bytearray`. The result is stored into two C variables,
+ the first one a pointer to a C string, the second one its length.
+ The string may contain embedded null bytes. Unicode objects are converted
+ to C strings using ``'utf-8'`` encoding.
+
+``z`` (:class:`str` or ``None``) [const char \*]
Like ``s``, but the Python object may also be ``None``, in which case the C
pointer is set to *NULL*.
-``z#`` (string, Unicode, ``None`` or any read buffer compatible object) [const char \*, int]
- This is to ``s#`` as ``z`` is to ``s``.
+``z*`` (:class:`str`, :class:`bytes`, :class:`bytearray`, buffer compatible object or ``None``) [Py_buffer]
+ Like ``s*``, but the Python object may also be ``None``, in which case the
+ ``buf`` member of the :c:type:`Py_buffer` structure is set to *NULL*.
+
+``z#`` (:class:`str`, :class:`bytes`, read-only buffer compatible object or ``None``) [const char \*, int]
+ Like ``s#``, but the Python object may also be ``None``, in which case the C
+ pointer is set to *NULL*.
+
+``y`` (:class:`bytes`) [const char \*]
+ This format converts a bytes-like object to a C pointer to a character
+ string; it does not accept Unicode objects. The bytes buffer must not
+ contain embedded NUL bytes; if it does, a :exc:`TypeError`
+ exception is raised.
+
+``y*`` (:class:`bytes`, :class:`bytearray` or buffer compatible object) [Py_buffer]
+ This variant on ``s*`` doesn't accept Unicode objects, only objects
+ supporting the buffer protocol. **This is the recommended way to accept
+ binary data.**
+
+``y#`` (:class:`bytes`) [const char \*, int]
+ This variant on ``s#`` doesn't accept Unicode objects, only bytes-like
+ objects.
+
+``S`` (:class:`bytes`) [PyBytesObject \*]
+ Requires that the Python object is a :class:`bytes` object, without
+ attempting any conversion. Raises :exc:`TypeError` if the object is not
+ a bytes object. The C variable may also be declared as :c:type:`PyObject\*`.
+
+``Y`` (:class:`bytearray`) [PyByteArrayObject \*]
+ Requires that the Python object is a :class:`bytearray` object, without
+ attempting any conversion. Raises :exc:`TypeError` if the object is not
+ a :class:`bytearray` object. The C variable may also be declared as :c:type:`PyObject\*`.
+
+``u`` (:class:`str`) [Py_UNICODE \*]
+ Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of
+ Unicode characters. You must pass the address of a :c:type:`Py_UNICODE`
+ pointer variable, which will be filled with the pointer to an existing
+ Unicode buffer. Please note that the width of a :c:type:`Py_UNICODE`
+ character depends on compilation options (it is either 16 or 32 bits).
+ The Python string must not contain embedded NUL characters; if it does,
+ a :exc:`TypeError` exception is raised.
+
+ .. note::
+ Since ``u`` doesn't give you back the length of the string, and it
+ may contain embedded NUL characters, it is recommended to use ``u#``
+ or ``U`` instead.
+
+``u#`` (:class:`str`) [Py_UNICODE \*, int]
+ This variant on ``u`` stores into two C variables, the first one a pointer to a
+ Unicode data buffer, the second one its length.
-``z*`` (string, Unicode, ``None`` or any buffer compatible object) [Py_buffer]
- This is to ``s*`` as ``z`` is to ``s``.
+``Z`` (:class:`str` or ``None``) [Py_UNICODE \*]
+ Like ``u``, but the Python object may also be ``None``, in which case the
+ :c:type:`Py_UNICODE` pointer is set to *NULL*.
- .. versionadded:: 2.6
+``Z#`` (:class:`str` or ``None``) [Py_UNICODE \*, int]
+ Like ``u#``, but the Python object may also be ``None``, in which case the
+ :c:type:`Py_UNICODE` pointer is set to *NULL*.
-``u`` (Unicode) [Py_UNICODE \*]
- Convert a Python Unicode object to a C pointer to a NUL-terminated buffer
- of 16-bit Unicode (UTF-16) data. As with ``s``, there is no need to
- provide storage for the Unicode data buffer; a pointer to the existing
- Unicode data is stored into the :c:type:`Py_UNICODE` pointer variable whose
- address you pass.
+``U`` (:class:`str`) [PyUnicodeObject \*]
+ Requires that the Python object is a Unicode object, without attempting
+ any conversion. Raises :exc:`TypeError` if the object is not a Unicode
+ object. The C variable may also be declared as :c:type:`PyObject\*`.
-``u#`` (Unicode) [Py_UNICODE \*, int]
- This variant on ``u`` stores into two C variables, the first one a pointer
- to a Unicode data buffer, the second one its length. Non-Unicode objects
- are handled by interpreting their read-buffer pointer as pointer to a
- :c:type:`Py_UNICODE` array.
+``w*`` (:class:`bytearray` or read-write byte-oriented buffer) [Py_buffer]
+ This format accepts any object which implements the read-write buffer
+ interface. It fills a :c:type:`Py_buffer` structure provided by the caller.
+ The buffer may contain embedded null bytes. The caller have to call
+ :c:func:`PyBuffer_Release` when it is done with the buffer.
-``es`` (string, Unicode or character buffer compatible object) [const char \*encoding, char \*\*buffer]
- This variant on ``s`` is used for encoding Unicode and objects convertible
- to Unicode into a character buffer. It only works for encoded data without
- embedded NUL bytes.
+``es`` (:class:`str`) [const char \*encoding, char \*\*buffer]
+ This variant on ``s`` is used for encoding Unicode into a character buffer.
+ It only works for encoded data without embedded NUL bytes.
This format requires two arguments. The first is only used as input, and
- must be a :c:type:`const char\*` which points to the name of an encoding as
- a NUL-terminated string, or *NULL*, in which case the default encoding is
- used. An exception is raised if the named encoding is not known to Python.
- The second argument must be a :c:type:`char\*\*`; the value of the pointer
- it references will be set to a buffer with the contents of the argument
- text. The text will be encoded in the encoding specified by the first
- argument.
-
- :c:func:`PyArg_ParseTuple` will allocate a buffer of the needed size, copy
- the encoded data into this buffer and adjust *\*buffer* to reference the
- newly allocated storage. The caller is responsible for calling
- :c:func:`PyMem_Free` to free the allocated buffer after use.
-
-``et`` (string, Unicode or character buffer compatible object) [const char \*encoding, char \*\*buffer]
- Same as ``es`` except that 8-bit string objects are passed through without
- recoding them. Instead, the implementation assumes that the string object
- uses the encoding passed in as parameter.
-
-``es#`` (string, Unicode or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length]
- This variant on ``s#`` is used for encoding Unicode and objects convertible
- to Unicode into a character buffer. Unlike the ``es`` format, this variant
- allows input data which contains NUL characters.
-
- It requires three arguments. The first is only used as input, and must be
- a :c:type:`const char\*` which points to the name of an encoding as a
- NUL-terminated string, or *NULL*, in which case the default encoding is
- used. An exception is raised if the named encoding is not known to Python.
- The second argument must be a :c:type:`char\*\*`; the value of the pointer
- it references will be set to a buffer with the contents of the argument
- text. The text will be encoded in the encoding specified by the first
- argument. The third argument must be a pointer to an integer; the
- referenced integer will be set to the number of bytes in the output buffer.
+ must be a :c:type:`const char\*` which points to the name of an encoding as a
+ NUL-terminated string, or *NULL*, in which case ``'utf-8'`` encoding is used.
+ An exception is raised if the named encoding is not known to Python. The
+ second argument must be a :c:type:`char\*\*`; the value of the pointer it
+ references will be set to a buffer with the contents of the argument text.
+ The text will be encoded in the encoding specified by the first argument.
+
+ :c:func:`PyArg_ParseTuple` will allocate a buffer of the needed size, copy the
+ encoded data into this buffer and adjust *\*buffer* to reference the newly
+ allocated storage. The caller is responsible for calling :c:func:`PyMem_Free` to
+ free the allocated buffer after use.
+
+``et`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer]
+ Same as ``es`` except that byte string objects are passed through without
+ recoding them. Instead, the implementation assumes that the byte string object uses
+ the encoding passed in as parameter.
+
+``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int \*buffer_length]
+ This variant on ``s#`` is used for encoding Unicode into a character buffer.
+ Unlike the ``es`` format, this variant allows input data which contains NUL
+ characters.
+
+ It requires three arguments. The first is only used as input, and must be a
+ :c:type:`const char\*` which points to the name of an encoding as a
+ NUL-terminated string, or *NULL*, in which case ``'utf-8'`` encoding is used.
+ An exception is raised if the named encoding is not known to Python. The
+ second argument must be a :c:type:`char\*\*`; the value of the pointer it
+ references will be set to a buffer with the contents of the argument text.
+ The text will be encoded in the encoding specified by the first argument.
+ The third argument must be a pointer to an integer; the referenced integer
+ will be set to the number of bytes in the output buffer.
There are two modes of operation:
- If *\*buffer* points a *NULL* pointer, the function will allocate a buffer
- of the needed size, copy the encoded data into this buffer and set
- *\*buffer* to reference the newly allocated storage. The caller is
- responsible for calling :c:func:`PyMem_Free` to free the allocated buffer
- after usage.
+ If *\*buffer* points a *NULL* pointer, the function will allocate a buffer of
+ the needed size, copy the encoded data into this buffer and set *\*buffer* to
+ reference the newly allocated storage. The caller is responsible for calling
+ :c:func:`PyMem_Free` to free the allocated buffer after usage.
If *\*buffer* points to a non-*NULL* pointer (an already allocated buffer),
- :c:func:`PyArg_ParseTuple` will use this location as the buffer and
- interpret the initial value of *\*buffer_length* as the buffer size. It
- will then copy the encoded data into the buffer and NUL-terminate it. If
- the buffer is not large enough, a :exc:`ValueError` will be set.
+ :c:func:`PyArg_ParseTuple` will use this location as the buffer and interpret the
+ initial value of *\*buffer_length* as the buffer size. It will then copy the
+ encoded data into the buffer and NUL-terminate it. If the buffer is not large
+ enough, a :exc:`ValueError` will be set.
In both cases, *\*buffer_length* is set to the length of the encoded data
without the trailing NUL byte.
-``et#`` (string, Unicode or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length]
- Same as ``es#`` except that string objects are passed through without
- recoding them. Instead, the implementation assumes that the string object
- uses the encoding passed in as parameter.
+``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int \*buffer_length]
+ Same as ``es#`` except that byte string objects are passed through without recoding
+ them. Instead, the implementation assumes that the byte string object uses the
+ encoding passed in as parameter.
+
+Numbers
+-------
-``b`` (integer) [unsigned char]
+``b`` (:class:`int`) [unsigned char]
Convert a nonnegative Python integer to an unsigned tiny int, stored in a C
:c:type:`unsigned char`.
-``B`` (integer) [unsigned char]
- Convert a Python integer to a tiny int without overflow checking, stored in
- a C :c:type:`unsigned char`.
-
- .. versionadded:: 2.3
+``B`` (:class:`int`) [unsigned char]
+ Convert a Python integer to a tiny int without overflow checking, stored in a C
+ :c:type:`unsigned char`.
-``h`` (integer) [short int]
+``h`` (:class:`int`) [short int]
Convert a Python integer to a C :c:type:`short int`.
-``H`` (integer) [unsigned short int]
- Convert a Python integer to a C :c:type:`unsigned short int`, without
- overflow checking.
-
- .. versionadded:: 2.3
+``H`` (:class:`int`) [unsigned short int]
+ Convert a Python integer to a C :c:type:`unsigned short int`, without overflow
+ checking.
-``i`` (integer) [int]
+``i`` (:class:`int`) [int]
Convert a Python integer to a plain C :c:type:`int`.
-``I`` (integer) [unsigned int]
+``I`` (:class:`int`) [unsigned int]
Convert a Python integer to a C :c:type:`unsigned int`, without overflow
checking.
- .. versionadded:: 2.3
-
-``l`` (integer) [long int]
+``l`` (:class:`int`) [long int]
Convert a Python integer to a C :c:type:`long int`.
-``k`` (integer) [unsigned long]
- Convert a Python integer or long integer to a C :c:type:`unsigned long`
- without overflow checking.
-
- .. versionadded:: 2.3
+``k`` (:class:`int`) [unsigned long]
+ Convert a Python integer to a C :c:type:`unsigned long` without
+ overflow checking.
-``L`` (integer) [PY_LONG_LONG]
+``L`` (:class:`int`) [PY_LONG_LONG]
Convert a Python integer to a C :c:type:`long long`. This format is only
- available on platforms that support :c:type:`long long` (or :c:type:`_int64`
- on Windows).
-
-``K`` (integer) [unsigned PY_LONG_LONG]
- Convert a Python integer or long integer to a C :c:type:`unsigned long long`
- without overflow checking. This format is only available on platforms that
- support :c:type:`unsigned long long` (or :c:type:`unsigned _int64` on
+ available on platforms that support :c:type:`long long` (or :c:type:`_int64` on
Windows).
- .. versionadded:: 2.3
+``K`` (:class:`int`) [unsigned PY_LONG_LONG]
+ Convert a Python integer to a C :c:type:`unsigned long long`
+ without overflow checking. This format is only available on platforms that
+ support :c:type:`unsigned long long` (or :c:type:`unsigned _int64` on Windows).
-``n`` (integer) [Py_ssize_t]
- Convert a Python integer or long integer to a C :c:type:`Py_ssize_t`.
+``n`` (:class:`int`) [Py_ssize_t]
+ Convert a Python integer to a C :c:type:`Py_ssize_t`.
- .. versionadded:: 2.5
+``c`` (:class:`bytes` of length 1) [char]
+ Convert a Python byte, represented as a :class:`bytes` object of length 1,
+ to a C :c:type:`char`.
-``c`` (string of length 1) [char]
- Convert a Python character, represented as a string of length 1, to a C
- :c:type:`char`.
+``C`` (:class:`str` of length 1) [int]
+ Convert a Python character, represented as a :class:`str` object of
+ length 1, to a C :c:type:`int`.
-``f`` (float) [float]
+``f`` (:class:`float`) [float]
Convert a Python floating point number to a C :c:type:`float`.
-``d`` (float) [double]
+``d`` (:class:`float`) [double]
Convert a Python floating point number to a C :c:type:`double`.
-``D`` (complex) [Py_complex]
+``D`` (:class:`complex`) [Py_complex]
Convert a Python complex number to a C :c:type:`Py_complex` structure.
+Other objects
+-------------
+
``O`` (object) [PyObject \*]
- Store a Python object (without any conversion) in a C object pointer. The
- C program thus receives the actual object that was passed. The object's
- reference count is not increased. The pointer stored is not *NULL*.
+ Store a Python object (without any conversion) in a C object pointer. The C
+ program thus receives the actual object that was passed. The object's reference
+ count is not increased. The pointer stored is not *NULL*.
``O!`` (object) [*typeobject*, PyObject \*]
Store a Python object in a C object pointer. This is similar to ``O``, but
- takes two C arguments: the first is the address of a Python type object,
- the second is the address of the C variable (of type :c:type:`PyObject\*`)
- into which the object pointer is stored. If the Python object does not
- have the required type, :exc:`TypeError` is raised.
+ takes two C arguments: the first is the address of a Python type object, the
+ second is the address of the C variable (of type :c:type:`PyObject\*`) into which
+ the object pointer is stored. If the Python object does not have the required
+ type, :exc:`TypeError` is raised.
``O&`` (object) [*converter*, *anything*]
- Convert a Python object to a C variable through a *converter* function.
- This takes two arguments: the first is a function, the second is the
- address of a C variable (of arbitrary type), converted to :c:type:`void \*`.
- The *converter* function in turn is called as follows::
+ Convert a Python object to a C variable through a *converter* function. This
+ takes two arguments: the first is a function, the second is the address of a C
+ variable (of arbitrary type), converted to :c:type:`void \*`. The *converter*
+ function in turn is called as follows::
status = converter(object, address);
where *object* is the Python object to be converted and *address* is the
- :c:type:`void\*` argument that was passed to the :c:func:`PyArg_Parse\*`
- function. The returned *status* should be ``1`` for a successful
- conversion and ``0`` if the conversion has failed. When the conversion
- fails, the *converter* function should raise an exception and leave the
- content of *address* unmodified.
-
-``S`` (string) [PyStringObject \*]
- Like ``O`` but requires that the Python object is a string object. Raises
- :exc:`TypeError` if the object is not a string object. The C variable may
- also be declared as :c:type:`PyObject\*`.
-
-``U`` (Unicode string) [PyUnicodeObject \*]
- Like ``O`` but requires that the Python object is a Unicode object. Raises
- :exc:`TypeError` if the object is not a Unicode object. The C variable may
- also be declared as :c:type:`PyObject\*`.
-
-``t#`` (read-only character buffer) [char \*, int]
- Like ``s#``, but accepts any object which implements the read-only buffer
- interface. The :c:type:`char\*` variable is set to point to the first byte
- of the buffer, and the :c:type:`int` is set to the length of the buffer.
- Only single-segment buffer objects are accepted; :exc:`TypeError` is raised
- for all others.
-
-``w`` (read-write character buffer) [char \*]
- Similar to ``s``, but accepts any object which implements the read-write
- buffer interface. The caller must determine the length of the buffer by
- other means, or use ``w#`` instead. Only single-segment buffer objects are
- accepted; :exc:`TypeError` is raised for all others.
-
-``w#`` (read-write character buffer) [char \*, Py_ssize_t]
- Like ``s#``, but accepts any object which implements the read-write buffer
- interface. The :c:type:`char \*` variable is set to point to the first byte
- of the buffer, and the :c:type:`Py_ssize_t` is set to the length of the
- buffer. Only single-segment buffer objects are accepted; :exc:`TypeError`
- is raised for all others.
-
-``w*`` (read-write byte-oriented buffer) [Py_buffer]
- This is to ``w`` what ``s*`` is to ``s``.
-
- .. versionadded:: 2.6
-
-``(items)`` (tuple) [*matching-items*]
- The object must be a Python sequence whose length is the number of format
- units in *items*. The C arguments must correspond to the individual format
- units in *items*. Format units for sequences may be nested.
-
- .. note::
-
- Prior to Python version 1.5.2, this format specifier only accepted a
- tuple containing the individual parameters, not an arbitrary sequence.
- Code which previously caused :exc:`TypeError` to be raised here may now
- proceed without an exception. This is not expected to be a problem for
- existing code.
-
-It is possible to pass Python long integers where integers are requested;
-however no proper range checking is done --- the most significant bits are
-silently truncated when the receiving field is too small to receive the value
-(actually, the semantics are inherited from downcasts in C --- your mileage
-may vary).
+ :c:type:`void\*` argument that was passed to the :c:func:`PyArg_Parse\*` function.
+ The returned *status* should be ``1`` for a successful conversion and ``0`` if
+ the conversion has failed. When the conversion fails, the *converter* function
+ should raise an exception and leave the content of *address* unmodified.
+
+ If the *converter* returns ``Py_CLEANUP_SUPPORTED``, it may get called a
+ second time if the argument parsing eventually fails, giving the converter a
+ chance to release any memory that it had already allocated. In this second
+ call, the *object* parameter will be NULL; *address* will have the same value
+ as in the original call.
+
+ .. versionchanged:: 3.1
+ ``Py_CLEANUP_SUPPORTED`` was added.
+
+``(items)`` (:class:`tuple`) [*matching-items*]
+ The object must be a Python sequence whose length is the number of format units
+ in *items*. The C arguments must correspond to the individual format units in
+ *items*. Format units for sequences may be nested.
+
+It is possible to pass "long" integers (integers whose value exceeds the
+platform's :const:`LONG_MAX`) however no proper range checking is done --- the
+most significant bits are silently truncated when the receiving field is too
+small to receive the value (actually, the semantics are inherited from downcasts
+in C --- your mileage may vary).
A few other characters have a meaning in a format string. These may not occur
inside nested parentheses. They are:
``|``
- Indicates that the remaining arguments in the Python argument list are
- optional. The C variables corresponding to optional arguments should be
- initialized to their default value --- when an optional argument is not
- specified, :c:func:`PyArg_ParseTuple` does not touch the contents of the
- corresponding C variable(s).
+ Indicates that the remaining arguments in the Python argument list are optional.
+ The C variables corresponding to optional arguments should be initialized to
+ their default value --- when an optional argument is not specified,
+ :c:func:`PyArg_ParseTuple` does not touch the contents of the corresponding C
+ variable(s).
``:``
- The list of format units ends here; the string after the colon is used as
- the function name in error messages (the "associated value" of the
- exception that :c:func:`PyArg_ParseTuple` raises).
+ The list of format units ends here; the string after the colon is used as the
+ function name in error messages (the "associated value" of the exception that
+ :c:func:`PyArg_ParseTuple` raises).
``;``
- The list of format units ends here; the string after the semicolon is used
- as the error message *instead* of the default error message. ``:`` and
- ``;`` mutually exclude each other.
+ The list of format units ends here; the string after the semicolon is used as
+ the error message *instead* of the default error message. ``:`` and ``;``
+ mutually exclude each other.
Note that any Python object references which are provided to the caller are
*borrowed* references; do not decrement their reference count!
Additional arguments passed to these functions must be addresses of variables
whose type is determined by the format string; these are used to store values
-from the input tuple. There are a few cases, as described in the list of
-format units above, where these parameters are used as input values; they
-should match what is specified for the corresponding format unit in that case.
-
-For the conversion to succeed, the *arg* object must match the format and the
-format must be exhausted. On success, the :c:func:`PyArg_Parse\*` functions
-return true, otherwise they return false and raise an appropriate exception.
-When the :c:func:`PyArg_Parse\*` functions fail due to conversion failure in
-one of the format units, the variables at the addresses corresponding to that
+from the input tuple. There are a few cases, as described in the list of format
+units above, where these parameters are used as input values; they should match
+what is specified for the corresponding format unit in that case.
+
+For the conversion to succeed, the *arg* object must match the format
+and the format must be exhausted. On success, the
+:c:func:`PyArg_Parse\*` functions return true, otherwise they return
+false and raise an appropriate exception. When the
+:c:func:`PyArg_Parse\*` functions fail due to conversion failure in one
+of the format units, the variables at the addresses corresponding to that
and the following format units are left untouched.
+API Functions
+-------------
.. c:function:: int PyArg_ParseTuple(PyObject *args, const char *format, ...)
- Parse the parameters of a function that takes only positional parameters
- into local variables. Returns true on success; on failure, it returns
- false and raises the appropriate exception.
+ Parse the parameters of a function that takes only positional parameters into
+ local variables. Returns true on success; on failure, it returns false and
+ raises the appropriate exception.
.. c:function:: int PyArg_VaParse(PyObject *args, const char *format, va_list vargs)
- Identical to :c:func:`PyArg_ParseTuple`, except that it accepts a va_list
- rather than a variable number of arguments.
+ Identical to :c:func:`PyArg_ParseTuple`, except that it accepts a va_list rather
+ than a variable number of arguments.
.. c:function:: int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], ...)
@@ -358,35 +392,44 @@ and the following format units are left untouched.
va_list rather than a variable number of arguments.
+.. c:function:: int PyArg_ValidateKeywordArguments(PyObject *)
+
+ Ensure that the keys in the keywords argument dictionary are strings. This
+ is only needed if :c:func:`PyArg_ParseTupleAndKeywords` is not used, since the
+ latter already does this check.
+
+ .. versionadded:: 3.2
+
+
+.. XXX deprecated, will be removed
.. c:function:: int PyArg_Parse(PyObject *args, const char *format, ...)
- Function used to deconstruct the argument lists of "old-style" functions
- --- these are functions which use the :const:`METH_OLDARGS` parameter
- parsing method. This is not recommended for use in parameter parsing in
- new code, and most code in the standard interpreter has been modified to no
- longer use this for that purpose. It does remain a convenient way to
- decompose other tuples, however, and may continue to be used for that
- purpose.
+ Function used to deconstruct the argument lists of "old-style" functions ---
+ these are functions which use the :const:`METH_OLDARGS` parameter parsing
+ method. This is not recommended for use in parameter parsing in new code, and
+ most code in the standard interpreter has been modified to no longer use this
+ for that purpose. It does remain a convenient way to decompose other tuples,
+ however, and may continue to be used for that purpose.
.. c:function:: int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)
A simpler form of parameter retrieval which does not use a format string to
- specify the types of the arguments. Functions which use this method to
- retrieve their parameters should be declared as :const:`METH_VARARGS` in
- function or method tables. The tuple containing the actual parameters
- should be passed as *args*; it must actually be a tuple. The length of the
- tuple must be at least *min* and no more than *max*; *min* and *max* may be
- equal. Additional arguments must be passed to the function, each of which
- should be a pointer to a :c:type:`PyObject\*` variable; these will be filled
- in with the values from *args*; they will contain borrowed references. The
- variables which correspond to optional parameters not given by *args* will
- not be filled in; these should be initialized by the caller. This function
- returns true on success and false if *args* is not a tuple or contains the
- wrong number of elements; an exception will be set if there was a failure.
-
- This is an example of the use of this function, taken from the sources for
- the :mod:`_weakref` helper module for weak references::
+ specify the types of the arguments. Functions which use this method to retrieve
+ their parameters should be declared as :const:`METH_VARARGS` in function or
+ method tables. The tuple containing the actual parameters should be passed as
+ *args*; it must actually be a tuple. The length of the tuple must be at least
+ *min* and no more than *max*; *min* and *max* may be equal. Additional
+ arguments must be passed to the function, each of which should be a pointer to a
+ :c:type:`PyObject\*` variable; these will be filled in with the values from
+ *args*; they will contain borrowed references. The variables which correspond
+ to optional parameters not given by *args* will not be filled in; these should
+ be initialized by the caller. This function returns true on success and false if
+ *args* is not a tuple or contains the wrong number of elements; an exception
+ will be set if there was a failure.
+
+ This is an example of the use of this function, taken from the sources for the
+ :mod:`_weakref` helper module for weak references::
static PyObject *
weakref_ref(PyObject *self, PyObject *args)
@@ -401,162 +444,172 @@ and the following format units are left untouched.
return result;
}
- The call to :c:func:`PyArg_UnpackTuple` in this example is entirely
- equivalent to this call to :c:func:`PyArg_ParseTuple`::
+ The call to :c:func:`PyArg_UnpackTuple` in this example is entirely equivalent to
+ this call to :c:func:`PyArg_ParseTuple`::
PyArg_ParseTuple(args, "O|O:ref", &object, &callback)
- .. versionadded:: 2.2
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *min* and *max*. This might
- require changes in your code for properly supporting 64-bit systems.
+---------------
+Building values
+---------------
.. c:function:: PyObject* Py_BuildValue(const char *format, ...)
- Create a new value based on a format string similar to those accepted by
- the :c:func:`PyArg_Parse\*` family of functions and a sequence of values.
- Returns the value or *NULL* in the case of an error; an exception will be
- raised if *NULL* is returned.
-
- :c:func:`Py_BuildValue` does not always build a tuple. It builds a tuple
- only if its format string contains two or more format units. If the format
- string is empty, it returns ``None``; if it contains exactly one format
- unit, it returns whatever object is described by that format unit. To
- force it to return a tuple of size 0 or one, parenthesize the format
- string.
-
- When memory buffers are passed as parameters to supply data to build
- objects, as for the ``s`` and ``s#`` formats, the required data is copied.
- Buffers provided by the caller are never referenced by the objects created
- by :c:func:`Py_BuildValue`. In other words, if your code invokes
- :c:func:`malloc` and passes the allocated memory to :c:func:`Py_BuildValue`,
- your code is responsible for calling :c:func:`free` for that memory once
+ Create a new value based on a format string similar to those accepted by the
+ :c:func:`PyArg_Parse\*` family of functions and a sequence of values. Returns
+ the value or *NULL* in the case of an error; an exception will be raised if
+ *NULL* is returned.
+
+ :c:func:`Py_BuildValue` does not always build a tuple. It builds a tuple only if
+ its format string contains two or more format units. If the format string is
+ empty, it returns ``None``; if it contains exactly one format unit, it returns
+ whatever object is described by that format unit. To force it to return a tuple
+ of size 0 or one, parenthesize the format string.
+
+ When memory buffers are passed as parameters to supply data to build objects, as
+ for the ``s`` and ``s#`` formats, the required data is copied. Buffers provided
+ by the caller are never referenced by the objects created by
+ :c:func:`Py_BuildValue`. In other words, if your code invokes :c:func:`malloc`
+ and passes the allocated memory to :c:func:`Py_BuildValue`, your code is
+ responsible for calling :c:func:`free` for that memory once
:c:func:`Py_BuildValue` returns.
- In the following description, the quoted form is the format unit; the entry
- in (round) parentheses is the Python object type that the format unit will
- return; and the entry in [square] brackets is the type of the C value(s) to
- be passed.
+ In the following description, the quoted form is the format unit; the entry in
+ (round) parentheses is the Python object type that the format unit will return;
+ and the entry in [square] brackets is the type of the C value(s) to be passed.
- The characters space, tab, colon and comma are ignored in format strings
- (but not within format units such as ``s#``). This can be used to make
- long format strings a tad more readable.
+ The characters space, tab, colon and comma are ignored in format strings (but
+ not within format units such as ``s#``). This can be used to make long format
+ strings a tad more readable.
+
+ ``s`` (:class:`str` or ``None``) [char \*]
+ Convert a null-terminated C string to a Python :class:`str` object using ``'utf-8'``
+ encoding. If the C string pointer is *NULL*, ``None`` is used.
+
+ ``s#`` (:class:`str` or ``None``) [char \*, int]
+ Convert a C string and its length to a Python :class:`str` object using ``'utf-8'``
+ encoding. If the C string pointer is *NULL*, the length is ignored and
+ ``None`` is returned.
- ``s`` (string) [char \*]
- Convert a null-terminated C string to a Python object. If the C string
- pointer is *NULL*, ``None`` is used.
+ ``y`` (:class:`bytes`) [char \*]
+ This converts a C string to a Python :func:`bytes` object. If the C
+ string pointer is *NULL*, ``None`` is returned.
- ``s#`` (string) [char \*, int]
- Convert a C string and its length to a Python object. If the C string
- pointer is *NULL*, the length is ignored and ``None`` is returned.
+ ``y#`` (:class:`bytes`) [char \*, int]
+ This converts a C string and its lengths to a Python object. If the C
+ string pointer is *NULL*, ``None`` is returned.
- ``z`` (string or ``None``) [char \*]
+ ``z`` (:class:`str` or ``None``) [char \*]
Same as ``s``.
- ``z#`` (string or ``None``) [char \*, int]
+ ``z#`` (:class:`str` or ``None``) [char \*, int]
Same as ``s#``.
- ``u`` (Unicode string) [Py_UNICODE \*]
- Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a
- Python Unicode object. If the Unicode buffer pointer is *NULL*,
- ``None`` is returned.
+ ``u`` (:class:`str`) [Py_UNICODE \*]
+ Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a Python
+ Unicode object. If the Unicode buffer pointer is *NULL*, ``None`` is returned.
+
+ ``u#`` (:class:`str`) [Py_UNICODE \*, int]
+ Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a Python
+ Unicode object. If the Unicode buffer pointer is *NULL*, the length is ignored
+ and ``None`` is returned.
+
+ ``U`` (:class:`str` or ``None``) [char \*]
+ Same as ``s``.
- ``u#`` (Unicode string) [Py_UNICODE \*, int]
- Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a
- Python Unicode object. If the Unicode buffer pointer is *NULL*, the
- length is ignored and ``None`` is returned.
+ ``U#`` (:class:`str` or ``None``) [char \*, int]
+ Same as ``s#``.
- ``i`` (integer) [int]
+ ``i`` (:class:`int`) [int]
Convert a plain C :c:type:`int` to a Python integer object.
- ``b`` (integer) [char]
+ ``b`` (:class:`int`) [char]
Convert a plain C :c:type:`char` to a Python integer object.
- ``h`` (integer) [short int]
+ ``h`` (:class:`int`) [short int]
Convert a plain C :c:type:`short int` to a Python integer object.
- ``l`` (integer) [long int]
+ ``l`` (:class:`int`) [long int]
Convert a C :c:type:`long int` to a Python integer object.
- ``B`` (integer) [unsigned char]
+ ``B`` (:class:`int`) [unsigned char]
Convert a C :c:type:`unsigned char` to a Python integer object.
- ``H`` (integer) [unsigned short int]
+ ``H`` (:class:`int`) [unsigned short int]
Convert a C :c:type:`unsigned short int` to a Python integer object.
- ``I`` (integer/long) [unsigned int]
- Convert a C :c:type:`unsigned int` to a Python integer object or a Python
- long integer object, if it is larger than ``sys.maxint``.
-
- ``k`` (integer/long) [unsigned long]
- Convert a C :c:type:`unsigned long` to a Python integer object or a
- Python long integer object, if it is larger than ``sys.maxint``.
+ ``I`` (:class:`int`) [unsigned int]
+ Convert a C :c:type:`unsigned int` to a Python integer object.
- ``L`` (long) [PY_LONG_LONG]
- Convert a C :c:type:`long long` to a Python long integer object. Only
- available on platforms that support :c:type:`long long`.
+ ``k`` (:class:`int`) [unsigned long]
+ Convert a C :c:type:`unsigned long` to a Python integer object.
- ``K`` (long) [unsigned PY_LONG_LONG]
- Convert a C :c:type:`unsigned long long` to a Python long integer object.
- Only available on platforms that support :c:type:`unsigned long long`.
+ ``L`` (:class:`int`) [PY_LONG_LONG]
+ Convert a C :c:type:`long long` to a Python integer object. Only available
+ on platforms that support :c:type:`long long` (or :c:type:`_int64` on
+ Windows).
- ``n`` (int) [Py_ssize_t]
- Convert a C :c:type:`Py_ssize_t` to a Python integer or long integer.
+ ``K`` (:class:`int`) [unsigned PY_LONG_LONG]
+ Convert a C :c:type:`unsigned long long` to a Python integer object. Only
+ available on platforms that support :c:type:`unsigned long long` (or
+ :c:type:`unsigned _int64` on Windows).
- .. versionadded:: 2.5
+ ``n`` (:class:`int`) [Py_ssize_t]
+ Convert a C :c:type:`Py_ssize_t` to a Python integer.
- ``c`` (string of length 1) [char]
- Convert a C :c:type:`int` representing a character to a Python string of
+ ``c`` (:class:`bytes` of length 1) [char]
+ Convert a C :c:type:`int` representing a byte to a Python :class:`bytes` object of
length 1.
- ``d`` (float) [double]
+ ``C`` (:class:`str` of length 1) [int]
+ Convert a C :c:type:`int` representing a character to Python :class:`str`
+ object of length 1.
+
+ ``d`` (:class:`float`) [double]
Convert a C :c:type:`double` to a Python floating point number.
- ``f`` (float) [float]
- Same as ``d``.
+ ``f`` (:class:`float`) [float]
+ Convert a C :c:type:`float` to a Python floating point number.
- ``D`` (complex) [Py_complex \*]
+ ``D`` (:class:`complex`) [Py_complex \*]
Convert a C :c:type:`Py_complex` structure to a Python complex number.
``O`` (object) [PyObject \*]
Pass a Python object untouched (except for its reference count, which is
- incremented by one). If the object passed in is a *NULL* pointer, it is
- assumed that this was caused because the call producing the argument
- found an error and set an exception. Therefore, :c:func:`Py_BuildValue`
- will return *NULL* but won't raise an exception. If no exception has
- been raised yet, :exc:`SystemError` is set.
+ incremented by one). If the object passed in is a *NULL* pointer, it is assumed
+ that this was caused because the call producing the argument found an error and
+ set an exception. Therefore, :c:func:`Py_BuildValue` will return *NULL* but won't
+ raise an exception. If no exception has been raised yet, :exc:`SystemError` is
+ set.
``S`` (object) [PyObject \*]
Same as ``O``.
``N`` (object) [PyObject \*]
- Same as ``O``, except it doesn't increment the reference count on the
- object. Useful when the object is created by a call to an object
- constructor in the argument list.
+ Same as ``O``, except it doesn't increment the reference count on the object.
+ Useful when the object is created by a call to an object constructor in the
+ argument list.
``O&`` (object) [*converter*, *anything*]
- Convert *anything* to a Python object through a *converter* function.
- The function is called with *anything* (which should be compatible with
- :c:type:`void \*`) as its argument and should return a "new" Python
- object, or *NULL* if an error occurred.
-
- ``(items)`` (tuple) [*matching-items*]
- Convert a sequence of C values to a Python tuple with the same number of
- items.
-
- ``[items]`` (list) [*matching-items*]
- Convert a sequence of C values to a Python list with the same number of
- items.
-
- ``{items}`` (dictionary) [*matching-items*]
- Convert a sequence of C values to a Python dictionary. Each pair of
- consecutive C values adds one item to the dictionary, serving as key and
- value, respectively.
-
- If there is an error in the format string, the :exc:`SystemError` exception
- is set and *NULL* returned.
+ Convert *anything* to a Python object through a *converter* function. The
+ function is called with *anything* (which should be compatible with :c:type:`void
+ \*`) as its argument and should return a "new" Python object, or *NULL* if an
+ error occurred.
+
+ ``(items)`` (:class:`tuple`) [*matching-items*]
+ Convert a sequence of C values to a Python tuple with the same number of items.
+
+ ``[items]`` (:class:`list`) [*matching-items*]
+ Convert a sequence of C values to a Python list with the same number of items.
+
+ ``{items}`` (:class:`dict`) [*matching-items*]
+ Convert a sequence of C values to a Python dictionary. Each pair of consecutive
+ C values adds one item to the dictionary, serving as key and value,
+ respectively.
+
+ If there is an error in the format string, the :exc:`SystemError` exception is
+ set and *NULL* returned.
.. c:function:: PyObject* Py_VaBuildValue(const char *format, va_list vargs)
diff --git a/Doc/c-api/bool.rst b/Doc/c-api/bool.rst
index fede348..a9fb342 100644
--- a/Doc/c-api/bool.rst
+++ b/Doc/c-api/bool.rst
@@ -15,8 +15,6 @@ are available, however.
Return true if *o* is of type :c:data:`PyBool_Type`.
- .. versionadded:: 2.3
-
.. c:var:: PyObject* Py_False
@@ -35,20 +33,14 @@ are available, however.
Return :const:`Py_False` from a function, properly incrementing its reference
count.
- .. versionadded:: 2.4
-
.. c:macro:: Py_RETURN_TRUE
Return :const:`Py_True` from a function, properly incrementing its reference
count.
- .. versionadded:: 2.4
-
.. c:function:: PyObject* PyBool_FromLong(long v)
Return a new reference to :const:`Py_True` or :const:`Py_False` depending on the
truth value of *v*.
-
- .. versionadded:: 2.3
diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst
index e028369..740b575 100644
--- a/Doc/c-api/buffer.rst
+++ b/Doc/c-api/buffer.rst
@@ -1,50 +1,84 @@
.. highlightlang:: c
+.. index::
+ single: buffer protocol
+ single: buffer interface; (see buffer protocol)
+ single: buffer object; (see buffer protocol)
+
.. _bufferobjects:
-Buffers and Memoryview Objects
-------------------------------
+Buffer Protocol
+---------------
.. sectionauthor:: Greg Stein <gstein@lyra.org>
.. sectionauthor:: Benjamin Peterson
-.. index::
- object: buffer
- single: buffer interface
+Certain objects available in Python wrap access to an underlying memory
+array or *buffer*. Such objects include the built-in :class:`bytes` and
+:class:`bytearray`, and some extension types like :class:`array.array`.
+Third-party libraries may define their own types for special purposes, such
+as image processing or numeric analysis.
+
+While each of these types have their own semantics, they share the common
+characteristic of being backed by a possibly large memory buffer. It is
+then desireable, in some situations, to access that buffer directly and
+without intermediate copying.
+
+Python provides such a facility at the C level in the form of the :ref:`buffer
+protocol <bufferobjects>`. This protocol has two sides:
+
+.. index:: single: PyBufferProcs
+
+- on the producer side, a type can export a "buffer interface" which allows
+ objects of that type to expose information about their underlying buffer.
+ This interface is described in the section :ref:`buffer-structs`;
+
+- on the consumer side, several means are available to obtain a pointer to
+ the raw underlying data of an object (for example a method parameter).
-Python objects implemented in C can export a group of functions called the
-"buffer interface." These functions can be used by an object to expose its
-data in a raw, byte-oriented format. Clients of the object can use the buffer
-interface to access the object data directly, without needing to copy it
-first.
+Simple objects such as :class:`bytes` and :class:`bytearray` expose their
+underlying buffer in byte-oriented form. Other forms are possible; for example,
+the elements exposed by a :class:`array.array` can be multi-byte values.
-Two examples of objects that support the buffer interface are strings and
-arrays. The string object exposes the character contents in the buffer
-interface's byte-oriented form. An array can also expose its contents, but it
-should be noted that array elements may be multi-byte values.
+An example consumer of the buffer interface is the :meth:`~io.BufferedIOBase.write`
+method of file objects: any object that can export a series of bytes through
+the buffer interface can be written to a file. While :meth:`write` only
+needs read-only access to the internal contents of the object passed to it,
+other methods such as :meth:`~io.BufferedIOBase.readinto` need write access
+to the contents of their argument. The buffer interface allows objects to
+selectively allow or reject exporting of read-write and read-only buffers.
-An example user of the buffer interface is the file object's :meth:`write`
-method. Any object that can export a series of bytes through the buffer
-interface can be written to a file. There are a number of format codes to
-:c:func:`PyArg_ParseTuple` that operate against an object's buffer interface,
-returning data from the target object.
+There are two ways for a consumer of the buffer interface to acquire a buffer
+over a target object:
-Starting from version 1.6, Python has been providing Python-level buffer
-objects and a C-level buffer API so that any built-in or used-defined type can
-expose its characteristics. Both, however, have been deprecated because of
-various shortcomings, and have been officially removed in Python 3 in favour
-of a new C-level buffer API and a new Python-level object named
-:class:`memoryview`.
+* call :c:func:`PyObject_GetBuffer` with the right parameters;
-The new buffer API has been backported to Python 2.6, and the
-:class:`memoryview` object has been backported to Python 2.7. It is strongly
-advised to use them rather than the old APIs, unless you are blocked from
-doing so for compatibility reasons.
+* call :c:func:`PyArg_ParseTuple` (or one of its siblings) with one of the
+ ``y*``, ``w*`` or ``s*`` :ref:`format codes <arg-parsing>`.
+In both cases, :c:func:`PyBuffer_Release` must be called when the buffer
+isn't needed anymore. Failure to do so could lead to various issues such as
+resource leaks.
-The new-style Py_buffer struct
-==============================
+
+The buffer structure
+====================
+
+Buffer structures (or simply "buffers") are useful as a way to expose the
+binary data from another object to the Python programmer. They can also be
+used as a zero-copy slicing mechanism. Using their ability to reference a
+block of memory, it is possible to expose any data to the Python programmer
+quite easily. The memory could be a large, constant array in a C extension,
+it could be a raw block of memory for manipulation before passing to an
+operating system library, or it could be used to pass around structured data
+in its native, in-memory format.
+
+Contrary to most data types exposed by the Python interpreter, buffers
+are not :c:type:`PyObject` pointers but rather simple C structures. This
+allows them to be created and copied very simply. When a generic wrapper
+around a buffer is needed, a :ref:`memoryview <memoryview-objects>` object
+can be created.
.. c:type:: Py_buffer
@@ -97,7 +131,7 @@ The new-style Py_buffer struct
occur (striding in a contiguous memory block).
Here is a function that returns a pointer to the element in an N-D array
- pointed to by an N-dimesional index when there are both non-NULL strides
+ pointed to by an N-dimensional index when there are both non-NULL strides
and suboffsets::
void *get_item_pointer(int ndim, void *buf, Py_ssize_t *strides,
@@ -132,24 +166,29 @@ The new-style Py_buffer struct
value.
-Buffer related functions
+Buffer-related functions
========================
.. c:function:: int PyObject_CheckBuffer(PyObject *obj)
- Return 1 if *obj* supports the buffer interface otherwise 0.
+ Return 1 if *obj* supports the buffer interface otherwise 0. When 1 is
+ returned, it doesn't guarantee that :c:func:`PyObject_GetBuffer` will
+ succeed.
.. c:function:: int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
- Export *obj* into a :c:type:`Py_buffer`, *view*. These arguments must
- never be *NULL*. The *flags* argument is a bit field indicating what
- kind of buffer the caller is prepared to deal with and therefore what
- kind of buffer the exporter is allowed to return. The buffer interface
- allows for complicated memory sharing possibilities, but some caller may
- not be able to handle all the complexity but may want to see if the
- exporter will let them take a simpler view to its memory.
+ Export a view over some internal data from the target object *obj*.
+ *obj* must not be NULL, and *view* must point to an existing
+ :c:type:`Py_buffer` structure allocated by the caller (most uses of
+ this function will simply declare a local variable of type
+ :c:type:`Py_buffer`). The *flags* argument is a bit field indicating
+ what kind of buffer is requested. The buffer interface allows
+ for complicated memory layout possibilities; however, some callers
+ won't want to handle all the complexity and instead request a simple
+ view of the target object (using :c:macro:`PyBUF_SIMPLE` for a read-only
+ view and :c:macro:`PyBUF_WRITABLE` for a read-write view).
Some exporters may not be able to share memory in every possible way and
may need to raise errors to signal to some consumers that something is
@@ -159,292 +198,131 @@ Buffer related functions
:c:data:`Py_buffer` structure is filled in with non-default values and/or
raise an error if the object can't support a simpler view of its memory.
- 0 is returned on success and -1 on error.
-
- The following table gives possible values to the *flags* arguments.
-
- +-------------------------------+---------------------------------------------------+
- | Flag | Description |
- +===============================+===================================================+
- | :c:macro:`PyBUF_SIMPLE` | This is the default flag state. The returned |
- | | buffer may or may not have writable memory. The |
- | | format of the data will be assumed to be unsigned |
- | | bytes. This is a "stand-alone" flag constant. It |
- | | never needs to be '|'d to the others. The exporter|
- | | will raise an error if it cannot provide such a |
- | | contiguous buffer of bytes. |
- | | |
- +-------------------------------+---------------------------------------------------+
- | :c:macro:`PyBUF_WRITABLE` | The returned buffer must be writable. If it is |
- | | not writable, then raise an error. |
- +-------------------------------+---------------------------------------------------+
- | :c:macro:`PyBUF_STRIDES` | This implies :c:macro:`PyBUF_ND`. The returned |
- | | buffer must provide strides information (i.e. the |
- | | strides cannot be NULL). This would be used when |
- | | the consumer can handle strided, discontiguous |
- | | arrays. Handling strides automatically assumes |
- | | you can handle shape. The exporter can raise an |
- | | error if a strided representation of the data is |
- | | not possible (i.e. without the suboffsets). |
- | | |
- +-------------------------------+---------------------------------------------------+
- | :c:macro:`PyBUF_ND` | The returned buffer must provide shape |
- | | information. The memory will be assumed C-style |
- | | contiguous (last dimension varies the |
- | | fastest). The exporter may raise an error if it |
- | | cannot provide this kind of contiguous buffer. If |
- | | this is not given then shape will be *NULL*. |
- | | |
- | | |
- | | |
- +-------------------------------+---------------------------------------------------+
- |:c:macro:`PyBUF_C_CONTIGUOUS` | These flags indicate that the contiguity returned |
- |:c:macro:`PyBUF_F_CONTIGUOUS` | buffer must be respectively, C-contiguous (last |
- |:c:macro:`PyBUF_ANY_CONTIGUOUS`| dimension varies the fastest), Fortran contiguous |
- | | (first dimension varies the fastest) or either |
- | | one. All of these flags imply |
- | | :c:macro:`PyBUF_STRIDES` and guarantee that the |
- | | strides buffer info structure will be filled in |
- | | correctly. |
- | | |
- +-------------------------------+---------------------------------------------------+
- | :c:macro:`PyBUF_INDIRECT` | This flag indicates the returned buffer must have |
- | | suboffsets information (which can be NULL if no |
- | | suboffsets are needed). This can be used when |
- | | the consumer can handle indirect array |
- | | referencing implied by these suboffsets. This |
- | | implies :c:macro:`PyBUF_STRIDES`. |
- | | |
- | | |
- | | |
- +-------------------------------+---------------------------------------------------+
- | :c:macro:`PyBUF_FORMAT` | The returned buffer must have true format |
- | | information if this flag is provided. This would |
- | | be used when the consumer is going to be checking |
- | | for what 'kind' of data is actually stored. An |
- | | exporter should always be able to provide this |
- | | information if requested. If format is not |
- | | explicitly requested then the format must be |
- | | returned as *NULL* (which means ``'B'``, or |
- | | unsigned bytes) |
- +-------------------------------+---------------------------------------------------+
- | :c:macro:`PyBUF_STRIDED` | This is equivalent to ``(PyBUF_STRIDES | |
- | | PyBUF_WRITABLE)``. |
- +-------------------------------+---------------------------------------------------+
- | :c:macro:`PyBUF_STRIDED_RO` | This is equivalent to ``(PyBUF_STRIDES)``. |
- | | |
- +-------------------------------+---------------------------------------------------+
- | :c:macro:`PyBUF_RECORDS` | This is equivalent to ``(PyBUF_STRIDES | |
- | | PyBUF_FORMAT | PyBUF_WRITABLE)``. |
- +-------------------------------+---------------------------------------------------+
- | :c:macro:`PyBUF_RECORDS_RO` | This is equivalent to ``(PyBUF_STRIDES | |
- | | PyBUF_FORMAT)``. |
- +-------------------------------+---------------------------------------------------+
- | :c:macro:`PyBUF_FULL` | This is equivalent to ``(PyBUF_INDIRECT | |
- | | PyBUF_FORMAT | PyBUF_WRITABLE)``. |
- +-------------------------------+---------------------------------------------------+
- | :c:macro:`PyBUF_FULL_RO` | This is equivalent to ``(PyBUF_INDIRECT | |
- | | PyBUF_FORMAT)``. |
- +-------------------------------+---------------------------------------------------+
- | :c:macro:`PyBUF_CONTIG` | This is equivalent to ``(PyBUF_ND | |
- | | PyBUF_WRITABLE)``. |
- +-------------------------------+---------------------------------------------------+
- | :c:macro:`PyBUF_CONTIG_RO` | This is equivalent to ``(PyBUF_ND)``. |
- | | |
- +-------------------------------+---------------------------------------------------+
-
-
-.. c:function:: void PyBuffer_Release(Py_buffer *view)
-
- Release the buffer *view*. This should be called when the buffer
- is no longer being used as it may free memory from it.
-
-
-.. c:function:: Py_ssize_t PyBuffer_SizeFromFormat(const char *)
+ On success, 0 is returned and the *view* structure is filled with useful
+ values. On error, -1 is returned and an exception is raised; the *view*
+ is left in an undefined state.
- Return the implied :c:data:`~Py_buffer.itemsize` from the struct-stype
- :c:data:`~Py_buffer.format`.
+ The following are the possible values to the *flags* arguments.
+ .. c:macro:: PyBUF_SIMPLE
-.. c:function:: int PyBuffer_IsContiguous(Py_buffer *view, char fortran)
+ This is the default flag. The returned buffer exposes a read-only
+ memory area. The format of data is assumed to be raw unsigned bytes,
+ without any particular structure. This is a "stand-alone" flag
+ constant. It never needs to be '|'d to the others. The exporter will
+ raise an error if it cannot provide such a contiguous buffer of bytes.
- Return 1 if the memory defined by the *view* is C-style (*fortran* is
- ``'C'``) or Fortran-style (*fortran* is ``'F'``) contiguous or either one
- (*fortran* is ``'A'``). Return 0 otherwise.
+ .. c:macro:: PyBUF_WRITABLE
+ Like :c:macro:`PyBUF_SIMPLE`, but the returned buffer is writable. If
+ the exporter doesn't support writable buffers, an error is raised.
-.. c:function:: void PyBuffer_FillContiguousStrides(int ndim, Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t itemsize, char fortran)
-
- Fill the *strides* array with byte-strides of a contiguous (C-style if
- *fortran* is ``'C'`` or Fortran-style if *fortran* is ``'F'``) array of the
- given shape with the given number of bytes per element.
+ .. c:macro:: PyBUF_STRIDES
+ This implies :c:macro:`PyBUF_ND`. The returned buffer must provide
+ strides information (i.e. the strides cannot be NULL). This would be
+ used when the consumer can handle strided, discontiguous arrays.
+ Handling strides automatically assumes you can handle shape. The
+ exporter can raise an error if a strided representation of the data is
+ not possible (i.e. without the suboffsets).
-.. c:function:: int PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, int readonly, int infoflags)
+ .. c:macro:: PyBUF_ND
- Fill in a buffer-info structure, *view*, correctly for an exporter that can
- only share a contiguous chunk of memory of "unsigned bytes" of the given
- length. Return 0 on success and -1 (with raising an error) on error.
+ The returned buffer must provide shape information. The memory will be
+ assumed C-style contiguous (last dimension varies the fastest). The
+ exporter may raise an error if it cannot provide this kind of
+ contiguous buffer. If this is not given then shape will be *NULL*.
+ .. c:macro:: PyBUF_C_CONTIGUOUS
+ PyBUF_F_CONTIGUOUS
+ PyBUF_ANY_CONTIGUOUS
-MemoryView objects
-==================
+ These flags indicate that the contiguity returned buffer must be
+ respectively, C-contiguous (last dimension varies the fastest), Fortran
+ contiguous (first dimension varies the fastest) or either one. All of
+ these flags imply :c:macro:`PyBUF_STRIDES` and guarantee that the
+ strides buffer info structure will be filled in correctly.
-.. versionadded:: 2.7
+ .. c:macro:: PyBUF_INDIRECT
-A :class:`memoryview` object exposes the new C level buffer interface as a
-Python object which can then be passed around like any other object.
+ This flag indicates the returned buffer must have suboffsets
+ information (which can be NULL if no suboffsets are needed). This can
+ be used when the consumer can handle indirect array referencing implied
+ by these suboffsets. This implies :c:macro:`PyBUF_STRIDES`.
-.. c:function:: PyObject *PyMemoryView_FromObject(PyObject *obj)
+ .. c:macro:: PyBUF_FORMAT
- Create a memoryview object from an object that defines the new buffer
- interface.
+ The returned buffer must have true format information if this flag is
+ provided. This would be used when the consumer is going to be checking
+ for what 'kind' of data is actually stored. An exporter should always
+ be able to provide this information if requested. If format is not
+ explicitly requested then the format must be returned as *NULL* (which
+ means ``'B'``, or unsigned bytes).
+ .. c:macro:: PyBUF_STRIDED
-.. c:function:: PyObject *PyMemoryView_FromBuffer(Py_buffer *view)
+ This is equivalent to ``(PyBUF_STRIDES | PyBUF_WRITABLE)``.
- Create a memoryview object wrapping the given buffer-info structure *view*.
- The memoryview object then owns the buffer, which means you shouldn't
- try to release it yourself: it will be released on deallocation of the
- memoryview object.
+ .. c:macro:: PyBUF_STRIDED_RO
+ This is equivalent to ``(PyBUF_STRIDES)``.
-.. c:function:: PyObject *PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order)
+ .. c:macro:: PyBUF_RECORDS
- Create a memoryview object to a contiguous chunk of memory (in either
- 'C' or 'F'ortran *order*) from an object that defines the buffer
- interface. If memory is contiguous, the memoryview object points to the
- original memory. Otherwise copy is made and the memoryview points to a
- new bytes object.
+ This is equivalent to ``(PyBUF_STRIDES | PyBUF_FORMAT |
+ PyBUF_WRITABLE)``.
+ .. c:macro:: PyBUF_RECORDS_RO
-.. c:function:: int PyMemoryView_Check(PyObject *obj)
+ This is equivalent to ``(PyBUF_STRIDES | PyBUF_FORMAT)``.
- Return true if the object *obj* is a memoryview object. It is not
- currently allowed to create subclasses of :class:`memoryview`.
+ .. c:macro:: PyBUF_FULL
+ This is equivalent to ``(PyBUF_INDIRECT | PyBUF_FORMAT |
+ PyBUF_WRITABLE)``.
-.. c:function:: Py_buffer *PyMemoryView_GET_BUFFER(PyObject *obj)
+ .. c:macro:: PyBUF_FULL_RO
- Return a pointer to the buffer-info structure wrapped by the given
- object. The object **must** be a memoryview instance; this macro doesn't
- check its type, you must do it yourself or you will risk crashes.
+ This is equivalent to ``(PyBUF_INDIRECT | PyBUF_FORMAT)``.
+ .. c:macro:: PyBUF_CONTIG
-Old-style buffer objects
-========================
+ This is equivalent to ``(PyBUF_ND | PyBUF_WRITABLE)``.
-.. index:: single: PyBufferProcs
+ .. c:macro:: PyBUF_CONTIG_RO
-More information on the old buffer interface is provided in the section
-:ref:`buffer-structs`, under the description for :c:type:`PyBufferProcs`.
+ This is equivalent to ``(PyBUF_ND)``.
-A "buffer object" is defined in the :file:`bufferobject.h` header (included by
-:file:`Python.h`). These objects look very similar to string objects at the
-Python programming level: they support slicing, indexing, concatenation, and
-some other standard string operations. However, their data can come from one
-of two sources: from a block of memory, or from another object which exports
-the buffer interface.
-Buffer objects are useful as a way to expose the data from another object's
-buffer interface to the Python programmer. They can also be used as a
-zero-copy slicing mechanism. Using their ability to reference a block of
-memory, it is possible to expose any data to the Python programmer quite
-easily. The memory could be a large, constant array in a C extension, it could
-be a raw block of memory for manipulation before passing to an operating
-system library, or it could be used to pass around structured data in its
-native, in-memory format.
-
-
-.. c:type:: PyBufferObject
-
- This subtype of :c:type:`PyObject` represents a buffer object.
-
-
-.. c:var:: PyTypeObject PyBuffer_Type
-
- .. index:: single: BufferType (in module types)
-
- The instance of :c:type:`PyTypeObject` which represents the Python buffer type;
- it is the same object as ``buffer`` and ``types.BufferType`` in the Python
- layer. .
-
-
-.. c:var:: int Py_END_OF_BUFFER
-
- This constant may be passed as the *size* parameter to
- :c:func:`PyBuffer_FromObject` or :c:func:`PyBuffer_FromReadWriteObject`. It
- indicates that the new :c:type:`PyBufferObject` should refer to *base*
- object from the specified *offset* to the end of its exported buffer.
- Using this enables the caller to avoid querying the *base* object for its
- length.
-
-
-.. c:function:: int PyBuffer_Check(PyObject *p)
-
- Return true if the argument has type :c:data:`PyBuffer_Type`.
-
-
-.. c:function:: PyObject* PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
-
- Return a new read-only buffer object. This raises :exc:`TypeError` if
- *base* doesn't support the read-only buffer protocol or doesn't provide
- exactly one buffer segment, or it raises :exc:`ValueError` if *offset* is
- less than zero. The buffer will hold a reference to the *base* object, and
- the buffer's contents will refer to the *base* object's buffer interface,
- starting as position *offset* and extending for *size* bytes. If *size* is
- :const:`Py_END_OF_BUFFER`, then the new buffer's contents extend to the
- length of the *base* object's exported buffer data.
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *offset* and *size*. This
- might require changes in your code for properly supporting 64-bit
- systems.
-
-
-.. c:function:: PyObject* PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
+.. c:function:: void PyBuffer_Release(Py_buffer *view)
- Return a new writable buffer object. Parameters and exceptions are similar
- to those for :c:func:`PyBuffer_FromObject`. If the *base* object does not
- export the writeable buffer protocol, then :exc:`TypeError` is raised.
+ Release the buffer *view*. This should be called when the buffer is no
+ longer being used as it may free memory from it.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *offset* and *size*. This
- might require changes in your code for properly supporting 64-bit
- systems.
+.. c:function:: Py_ssize_t PyBuffer_SizeFromFormat(const char *)
-.. c:function:: PyObject* PyBuffer_FromMemory(void *ptr, Py_ssize_t size)
+ Return the implied :c:data:`~Py_buffer.itemsize` from the struct-stype
+ :c:data:`~Py_buffer.format`.
- Return a new read-only buffer object that reads from a specified location
- in memory, with a specified size. The caller is responsible for ensuring
- that the memory buffer, passed in as *ptr*, is not deallocated while the
- returned buffer object exists. Raises :exc:`ValueError` if *size* is less
- than zero. Note that :const:`Py_END_OF_BUFFER` may *not* be passed for the
- *size* parameter; :exc:`ValueError` will be raised in that case.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
+.. c:function:: int PyBuffer_IsContiguous(Py_buffer *view, char fortran)
+ Return 1 if the memory defined by the *view* is C-style (*fortran* is
+ ``'C'``) or Fortran-style (*fortran* is ``'F'``) contiguous or either one
+ (*fortran* is ``'A'``). Return 0 otherwise.
-.. c:function:: PyObject* PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size)
- Similar to :c:func:`PyBuffer_FromMemory`, but the returned buffer is
- writable.
+.. c:function:: void PyBuffer_FillContiguousStrides(int ndim, Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t itemsize, char fortran)
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
+ Fill the *strides* array with byte-strides of a contiguous (C-style if
+ *fortran* is ``'C'`` or Fortran-style if *fortran* is ``'F'``) array of the
+ given shape with the given number of bytes per element.
-.. c:function:: PyObject* PyBuffer_New(Py_ssize_t size)
+.. c:function:: int PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, int readonly, int infoflags)
- Return a new writable buffer object that maintains its own memory buffer of
- *size* bytes. :exc:`ValueError` is returned if *size* is not zero or
- positive. Note that the memory buffer (as returned by
- :c:func:`PyObject_AsWriteBuffer`) is not specifically aligned.
+ Fill in a buffer-info structure, *view*, correctly for an exporter that can
+ only share a contiguous chunk of memory of "unsigned bytes" of the given
+ length. Return 0 on success and -1 (with raising an error) on error.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
diff --git a/Doc/c-api/bytearray.rst b/Doc/c-api/bytearray.rst
index 858c8db..95ded96 100644
--- a/Doc/c-api/bytearray.rst
+++ b/Doc/c-api/bytearray.rst
@@ -7,8 +7,6 @@ Byte Array Objects
.. index:: object: bytearray
-.. versionadded:: 2.6
-
.. c:type:: PyByteArrayObject
@@ -18,7 +16,8 @@ Byte Array Objects
.. c:var:: PyTypeObject PyByteArray_Type
This instance of :c:type:`PyTypeObject` represents the Python bytearray type;
- it is the same object as ``bytearray`` in the Python layer.
+ it is the same object as :class:`bytearray` in the Python layer.
+
Type check macros
^^^^^^^^^^^^^^^^^
diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst
new file mode 100644
index 0000000..12ec80c
--- /dev/null
+++ b/Doc/c-api/bytes.rst
@@ -0,0 +1,192 @@
+.. highlightlang:: c
+
+.. _bytesobjects:
+
+Bytes Objects
+-------------
+
+These functions raise :exc:`TypeError` when expecting a bytes parameter and are
+called with a non-bytes parameter.
+
+.. index:: object: bytes
+
+
+.. c:type:: PyBytesObject
+
+ This subtype of :c:type:`PyObject` represents a Python bytes object.
+
+
+.. c:var:: PyTypeObject PyBytes_Type
+
+ This instance of :c:type:`PyTypeObject` represents the Python bytes type; it
+ is the same object as :class:`bytes` in the Python layer.
+
+
+.. c:function:: int PyBytes_Check(PyObject *o)
+
+ Return true if the object *o* is a bytes object or an instance of a subtype
+ of the bytes type.
+
+
+.. c:function:: int PyBytes_CheckExact(PyObject *o)
+
+ Return true if the object *o* is a bytes object, but not an instance of a
+ subtype of the bytes type.
+
+
+.. c:function:: PyObject* PyBytes_FromString(const char *v)
+
+ Return a new bytes object with a copy of the string *v* as value on success,
+ and *NULL* on failure. The parameter *v* must not be *NULL*; it will not be
+ checked.
+
+
+.. c:function:: PyObject* PyBytes_FromStringAndSize(const char *v, Py_ssize_t len)
+
+ Return a new bytes object with a copy of the string *v* as value and length
+ *len* on success, and *NULL* on failure. If *v* is *NULL*, the contents of
+ the bytes object are uninitialized.
+
+
+.. c:function:: PyObject* PyBytes_FromFormat(const char *format, ...)
+
+ Take a C :c:func:`printf`\ -style *format* string and a variable number of
+ arguments, calculate the size of the resulting Python bytes object and return
+ a bytes object with the values formatted into it. The variable arguments
+ must be C types and must correspond exactly to the format characters in the
+ *format* string. The following format characters are allowed:
+
+ .. % XXX: This should be exactly the same as the table in PyErr_Format.
+ .. % One should just refer to the other.
+ .. % XXX: The descriptions for %zd and %zu are wrong, but the truth is complicated
+ .. % because not all compilers support the %z width modifier -- we fake it
+ .. % when necessary via interpolating PY_FORMAT_SIZE_T.
+
+ +-------------------+---------------+--------------------------------+
+ | Format Characters | Type | Comment |
+ +===================+===============+================================+
+ | :attr:`%%` | *n/a* | The literal % character. |
+ +-------------------+---------------+--------------------------------+
+ | :attr:`%c` | int | A single character, |
+ | | | represented as an C int. |
+ +-------------------+---------------+--------------------------------+
+ | :attr:`%d` | int | Exactly equivalent to |
+ | | | ``printf("%d")``. |
+ +-------------------+---------------+--------------------------------+
+ | :attr:`%u` | unsigned int | Exactly equivalent to |
+ | | | ``printf("%u")``. |
+ +-------------------+---------------+--------------------------------+
+ | :attr:`%ld` | long | Exactly equivalent to |
+ | | | ``printf("%ld")``. |
+ +-------------------+---------------+--------------------------------+
+ | :attr:`%lu` | unsigned long | Exactly equivalent to |
+ | | | ``printf("%lu")``. |
+ +-------------------+---------------+--------------------------------+
+ | :attr:`%zd` | Py_ssize_t | Exactly equivalent to |
+ | | | ``printf("%zd")``. |
+ +-------------------+---------------+--------------------------------+
+ | :attr:`%zu` | size_t | Exactly equivalent to |
+ | | | ``printf("%zu")``. |
+ +-------------------+---------------+--------------------------------+
+ | :attr:`%i` | int | Exactly equivalent to |
+ | | | ``printf("%i")``. |
+ +-------------------+---------------+--------------------------------+
+ | :attr:`%x` | int | Exactly equivalent to |
+ | | | ``printf("%x")``. |
+ +-------------------+---------------+--------------------------------+
+ | :attr:`%s` | char\* | A null-terminated C character |
+ | | | array. |
+ +-------------------+---------------+--------------------------------+
+ | :attr:`%p` | void\* | The hex representation of a C |
+ | | | pointer. Mostly equivalent to |
+ | | | ``printf("%p")`` except that |
+ | | | it is guaranteed to start with |
+ | | | the literal ``0x`` regardless |
+ | | | of what the platform's |
+ | | | ``printf`` yields. |
+ +-------------------+---------------+--------------------------------+
+
+ An unrecognized format character causes all the rest of the format string to be
+ copied as-is to the result string, and any extra arguments discarded.
+
+
+.. c:function:: PyObject* PyBytes_FromFormatV(const char *format, va_list vargs)
+
+ Identical to :c:func:`PyBytes_FromFormat` except that it takes exactly two
+ arguments.
+
+
+.. c:function:: PyObject* PyBytes_FromObject(PyObject *o)
+
+ Return the bytes representation of object *o* that implements the buffer
+ protocol.
+
+
+.. c:function:: Py_ssize_t PyBytes_Size(PyObject *o)
+
+ Return the length of the bytes in bytes object *o*.
+
+
+.. c:function:: Py_ssize_t PyBytes_GET_SIZE(PyObject *o)
+
+ Macro form of :c:func:`PyBytes_Size` but without error checking.
+
+
+.. c:function:: char* PyBytes_AsString(PyObject *o)
+
+ Return a NUL-terminated representation of the contents of *o*. The pointer
+ refers to the internal buffer of *o*, not a copy. The data must not be
+ modified in any way, unless the string was just created using
+ ``PyBytes_FromStringAndSize(NULL, size)``. It must not be deallocated. If
+ *o* is not a string object at all, :c:func:`PyBytes_AsString` returns *NULL*
+ and raises :exc:`TypeError`.
+
+
+.. c:function:: char* PyBytes_AS_STRING(PyObject *string)
+
+ Macro form of :c:func:`PyBytes_AsString` but without error checking.
+
+
+.. c:function:: int PyBytes_AsStringAndSize(PyObject *obj, char **buffer, Py_ssize_t *length)
+
+ Return a NUL-terminated representation of the contents of the object *obj*
+ through the output variables *buffer* and *length*.
+
+ If *length* is *NULL*, the resulting buffer may not contain NUL characters;
+ if it does, the function returns ``-1`` and a :exc:`TypeError` is raised.
+
+ The buffer refers to an internal string buffer of *obj*, not a copy. The data
+ must not be modified in any way, unless the string was just created using
+ ``PyBytes_FromStringAndSize(NULL, size)``. It must not be deallocated. If
+ *string* is not a string object at all, :c:func:`PyBytes_AsStringAndSize`
+ returns ``-1`` and raises :exc:`TypeError`.
+
+
+.. c:function:: void PyBytes_Concat(PyObject **bytes, PyObject *newpart)
+
+ Create a new bytes object in *\*bytes* containing the contents of *newpart*
+ appended to *bytes*; the caller will own the new reference. The reference to
+ the old value of *bytes* will be stolen. If the new string cannot be
+ created, the old reference to *bytes* will still be discarded and the value
+ of *\*bytes* will be set to *NULL*; the appropriate exception will be set.
+
+
+.. c:function:: void PyBytes_ConcatAndDel(PyObject **bytes, PyObject *newpart)
+
+ Create a new string object in *\*bytes* containing the contents of *newpart*
+ appended to *bytes*. This version decrements the reference count of
+ *newpart*.
+
+
+.. c:function:: int _PyBytes_Resize(PyObject **bytes, Py_ssize_t newsize)
+
+ A way to resize a bytes object even though it is "immutable". Only use this
+ to build up a brand new bytes object; don't use this if the bytes may already
+ be known in other parts of the code. It is an error to call this function if
+ the refcount on the input bytes object is not one. Pass the address of an
+ existing bytes object as an lvalue (it may be written into), and the new size
+ desired. On success, *\*bytes* holds the resized bytes object and ``0`` is
+ returned; the address in *\*bytes* may differ from its input value. If the
+ reallocation fails, the original bytes object at *\*bytes* is deallocated,
+ *\*bytes* is set to *NULL*, a memory exception is set, and ``-1`` is
+ returned.
diff --git a/Doc/c-api/class.rst b/Doc/c-api/class.rst
deleted file mode 100644
index 4dbe508..0000000
--- a/Doc/c-api/class.rst
+++ /dev/null
@@ -1,65 +0,0 @@
-.. highlightlang:: c
-
-.. _classobjects:
-
-Class and Instance Objects
---------------------------
-
-.. index:: object: class
-
-Note that the class objects described here represent old-style classes, which
-will go away in Python 3. When creating new types for extension modules, you
-will want to work with type objects (section :ref:`typeobjects`).
-
-
-.. c:type:: PyClassObject
-
- The C structure of the objects used to describe built-in classes.
-
-
-.. c:var:: PyObject* PyClass_Type
-
- .. index:: single: ClassType (in module types)
-
- This is the type object for class objects; it is the same object as
- ``types.ClassType`` in the Python layer.
-
-
-.. c:function:: int PyClass_Check(PyObject *o)
-
- Return true if the object *o* is a class object, including instances of types
- derived from the standard class object. Return false in all other cases.
-
-
-.. c:function:: int PyClass_IsSubclass(PyObject *klass, PyObject *base)
-
- Return true if *klass* is a subclass of *base*. Return false in all other cases.
-
-
-.. index:: object: instance
-
-There are very few functions specific to instance objects.
-
-
-.. c:var:: PyTypeObject PyInstance_Type
-
- Type object for class instances.
-
-
-.. c:function:: int PyInstance_Check(PyObject *obj)
-
- Return true if *obj* is an instance.
-
-
-.. c:function:: PyObject* PyInstance_New(PyObject *class, PyObject *arg, PyObject *kw)
-
- Create a new instance of a specific class. The parameters *arg* and *kw* are
- used as the positional and keyword parameters to the object's constructor.
-
-
-.. c:function:: PyObject* PyInstance_NewRaw(PyObject *class, PyObject *dict)
-
- Create a new instance of a specific class without calling its constructor.
- *class* is the class of new object. The *dict* parameter will be used as the
- object's :attr:`__dict__`; if *NULL*, a new dictionary will be created for the
- instance.
diff --git a/Doc/c-api/cobject.rst b/Doc/c-api/cobject.rst
deleted file mode 100644
index eafac0e..0000000
--- a/Doc/c-api/cobject.rst
+++ /dev/null
@@ -1,59 +0,0 @@
-.. highlightlang:: c
-
-.. _cobjects:
-
-CObjects
---------
-
-.. index:: object: CObject
-
-
-.. warning::
-
- The CObject API is deprecated as of Python 2.7. Please switch to the new
- :ref:`capsules` API.
-
-.. c:type:: PyCObject
-
- This subtype of :c:type:`PyObject` represents an opaque value, useful for C
- extension modules who need to pass an opaque value (as a :c:type:`void\*`
- pointer) through Python code to other C code. It is often used to make a C
- function pointer defined in one module available to other modules, so the
- regular import mechanism can be used to access C APIs defined in dynamically
- loaded modules.
-
-
-.. c:function:: int PyCObject_Check(PyObject *p)
-
- Return true if its argument is a :c:type:`PyCObject`.
-
-
-.. c:function:: PyObject* PyCObject_FromVoidPtr(void* cobj, void (*destr)(void *))
-
- Create a :c:type:`PyCObject` from the ``void *`` *cobj*. The *destr* function
- will be called when the object is reclaimed, unless it is *NULL*.
-
-
-.. c:function:: PyObject* PyCObject_FromVoidPtrAndDesc(void* cobj, void* desc, void (*destr)(void *, void *))
-
- Create a :c:type:`PyCObject` from the :c:type:`void \*` *cobj*. The *destr*
- function will be called when the object is reclaimed. The *desc* argument can
- be used to pass extra callback data for the destructor function.
-
-
-.. c:function:: void* PyCObject_AsVoidPtr(PyObject* self)
-
- Return the object :c:type:`void \*` that the :c:type:`PyCObject` *self* was
- created with.
-
-
-.. c:function:: void* PyCObject_GetDesc(PyObject* self)
-
- Return the description :c:type:`void \*` that the :c:type:`PyCObject` *self* was
- created with.
-
-
-.. c:function:: int PyCObject_SetVoidPtr(PyObject* self, void* cobj)
-
- Set the void pointer inside *self* to *cobj*. The :c:type:`PyCObject` must not
- have an associated destructor. Return true on success, false on failure.
diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst
index 7d9b4b6..6932bb1 100644
--- a/Doc/c-api/code.rst
+++ b/Doc/c-api/code.rst
@@ -35,7 +35,7 @@ bound into a function.
Return the number of free variables in *co*.
-.. c:function:: PyCodeObject *PyCode_New(int argcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *lnotab)
+.. c:function:: PyCodeObject *PyCode_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *lnotab)
Return a new code object. If you need a dummy code object to
create a frame, use :c:func:`PyCode_NewEmpty` instead. Calling
@@ -47,4 +47,4 @@ bound into a function.
Return a new empty code object with the specified filename,
function name, and first line number. It is illegal to
- :keyword:`exec` or :func:`eval` the resulting code object.
+ :func:`exec` or :func:`eval` the resulting code object.
diff --git a/Doc/c-api/complex.rst b/Doc/c-api/complex.rst
index 2547c1c..fc63b57 100644
--- a/Doc/c-api/complex.rst
+++ b/Doc/c-api/complex.rst
@@ -88,7 +88,7 @@ Complex Numbers as Python Objects
.. c:var:: PyTypeObject PyComplex_Type
This instance of :c:type:`PyTypeObject` represents the Python complex number
- type. It is the same object as ``complex`` and ``types.ComplexType``.
+ type. It is the same object as :class:`complex` in the Python layer.
.. c:function:: int PyComplex_Check(PyObject *p)
@@ -96,17 +96,12 @@ Complex Numbers as Python Objects
Return true if its argument is a :c:type:`PyComplexObject` or a subtype of
:c:type:`PyComplexObject`.
- .. versionchanged:: 2.2
- Allowed subtypes to be accepted.
-
.. c:function:: int PyComplex_CheckExact(PyObject *p)
Return true if its argument is a :c:type:`PyComplexObject`, but not a subtype of
:c:type:`PyComplexObject`.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyComplex_FromCComplex(Py_complex v)
@@ -131,9 +126,7 @@ Complex Numbers as Python Objects
.. c:function:: Py_complex PyComplex_AsCComplex(PyObject *op)
Return the :c:type:`Py_complex` value of the complex number *op*.
- Upon failure, this method returns ``-1.0`` as a real value.
- .. versionchanged:: 2.6
- If *op* is not a Python complex number object but has a :meth:`__complex__`
- method, this method will first be called to convert *op* to a Python complex
- number object.
+ If *op* is not a Python complex number object but has a :meth:`__complex__`
+ method, this method will first be called to convert *op* to a Python complex
+ number object. Upon failure, this method returns ``-1.0`` as a real value.
diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst
index 30eb78d..65904ee 100644
--- a/Doc/c-api/concrete.rst
+++ b/Doc/c-api/concrete.rst
@@ -44,9 +44,8 @@ Numeric Objects
.. toctree::
- int.rst
- bool.rst
long.rst
+ bool.rst
float.rst
complex.rst
@@ -62,12 +61,13 @@ Generic operations on sequence objects were discussed in the previous chapter;
this section deals with the specific kinds of sequence objects that are
intrinsic to the Python language.
+.. XXX sort out unicode, str, bytes and bytearray
+
.. toctree::
+ bytes.rst
bytearray.rst
- string.rst
unicode.rst
- buffer.rst
tuple.rst
list.rst
@@ -91,7 +91,7 @@ Other Objects
.. toctree::
- class.rst
+ set.rst
function.rst
method.rst
file.rst
@@ -99,11 +99,10 @@ Other Objects
iterator.rst
descriptor.rst
slice.rst
+ memoryview.rst
weakref.rst
capsule.rst
- cobject.rst
cell.rst
gen.rst
datetime.rst
- set.rst
code.rst
diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst
index b987469..dfc0a3a 100644
--- a/Doc/c-api/conversion.rst
+++ b/Doc/c-api/conversion.rst
@@ -26,7 +26,7 @@ guarantee consistent behavior in corner cases, which the Standard C functions do
not.
The wrappers ensure that *str*[*size*-1] is always ``'\0'`` upon return. They
-never write more than *size* bytes (including the trailing ``'\0'`` into str.
+never write more than *size* bytes (including the trailing ``'\0'``) into str.
Both functions require that ``str != NULL``, ``size > 0`` and ``format !=
NULL``.
@@ -82,41 +82,7 @@ The following functions provide locale-independent string to number conversions.
out-of-memory error), set the appropriate Python exception and
return ``-1.0``.
- .. versionadded:: 2.7
-
-
-.. c:function:: double PyOS_ascii_strtod(const char *nptr, char **endptr)
-
- Convert a string to a :c:type:`double`. This function behaves like the Standard C
- function :c:func:`strtod` does in the C locale. It does this without changing the
- current locale, since that would not be thread-safe.
-
- :c:func:`PyOS_ascii_strtod` should typically be used for reading configuration
- files or other non-user input that should be locale independent.
-
- See the Unix man page :manpage:`strtod(2)` for details.
-
- .. versionadded:: 2.4
-
- .. deprecated:: 2.7
- Use :c:func:`PyOS_string_to_double` instead.
-
-
-
-.. c:function:: char* PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d)
-
- Convert a :c:type:`double` to a string using the ``'.'`` as the decimal
- separator. *format* is a :c:func:`printf`\ -style format string specifying the
- number format. Allowed conversion characters are ``'e'``, ``'E'``, ``'f'``,
- ``'F'``, ``'g'`` and ``'G'``.
-
- The return value is a pointer to *buffer* with the converted string or NULL if
- the conversion failed.
-
- .. versionadded:: 2.4
- .. deprecated:: 2.7
- This function is removed in Python 2.7 and 3.1. Use :func:`PyOS_double_to_string`
- instead.
+ .. versionadded:: 3.1
.. c:function:: char* PyOS_double_to_string(double val, char format_code, int precision, int flags, int *ptype)
@@ -150,19 +116,7 @@ The following functions provide locale-independent string to number conversions.
*NULL* if the conversion failed. The caller is responsible for freeing the
returned string by calling :c:func:`PyMem_Free`.
- .. versionadded:: 2.7
-
-
-.. c:function:: double PyOS_ascii_atof(const char *nptr)
-
- Convert a string to a :c:type:`double` in a locale-independent way.
-
- See the Unix man page :manpage:`atof(2)` for details.
-
- .. versionadded:: 2.4
-
- .. deprecated:: 3.1
- Use :c:func:`PyOS_string_to_double` instead.
+ .. versionadded:: 3.1
.. c:function:: char* PyOS_stricmp(char *s1, char *s2)
@@ -170,12 +124,8 @@ The following functions provide locale-independent string to number conversions.
Case insensitive comparison of strings. The function works almost
identically to :c:func:`strcmp` except that it ignores the case.
- .. versionadded:: 2.6
-
.. c:function:: char* PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size)
Case insensitive comparison of strings. The function works almost
identically to :c:func:`strncmp` except that it ignores the case.
-
- .. versionadded:: 2.6
diff --git a/Doc/c-api/datetime.rst b/Doc/c-api/datetime.rst
index e2d832c..fcd1395 100644
--- a/Doc/c-api/datetime.rst
+++ b/Doc/c-api/datetime.rst
@@ -15,111 +15,84 @@ macros.
Type-check macros:
-
.. c:function:: int PyDate_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DateType` or a subtype of
:c:data:`PyDateTime_DateType`. *ob* must not be *NULL*.
- .. versionadded:: 2.4
-
.. c:function:: int PyDate_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DateType`. *ob* must not be
*NULL*.
- .. versionadded:: 2.4
-
.. c:function:: int PyDateTime_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DateTimeType` or a subtype of
:c:data:`PyDateTime_DateTimeType`. *ob* must not be *NULL*.
- .. versionadded:: 2.4
-
.. c:function:: int PyDateTime_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DateTimeType`. *ob* must not
be *NULL*.
- .. versionadded:: 2.4
-
.. c:function:: int PyTime_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_TimeType` or a subtype of
:c:data:`PyDateTime_TimeType`. *ob* must not be *NULL*.
- .. versionadded:: 2.4
-
.. c:function:: int PyTime_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_TimeType`. *ob* must not be
*NULL*.
- .. versionadded:: 2.4
-
.. c:function:: int PyDelta_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DeltaType` or a subtype of
:c:data:`PyDateTime_DeltaType`. *ob* must not be *NULL*.
- .. versionadded:: 2.4
-
.. c:function:: int PyDelta_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DeltaType`. *ob* must not be
*NULL*.
- .. versionadded:: 2.4
-
.. c:function:: int PyTZInfo_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_TZInfoType` or a subtype of
:c:data:`PyDateTime_TZInfoType`. *ob* must not be *NULL*.
- .. versionadded:: 2.4
-
.. c:function:: int PyTZInfo_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_TZInfoType`. *ob* must not be
*NULL*.
- .. versionadded:: 2.4
Macros to create objects:
-
.. c:function:: PyObject* PyDate_FromDate(int year, int month, int day)
Return a ``datetime.date`` object with the specified year, month and day.
- .. versionadded:: 2.4
-
.. c:function:: PyObject* PyDateTime_FromDateAndTime(int year, int month, int day, int hour, int minute, int second, int usecond)
Return a ``datetime.datetime`` object with the specified year, month, day, hour,
minute, second and microsecond.
- .. versionadded:: 2.4
-
.. c:function:: PyObject* PyTime_FromTime(int hour, int minute, int second, int usecond)
Return a ``datetime.time`` object with the specified hour, minute, second and
microsecond.
- .. versionadded:: 2.4
-
.. c:function:: PyObject* PyDelta_FromDSU(int days, int seconds, int useconds)
@@ -128,112 +101,84 @@ Macros to create objects:
number of microseconds and seconds lie in the ranges documented for
``datetime.timedelta`` objects.
- .. versionadded:: 2.4
Macros to extract fields from date objects. The argument must be an instance of
:c:data:`PyDateTime_Date`, including subclasses (such as
:c:data:`PyDateTime_DateTime`). The argument must not be *NULL*, and the type is
not checked:
-
.. c:function:: int PyDateTime_GET_YEAR(PyDateTime_Date *o)
Return the year, as a positive int.
- .. versionadded:: 2.4
-
.. c:function:: int PyDateTime_GET_MONTH(PyDateTime_Date *o)
Return the month, as an int from 1 through 12.
- .. versionadded:: 2.4
-
.. c:function:: int PyDateTime_GET_DAY(PyDateTime_Date *o)
Return the day, as an int from 1 through 31.
- .. versionadded:: 2.4
Macros to extract fields from datetime objects. The argument must be an
instance of :c:data:`PyDateTime_DateTime`, including subclasses. The argument
must not be *NULL*, and the type is not checked:
-
.. c:function:: int PyDateTime_DATE_GET_HOUR(PyDateTime_DateTime *o)
Return the hour, as an int from 0 through 23.
- .. versionadded:: 2.4
-
.. c:function:: int PyDateTime_DATE_GET_MINUTE(PyDateTime_DateTime *o)
Return the minute, as an int from 0 through 59.
- .. versionadded:: 2.4
-
.. c:function:: int PyDateTime_DATE_GET_SECOND(PyDateTime_DateTime *o)
Return the second, as an int from 0 through 59.
- .. versionadded:: 2.4
-
.. c:function:: int PyDateTime_DATE_GET_MICROSECOND(PyDateTime_DateTime *o)
Return the microsecond, as an int from 0 through 999999.
- .. versionadded:: 2.4
Macros to extract fields from time objects. The argument must be an instance of
:c:data:`PyDateTime_Time`, including subclasses. The argument must not be *NULL*,
and the type is not checked:
-
.. c:function:: int PyDateTime_TIME_GET_HOUR(PyDateTime_Time *o)
Return the hour, as an int from 0 through 23.
- .. versionadded:: 2.4
-
.. c:function:: int PyDateTime_TIME_GET_MINUTE(PyDateTime_Time *o)
Return the minute, as an int from 0 through 59.
- .. versionadded:: 2.4
-
.. c:function:: int PyDateTime_TIME_GET_SECOND(PyDateTime_Time *o)
Return the second, as an int from 0 through 59.
- .. versionadded:: 2.4
-
.. c:function:: int PyDateTime_TIME_GET_MICROSECOND(PyDateTime_Time *o)
Return the microsecond, as an int from 0 through 999999.
- .. versionadded:: 2.4
Macros for the convenience of modules implementing the DB API:
-
.. c:function:: PyObject* PyDateTime_FromTimestamp(PyObject *args)
Create and return a new ``datetime.datetime`` object given an argument tuple
suitable for passing to ``datetime.datetime.fromtimestamp()``.
- .. versionadded:: 2.4
-
.. c:function:: PyObject* PyDate_FromTimestamp(PyObject *args)
Create and return a new ``datetime.date`` object given an argument tuple
suitable for passing to ``datetime.date.fromtimestamp()``.
-
- .. versionadded:: 2.4
diff --git a/Doc/c-api/descriptor.rst b/Doc/c-api/descriptor.rst
index 43baeaf..c8f6fa5 100644
--- a/Doc/c-api/descriptor.rst
+++ b/Doc/c-api/descriptor.rst
@@ -8,38 +8,27 @@ Descriptor Objects
"Descriptors" are objects that describe some attribute of an object. They are
found in the dictionary of type objects.
+.. XXX document these!
.. c:var:: PyTypeObject PyProperty_Type
The type object for the built-in descriptor types.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyDescr_NewGetSet(PyTypeObject *type, struct PyGetSetDef *getset)
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyDescr_NewMember(PyTypeObject *type, struct PyMemberDef *meth)
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyDescr_NewMethod(PyTypeObject *type, struct PyMethodDef *meth)
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *wrapper, void *wrapped)
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
- .. versionadded:: 2.3
-
.. c:function:: int PyDescr_IsData(PyObject *descr)
@@ -47,9 +36,5 @@ found in the dictionary of type objects.
false if it describes a method. *descr* must be a descriptor object; there is
no error checking.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyWrapper_New(PyObject *, PyObject *)
-
- .. versionadded:: 2.2
diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst
index 3e967bd..6df84e0 100644
--- a/Doc/c-api/dict.rst
+++ b/Doc/c-api/dict.rst
@@ -15,13 +15,8 @@ Dictionary Objects
.. c:var:: PyTypeObject PyDict_Type
- .. index::
- single: DictType (in module types)
- single: DictionaryType (in module types)
-
This instance of :c:type:`PyTypeObject` represents the Python dictionary
- type. This is exposed to Python programs as ``dict`` and
- ``types.DictType``.
+ type. This is the same object as :class:`dict` in the Python layer.
.. c:function:: int PyDict_Check(PyObject *p)
@@ -29,17 +24,12 @@ Dictionary Objects
Return true if *p* is a dict object or an instance of a subtype of the dict
type.
- .. versionchanged:: 2.2
- Allowed subtypes to be accepted.
-
.. c:function:: int PyDict_CheckExact(PyObject *p)
Return true if *p* is a dict object, but not an instance of a subtype of
the dict type.
- .. versionadded:: 2.4
-
.. c:function:: PyObject* PyDict_New()
@@ -52,8 +42,6 @@ Dictionary Objects
This is normally used to create a proxy to prevent modification of the
dictionary for non-dynamic class types.
- .. versionadded:: 2.2
-
.. c:function:: void PyDict_Clear(PyObject *p)
@@ -66,15 +54,11 @@ Dictionary Objects
*key*, return ``1``, otherwise return ``0``. On error, return ``-1``.
This is equivalent to the Python expression ``key in p``.
- .. versionadded:: 2.4
-
.. c:function:: PyObject* PyDict_Copy(PyObject *p)
Return a new dictionary that contains the same key-value pairs as *p*.
- .. versionadded:: 1.6
-
.. c:function:: int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val)
@@ -85,11 +69,11 @@ Dictionary Objects
.. c:function:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val)
- .. index:: single: PyString_FromString()
+ .. index:: single: PyUnicode_FromString()
Insert *value* into the dictionary *p* using *key* as a key. *key* should
be a :c:type:`char\*`. The key object is created using
- ``PyString_FromString(key)``. Return ``0`` on success or ``-1`` on
+ ``PyUnicode_FromString(key)``. Return ``0`` on success or ``-1`` on
failure.
@@ -112,6 +96,14 @@ Dictionary Objects
if the key *key* is not present, but *without* setting an exception.
+.. c:function:: PyObject* PyDict_GetItemWithError(PyObject *p, PyObject *key)
+
+ Variant of :c:func:`PyDict_GetItem` that does not suppress
+ exceptions. Return *NULL* **with** an exception set if an exception
+ occurred. Return *NULL* **without** an exception set if the key
+ wasn't present.
+
+
.. c:function:: PyObject* PyDict_GetItemString(PyObject *p, const char *key)
This is the same as :c:func:`PyDict_GetItem`, but *key* is specified as a
@@ -120,20 +112,18 @@ Dictionary Objects
.. c:function:: PyObject* PyDict_Items(PyObject *p)
- Return a :c:type:`PyListObject` containing all the items from the
- dictionary, as in the dictionary method :meth:`dict.items`.
+ Return a :c:type:`PyListObject` containing all the items from the dictionary.
.. c:function:: PyObject* PyDict_Keys(PyObject *p)
- Return a :c:type:`PyListObject` containing all the keys from the dictionary,
- as in the dictionary method :meth:`dict.keys`.
+ Return a :c:type:`PyListObject` containing all the keys from the dictionary.
.. c:function:: PyObject* PyDict_Values(PyObject *p)
- Return a :c:type:`PyListObject` containing all the values from the
- dictionary *p*, as in the dictionary method :meth:`dict.values`.
+ Return a :c:type:`PyListObject` containing all the values from the dictionary
+ *p*.
.. c:function:: Py_ssize_t PyDict_Size(PyObject *p)
@@ -143,10 +133,6 @@ Dictionary Objects
Return the number of items in the dictionary. This is equivalent to
``len(p)`` on a dictionary.
- .. versionchanged:: 2.5
- This function returned an :c:type:`int` type. This might require changes
- in your code for properly supporting 64-bit systems.
-
.. c:function:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
@@ -171,17 +157,19 @@ Dictionary Objects
...
}
- The dictionary *p* should not be mutated during iteration. It is safe
- (since Python 2.1) to modify the values of the keys as you iterate over the
- dictionary, but only so long as the set of keys does not change. For
- example::
+ The dictionary *p* should not be mutated during iteration. It is safe to
+ modify the values of the keys as you iterate over the dictionary, but only
+ so long as the set of keys does not change. For example::
PyObject *key, *value;
Py_ssize_t pos = 0;
while (PyDict_Next(self->dict, &pos, &key, &value)) {
- int i = PyInt_AS_LONG(value) + 1;
- PyObject *o = PyInt_FromLong(i);
+ long i = PyLong_AsLong(value);
+ if (i == -1 && PyErr_Occurred()) {
+ return -1;
+ }
+ PyObject *o = PyLong_FromLong(i + 1);
if (o == NULL)
return -1;
if (PyDict_SetItem(self->dict, key, o) < 0) {
@@ -191,10 +179,6 @@ Dictionary Objects
Py_DECREF(o);
}
- .. versionchanged:: 2.5
- This function used an :c:type:`int *` type for *ppos*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PyDict_Merge(PyObject *a, PyObject *b, int override)
@@ -205,16 +189,12 @@ Dictionary Objects
only be added if there is not a matching key in *a*. Return ``0`` on
success or ``-1`` if an exception was raised.
- .. versionadded:: 2.2
-
.. c:function:: int PyDict_Update(PyObject *a, PyObject *b)
This is the same as ``PyDict_Merge(a, b, 1)`` in C, or ``a.update(b)`` in
Python. Return ``0`` on success or ``-1`` if an exception was raised.
- .. versionadded:: 2.2
-
.. c:function:: int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override)
@@ -229,5 +209,3 @@ Dictionary Objects
for key, value in seq2:
if override or key not in a:
a[key] = value
-
- .. versionadded:: 2.2
diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
index 025b75a..6f13c80 100644
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -27,15 +27,9 @@ the caller that an error has been set. If the error is not handled or carefully
propagated, additional calls into the Python/C API may not behave as intended
and may fail in mysterious ways.
-.. index::
- single: exc_type (in module sys)
- single: exc_value (in module sys)
- single: exc_traceback (in module sys)
-
-The error indicator consists of three Python objects corresponding to the
-Python variables ``sys.exc_type``, ``sys.exc_value`` and ``sys.exc_traceback``.
-API functions exist to interact with the error indicator in various ways. There
-is a separate error indicator for each thread.
+The error indicator consists of three Python objects corresponding to the result
+of ``sys.exc_info()``. API functions exist to interact with the error indicator
+in various ways. There is a separate error indicator for each thread.
.. XXX Order of these should be more thoughtful.
Either alphabetical or some kind of structure.
@@ -140,7 +134,7 @@ is a separate error indicator for each thread.
This is the most common way to set the error indicator. The first argument
specifies the exception type; it is normally one of the standard exceptions,
e.g. :c:data:`PyExc_RuntimeError`. You need not increment its reference count.
- The second argument is an error message; it is converted to a string object.
+ The second argument is an error message; it is decoded from ``'utf-8``'.
.. c:function:: void PyErr_SetObject(PyObject *type, PyObject *value)
@@ -154,7 +148,8 @@ is a separate error indicator for each thread.
This function sets the error indicator and returns *NULL*. *exception*
should be a Python exception class. The *format* and subsequent
parameters help format the error message; they have the same meaning and
- values as in :c:func:`PyString_FromFormat`.
+ values as in :c:func:`PyUnicode_FromFormat`. *format* is an ASCII-encoded
+ string.
.. c:function:: void PyErr_SetNone(PyObject *type)
@@ -198,6 +193,8 @@ is a separate error indicator for each thread.
*filename* is not *NULL*, it is passed to the constructor of *type* as a third
parameter. In the case of exceptions such as :exc:`IOError` and :exc:`OSError`,
this is used to define the :attr:`filename` attribute of the exception instance.
+ *filename* is decoded from the filesystem encoding
+ (:func:`sys.getfilesystemencoding`).
.. c:function:: PyObject* PyErr_SetFromWindowsErr(int ierr)
@@ -217,14 +214,14 @@ is a separate error indicator for each thread.
Similar to :c:func:`PyErr_SetFromWindowsErr`, with an additional parameter
specifying the exception type to be raised. Availability: Windows.
- .. versionadded:: 2.3
-
.. c:function:: PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename)
Similar to :c:func:`PyErr_SetFromWindowsErr`, with the additional behavior that
if *filename* is not *NULL*, it is passed to the constructor of
- :exc:`WindowsError` as a third parameter. Availability: Windows.
+ :exc:`WindowsError` as a third parameter. *filename* is decoded from the
+ filesystem encoding (:func:`sys.getfilesystemencoding`). Availability:
+ Windows.
.. c:function:: PyObject* PyErr_SetExcFromWindowsErrWithFilename(PyObject *type, int ierr, char *filename)
@@ -232,7 +229,22 @@ is a separate error indicator for each thread.
Similar to :c:func:`PyErr_SetFromWindowsErrWithFilename`, with an additional
parameter specifying the exception type to be raised. Availability: Windows.
- .. versionadded:: 2.3
+
+.. c:function:: void PyErr_SyntaxLocationEx(char *filename, int lineno, int col_offset)
+
+ Set file, line, and offset information for the current exception. If the
+ current exception is not a :exc:`SyntaxError`, then it sets additional
+ attributes, which make the exception printing subsystem think the exception
+ is a :exc:`SyntaxError`. *filename* is decoded from the filesystem encoding
+ (:func:`sys.getfilesystemencoding`).
+
+.. versionadded:: 3.2
+
+
+.. c:function:: void PyErr_SyntaxLocation(char *filename, int lineno)
+
+ Like :c:func:`PyErr_SyntaxLocationExc`, but the col_offset parameter is
+ omitted.
.. c:function:: void PyErr_BadInternalCall()
@@ -243,12 +255,12 @@ is a separate error indicator for each thread.
use.
-.. c:function:: int PyErr_WarnEx(PyObject *category, char *message, int stacklevel)
+.. c:function:: int PyErr_WarnEx(PyObject *category, char *message, int stack_level)
Issue a warning message. The *category* argument is a warning category (see
- below) or *NULL*; the *message* argument is a message string. *stacklevel* is a
+ below) or *NULL*; the *message* argument is an UTF-8 encoded string. *stack_level* is a
positive number giving a number of stack frames; the warning will be issued from
- the currently executing line of code in that stack frame. A *stacklevel* of 1
+ the currently executing line of code in that stack frame. A *stack_level* of 1
is the function calling :c:func:`PyErr_WarnEx`, 2 is the function above that,
and so forth.
@@ -280,32 +292,24 @@ is a separate error indicator for each thread.
documentation. There is no C API for warning control.
-.. c:function:: int PyErr_Warn(PyObject *category, char *message)
-
- Issue a warning message. The *category* argument is a warning category (see
- below) or *NULL*; the *message* argument is a message string. The warning will
- appear to be issued from the function calling :c:func:`PyErr_Warn`, equivalent to
- calling :c:func:`PyErr_WarnEx` with a *stacklevel* of 1.
-
- Deprecated; use :c:func:`PyErr_WarnEx` instead.
-
-
.. c:function:: int PyErr_WarnExplicit(PyObject *category, const char *message, const char *filename, int lineno, const char *module, PyObject *registry)
Issue a warning message with explicit control over all warning attributes. This
is a straightforward wrapper around the Python function
:func:`warnings.warn_explicit`, see there for more information. The *module*
and *registry* arguments may be set to *NULL* to get the default effect
- described there.
-
+ described there. *message* and *module* are UTF-8 encoded strings,
+ *filename* is decoded from the filesystem encoding
+ (:func:`sys.getfilesystemencoding`).
-.. c:function:: int PyErr_WarnPy3k(char *message, int stacklevel)
- Issue a :exc:`DeprecationWarning` with the given *message* and *stacklevel*
- if the :c:data:`Py_Py3kWarningFlag` flag is enabled.
+.. c:function:: int PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, const char *format, ...)
- .. versionadded:: 2.6
+ Function similar to :c:func:`PyErr_WarnEx`, but use
+ :c:func:`PyUnicode_FromFormat` to format the warning message. *format* is
+ an ASCII-encoded string.
+ .. versionadded:: 3.2
.. c:function:: int PyErr_CheckSignals()
@@ -335,7 +339,7 @@ is a separate error indicator for each thread.
be raised. It may be called without holding the interpreter lock.
.. % XXX This was described as obsolete, but is used in
- .. % thread.interrupt_main() (used from IDLE), so it's still needed.
+ .. % _thread.interrupt_main() (used from IDLE), so it's still needed.
.. c:function:: int PySignal_SetWakeupFd(int fd)
@@ -347,8 +351,6 @@ is a separate error indicator for each thread.
error checking. *fd* should be a valid file descriptor. The function should
only be called from the main thread.
- .. versionadded:: 2.6
-
.. c:function:: PyObject* PyErr_NewException(char *name, PyObject *base, PyObject *dict)
@@ -371,7 +373,7 @@ is a separate error indicator for each thread.
easily be given a docstring: If *doc* is non-*NULL*, it will be used as the
docstring for the exception class.
- .. versionadded:: 2.7
+ .. versionadded:: 3.2
.. c:function:: void PyErr_WriteUnraisable(PyObject *obj)
@@ -386,6 +388,52 @@ is a separate error indicator for each thread.
the warning message.
+Exception Objects
+=================
+
+.. c:function:: PyObject* PyException_GetTraceback(PyObject *ex)
+
+ Return the traceback associated with the exception as a new reference, as
+ accessible from Python through :attr:`__traceback__`. If there is no
+ traceback associated, this returns *NULL*.
+
+
+.. c:function:: int PyException_SetTraceback(PyObject *ex, PyObject *tb)
+
+ Set the traceback associated with the exception to *tb*. Use ``Py_None`` to
+ clear it.
+
+
+.. c:function:: PyObject* PyException_GetContext(PyObject *ex)
+
+ Return the context (another exception instance during whose handling *ex* was
+ raised) associated with the exception as a new reference, as accessible from
+ Python through :attr:`__context__`. If there is no context associated, this
+ returns *NULL*.
+
+
+.. c:function:: void PyException_SetContext(PyObject *ex, PyObject *ctx)
+
+ Set the context associated with the exception to *ctx*. Use *NULL* to clear
+ it. There is no type check to make sure that *ctx* is an exception instance.
+ This steals a reference to *ctx*.
+
+
+.. c:function:: PyObject* PyException_GetCause(PyObject *ex)
+
+ Return the cause (another exception instance set by ``raise ... from ...``)
+ associated with the exception as a new reference, as accessible from Python
+ through :attr:`__cause__`. If there is no cause associated, this returns
+ *NULL*.
+
+
+.. c:function:: void PyException_SetCause(PyObject *ex, PyObject *ctx)
+
+ Set the cause associated with the exception to *ctx*. Use *NULL* to clear
+ it. There is no type check to make sure that *ctx* is an exception instance.
+ This steals a reference to *ctx*.
+
+
.. _unicodeexceptions:
Unicode Exception Objects
@@ -396,68 +444,70 @@ The following functions are used to create and modify Unicode exceptions from C.
.. c:function:: PyObject* PyUnicodeDecodeError_Create(const char *encoding, const char *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)
Create a :class:`UnicodeDecodeError` object with the attributes *encoding*,
- *object*, *length*, *start*, *end* and *reason*.
+ *object*, *length*, *start*, *end* and *reason*. *encoding* and *reason* are
+ UTF-8 encoded strings.
.. c:function:: PyObject* PyUnicodeEncodeError_Create(const char *encoding, const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)
Create a :class:`UnicodeEncodeError` object with the attributes *encoding*,
- *object*, *length*, *start*, *end* and *reason*.
+ *object*, *length*, *start*, *end* and *reason*. *encoding* and *reason* are
+ UTF-8 encoded strings.
.. c:function:: PyObject* PyUnicodeTranslateError_Create(const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)
Create a :class:`UnicodeTranslateError` object with the attributes *object*,
- *length*, *start*, *end* and *reason*.
+ *length*, *start*, *end* and *reason*. *reason* is an UTF-8 encoded string.
.. c:function:: PyObject* PyUnicodeDecodeError_GetEncoding(PyObject *exc)
- PyObject* PyUnicodeEncodeError_GetEncoding(PyObject *exc)
+ PyObject* PyUnicodeEncodeError_GetEncoding(PyObject *exc)
Return the *encoding* attribute of the given exception object.
.. c:function:: PyObject* PyUnicodeDecodeError_GetObject(PyObject *exc)
- PyObject* PyUnicodeEncodeError_GetObject(PyObject *exc)
- PyObject* PyUnicodeTranslateError_GetObject(PyObject *exc)
+ PyObject* PyUnicodeEncodeError_GetObject(PyObject *exc)
+ PyObject* PyUnicodeTranslateError_GetObject(PyObject *exc)
Return the *object* attribute of the given exception object.
.. c:function:: int PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
- int PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
- int PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
+ int PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
+ int PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
Get the *start* attribute of the given exception object and place it into
*\*start*. *start* must not be *NULL*. Return ``0`` on success, ``-1`` on
failure.
.. c:function:: int PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
- int PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
- int PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
+ int PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
+ int PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
Set the *start* attribute of the given exception object to *start*. Return
``0`` on success, ``-1`` on failure.
.. c:function:: int PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
- int PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
- int PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end)
+ int PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
+ int PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end)
Get the *end* attribute of the given exception object and place it into
*\*end*. *end* must not be *NULL*. Return ``0`` on success, ``-1`` on
failure.
.. c:function:: int PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
- int PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
- int PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
+ int PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
+ int PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
Set the *end* attribute of the given exception object to *end*. Return ``0``
on success, ``-1`` on failure.
.. c:function:: PyObject* PyUnicodeDecodeError_GetReason(PyObject *exc)
- PyObject* PyUnicodeEncodeError_GetReason(PyObject *exc)
- PyObject* PyUnicodeTranslateError_GetReason(PyObject *exc)
+ PyObject* PyUnicodeEncodeError_GetReason(PyObject *exc)
+ PyObject* PyUnicodeTranslateError_GetReason(PyObject *exc)
Return the *reason* attribute of the given exception object.
.. c:function:: int PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
- int PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
- int PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
+ int PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
+ int PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
Set the *reason* attribute of the given exception object to *reason*. Return
``0`` on success, ``-1`` on failure.
@@ -475,7 +525,7 @@ recursion depth automatically).
Marks a point where a recursive C-level call is about to be performed.
- If :const:`USE_STACKCHECK` is defined, this function checks if the OS
+ If :const:`USE_STACKCHECK` is defined, this function checks if the the OS
stack overflowed using :c:func:`PyOS_CheckStack`. In this is the case, it
sets a :exc:`MemoryError` and returns a nonzero value.
@@ -492,6 +542,35 @@ recursion depth automatically).
Ends a :c:func:`Py_EnterRecursiveCall`. Must be called once for each
*successful* invocation of :c:func:`Py_EnterRecursiveCall`.
+Properly implementing :attr:`tp_repr` for container types requires
+special recursion handling. In addition to protecting the stack,
+:attr:`tp_repr` also needs to track objects to prevent cycles. The
+following two functions facilitate this functionality. Effectively,
+these are the C equivalent to :func:`reprlib.recursive_repr`.
+
+.. c:function:: int Py_ReprEnter(PyObject *object)
+
+ Called at the beginning of the :attr:`tp_repr` implementation to
+ detect cycles.
+
+ If the object has already been processed, the function returns a
+ positive integer. In that case the :attr:`tp_repr` implementation
+ should return a string object indicating a cycle. As examples,
+ :class:`dict` objects return ``{...}`` and :class:`list` objects
+ return ``[...]``.
+
+ The function will return a negative integer if the recursion limit
+ is reached. In that case the :attr:`tp_repr` implementation should
+ typically return ``NULL``.
+
+ Otherwise, the function returns zero and the :attr:`tp_repr`
+ implementation can continue normally.
+
+.. c:function:: void Py_ReprLeave(PyObject *object)
+
+ Ends a :c:func:`Py_ReprEnter`. Must be called once for each
+ invocation of :c:func:`Py_ReprEnter` that returns zero.
+
.. _standardexceptions:
@@ -506,12 +585,10 @@ the variables:
+-------------------------------------+----------------------------+----------+
| C Name | Python Name | Notes |
+=====================================+============================+==========+
-| :c:data:`PyExc_BaseException` | :exc:`BaseException` | (1), (4) |
+| :c:data:`PyExc_BaseException` | :exc:`BaseException` | \(1) |
+-------------------------------------+----------------------------+----------+
| :c:data:`PyExc_Exception` | :exc:`Exception` | \(1) |
+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_StandardError` | :exc:`StandardError` | \(1) |
-+-------------------------------------+----------------------------+----------+
| :c:data:`PyExc_ArithmeticError` | :exc:`ArithmeticError` | \(1) |
+-------------------------------------+----------------------------+----------+
| :c:data:`PyExc_LookupError` | :exc:`LookupError` | \(1) |
@@ -568,7 +645,6 @@ the variables:
.. index::
single: PyExc_BaseException
single: PyExc_Exception
- single: PyExc_StandardError
single: PyExc_ArithmeticError
single: PyExc_LookupError
single: PyExc_AssertionError
@@ -607,15 +683,3 @@ Notes:
(3)
Only defined on Windows; protect code that uses this by testing that the
preprocessor macro ``MS_WINDOWS`` is defined.
-
-(4)
- .. versionadded:: 2.5
-
-
-String Exceptions
-=================
-
-.. versionchanged:: 2.6
- All exceptions to be raised or caught must be derived from :exc:`BaseException`.
- Trying to raise a string exception now raises :exc:`TypeError`.
-
diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst
index 20a7a60..c5a4a59 100644
--- a/Doc/c-api/file.rst
+++ b/Doc/c-api/file.rst
@@ -7,103 +7,42 @@ File Objects
.. index:: object: file
-Python's built-in file objects are implemented entirely on the :c:type:`FILE\*`
-support from the C standard library. This is an implementation detail and may
-change in future releases of Python.
+These APIs are a minimal emulation of the Python 2 C API for built-in file
+objects, which used to rely on the buffered I/O (:c:type:`FILE\*`) support
+from the C standard library. In Python 3, files and streams use the new
+:mod:`io` module, which defines several layers over the low-level unbuffered
+I/O of the operating system. The functions described below are
+convenience C wrappers over these new APIs, and meant mostly for internal
+error reporting in the interpreter; third-party code is advised to access
+the :mod:`io` APIs instead.
-.. c:type:: PyFileObject
+.. c:function:: PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *errors, char *newline, int closefd)
- This subtype of :c:type:`PyObject` represents a Python file object.
+ Create a Python file object from the file descriptor of an already
+ opened file *fd*. The arguments *name*, *encoding*, *errors* and *newline*
+ can be *NULL* to use the defaults; *buffering* can be *-1* to use the
+ default. *name* is ignored and kept for backward compatibility. Return
+ *NULL* on failure. For a more comprehensive description of the arguments,
+ please refer to the :func:`io.open` function documentation.
+ .. warning::
-.. c:var:: PyTypeObject PyFile_Type
+ Since Python streams have their own buffering layer, mixing them with
+ OS-level file descriptors can produce various issues (such as unexpected
+ ordering of data).
- .. index:: single: FileType (in module types)
+ .. versionchanged:: 3.2
+ Ignore *name* attribute.
- This instance of :c:type:`PyTypeObject` represents the Python file type. This is
- exposed to Python programs as ``file`` and ``types.FileType``.
+.. c:function:: int PyObject_AsFileDescriptor(PyObject *p)
-.. c:function:: int PyFile_Check(PyObject *p)
-
- Return true if its argument is a :c:type:`PyFileObject` or a subtype of
- :c:type:`PyFileObject`.
-
- .. versionchanged:: 2.2
- Allowed subtypes to be accepted.
-
-
-.. c:function:: int PyFile_CheckExact(PyObject *p)
-
- Return true if its argument is a :c:type:`PyFileObject`, but not a subtype of
- :c:type:`PyFileObject`.
-
- .. versionadded:: 2.2
-
-
-.. c:function:: PyObject* PyFile_FromString(char *filename, char *mode)
-
- .. index:: single: fopen()
-
- On success, return a new file object that is opened on the file given by
- *filename*, with a file mode given by *mode*, where *mode* has the same
- semantics as the standard C routine :c:func:`fopen`. On failure, return *NULL*.
-
-
-.. c:function:: PyObject* PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE*))
-
- Create a new :c:type:`PyFileObject` from the already-open standard C file
- pointer, *fp*. The function *close* will be called when the file should be
- closed. Return *NULL* and close the file using *close* on failure.
- *close* is optional and can be set to *NULL*.
-
-
-.. c:function:: FILE* PyFile_AsFile(PyObject \*p)
-
- Return the file object associated with *p* as a :c:type:`FILE\*`.
-
- If the caller will ever use the returned :c:type:`FILE\*` object while
- the :term:`GIL` is released it must also call the :c:func:`PyFile_IncUseCount` and
- :c:func:`PyFile_DecUseCount` functions described below as appropriate.
-
-
-.. c:function:: void PyFile_IncUseCount(PyFileObject \*p)
-
- Increments the PyFileObject's internal use count to indicate
- that the underlying :c:type:`FILE\*` is being used.
- This prevents Python from calling f_close() on it from another thread.
- Callers of this must call :c:func:`PyFile_DecUseCount` when they are
- finished with the :c:type:`FILE\*`. Otherwise the file object will
- never be closed by Python.
-
- The :term:`GIL` must be held while calling this function.
-
- The suggested use is to call this after :c:func:`PyFile_AsFile` and before
- you release the GIL::
-
- FILE *fp = PyFile_AsFile(p);
- PyFile_IncUseCount(p);
- /* ... */
- Py_BEGIN_ALLOW_THREADS
- do_something(fp);
- Py_END_ALLOW_THREADS
- /* ... */
- PyFile_DecUseCount(p);
-
- .. versionadded:: 2.6
-
-
-.. c:function:: void PyFile_DecUseCount(PyFileObject \*p)
-
- Decrements the PyFileObject's internal unlocked_count member to
- indicate that the caller is done with its own use of the :c:type:`FILE\*`.
- This may only be called to undo a prior call to :c:func:`PyFile_IncUseCount`.
-
- The :term:`GIL` must be held while calling this function (see the example
- above).
-
- .. versionadded:: 2.6
+ Return the file descriptor associated with *p* as an :c:type:`int`. If the
+ object is an integer, its value is returned. If not, the
+ object's :meth:`fileno` method is called if it exists; the method must return
+ an integer, which is returned as the file descriptor value. Sets an
+ exception and returns ``-1`` on failure.
.. c:function:: PyObject* PyFile_GetLine(PyObject *p, int n)
@@ -120,49 +59,6 @@ change in future releases of Python.
raised if the end of the file is reached immediately.
-.. c:function:: PyObject* PyFile_Name(PyObject *p)
-
- Return the name of the file specified by *p* as a string object.
-
-
-.. c:function:: void PyFile_SetBufSize(PyFileObject *p, int n)
-
- .. index:: single: setvbuf()
-
- Available on systems with :c:func:`setvbuf` only. This should only be called
- immediately after file object creation.
-
-
-.. c:function:: int PyFile_SetEncoding(PyFileObject *p, const char *enc)
-
- Set the file's encoding for Unicode output to *enc*. Return 1 on success and 0
- on failure.
-
- .. versionadded:: 2.3
-
-
-.. c:function:: int PyFile_SetEncodingAndErrors(PyFileObject *p, const char *enc, *errors)
-
- Set the file's encoding for Unicode output to *enc*, and its error
- mode to *err*. Return 1 on success and 0 on failure.
-
- .. versionadded:: 2.6
-
-
-.. c:function:: int PyFile_SoftSpace(PyObject *p, int newflag)
-
- .. index:: single: softspace (file attribute)
-
- This function exists for internal use by the interpreter. Set the
- :attr:`softspace` attribute of *p* to *newflag* and return the previous value.
- *p* does not have to be a file object for this function to work properly; any
- object is supported (thought its only interesting if the :attr:`softspace`
- attribute can be set). This function clears any errors, and will return ``0``
- as the previous value if the attribute either does not exist or if there were
- errors in retrieving it. There is no way to detect errors from this function,
- but doing so should not be needed.
-
-
.. c:function:: int PyFile_WriteObject(PyObject *obj, PyObject *p, int flags)
.. index:: single: Py_PRINT_RAW
diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst
index 3aa7d18..27a75e3 100644
--- a/Doc/c-api/float.rst
+++ b/Doc/c-api/float.rst
@@ -15,10 +15,8 @@ Floating Point Objects
.. c:var:: PyTypeObject PyFloat_Type
- .. index:: single: FloatType (in modules types)
-
This instance of :c:type:`PyTypeObject` represents the Python floating point
- type. This is the same object as ``float`` and ``types.FloatType``.
+ type. This is the same object as :class:`float` in the Python layer.
.. c:function:: int PyFloat_Check(PyObject *p)
@@ -26,23 +24,17 @@ Floating Point Objects
Return true if its argument is a :c:type:`PyFloatObject` or a subtype of
:c:type:`PyFloatObject`.
- .. versionchanged:: 2.2
- Allowed subtypes to be accepted.
-
.. c:function:: int PyFloat_CheckExact(PyObject *p)
Return true if its argument is a :c:type:`PyFloatObject`, but not a subtype of
:c:type:`PyFloatObject`.
- .. versionadded:: 2.2
-
-.. c:function:: PyObject* PyFloat_FromString(PyObject *str, char **pend)
+.. c:function:: PyObject* PyFloat_FromString(PyObject *str)
Create a :c:type:`PyFloatObject` object based on the string value in *str*, or
- *NULL* on failure. The *pend* argument is ignored. It remains only for
- backward compatibility.
+ *NULL* on failure.
.. c:function:: PyObject* PyFloat_FromDouble(double v)
@@ -71,50 +63,17 @@ Floating Point Objects
precision, minimum and maximum values of a float. It's a thin wrapper
around the header file :file:`float.h`.
- .. versionadded:: 2.6
-
.. c:function:: double PyFloat_GetMax()
Return the maximum representable finite float *DBL_MAX* as C :c:type:`double`.
- .. versionadded:: 2.6
-
.. c:function:: double PyFloat_GetMin()
Return the minimum normalized positive float *DBL_MIN* as C :c:type:`double`.
- .. versionadded:: 2.6
-
-
.. c:function:: int PyFloat_ClearFreeList()
Clear the float free list. Return the number of items that could not
be freed.
-
- .. versionadded:: 2.6
-
-
-.. c:function:: void PyFloat_AsString(char *buf, PyFloatObject *v)
-
- Convert the argument *v* to a string, using the same rules as
- :func:`str`. The length of *buf* should be at least 100.
-
- This function is unsafe to call because it writes to a buffer whose
- length it does not know.
-
- .. deprecated:: 2.7
- Use :func:`PyObject_Str` or :func:`PyOS_double_to_string` instead.
-
-
-.. c:function:: void PyFloat_AsReprString(char *buf, PyFloatObject *v)
-
- Same as PyFloat_AsString, except uses the same rules as
- :func:`repr`. The length of *buf* should be at least 100.
-
- This function is unsafe to call because it writes to a buffer whose
- length it does not know.
-
- .. deprecated:: 2.7
- Use :func:`PyObject_Repr` or :func:`PyOS_double_to_string` instead.
diff --git a/Doc/c-api/function.rst b/Doc/c-api/function.rst
index 66f8675..31805fd 100644
--- a/Doc/c-api/function.rst
+++ b/Doc/c-api/function.rst
@@ -81,3 +81,17 @@ There are a few functions specific to Python functions.
*Py_None* or a tuple of cell objects.
Raises :exc:`SystemError` and returns ``-1`` on failure.
+
+
+.. c:function:: PyObject *PyFunction_GetAnnotations(PyObject *op)
+
+ Return the annotations of the function object *op*. This can be a
+ mutable dictionary or *NULL*.
+
+
+.. c:function:: int PyFunction_SetAnnotations(PyObject *op, PyObject *annotations)
+
+ Set the annotations for the function object *op*. *annotations*
+ must be a dictionary or *Py_None*.
+
+ Raises :exc:`SystemError` and returns ``-1`` on failure.
diff --git a/Doc/c-api/gcsupport.rst b/Doc/c-api/gcsupport.rst
index 2a4fda4..3875ff2 100644
--- a/Doc/c-api/gcsupport.rst
+++ b/Doc/c-api/gcsupport.rst
@@ -12,9 +12,6 @@ other objects, or which only store references to atomic types (such as numbers
or strings), do not need to provide any explicit support for garbage
collection.
-.. An example showing the use of these interfaces can be found in "Supporting the
-.. Cycle Collector (XXX not found: ../ext/example-cycle-support.html)".
-
To create a container type, the :attr:`tp_flags` field of the type object must
include the :const:`Py_TPFLAGS_HAVE_GC` and provide an implementation of the
:attr:`tp_traverse` handler. If instances of the type are mutable, a
@@ -48,20 +45,12 @@ Constructors for container types must conform to two rules:
Analogous to :c:func:`PyObject_NewVar` but for container objects with the
:const:`Py_TPFLAGS_HAVE_GC` flag set.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize)
Resize an object allocated by :c:func:`PyObject_NewVar`. Returns the
resized object or *NULL* on failure.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *newsize*. This might
- require changes in your code for properly supporting 64-bit systems.
-
.. c:function:: void PyObject_GC_Track(PyObject *op)
@@ -149,8 +138,6 @@ must name its arguments exactly *visit* and *arg*:
return 0;
}
- .. versionadded:: 2.4
-
The :attr:`tp_clear` handler must be of the :c:type:`inquiry` type, or *NULL*
if the object is immutable.
diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst
index 6f5678c..cf48363 100644
--- a/Doc/c-api/import.rst
+++ b/Doc/c-api/import.rst
@@ -22,16 +22,10 @@ Importing Modules
be the case. (Unfortunately, this has an additional side effect when *name* in
fact specifies a subpackage instead of a submodule: the submodules specified in
the package's ``__all__`` variable are loaded.) Return a new reference to the
- imported module, or *NULL* with an exception set on failure. Before Python 2.4,
- the module may still be created in the failure case --- examine ``sys.modules``
- to find out. Starting with Python 2.4, a failing import of a module no longer
- leaves the module in ``sys.modules``.
+ imported module, or *NULL* with an exception set on failure. A failing
+ import of a module doesn't leave the module in :data:`sys.modules`.
- .. versionchanged:: 2.4
- Failing imports remove incomplete module objects.
-
- .. versionchanged:: 2.6
- Always uses absolute imports.
+ This function always uses absolute imports.
.. c:function:: PyObject* PyImport_ImportModuleNoBlock(const char *name)
@@ -44,8 +38,6 @@ Importing Modules
unless the lock is held, in which case the function will raise an
:exc:`ImportError`.
- .. versionadded:: 2.6
-
.. c:function:: PyObject* PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist)
@@ -55,18 +47,14 @@ Importing Modules
function :func:`__import__`, as the standard :func:`__import__` function calls
this function directly.
- The return value is a new reference to the imported module or top-level package,
- or *NULL* with an exception set on failure (before Python 2.4, the module may
- still be created in this case). Like for :func:`__import__`, the return value
- when a submodule of a package was requested is normally the top-level package,
- unless a non-empty *fromlist* was given.
-
- .. versionchanged:: 2.4
- Failing imports remove incomplete module objects.
+ The return value is a new reference to the imported module or top-level
+ package, or *NULL* with an exception set on failure. Like for
+ :func:`__import__`, the return value when a submodule of a package was
+ requested is normally the top-level package, unless a non-empty *fromlist*
+ was given.
- .. versionchanged:: 2.6
- The function is an alias for :c:func:`PyImport_ImportModuleLevel` with
- -1 as level, meaning relative import.
+ Failing imports remove incomplete module objects, like with
+ :c:func:`PyImport_ImportModule`.
.. c:function:: PyObject* PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level)
@@ -80,32 +68,22 @@ Importing Modules
the return value when a submodule of a package was requested is normally the
top-level package, unless a non-empty *fromlist* was given.
- .. versionadded:: 2.5
-
.. c:function:: PyObject* PyImport_Import(PyObject *name)
- .. index::
- module: rexec
- module: ihooks
-
- This is a higher-level interface that calls the current "import hook function".
- It invokes the :func:`__import__` function from the ``__builtins__`` of the
- current globals. This means that the import is done using whatever import hooks
- are installed in the current environment, e.g. by :mod:`rexec` or :mod:`ihooks`.
+ This is a higher-level interface that calls the current "import hook
+ function" (with an explicit *level* of 0, meaning absolute import). It
+ invokes the :func:`__import__` function from the ``__builtins__`` of the
+ current globals. This means that the import is done using whatever import
+ hooks are installed in the current environment.
- .. versionchanged:: 2.6
- Always uses absolute imports.
+ This function always uses absolute imports.
.. c:function:: PyObject* PyImport_ReloadModule(PyObject *m)
- .. index:: builtin: reload
-
- Reload a module. This is best described by referring to the built-in Python
- function :func:`reload`, as the standard :func:`reload` function calls this
- function directly. Return a new reference to the reloaded module, or *NULL*
- with an exception set on failure (the module still exists in this case).
+ Reload a module. Return a new reference to the reloaded module, or *NULL* with
+ an exception set on failure (the module still exists in this case).
.. c:function:: PyObject* PyImport_AddModule(const char *name)
@@ -130,9 +108,8 @@ Importing Modules
Given a module name (possibly of the form ``package.module``) and a code object
read from a Python bytecode file or obtained from the built-in function
:func:`compile`, load the module. Return a new reference to the module object,
- or *NULL* with an exception set if an error occurred. Before Python 2.4, the
- module could still be created in error cases. Starting with Python 2.4, *name*
- is removed from :attr:`sys.modules` in error cases, and even if *name* was already
+ or *NULL* with an exception set if an error occurred. *name*
+ is removed from :attr:`sys.modules` in error cases, even if *name* was already
in :attr:`sys.modules` on entry to :c:func:`PyImport_ExecCodeModule`. Leaving
incompletely initialized modules in :attr:`sys.modules` is dangerous, as imports of
such modules have no way to know that the module object is an unknown (and
@@ -147,8 +124,8 @@ Importing Modules
If *name* points to a dotted name of the form ``package.module``, any package
structures not already created will still not be created.
- .. versionchanged:: 2.4
- *name* is removed from :attr:`sys.modules` in error cases.
+ See also :c:func:`PyImport_ExecCodeModuleEx` and
+ :c:func:`PyImport_ExecCodeModuleWithPathnames`.
.. c:function:: PyObject* PyImport_ExecCodeModuleEx(char *name, PyObject *co, char *pathname)
@@ -156,6 +133,16 @@ Importing Modules
Like :c:func:`PyImport_ExecCodeModule`, but the :attr:`__file__` attribute of
the module object is set to *pathname* if it is non-``NULL``.
+ See also :c:func:`PyImport_ExecCodeModuleWithPathnames`.
+
+
+.. c:function:: PyObject* PyImport_ExecCodeModuleWithPathnames(char *name, PyObject *co, char *pathname, char *cpathname)
+
+ Like :c:func:`PyImport_ExecCodeModuleEx`, but the :attr:`__cached__`
+ attribute of the module object is set to *cpathname* if it is
+ non-``NULL``. Of the three functions, this is the preferred one to use.
+
+ .. versionadded:: 3.2
.. c:function:: long PyImport_GetMagicNumber()
@@ -164,6 +151,13 @@ Importing Modules
of the bytecode file, in little-endian byte order.
+.. c:function:: const char * PyImport_GetMagicTag()
+
+ Return the magic tag string for :pep:`3147` format Python bytecode file
+ names.
+
+ .. versionadded:: 3.2
+
.. c:function:: PyObject* PyImport_GetModuleDict()
Return the dictionary used for the module administration (a.k.a.
@@ -180,8 +174,6 @@ Importing Modules
Cache the result in :data:`sys.path_importer_cache`. Return a new reference
to the importer object.
- .. versionadded:: 2.6
-
.. c:function:: void _PyImport_Init()
@@ -241,7 +233,7 @@ Importing Modules
tricks with this to provide a dynamically created collection of frozen modules.
-.. c:function:: int PyImport_AppendInittab(const char *name, void (*initfunc)(void))
+.. c:function:: int PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void))
Add a single module to the existing table of built-in modules. This is a
convenience wrapper around :c:func:`PyImport_ExtendInittab`, returning ``-1`` if
@@ -262,7 +254,7 @@ Importing Modules
struct _inittab {
char *name;
- void (*initfunc)(void);
+ PyObject* (*initfunc)(void);
};
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index 6c58c5d..7507e3b 100644
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -17,11 +17,9 @@ Initializing and finalizing the interpreter
.. index::
single: Py_SetProgramName()
single: PyEval_InitThreads()
- single: PyEval_ReleaseLock()
- single: PyEval_AcquireLock()
single: modules (in module sys)
single: path (in module sys)
- module: __builtin__
+ module: builtins
module: __main__
module: sys
triple: module; search; path
@@ -31,10 +29,9 @@ Initializing and finalizing the interpreter
Initialize the Python interpreter. In an application embedding Python, this
should be called before using any other Python/C API functions; with the
- exception of :c:func:`Py_SetProgramName`, :c:func:`Py_SetPythonHome`, :c:func:`PyEval_InitThreads`,
- :c:func:`PyEval_ReleaseLock`, and :c:func:`PyEval_AcquireLock`. This initializes
+ exception of :c:func:`Py_SetProgramName`, :c:func:`Py_SetPythonHome` and :c:func:`Py_SetPath`. This initializes
the table of loaded modules (``sys.modules``), and creates the fundamental
- modules :mod:`__builtin__`, :mod:`__main__` and :mod:`sys`. It also initializes
+ modules :mod:`builtins`, :mod:`__main__` and :mod:`sys`. It also initializes
the module search path (``sys.path``). It does not set ``sys.argv``; use
:c:func:`PySys_SetArgvEx` for that. This is a no-op when called for a second time
(without calling :c:func:`Py_Finalize` first). There is no return value; it is a
@@ -47,8 +44,6 @@ Initializing and finalizing the interpreter
*initsigs* is 0, it skips initialization registration of signal handlers, which
might be useful when Python is embedded.
- .. versionadded:: 2.4
-
.. c:function:: int Py_IsInitialized()
@@ -91,7 +86,7 @@ Process-wide parameters
=======================
-.. c:function:: void Py_SetProgramName(char *name)
+.. c:function:: void Py_SetProgramName(wchar_t *name)
.. index::
single: Py_Initialize()
@@ -100,16 +95,17 @@ Process-wide parameters
This function should be called before :c:func:`Py_Initialize` is called for
the first time, if it is called at all. It tells the interpreter the value
- of the ``argv[0]`` argument to the :c:func:`main` function of the program.
+ of the ``argv[0]`` argument to the :c:func:`main` function of the program
+ (converted to wide characters).
This is used by :c:func:`Py_GetPath` and some other functions below to find
the Python run-time libraries relative to the interpreter executable. The
default value is ``'python'``. The argument should point to a
- zero-terminated character string in static storage whose contents will not
+ zero-terminated wide character string in static storage whose contents will not
change for the duration of the program's execution. No code in the Python
interpreter will change the contents of this storage.
-.. c:function:: char* Py_GetProgramName()
+.. c:function:: wchar* Py_GetProgramName()
.. index:: single: Py_SetProgramName()
@@ -118,7 +114,7 @@ Process-wide parameters
value.
-.. c:function:: char* Py_GetPrefix()
+.. c:function:: wchar_t* Py_GetPrefix()
Return the *prefix* for installed platform-independent files. This is derived
through a number of complicated rules from the program name set with
@@ -131,7 +127,7 @@ Process-wide parameters
It is only useful on Unix. See also the next function.
-.. c:function:: char* Py_GetExecPrefix()
+.. c:function:: wchar_t* Py_GetExecPrefix()
Return the *exec-prefix* for installed platform-*dependent* files. This is
derived through a number of complicated rules from the program name set with
@@ -166,7 +162,7 @@ Process-wide parameters
platform.
-.. c:function:: char* Py_GetProgramFullPath()
+.. c:function:: wchar_t* Py_GetProgramFullPath()
.. index::
single: Py_SetProgramName()
@@ -179,11 +175,12 @@ Process-wide parameters
to Python code as ``sys.executable``.
-.. c:function:: char* Py_GetPath()
+.. c:function:: wchar_t* Py_GetPath()
.. index::
triple: module; search; path
single: path (in module sys)
+ single: Py_SetPath()
Return the default module search path; this is computed from the program name
(set by :c:func:`Py_SetProgramName` above) and some environment variables.
@@ -198,19 +195,38 @@ Process-wide parameters
.. XXX should give the exact rules
+.. c:function:: void Py_SetPath(const wchar_t *)
+
+ .. index::
+ triple: module; search; path
+ single: path (in module sys)
+ single: Py_GetPath()
+
+ Set the default module search path. If this function is called before
+ :c:func:`Py_Initialize`, then :c:func:`Py_GetPath` won't attempt to compute a
+ default search path but uses the one provided instead. This is useful if
+ Python is embedded by an application that has full knowledge of the location
+ of all modules. The path components should be separated by semicolons.
+
+ This also causes :data:`sys.executable` to be set only to the raw program
+ name (see :c:func:`Py_SetProgramName`) and for :data:`sys.prefix` and
+ :data:`sys.exec_prefix` to be empty. It is up to the caller to modify these
+ if required after calling :c:func:`Py_Initialize`.
+
+
.. c:function:: const char* Py_GetVersion()
Return the version of this Python interpreter. This is a string that looks
something like ::
- "1.5 (#67, Dec 31 1997, 22:34:28) [GCC 2.7.2.2]"
+ "3.0a5+ (py3k:63103M, May 12 2008, 00:53:55) \n[GCC 4.2.3]"
.. index:: single: version (in module sys)
The first word (up to the first space character) is the current Python version;
the first three characters are the major and minor version separated by a
period. The returned string points into static storage; the caller should not
- modify its value. The value is available to Python code as ``sys.version``.
+ modify its value. The value is available to Python code as :data:`sys.version`.
.. c:function:: const char* Py_GetPlatform()
@@ -266,7 +282,7 @@ Process-wide parameters
``sys.version``.
-.. c:function:: void PySys_SetArgvEx(int argc, char **argv, int updatepath)
+.. c:function:: void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
.. index::
single: main()
@@ -299,24 +315,24 @@ Process-wide parameters
and update :data:`sys.path` themselves if desired.
See `CVE-2008-5983 <http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5983>`_.
- On versions before 2.6.6, you can achieve the same effect by manually
+ On versions before 3.1.3, you can achieve the same effect by manually
popping the first :data:`sys.path` element after having called
:c:func:`PySys_SetArgv`, for example using::
PyRun_SimpleString("import sys; sys.path.pop(0)\n");
- .. versionadded:: 2.6.6
+ .. versionadded:: 3.1.3
.. XXX impl. doesn't seem consistent in allowing 0/NULL for the params;
check w/ Guido.
-.. c:function:: void PySys_SetArgv(int argc, char **argv)
+.. c:function:: void PySys_SetArgv(int argc, wchar_t **argv)
This function works like :c:func:`PySys_SetArgvEx` with *updatepath* set to 1.
-.. c:function:: void Py_SetPythonHome(char *home)
+.. c:function:: void Py_SetPythonHome(wchar_t *home)
Set the default "home" directory, that is, the location of the standard
Python libraries. See :envvar:`PYTHONHOME` for the meaning of the
@@ -328,7 +344,7 @@ Process-wide parameters
this storage.
-.. c:function:: char* Py_GetPythonHome()
+.. c:function:: w_char* Py_GetPythonHome()
Return the default "home", that is, the value set by a previous call to
:c:func:`Py_SetPythonHome`, or the value of the :envvar:`PYTHONHOME`
@@ -341,7 +357,6 @@ Thread State and the Global Interpreter Lock
============================================
.. index::
- single: GIL
single: global interpreter lock
single: interpreter lock
single: lock, interpreter
@@ -354,12 +369,12 @@ operations could cause problems in a multi-threaded program: for example, when
two threads simultaneously increment the reference count of the same object, the
reference count could end up being incremented only once instead of twice.
-.. index:: single: setcheckinterval() (in module sys)
+.. index:: single: setswitchinterval() (in module sys)
Therefore, the rule exists that only the thread that has acquired the
:term:`GIL` may operate on Python objects or call Python/C API functions.
In order to emulate concurrency of execution, the interpreter regularly
-tries to switch threads (see :func:`sys.setcheckinterval`). The lock is also
+tries to switch threads (see :func:`sys.setswitchinterval`). The lock is also
released around potentially blocking I/O operations like reading or writing
a file, so that other Python threads can run in the meantime.
@@ -512,23 +527,22 @@ code, or when embedding the Python interpreter:
.. c:function:: void PyEval_InitThreads()
.. index::
- single: PyEval_ReleaseLock()
+ single: PyEval_AcquireThread()
single: PyEval_ReleaseThread()
single: PyEval_SaveThread()
single: PyEval_RestoreThread()
Initialize and acquire the global interpreter lock. It should be called in the
main thread before creating a second thread or engaging in any other thread
- operations such as :c:func:`PyEval_ReleaseLock` or
- ``PyEval_ReleaseThread(tstate)``. It is not needed before calling
- :c:func:`PyEval_SaveThread` or :c:func:`PyEval_RestoreThread`.
+ operations such as ``PyEval_ReleaseThread(tstate)``. It is not needed before
+ calling :c:func:`PyEval_SaveThread` or :c:func:`PyEval_RestoreThread`.
- .. index:: single: Py_Initialize()
+ This is a no-op when called for a second time.
- This is a no-op when called for a second time. It is safe to call this function
- before calling :c:func:`Py_Initialize`.
+ .. versionchanged:: 3.2
+ This function cannot be called before :c:func:`Py_Initialize()` anymore.
- .. index:: module: thread
+ .. index:: module: _thread
.. note::
When only the main thread exists, no GIL operations are needed. This is a
@@ -555,8 +569,6 @@ code, or when embedding the Python interpreter:
avoid calls to the locking API when running single-threaded. This function is
not available when thread support is disabled at compile time.
- .. versionadded:: 2.4
-
.. c:function:: PyThreadState* PyEval_SaveThread()
@@ -622,8 +634,6 @@ with sub-interpreters:
When the function returns, the current thread will hold the GIL and be able
to call arbitrary Python code. Failure is a fatal error.
- .. versionadded:: 2.3
-
.. c:function:: void PyGILState_Release(PyGILState_STATE)
@@ -635,8 +645,6 @@ with sub-interpreters:
Every call to :c:func:`PyGILState_Ensure` must be matched by a call to
:c:func:`PyGILState_Release` on the same thread.
- .. versionadded:: 2.3
-
.. c:function:: PyThreadState PyGILState_GetThisThreadState()
@@ -645,8 +653,6 @@ with sub-interpreters:
always has such a thread-state, even if no auto-thread-state call has been
made on the main thread. This is mainly a helper/diagnostic function.
- .. versionadded:: 2.3
-
The following macros are normally used without a trailing semicolon; look for
example usage in the Python source distribution.
@@ -738,10 +744,6 @@ been created.
is available. If this function returns *NULL*, no exception has been raised and
the caller should assume no current thread state is available.
- .. versionchanged:: 2.3
- Previously this could only be called when a current thread is active, and *NULL*
- meant that an exception was raised.
-
.. c:function:: int PyThreadState_SetAsyncExc(long id, PyObject *exc)
@@ -753,8 +755,6 @@ been created.
zero if the thread id isn't found. If *exc* is :const:`NULL`, the pending
exception (if any) for the thread is cleared. This raises no exceptions.
- .. versionadded:: 2.3
-
.. c:function:: void PyEval_AcquireThread(PyThreadState *tstate)
@@ -785,8 +785,8 @@ been created.
Acquire the global interpreter lock. The lock must have been created earlier.
If this thread already has the lock, a deadlock ensues.
- .. warning::
- This function does not change the current thread state. Please use
+ .. deprecated:: 3.2
+ This function does not update the current thread state. Please use
:c:func:`PyEval_RestoreThread` or :c:func:`PyEval_AcquireThread`
instead.
@@ -795,8 +795,8 @@ been created.
Release the global interpreter lock. The lock must have been created earlier.
- .. warning::
- This function does not change the current thread state. Please use
+ .. deprecated:: 3.2
+ This function does not update the current thread state. Please use
:c:func:`PyEval_SaveThread` or :c:func:`PyEval_ReleaseThread`
instead.
@@ -938,8 +938,7 @@ perform any Python API calls.
other system thread. If it is a Python thread, it doesn't matter if it holds
the global interpreter lock or not.
- .. versionadded:: 2.7
-
+ .. versionadded:: 3.1
.. _profiling:
@@ -954,14 +953,12 @@ The Python interpreter provides some low-level support for attaching profiling
and execution tracing facilities. These are used for profiling, debugging, and
coverage analysis tools.
-Starting with Python 2.2, the implementation of this facility was substantially
-revised, and an interface from C was added. This C interface allows the
-profiling or tracing code to avoid the overhead of calling through Python-level
-callable objects, making a direct C function call instead. The essential
-attributes of the facility have not changed; the interface allows trace
-functions to be installed per-thread, and the basic events reported to the trace
-function are the same as had been reported to the Python-level trace functions
-in previous versions.
+This C interface allows the profiling or tracing code to avoid the overhead of
+calling through Python-level callable objects, making a direct C function call
+instead. The essential attributes of the facility have not changed; the
+interface allows trace functions to be installed per-thread, and the basic
+events reported to the trace function are the same as had been reported to the
+Python-level trace functions in previous versions.
.. c:type:: int (*Py_tracefunc)(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg)
@@ -1117,29 +1114,21 @@ These functions are only intended to be used by advanced debugging tools.
Return the interpreter state object at the head of the list of all such objects.
- .. versionadded:: 2.2
-
.. c:function:: PyInterpreterState* PyInterpreterState_Next(PyInterpreterState *interp)
Return the next interpreter state object after *interp* from the list of all
such objects.
- .. versionadded:: 2.2
-
.. c:function:: PyThreadState * PyInterpreterState_ThreadHead(PyInterpreterState *interp)
Return the a pointer to the first :c:type:`PyThreadState` object in the list of
threads associated with the interpreter *interp*.
- .. versionadded:: 2.2
-
.. c:function:: PyThreadState* PyThreadState_Next(PyThreadState *tstate)
Return the next thread state object after *tstate* from the list of all such
objects belonging to the same :c:type:`PyInterpreterState` object.
- .. versionadded:: 2.2
-
diff --git a/Doc/c-api/int.rst b/Doc/c-api/int.rst
deleted file mode 100644
index 254219c..0000000
--- a/Doc/c-api/int.rst
+++ /dev/null
@@ -1,139 +0,0 @@
-.. highlightlang:: c
-
-.. _intobjects:
-
-Plain Integer Objects
----------------------
-
-.. index:: object: integer
-
-
-.. c:type:: PyIntObject
-
- This subtype of :c:type:`PyObject` represents a Python integer object.
-
-
-.. c:var:: PyTypeObject PyInt_Type
-
- .. index:: single: IntType (in modules types)
-
- This instance of :c:type:`PyTypeObject` represents the Python plain integer type.
- This is the same object as ``int`` and ``types.IntType``.
-
-
-.. c:function:: int PyInt_Check(PyObject *o)
-
- Return true if *o* is of type :c:data:`PyInt_Type` or a subtype of
- :c:data:`PyInt_Type`.
-
- .. versionchanged:: 2.2
- Allowed subtypes to be accepted.
-
-
-.. c:function:: int PyInt_CheckExact(PyObject *o)
-
- Return true if *o* is of type :c:data:`PyInt_Type`, but not a subtype of
- :c:data:`PyInt_Type`.
-
- .. versionadded:: 2.2
-
-
-.. c:function:: PyObject* PyInt_FromString(char *str, char **pend, int base)
-
- Return a new :c:type:`PyIntObject` or :c:type:`PyLongObject` based on the string
- value in *str*, which is interpreted according to the radix in *base*. If
- *pend* is non-*NULL*, ``*pend`` will point to the first character in *str* which
- follows the representation of the number. If *base* is ``0``, the radix will be
- determined based on the leading characters of *str*: if *str* starts with
- ``'0x'`` or ``'0X'``, radix 16 will be used; if *str* starts with ``'0'``, radix
- 8 will be used; otherwise radix 10 will be used. If *base* is not ``0``, it
- must be between ``2`` and ``36``, inclusive. Leading spaces are ignored. If
- there are no digits, :exc:`ValueError` will be raised. If the string represents
- a number too large to be contained within the machine's :c:type:`long int` type
- and overflow warnings are being suppressed, a :c:type:`PyLongObject` will be
- returned. If overflow warnings are not being suppressed, *NULL* will be
- returned in this case.
-
-
-.. c:function:: PyObject* PyInt_FromLong(long ival)
-
- Create a new integer object with a value of *ival*.
-
- The current implementation keeps an array of integer objects for all integers
- between ``-5`` and ``256``, when you create an int in that range you actually
- just get back a reference to the existing object. So it should be possible to
- change the value of ``1``. I suspect the behaviour of Python in this case is
- undefined. :-)
-
-
-.. c:function:: PyObject* PyInt_FromSsize_t(Py_ssize_t ival)
-
- Create a new integer object with a value of *ival*. If the value is larger
- than ``LONG_MAX`` or smaller than ``LONG_MIN``, a long integer object is
- returned.
-
- .. versionadded:: 2.5
-
-
-.. c:function:: PyObject* PyInt_FromSize_t(size_t ival)
-
- Create a new integer object with a value of *ival*. If the value exceeds
- ``LONG_MAX``, a long integer object is returned.
-
- .. versionadded:: 2.5
-
-
-.. c:function:: long PyInt_AsLong(PyObject *io)
-
- Will first attempt to cast the object to a :c:type:`PyIntObject`, if it is not
- already one, and then return its value. If there is an error, ``-1`` is
- returned, and the caller should check ``PyErr_Occurred()`` to find out whether
- there was an error, or whether the value just happened to be -1.
-
-
-.. c:function:: long PyInt_AS_LONG(PyObject *io)
-
- Return the value of the object *io*. No error checking is performed.
-
-
-.. c:function:: unsigned long PyInt_AsUnsignedLongMask(PyObject *io)
-
- Will first attempt to cast the object to a :c:type:`PyIntObject` or
- :c:type:`PyLongObject`, if it is not already one, and then return its value as
- unsigned long. This function does not check for overflow.
-
- .. versionadded:: 2.3
-
-
-.. c:function:: unsigned PY_LONG_LONG PyInt_AsUnsignedLongLongMask(PyObject *io)
-
- Will first attempt to cast the object to a :c:type:`PyIntObject` or
- :c:type:`PyLongObject`, if it is not already one, and then return its value as
- unsigned long long, without checking for overflow.
-
- .. versionadded:: 2.3
-
-
-.. c:function:: Py_ssize_t PyInt_AsSsize_t(PyObject *io)
-
- Will first attempt to cast the object to a :c:type:`PyIntObject` or
- :c:type:`PyLongObject`, if it is not already one, and then return its value as
- :c:type:`Py_ssize_t`.
-
- .. versionadded:: 2.5
-
-
-.. c:function:: long PyInt_GetMax()
-
- .. index:: single: LONG_MAX
-
- Return the system's idea of the largest integer it can handle
- (:const:`LONG_MAX`, as defined in the system header files).
-
-
-.. c:function:: int PyInt_ClearFreeList()
-
- Clear the integer free list. Return the number of items that could not
- be freed.
-
- .. versionadded:: 2.6
diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst
index 4216881..e136816 100644
--- a/Doc/c-api/intro.rst
+++ b/Doc/c-api/intro.rst
@@ -208,11 +208,11 @@ error handling for the moment; a better way to code this is shown below)::
PyObject *t;
t = PyTuple_New(3);
- PyTuple_SetItem(t, 0, PyInt_FromLong(1L));
- PyTuple_SetItem(t, 1, PyInt_FromLong(2L));
+ PyTuple_SetItem(t, 0, PyLong_FromLong(1L));
+ PyTuple_SetItem(t, 1, PyLong_FromLong(2L));
PyTuple_SetItem(t, 2, PyString_FromString("three"));
-Here, :c:func:`PyInt_FromLong` returns a new reference which is immediately
+Here, :c:func:`PyLong_FromLong` returns a new reference which is immediately
stolen by :c:func:`PyTuple_SetItem`. When you want to keep using an object
although the reference to it will be stolen, use :c:func:`Py_INCREF` to grab
another reference before calling the reference-stealing function.
@@ -246,17 +246,19 @@ sets all items of a list (actually, any mutable sequence) to a given item::
int
set_all(PyObject *target, PyObject *item)
{
- int i, n;
+ Py_ssize_t i, n;
n = PyObject_Length(target);
if (n < 0)
return -1;
for (i = 0; i < n; i++) {
- PyObject *index = PyInt_FromLong(i);
+ PyObject *index = PyLong_FromSsize_t(i);
if (!index)
return -1;
- if (PyObject_SetItem(target, index, item) < 0)
+ if (PyObject_SetItem(target, index, item) < 0) {
+ Py_DECREF(index);
return -1;
+ }
Py_DECREF(index);
}
return 0;
@@ -292,8 +294,8 @@ using :c:func:`PySequence_GetItem`. ::
long
sum_list(PyObject *list)
{
- int i, n;
- long total = 0;
+ Py_ssize_t i, n;
+ long total = 0, value;
PyObject *item;
n = PyList_Size(list);
@@ -301,8 +303,12 @@ using :c:func:`PySequence_GetItem`. ::
return -1; /* Not a list */
for (i = 0; i < n; i++) {
item = PyList_GetItem(list, i); /* Can't fail */
- if (!PyInt_Check(item)) continue; /* Skip non-integers */
- total += PyInt_AsLong(item);
+ if (!PyLong_Check(item)) continue; /* Skip non-integers */
+ value = PyLong_AsLong(item);
+ if (value == -1 && PyErr_Occurred())
+ /* Integer too big to fit in a C long, bail out */
+ return -1;
+ total += value;
}
return total;
}
@@ -314,8 +320,8 @@ using :c:func:`PySequence_GetItem`. ::
long
sum_sequence(PyObject *sequence)
{
- int i, n;
- long total = 0;
+ Py_ssize_t i, n;
+ long total = 0, value;
PyObject *item;
n = PySequence_Length(sequence);
if (n < 0)
@@ -324,9 +330,17 @@ using :c:func:`PySequence_GetItem`. ::
item = PySequence_GetItem(sequence, i);
if (item == NULL)
return -1; /* Not a sequence, or other failure */
- if (PyInt_Check(item))
- total += PyInt_AsLong(item);
- Py_DECREF(item); /* Discard reference ownership */
+ if (PyLong_Check(item)) {
+ value = PyLong_AsLong(item);
+ Py_DECREF(item);
+ if (value == -1 && PyErr_Occurred())
+ /* Integer too big to fit in a C long, bail out */
+ return -1;
+ total += value;
+ }
+ else {
+ Py_DECREF(item); /* Discard reference ownership */
+ }
}
return total;
}
@@ -386,20 +400,15 @@ reference to the exception type object when an exception has occurred, and
function to set the exception state, and :c:func:`PyErr_Clear` clears the
exception state.
-.. index::
- single: exc_type (in module sys)
- single: exc_value (in module sys)
- single: exc_traceback (in module sys)
-
The full exception state consists of three objects (all of which can be
*NULL*): the exception type, the corresponding exception value, and the
-traceback. These have the same meanings as the Python objects
-``sys.exc_type``, ``sys.exc_value``, and ``sys.exc_traceback``; however, they
-are not the same: the Python objects represent the last exception being handled
-by a Python :keyword:`try` ... :keyword:`except` statement, while the C level
-exception state only exists while an exception is being passed on between C
-functions until it reaches the Python bytecode interpreter's main loop, which
-takes care of transferring it to ``sys.exc_type`` and friends.
+traceback. These have the same meanings as the Python result of
+``sys.exc_info()``; however, they are not the same: the Python objects represent
+the last exception being handled by a Python :keyword:`try` ...
+:keyword:`except` statement, while the C level exception state only exists while
+an exception is being passed on between C functions until it reaches the Python
+bytecode interpreter's main loop, which takes care of transferring it to
+``sys.exc_info()`` and friends.
.. index:: single: exc_info() (in module sys)
@@ -455,11 +464,11 @@ Here is the corresponding C code, in all its glory::
/* Clear the error and use zero: */
PyErr_Clear();
- item = PyInt_FromLong(0L);
+ item = PyLong_FromLong(0L);
if (item == NULL)
goto error;
}
- const_one = PyInt_FromLong(1L);
+ const_one = PyLong_FromLong(1L);
if (const_one == NULL)
goto error;
@@ -513,16 +522,15 @@ interpreter can only be used after the interpreter has been initialized.
.. index::
single: Py_Initialize()
- module: __builtin__
+ module: builtins
module: __main__
module: sys
- module: exceptions
triple: module; search; path
single: path (in module sys)
The basic initialization function is :c:func:`Py_Initialize`. This initializes
the table of loaded modules, and creates the fundamental modules
-:mod:`__builtin__`, :mod:`__main__`, :mod:`sys`, and :mod:`exceptions`. It also
+:mod:`builtins`, :mod:`__main__`, and :mod:`sys`. It also
initializes the module search path (``sys.path``).
.. index:: single: PySys_SetArgvEx()
@@ -613,7 +621,7 @@ extra checks are performed:
* Sanity checks of the input arguments are added to frame creation.
-* The storage for long ints is initialized with a known invalid pattern to catch
+* The storage for ints is initialized with a known invalid pattern to catch
reference to uninitialized digits.
* Low-level tracing and extra exception checking are added to the runtime
diff --git a/Doc/c-api/iter.rst b/Doc/c-api/iter.rst
index 88ac0c1..3f0f554 100644
--- a/Doc/c-api/iter.rst
+++ b/Doc/c-api/iter.rst
@@ -5,11 +5,8 @@
Iterator Protocol
=================
-.. versionadded:: 2.2
-
There are only a couple of functions specifically for working with iterators.
-
.. c:function:: int PyIter_Check(PyObject *o)
Return true if the object *o* supports the iterator protocol.
diff --git a/Doc/c-api/iterator.rst b/Doc/c-api/iterator.rst
index 3931bb9..82cb4eb 100644
--- a/Doc/c-api/iterator.rst
+++ b/Doc/c-api/iterator.rst
@@ -18,15 +18,11 @@ sentinel value is returned.
one-argument form of the :func:`iter` built-in function for built-in sequence
types.
- .. versionadded:: 2.2
-
.. c:function:: int PySeqIter_Check(op)
Return true if the type of *op* is :c:data:`PySeqIter_Type`.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PySeqIter_New(PyObject *seq)
@@ -34,23 +30,17 @@ sentinel value is returned.
iteration ends when the sequence raises :exc:`IndexError` for the subscripting
operation.
- .. versionadded:: 2.2
-
.. c:var:: PyTypeObject PyCallIter_Type
Type object for iterator objects returned by :c:func:`PyCallIter_New` and the
two-argument form of the :func:`iter` built-in function.
- .. versionadded:: 2.2
-
.. c:function:: int PyCallIter_Check(op)
Return true if the type of *op* is :c:data:`PyCallIter_Type`.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyCallIter_New(PyObject *callable, PyObject *sentinel)
@@ -58,5 +48,3 @@ sentinel value is returned.
callable object that can be called with no parameters; each call to it should
return the next item in the iteration. When *callable* returns a value equal to
*sentinel*, the iteration will be terminated.
-
- .. versionadded:: 2.2
diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst
index 0aed0f3..feb9015 100644
--- a/Doc/c-api/list.rst
+++ b/Doc/c-api/list.rst
@@ -15,8 +15,8 @@ List Objects
.. c:var:: PyTypeObject PyList_Type
- This instance of :c:type:`PyTypeObject` represents the Python list type. This
- is the same object as ``list`` in the Python layer.
+ This instance of :c:type:`PyTypeObject` represents the Python list type.
+ This is the same object as :class:`list` in the Python layer.
.. c:function:: int PyList_Check(PyObject *p)
@@ -24,17 +24,12 @@ List Objects
Return true if *p* is a list object or an instance of a subtype of the list
type.
- .. versionchanged:: 2.2
- Allowed subtypes to be accepted.
-
.. c:function:: int PyList_CheckExact(PyObject *p)
Return true if *p* is a list object, but not an instance of a subtype of
the list type.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyList_New(Py_ssize_t len)
@@ -47,10 +42,6 @@ List Objects
:c:func:`PySequence_SetItem` or expose the object to Python code before
setting all items to a real object with :c:func:`PyList_SetItem`.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: Py_ssize_t PyList_Size(PyObject *list)
@@ -59,19 +50,11 @@ List Objects
Return the length of the list object in *list*; this is equivalent to
``len(list)`` on a list object.
- .. versionchanged:: 2.5
- This function returned an :c:type:`int`. This might require changes in
- your code for properly supporting 64-bit systems.
-
.. c:function:: Py_ssize_t PyList_GET_SIZE(PyObject *list)
Macro form of :c:func:`PyList_Size` without error checking.
- .. versionchanged:: 2.5
- This macro returned an :c:type:`int`. This might require changes in your
- code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index)
@@ -80,19 +63,11 @@ List Objects
supported. If *index* is out of bounds, return *NULL* and set an
:exc:`IndexError` exception.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` for *index*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i)
Macro form of :c:func:`PyList_GetItem` without error checking.
- .. versionchanged:: 2.5
- This macro used an :c:type:`int` for *i*. This might require changes in
- your code for properly supporting 64-bit systems.
-
.. c:function:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item)
@@ -104,10 +79,6 @@ List Objects
This function "steals" a reference to *item* and discards a reference to
an item already in the list at the affected position.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` for *index*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: void PyList_SET_ITEM(PyObject *list, Py_ssize_t i, PyObject *o)
@@ -118,13 +89,9 @@ List Objects
This macro "steals" a reference to *item*, and, unlike
:c:func:`PyList_SetItem`, does *not* discard a reference to any item that
- it being replaced; any reference in *list* at position *i* will be
+ is being replaced; any reference in *list* at position *i* will be
leaked.
- .. versionchanged:: 2.5
- This macro used an :c:type:`int` for *i*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PyList_Insert(PyObject *list, Py_ssize_t index, PyObject *item)
@@ -132,10 +99,6 @@ List Objects
``0`` if successful; return ``-1`` and set an exception if unsuccessful.
Analogous to ``list.insert(index, item)``.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` for *index*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PyList_Append(PyObject *list, PyObject *item)
@@ -151,10 +114,6 @@ List Objects
to ``list[low:high]``. Negative indices, as when slicing from Python, are not
supported.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` for *low* and *high*. This might
- require changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist)
@@ -164,10 +123,6 @@ List Objects
Return ``0`` on success, ``-1`` on failure. Negative indices, as when
slicing from Python, are not supported.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` for *low* and *high*. This might
- require changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PyList_Sort(PyObject *list)
diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst
index 5a8e51d..e2f58ad 100644
--- a/Doc/c-api/long.rst
+++ b/Doc/c-api/long.rst
@@ -2,23 +2,23 @@
.. _longobjects:
-Long Integer Objects
---------------------
+Integer Objects
+---------------
.. index:: object: long integer
+ object: integer
+All integers are implemented as "long" integer objects of arbitrary size.
.. c:type:: PyLongObject
- This subtype of :c:type:`PyObject` represents a Python long integer object.
+ This subtype of :c:type:`PyObject` represents a Python integer object.
.. c:var:: PyTypeObject PyLong_Type
- .. index:: single: LongType (in modules types)
-
- This instance of :c:type:`PyTypeObject` represents the Python long integer type.
- This is the same object as ``long`` and ``types.LongType``.
+ This instance of :c:type:`PyTypeObject` represents the Python integer type.
+ This is the same object as :class:`int` in the Python layer.
.. c:function:: int PyLong_Check(PyObject *p)
@@ -26,22 +26,23 @@ Long Integer Objects
Return true if its argument is a :c:type:`PyLongObject` or a subtype of
:c:type:`PyLongObject`.
- .. versionchanged:: 2.2
- Allowed subtypes to be accepted.
-
.. c:function:: int PyLong_CheckExact(PyObject *p)
Return true if its argument is a :c:type:`PyLongObject`, but not a subtype of
:c:type:`PyLongObject`.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyLong_FromLong(long v)
Return a new :c:type:`PyLongObject` object from *v*, or *NULL* on failure.
+ The current implementation keeps an array of integer objects for all integers
+ between ``-5`` and ``256``, when you create an int in that range you actually
+ just get back a reference to the existing object. So it should be possible to
+ change the value of ``1``. I suspect the behaviour of Python in this case is
+ undefined. :-)
+
.. c:function:: PyObject* PyLong_FromUnsignedLong(unsigned long v)
@@ -54,32 +55,12 @@ Long Integer Objects
Return a new :c:type:`PyLongObject` object from a C :c:type:`Py_ssize_t`, or
*NULL* on failure.
- .. versionadded:: 2.6
-
.. c:function:: PyObject* PyLong_FromSize_t(size_t v)
Return a new :c:type:`PyLongObject` object from a C :c:type:`size_t`, or
*NULL* on failure.
- .. versionadded:: 2.6
-
-
-.. c:function:: PyObject* PyLong_FromSsize_t(Py_ssize_t v)
-
- Return a new :c:type:`PyLongObject` object with a value of *v*, or *NULL*
- on failure.
-
- .. versionadded:: 2.6
-
-
-.. c:function:: PyObject* PyLong_FromSize_t(size_t v)
-
- Return a new :c:type:`PyLongObject` object with a value of *v*, or *NULL*
- on failure.
-
- .. versionadded:: 2.6
-
.. c:function:: PyObject* PyLong_FromLongLong(PY_LONG_LONG v)
@@ -101,126 +82,118 @@ Long Integer Objects
.. c:function:: PyObject* PyLong_FromString(char *str, char **pend, int base)
- Return a new :c:type:`PyLongObject` based on the string value in *str*, which is
- interpreted according to the radix in *base*. If *pend* is non-*NULL*,
+ Return a new :c:type:`PyLongObject` based on the string value in *str*, which
+ is interpreted according to the radix in *base*. If *pend* is non-*NULL*,
*\*pend* will point to the first character in *str* which follows the
- representation of the number. If *base* is ``0``, the radix will be determined
- based on the leading characters of *str*: if *str* starts with ``'0x'`` or
- ``'0X'``, radix 16 will be used; if *str* starts with ``'0'``, radix 8 will be
- used; otherwise radix 10 will be used. If *base* is not ``0``, it must be
- between ``2`` and ``36``, inclusive. Leading spaces are ignored. If there are
- no digits, :exc:`ValueError` will be raised.
+ representation of the number. If *base* is ``0``, the radix will be
+ determined based on the leading characters of *str*: if *str* starts with
+ ``'0x'`` or ``'0X'``, radix 16 will be used; if *str* starts with ``'0o'`` or
+ ``'0O'``, radix 8 will be used; if *str* starts with ``'0b'`` or ``'0B'``,
+ radix 2 will be used; otherwise radix 10 will be used. If *base* is not
+ ``0``, it must be between ``2`` and ``36``, inclusive. Leading spaces are
+ ignored. If there are no digits, :exc:`ValueError` will be raised.
.. c:function:: PyObject* PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
- Convert a sequence of Unicode digits to a Python long integer value. The first
- parameter, *u*, points to the first character of the Unicode string, *length*
- gives the number of characters, and *base* is the radix for the conversion. The
- radix must be in the range [2, 36]; if it is out of range, :exc:`ValueError`
- will be raised.
-
- .. versionadded:: 1.6
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` for *length*. This might require
- changes in your code for properly supporting 64-bit systems.
+ Convert a sequence of Unicode digits to a Python integer value. The Unicode
+ string is first encoded to a byte string using :c:func:`PyUnicode_EncodeDecimal`
+ and then converted using :c:func:`PyLong_FromString`.
.. c:function:: PyObject* PyLong_FromVoidPtr(void *p)
- Create a Python integer or long integer from the pointer *p*. The pointer value
- can be retrieved from the resulting value using :c:func:`PyLong_AsVoidPtr`.
-
- .. versionadded:: 1.5.2
-
- .. versionchanged:: 2.5
- If the integer is larger than LONG_MAX, a positive long integer is returned.
+ Create a Python integer from the pointer *p*. The pointer value can be
+ retrieved from the resulting value using :c:func:`PyLong_AsVoidPtr`.
-.. c:function:: long PyLong_AsLong(PyObject *pylong)
+.. XXX alias PyLong_AS_LONG (for now)
+.. c:function:: long PyLong_AsLong(PyObject *obj)
.. index::
single: LONG_MAX
single: OverflowError (built-in exception)
- Return a C :c:type:`long` representation of the contents of *pylong*. If
- *pylong* is greater than :const:`LONG_MAX`, an :exc:`OverflowError` is raised
- and ``-1`` will be returned.
+ Return a C :c:type:`long` representation of *obj*. If *obj* is not an
+ instance of :c:type:`PyLongObject`, first call its :meth:`__int__` method
+ (if present) to convert it to a :c:type:`PyLongObject`.
+ Raise :exc:`OverflowError` if the value of *obj* is out of range for a
+ :c:type:`long`.
-.. c:function:: long PyLong_AsLongAndOverflow(PyObject *pylong, int *overflow)
- Return a C :c:type:`long` representation of the contents of
- *pylong*. If *pylong* is greater than :const:`LONG_MAX` or less
- than :const:`LONG_MIN`, set *\*overflow* to ``1`` or ``-1``,
- respectively, and return ``-1``; otherwise, set *\*overflow* to
- ``0``. If any other exception occurs (for example a TypeError or
- MemoryError), then ``-1`` will be returned and *\*overflow* will
- be ``0``.
+.. c:function:: long PyLong_AsLongAndOverflow(PyObject *obj, int *overflow)
- .. versionadded:: 2.7
+ Return a C :c:type:`long` representation of *obj*. If *obj* is not an
+ instance of :c:type:`PyLongObject`, first call its :meth:`__int__` method
+ (if present) to convert it to a :c:type:`PyLongObject`.
+ If the value of *obj* is greater than :const:`LONG_MAX` or less than
+ :const:`LONG_MIN`, set *\*overflow* to ``1`` or ``-1``, respectively, and
+ return ``-1``; otherwise, set *\*overflow* to ``0``. If any other exception
+ occurs set *\*overflow* to ``0`` and return ``-1`` as usual.
-.. c:function:: PY_LONG_LONG PyLong_AsLongLongAndOverflow(PyObject *pylong, int *overflow)
- Return a C :c:type:`long long` representation of the contents of
- *pylong*. If *pylong* is greater than :const:`PY_LLONG_MAX` or less
- than :const:`PY_LLONG_MIN`, set *\*overflow* to ``1`` or ``-1``,
- respectively, and return ``-1``; otherwise, set *\*overflow* to
- ``0``. If any other exception occurs (for example a TypeError or
- MemoryError), then ``-1`` will be returned and *\*overflow* will
- be ``0``.
-
- .. versionadded:: 2.7
-
-
-.. c:function:: Py_ssize_t PyLong_AsSsize_t(PyObject *pylong)
+.. c:function:: PY_LONG_LONG PyLong_AsLongLong(PyObject *obj)
.. index::
- single: PY_SSIZE_T_MAX
single: OverflowError (built-in exception)
- Return a C :c:type:`Py_ssize_t` representation of the contents of *pylong*. If
- *pylong* is greater than :const:`PY_SSIZE_T_MAX`, an :exc:`OverflowError` is raised
- and ``-1`` will be returned.
+ Return a C :c:type:`long long` representation of *obj*. If *obj* is not an
+ instance of :c:type:`PyLongObject`, first call its :meth:`__int__` method
+ (if present) to convert it to a :c:type:`PyLongObject`.
- .. versionadded:: 2.6
+ Raise :exc:`OverflowError` if the value of *obj* is out of range for a
+ :c:type:`long`.
-.. c:function:: unsigned long PyLong_AsUnsignedLong(PyObject *pylong)
+.. c:function:: PY_LONG_LONG PyLong_AsLongLongAndOverflow(PyObject *obj, int *overflow)
- .. index::
- single: ULONG_MAX
- single: OverflowError (built-in exception)
+ Return a C :c:type:`long long` representation of *obj*. If *obj* is not an
+ instance of :c:type:`PyLongObject`, first call its :meth:`__int__` method
+ (if present) to convert it to a :c:type:`PyLongObject`.
- Return a C :c:type:`unsigned long` representation of the contents of *pylong*.
- If *pylong* is greater than :const:`ULONG_MAX`, an :exc:`OverflowError` is
- raised.
+ If the value of *obj* is greater than :const:`PY_LLONG_MAX` or less than
+ :const:`PY_LLONG_MIN`, set *\*overflow* to ``1`` or ``-1``, respectively,
+ and return ``-1``; otherwise, set *\*overflow* to ``0``. If any other
+ exception occurs set *\*overflow* to ``0`` and return ``-1`` as usual.
+
+ .. versionadded:: 3.2
.. c:function:: Py_ssize_t PyLong_AsSsize_t(PyObject *pylong)
.. index::
single: PY_SSIZE_T_MAX
+ single: OverflowError (built-in exception)
- Return a :c:type:`Py_ssize_t` representation of the contents of *pylong*. If
- *pylong* is greater than :const:`PY_SSIZE_T_MAX`, an :exc:`OverflowError` is
- raised.
+ Return a C :c:type:`Py_ssize_t` representation of *pylong*. *pylong* must
+ be an instance of :c:type:`PyLongObject`.
- .. versionadded:: 2.6
+ Raise :exc:`OverflowError` if the value of *pylong* is out of range for a
+ :c:type:`Py_ssize_t`.
-.. c:function:: PY_LONG_LONG PyLong_AsLongLong(PyObject *pylong)
+.. c:function:: unsigned long PyLong_AsUnsignedLong(PyObject *pylong)
.. index::
+ single: ULONG_MAX
single: OverflowError (built-in exception)
- Return a C :c:type:`long long` from a Python long integer. If
- *pylong* cannot be represented as a :c:type:`long long`, an
- :exc:`OverflowError` is raised and ``-1`` is returned.
+ Return a C :c:type:`unsigned long` representation of *pylong*. *pylong*
+ must be an instance of :c:type:`PyLongObject`.
+
+ Raise :exc:`OverflowError` if the value of *pylong* is out of range for a
+ :c:type:`unsigned long`.
+
+
+.. c:function:: size_t PyLong_AsSize_t(PyObject *pylong)
+
+ Return a C :c:type:`size_t` representation of of *pylong*. *pylong* must be
+ an instance of :c:type:`PyLongObject`.
- .. versionadded:: 2.2
+ Raise :exc:`OverflowError` if the value of *pylong* is out of range for a
+ :c:type:`size_t`.
.. c:function:: unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong(PyObject *pylong)
@@ -228,51 +201,48 @@ Long Integer Objects
.. index::
single: OverflowError (built-in exception)
- Return a C :c:type:`unsigned long long` from a Python long integer. If
- *pylong* cannot be represented as an :c:type:`unsigned long long`, an
- :exc:`OverflowError` is raised and ``(unsigned long long)-1`` is
- returned.
+ Return a C :c:type:`unsigned PY_LONG_LONG` representation of of *pylong*.
+ *pylong* must be an instance of :c:type:`PyLongObject`.
- .. versionadded:: 2.2
+ Raise :exc:`OverflowError` if the value of *pylong* is out of range for an
+ :c:type:`unsigned PY_LONG_LONG`.
- .. versionchanged:: 2.7
- A negative *pylong* now raises :exc:`OverflowError`, not
- :exc:`TypeError`.
+ .. versionchanged:: 3.1
+ A negative *pylong* now raises :exc:`OverflowError`, not :exc:`TypeError`.
-.. c:function:: unsigned long PyLong_AsUnsignedLongMask(PyObject *io)
+.. c:function:: unsigned long PyLong_AsUnsignedLongMask(PyObject *obj)
- Return a C :c:type:`unsigned long` from a Python long integer, without checking
- for overflow.
+ Return a C :c:type:`unsigned long` representation of *obj*. If *obj*
+ is not an instance of :c:type:`PyLongObject`, first call its :meth:`__int__`
+ method (if present) to convert it to a :c:type:`PyLongObject`.
- .. versionadded:: 2.3
+ If the value of *obj* is out of range for an :c:type:`unsigned long`,
+ return the reduction of that value modulo :const:`ULONG_MAX + 1`.
-.. c:function:: unsigned PY_LONG_LONG PyLong_AsUnsignedLongLongMask(PyObject *io)
+.. c:function:: unsigned PY_LONG_LONG PyLong_AsUnsignedLongLongMask(PyObject *obj)
- Return a C :c:type:`unsigned long long` from a Python long integer, without
- checking for overflow.
+ Return a C :c:type:`unsigned long long` representation of *obj*. If *obj*
+ is not an instance of :c:type:`PyLongObject`, first call its :meth:`__int__`
+ method (if present) to convert it to a :c:type:`PyLongObject`.
- .. versionadded:: 2.3
+ If the value of *obj* is out of range for an :c:type:`unsigned long long`,
+ return the reduction of that value modulo :const:`PY_ULLONG_MAX + 1`.
.. c:function:: double PyLong_AsDouble(PyObject *pylong)
- Return a C :c:type:`double` representation of the contents of *pylong*. If
- *pylong* cannot be approximately represented as a :c:type:`double`, an
- :exc:`OverflowError` exception is raised and ``-1.0`` will be returned.
+ Return a C :c:type:`double` representation of *pylong*. *pylong* must be
+ an instance of :c:type:`PyLongObject`.
+
+ Raise :exc:`OverflowError` if the value of *pylong* is out of range for a
+ :c:type:`double`.
.. c:function:: void* PyLong_AsVoidPtr(PyObject *pylong)
- Convert a Python integer or long integer *pylong* to a C :c:type:`void` pointer.
+ Convert a Python integer *pylong* to a C :c:type:`void` pointer.
If *pylong* cannot be converted, an :exc:`OverflowError` will be raised. This
is only assured to produce a usable :c:type:`void` pointer for values created
with :c:func:`PyLong_FromVoidPtr`.
-
- .. versionadded:: 1.5.2
-
- .. versionchanged:: 2.5
- For values outside 0..LONG_MAX, both signed and unsigned integers are accepted.
-
-
diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst
index 7a83a50..0ef2961 100644
--- a/Doc/c-api/mapping.rst
+++ b/Doc/c-api/mapping.rst
@@ -21,10 +21,6 @@ Mapping Protocol
objects that do not provide mapping protocol, this is equivalent to the Python
expression ``len(o)``.
- .. versionchanged:: 2.5
- These functions returned an :c:type:`int` type. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PyMapping_DelItemString(PyObject *o, char *key)
@@ -41,34 +37,34 @@ Mapping Protocol
.. c:function:: int PyMapping_HasKeyString(PyObject *o, char *key)
On success, return ``1`` if the mapping object has the key *key* and ``0``
- otherwise. This is equivalent to ``o[key]``, returning ``True`` on success
- and ``False`` on an exception. This function always succeeds.
+ otherwise. This is equivalent to the Python expression ``key in o``.
+ This function always succeeds.
.. c:function:: int PyMapping_HasKey(PyObject *o, PyObject *key)
- Return ``1`` if the mapping object has the key *key* and ``0`` otherwise.
- This is equivalent to ``o[key]``, returning ``True`` on success and ``False``
- on an exception. This function always succeeds.
+ Return ``1`` if the mapping object has the key *key* and ``0`` otherwise. This
+ is equivalent to the Python expression ``key in o``. This function always
+ succeeds.
.. c:function:: PyObject* PyMapping_Keys(PyObject *o)
On success, return a list of the keys in object *o*. On failure, return *NULL*.
- This is equivalent to the Python expression ``o.keys()``.
+ This is equivalent to the Python expression ``list(o.keys())``.
.. c:function:: PyObject* PyMapping_Values(PyObject *o)
On success, return a list of the values in object *o*. On failure, return
- *NULL*. This is equivalent to the Python expression ``o.values()``.
+ *NULL*. This is equivalent to the Python expression ``list(o.values())``.
.. c:function:: PyObject* PyMapping_Items(PyObject *o)
On success, return a list of the items in object *o*, where each item is a tuple
containing a key-value pair. On failure, return *NULL*. This is equivalent to
- the Python expression ``o.items()``.
+ the Python expression ``list(o.items())``.
.. c:function:: PyObject* PyMapping_GetItemString(PyObject *o, char *key)
diff --git a/Doc/c-api/marshal.rst b/Doc/c-api/marshal.rst
index b82cc96..da402a8 100644
--- a/Doc/c-api/marshal.rst
+++ b/Doc/c-api/marshal.rst
@@ -14,36 +14,28 @@ binary mode.
Numeric values are stored with the least significant byte first.
The module supports two versions of the data format: version 0 is the
-historical version, version 1 (new in Python 2.4) shares interned strings in
-the file, and upon unmarshalling. Version 2 (new in Python 2.5) uses a binary
-format for floating point numbers. *Py_MARSHAL_VERSION* indicates the current
-file format (currently 2).
+historical version, version 1 shares interned strings in the file, and upon
+unmarshalling. Version 2 uses a binary format for floating point numbers.
+*Py_MARSHAL_VERSION* indicates the current file format (currently 2).
.. c:function:: void PyMarshal_WriteLongToFile(long value, FILE *file, int version)
Marshal a :c:type:`long` integer, *value*, to *file*. This will only write
the least-significant 32 bits of *value*; regardless of the size of the
- native :c:type:`long` type.
-
- .. versionchanged:: 2.4
- *version* indicates the file format.
+ native :c:type:`long` type. *version* indicates the file format.
.. c:function:: void PyMarshal_WriteObjectToFile(PyObject *value, FILE *file, int version)
Marshal a Python object, *value*, to *file*.
-
- .. versionchanged:: 2.4
- *version* indicates the file format.
+ *version* indicates the file format.
.. c:function:: PyObject* PyMarshal_WriteObjectToString(PyObject *value, int version)
Return a string object containing the marshalled representation of *value*.
-
- .. versionchanged:: 2.4
- *version* indicates the file format.
+ *version* indicates the file format.
The following functions allow marshalled values to be read back in.
@@ -95,6 +87,3 @@ written using these routines?
appropriate exception (:exc:`EOFError` or :exc:`TypeError`) and returns
*NULL*.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *len*. This might require
- changes in your code for properly supporting 64-bit systems.
diff --git a/Doc/c-api/memoryview.rst b/Doc/c-api/memoryview.rst
new file mode 100644
index 0000000..6b49cdf
--- /dev/null
+++ b/Doc/c-api/memoryview.rst
@@ -0,0 +1,52 @@
+.. highlightlang:: c
+
+.. _memoryview-objects:
+
+.. index::
+ object: memoryview
+
+MemoryView objects
+------------------
+
+A :class:`memoryview` object exposes the C level :ref:`buffer interface
+<bufferobjects>` as a Python object which can then be passed around like
+any other object.
+
+
+.. c:function:: PyObject *PyMemoryView_FromObject(PyObject *obj)
+
+ Create a memoryview object from an object that provides the buffer interface.
+ If *obj* supports writable buffer exports, the memoryview object will be
+ readable and writable, otherwise it will be read-only.
+
+
+.. c:function:: PyObject *PyMemoryView_FromBuffer(Py_buffer *view)
+
+ Create a memoryview object wrapping the given buffer structure *view*.
+ The memoryview object then owns the buffer represented by *view*, which
+ means you shouldn't try to call :c:func:`PyBuffer_Release` yourself: it
+ will be done on deallocation of the memoryview object.
+
+
+.. c:function:: PyObject *PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order)
+
+ Create a memoryview object to a contiguous chunk of memory (in either
+ 'C' or 'F'ortran *order*) from an object that defines the buffer
+ interface. If memory is contiguous, the memoryview object points to the
+ original memory. Otherwise, a copy is made and the memoryview points to a
+ new bytes object.
+
+
+.. c:function:: int PyMemoryView_Check(PyObject *obj)
+
+ Return true if the object *obj* is a memoryview object. It is not
+ currently allowed to create subclasses of :class:`memoryview`.
+
+
+.. c:function:: Py_buffer *PyMemoryView_GET_BUFFER(PyObject *obj)
+
+ Return a pointer to the buffer structure wrapped by the given
+ memoryview object. The object **must** be a memoryview instance;
+ this macro doesn't check its type, you must do it yourself or you
+ will risk crashes.
+
diff --git a/Doc/c-api/method.rst b/Doc/c-api/method.rst
index 71ddeda..acc81e4 100644
--- a/Doc/c-api/method.rst
+++ b/Doc/c-api/method.rst
@@ -1,5 +1,46 @@
.. highlightlang:: c
+.. _instancemethod-objects:
+
+Instance Method Objects
+-----------------------
+
+.. index:: object: instancemethod
+
+An instance method is a wrapper for a :c:data:`PyCFunction` and the new way
+to bind a :c:data:`PyCFunction` to a class object. It replaces the former call
+``PyMethod_New(func, NULL, class)``.
+
+
+.. c:var:: PyTypeObject PyInstanceMethod_Type
+
+ This instance of :c:type:`PyTypeObject` represents the Python instance
+ method type. It is not exposed to Python programs.
+
+
+.. c:function:: int PyInstanceMethod_Check(PyObject *o)
+
+ Return true if *o* is an instance method object (has type
+ :c:data:`PyInstanceMethod_Type`). The parameter must not be *NULL*.
+
+
+.. c:function:: PyObject* PyInstanceMethod_New(PyObject *func)
+
+ Return a new instance method object, with *func* being any callable object
+ *func* is the function that will be called when the instance method is
+ called.
+
+
+.. c:function:: PyObject* PyInstanceMethod_Function(PyObject *im)
+
+ Return the function object associated with the instance method *im*.
+
+
+.. c:function:: PyObject* PyInstanceMethod_GET_FUNCTION(PyObject *im)
+
+ Macro version of :c:func:`PyInstanceMethod_Function` which avoids error checking.
+
+
.. _method-objects:
Method Objects
@@ -7,7 +48,9 @@ Method Objects
.. index:: object: method
-There are some useful functions that are useful for working with method objects.
+Methods are bound function objects. Methods are always bound to an instance of
+an user-defined class. Unbound methods (methods bound to a class object) are
+no longer available.
.. c:var:: PyTypeObject PyMethod_Type
@@ -24,24 +67,11 @@ There are some useful functions that are useful for working with method objects.
parameter must not be *NULL*.
-.. c:function:: PyObject* PyMethod_New(PyObject *func, PyObject *self, PyObject *class)
-
- Return a new method object, with *func* being any callable object; this is the
- function that will be called when the method is called. If this method should
- be bound to an instance, *self* should be the instance and *class* should be the
- class of *self*, otherwise *self* should be *NULL* and *class* should be the
- class which provides the unbound method..
-
-
-.. c:function:: PyObject* PyMethod_Class(PyObject *meth)
-
- Return the class object from which the method *meth* was created; if this was
- created from an instance, it will be the class of the instance.
-
-
-.. c:function:: PyObject* PyMethod_GET_CLASS(PyObject *meth)
+.. c:function:: PyObject* PyMethod_New(PyObject *func, PyObject *self)
- Macro version of :c:func:`PyMethod_Class` which avoids error checking.
+ Return a new method object, with *func* being any callable object and *self*
+ the instance the method should be bound. *func* is the function that will
+ be called when the method is called. *self* must not be *NULL*.
.. c:function:: PyObject* PyMethod_Function(PyObject *meth)
@@ -56,8 +86,7 @@ There are some useful functions that are useful for working with method objects.
.. c:function:: PyObject* PyMethod_Self(PyObject *meth)
- Return the instance associated with the method *meth* if it is bound, otherwise
- return *NULL*.
+ Return the instance associated with the method *meth*.
.. c:function:: PyObject* PyMethod_GET_SELF(PyObject *meth)
@@ -69,4 +98,3 @@ There are some useful functions that are useful for working with method objects.
Clear the free list. Return the total number of freed items.
- .. versionadded:: 2.6
diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst
index 56e63cf..ffd68e3 100644
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -22,17 +22,12 @@ There are only a few functions special to module objects.
Return true if *p* is a module object, or a subtype of a module object.
- .. versionchanged:: 2.2
- Allowed subtypes to be accepted.
-
.. c:function:: int PyModule_CheckExact(PyObject *p)
Return true if *p* is a module object, but not a subtype of
:c:data:`PyModule_Type`.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyModule_New(const char *name)
@@ -69,13 +64,121 @@ There are only a few functions special to module objects.
.. c:function:: char* PyModule_GetFilename(PyObject *module)
+ Similar to :c:func:`PyModule_GetFilenameObject` but return the filename
+ encoded to 'utf-8'.
+
+ .. deprecated:: 3.2
+ :c:func:`PyModule_GetFilename` raises :c:type:`UnicodeEncodeError` on
+ unencodable filenames, use :c:func:`PyModule_GetFilenameObject` instead.
+
+
+.. c:function:: PyObject* PyModule_GetFilenameObject(PyObject *module)
+
.. index::
single: __file__ (module attribute)
single: SystemError (built-in exception)
Return the name of the file from which *module* was loaded using *module*'s
- :attr:`__file__` attribute. If this is not defined, or if it is not a string,
- raise :exc:`SystemError` and return *NULL*.
+ :attr:`__file__` attribute. If this is not defined, or if it is not a
+ unicode string, raise :exc:`SystemError` and return *NULL*; otherwise return
+ a reference to a :c:type:`PyUnicodeObject`.
+
+ .. versionadded:: 3.2
+
+
+.. c:function:: void* PyModule_GetState(PyObject *module)
+
+ Return the "state" of the module, that is, a pointer to the block of memory
+ allocated at module creation time, or *NULL*. See
+ :c:member:`PyModuleDef.m_size`.
+
+
+.. c:function:: PyModuleDef* PyModule_GetDef(PyObject *module)
+
+ Return a pointer to the :c:type:`PyModuleDef` struct from which the module was
+ created, or *NULL* if the module wasn't created with
+ :c:func:`PyModule_Create`.
+
+
+Initializing C modules
+^^^^^^^^^^^^^^^^^^^^^^
+
+These functions are usually used in the module initialization function.
+
+.. c:function:: PyObject* PyModule_Create(PyModuleDef *module)
+
+ Create a new module object, given the definition in *module*. This behaves
+ like :c:func:`PyModule_Create2` with *module_api_version* set to
+ :const:`PYTHON_API_VERSION`.
+
+
+.. c:function:: PyObject* PyModule_Create2(PyModuleDef *module, int module_api_version)
+
+ Create a new module object, given the definition in *module*, assuming the
+ API version *module_api_version*. If that version does not match the version
+ of the running interpreter, a :exc:`RuntimeWarning` is emitted.
+
+ .. note::
+
+ Most uses of this function should be using :c:func:`PyModule_Create`
+ instead; only use this if you are sure you need it.
+
+
+.. c:type:: PyModuleDef
+
+ This struct holds all information that is needed to create a module object.
+ There is usually only one static variable of that type for each module, which
+ is statically initialized and then passed to :c:func:`PyModule_Create` in the
+ module initialization function.
+
+ .. c:member:: PyModuleDef_Base m_base
+
+ Always initialize this member to :const:`PyModuleDef_HEAD_INIT`.
+
+ .. c:member:: char* m_name
+
+ Name for the new module.
+
+ .. c:member:: char* m_doc
+
+ Docstring for the module; usually a docstring variable created with
+ :c:func:`PyDoc_STRVAR` is used.
+
+ .. c:member:: Py_ssize_t m_size
+
+ If the module object needs additional memory, this should be set to the
+ number of bytes to allocate; a pointer to the block of memory can be
+ retrieved with :c:func:`PyModule_GetState`. If no memory is needed, set
+ this to ``-1``.
+
+ This memory should be used, rather than static globals, to hold per-module
+ state, since it is then safe for use in multiple sub-interpreters. It is
+ freed when the module object is deallocated, after the :c:member:`m_free`
+ function has been called, if present.
+
+ .. c:member:: PyMethodDef* m_methods
+
+ A pointer to a table of module-level functions, described by
+ :c:type:`PyMethodDef` values. Can be *NULL* if no functions are present.
+
+ .. c:member:: inquiry m_reload
+
+ Currently unused, should be *NULL*.
+
+ .. c:member:: traverseproc m_traverse
+
+ A traversal function to call during GC traversal of the module object, or
+ *NULL* if not needed.
+
+ .. c:member:: inquiry m_clear
+
+ A clear function to call during GC clearing of the module object, or
+ *NULL* if not needed.
+
+ .. c:member:: freefunc m_free
+
+ A function to call during deallocation of the module object, or *NULL* if
+ not needed.
.. c:function:: int PyModule_AddObject(PyObject *module, const char *name, PyObject *value)
@@ -84,8 +187,6 @@ There are only a few functions special to module objects.
be used from the module's initialization function. This steals a reference to
*value*. Return ``-1`` on error, ``0`` on success.
- .. versionadded:: 2.0
-
.. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value)
@@ -93,8 +194,6 @@ There are only a few functions special to module objects.
used from the module's initialization function. Return ``-1`` on error, ``0`` on
success.
- .. versionadded:: 2.0
-
.. c:function:: int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value)
@@ -102,7 +201,6 @@ There are only a few functions special to module objects.
used from the module's initialization function. The string *value* must be
null-terminated. Return ``-1`` on error, ``0`` on success.
- .. versionadded:: 2.0
.. c:function:: int PyModule_AddIntMacro(PyObject *module, macro)
@@ -111,11 +209,7 @@ There are only a few functions special to module objects.
constant *AF_INET* with the value of *AF_INET* to *module*.
Return ``-1`` on error, ``0`` on success.
- .. versionadded:: 2.6
.. c:function:: int PyModule_AddStringMacro(PyObject *module, macro)
Add a string constant to *module*.
-
- .. versionadded:: 2.6
-
diff --git a/Doc/c-api/none.rst b/Doc/c-api/none.rst
index aeaca97..b9ac269 100644
--- a/Doc/c-api/none.rst
+++ b/Doc/c-api/none.rst
@@ -22,7 +22,5 @@ same reason.
.. c:macro:: Py_RETURN_NONE
- Properly handle returning :c:data:`Py_None` from within a C function.
-
- .. versionadded:: 2.4
-
+ Properly handle returning :c:data:`Py_None` from within a C function (that is,
+ increment the reference count of None and return it.)
diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst
index 75b7341..21951c3 100644
--- a/Doc/c-api/number.rst
+++ b/Doc/c-api/number.rst
@@ -30,19 +30,11 @@ Number Protocol
the equivalent of the Python expression ``o1 * o2``.
-.. c:function:: PyObject* PyNumber_Divide(PyObject *o1, PyObject *o2)
-
- Returns the result of dividing *o1* by *o2*, or *NULL* on failure. This is the
- equivalent of the Python expression ``o1 / o2``.
-
-
.. c:function:: PyObject* PyNumber_FloorDivide(PyObject *o1, PyObject *o2)
Return the floor of *o1* divided by *o2*, or *NULL* on failure. This is
equivalent to the "classic" division of integers.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyNumber_TrueDivide(PyObject *o1, PyObject *o2)
@@ -52,8 +44,6 @@ Number Protocol
numbers in base two. This function can return a floating point value when
passed two integers.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyNumber_Remainder(PyObject *o1, PyObject *o2)
@@ -156,21 +146,12 @@ Number Protocol
the Python statement ``o1 *= o2``.
-.. c:function:: PyObject* PyNumber_InPlaceDivide(PyObject *o1, PyObject *o2)
-
- Returns the result of dividing *o1* by *o2*, or *NULL* on failure. The
- operation is done *in-place* when *o1* supports it. This is the equivalent of
- the Python statement ``o1 /= o2``.
-
-
.. c:function:: PyObject* PyNumber_InPlaceFloorDivide(PyObject *o1, PyObject *o2)
Returns the mathematical floor of dividing *o1* by *o2*, or *NULL* on failure.
The operation is done *in-place* when *o1* supports it. This is the equivalent
of the Python statement ``o1 //= o2``.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyNumber_InPlaceTrueDivide(PyObject *o1, PyObject *o2)
@@ -180,8 +161,6 @@ Number Protocol
numbers in base two. This function can return a floating point value when
passed two integers. The operation is done *in-place* when *o1* supports it.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2)
@@ -236,42 +215,12 @@ Number Protocol
the Python statement ``o1 |= o2``.
-.. c:function:: int PyNumber_Coerce(PyObject **p1, PyObject **p2)
-
- .. index:: builtin: coerce
-
- This function takes the addresses of two variables of type :c:type:`PyObject\*`.
- If the objects pointed to by ``*p1`` and ``*p2`` have the same type, increment
- their reference count and return ``0`` (success). If the objects can be
- converted to a common numeric type, replace ``*p1`` and ``*p2`` by their
- converted value (with 'new' reference counts), and return ``0``. If no
- conversion is possible, or if some other error occurs, return ``-1`` (failure)
- and don't increment the reference counts. The call ``PyNumber_Coerce(&o1,
- &o2)`` is equivalent to the Python statement ``o1, o2 = coerce(o1, o2)``.
-
-
-.. c:function:: int PyNumber_CoerceEx(PyObject **p1, PyObject **p2)
-
- This function is similar to :c:func:`PyNumber_Coerce`, except that it returns
- ``1`` when the conversion is not possible and when no error is raised.
- Reference counts are still not increased in this case.
-
-
-.. c:function:: PyObject* PyNumber_Int(PyObject *o)
-
- .. index:: builtin: int
-
- Returns the *o* converted to an integer object on success, or *NULL* on failure.
- If the argument is outside the integer range a long object will be returned
- instead. This is the equivalent of the Python expression ``int(o)``.
-
-
.. c:function:: PyObject* PyNumber_Long(PyObject *o)
- .. index:: builtin: long
+ .. index:: builtin: int
- Returns the *o* converted to a long integer object on success, or *NULL* on
- failure. This is the equivalent of the Python expression ``long(o)``.
+ Returns the *o* converted to an integer object on success, or *NULL* on
+ failure. This is the equivalent of the Python expression ``int(o)``.
.. c:function:: PyObject* PyNumber_Float(PyObject *o)
@@ -284,39 +233,33 @@ Number Protocol
.. c:function:: PyObject* PyNumber_Index(PyObject *o)
- Returns the *o* converted to a Python int or long on success or *NULL* with a
+ Returns the *o* converted to a Python int on success or *NULL* with a
:exc:`TypeError` exception raised on failure.
- .. versionadded:: 2.5
-
.. c:function:: PyObject* PyNumber_ToBase(PyObject *n, int base)
- Returns the integer *n* converted to *base* as a string with a base
- marker of ``'0b'``, ``'0o'``, or ``'0x'`` if applicable. When
- *base* is not 2, 8, 10, or 16, the format is ``'x#num'`` where x is the
- base. If *n* is not an int object, it is converted with
+ Returns the integer *n* converted to base *base* as a string. The *base*
+ argument must be one of 2, 8, 10, or 16. For base 2, 8, or 16, the
+ returned string is prefixed with a base marker of ``'0b'``, ``'0o'``, or
+ ``'0x'``, respectively. If *n* is not a Python int, it is converted with
:c:func:`PyNumber_Index` first.
- .. versionadded:: 2.6
-
.. c:function:: Py_ssize_t PyNumber_AsSsize_t(PyObject *o, PyObject *exc)
Returns *o* converted to a Py_ssize_t value if *o* can be interpreted as an
- integer. If *o* can be converted to a Python int or long but the attempt to
+ integer. If the call fails, an exception is raised and -1 is returned.
+
+ If *o* can be converted to a Python int but the attempt to
convert to a Py_ssize_t value would raise an :exc:`OverflowError`, then the
*exc* argument is the type of exception that will be raised (usually
:exc:`IndexError` or :exc:`OverflowError`). If *exc* is *NULL*, then the
exception is cleared and the value is clipped to *PY_SSIZE_T_MIN* for a negative
integer or *PY_SSIZE_T_MAX* for a positive integer.
- .. versionadded:: 2.5
-
.. c:function:: int PyIndex_Check(PyObject *o)
Returns True if *o* is an index integer (has the nb_index slot of the
tp_as_number structure filled in).
-
- .. versionadded:: 2.5
diff --git a/Doc/c-api/objbuffer.rst b/Doc/c-api/objbuffer.rst
index c5228c6..e7f4fde 100644
--- a/Doc/c-api/objbuffer.rst
+++ b/Doc/c-api/objbuffer.rst
@@ -1,16 +1,21 @@
.. highlightlang:: c
-.. _abstract-buffer:
+Old Buffer Protocol
+-------------------
+.. deprecated:: 3.0
-Old Buffer Protocol
-===================
+These functions were part of the "old buffer protocol" API in Python 2.
+In Python 3, this protocol doesn't exist anymore but the functions are still
+exposed to ease porting 2.x code. They act as a compatibility wrapper
+around the :ref:`new buffer protocol <bufferobjects>`, but they don't give
+you control over the lifetime of the resources acquired when a buffer is
+exported.
-This section describes the legacy buffer protocol, which has been introduced
-in Python 1.6. It is still supported but deprecated in the Python 2.x series.
-Python 3 introduces a new buffer protocol which fixes weaknesses and
-shortcomings of the protocol, and has been backported to Python 2.6. See
-:ref:`bufferobjects` for more information.
+Therefore, it is recommended that you call :c:func:`PyObject_GetBuffer`
+(or the ``y*`` or ``w*`` :ref:`format codes <arg-parsing>` with the
+:c:func:`PyArg_ParseTuple` family of functions) to get a buffer view over
+an object, and :c:func:`PyBuffer_Release` when the buffer view can be released.
.. c:function:: int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len)
@@ -21,12 +26,6 @@ shortcomings of the protocol, and has been backported to Python 2.6. See
and *buffer_len* to the buffer length. Returns ``-1`` and sets a
:exc:`TypeError` on error.
- .. versionadded:: 1.6
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int *` type for *buffer_len*. This might
- require changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len)
@@ -36,31 +35,17 @@ shortcomings of the protocol, and has been backported to Python 2.6. See
and *buffer_len* to the buffer length. Returns ``-1`` and sets a
:exc:`TypeError` on error.
- .. versionadded:: 1.6
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int *` type for *buffer_len*. This might
- require changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PyObject_CheckReadBuffer(PyObject *o)
Returns ``1`` if *o* supports the single-segment readable buffer interface.
Otherwise returns ``0``.
- .. versionadded:: 2.2
-
.. c:function:: int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len)
- Returns a pointer to a writeable memory location. The *obj* argument must
+ Returns a pointer to a writable memory location. The *obj* argument must
support the single-segment, character buffer interface. On success,
returns ``0``, sets *buffer* to the memory location and *buffer_len* to the
buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error.
- .. versionadded:: 1.6
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int *` type for *buffer_len*. This might
- require changes in your code for properly supporting 64-bit systems.
-
diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst
index a02326f..d0d45ad 100644
--- a/Doc/c-api/object.rst
+++ b/Doc/c-api/object.rst
@@ -112,35 +112,24 @@ Object Protocol
If *o1* and *o2* are the same object, :c:func:`PyObject_RichCompareBool`
will always return ``1`` for :const:`Py_EQ` and ``0`` for :const:`Py_NE`.
-.. c:function:: int PyObject_Cmp(PyObject *o1, PyObject *o2, int *result)
-
- .. index:: builtin: cmp
-
- Compare the values of *o1* and *o2* using a routine provided by *o1*, if one
- exists, otherwise with a routine provided by *o2*. The result of the comparison
- is returned in *result*. Returns ``-1`` on failure. This is the equivalent of
- the Python statement ``result = cmp(o1, o2)``.
-
-
-.. c:function:: int PyObject_Compare(PyObject *o1, PyObject *o2)
-
- .. index:: builtin: cmp
-
- Compare the values of *o1* and *o2* using a routine provided by *o1*, if one
- exists, otherwise with a routine provided by *o2*. Returns the result of the
- comparison on success. On error, the value returned is undefined; use
- :c:func:`PyErr_Occurred` to detect an error. This is equivalent to the Python
- expression ``cmp(o1, o2)``.
-
-
.. c:function:: PyObject* PyObject_Repr(PyObject *o)
.. index:: builtin: repr
Compute a string representation of object *o*. Returns the string
representation on success, *NULL* on failure. This is the equivalent of the
- Python expression ``repr(o)``. Called by the :func:`repr` built-in function and
- by reverse quotes.
+ Python expression ``repr(o)``. Called by the :func:`repr` built-in function.
+
+
+.. c:function:: PyObject* PyObject_ASCII(PyObject *o)
+
+ .. index:: builtin: ascii
+
+ As :c:func:`PyObject_Repr`, compute a string representation of object *o*, but
+ escape the non-ASCII characters in the string returned by
+ :c:func:`PyObject_Repr` with ``\x``, ``\u`` or ``\U`` escapes. This generates
+ a string similar to that returned by :c:func:`PyObject_Repr` in Python 2.
+ Called by the :func:`ascii` built-in function.
.. c:function:: PyObject* PyObject_Str(PyObject *o)
@@ -149,27 +138,18 @@ Object Protocol
Compute a string representation of object *o*. Returns the string
representation on success, *NULL* on failure. This is the equivalent of the
- Python expression ``str(o)``. Called by the :func:`str` built-in function and
- by the :keyword:`print` statement.
-
+ Python expression ``str(o)``. Called by the :func:`str` built-in function
+ and, therefore, by the :func:`print` function.
.. c:function:: PyObject* PyObject_Bytes(PyObject *o)
.. index:: builtin: bytes
- Compute a bytes representation of object *o*. In 2.x, this is just a alias
- for :c:func:`PyObject_Str`.
-
-
-.. c:function:: PyObject* PyObject_Unicode(PyObject *o)
-
- .. index:: builtin: unicode
-
- Compute a Unicode string representation of object *o*. Returns the Unicode
- string representation on success, *NULL* on failure. This is the equivalent of
- the Python expression ``unicode(o)``. Called by the :func:`unicode` built-in
- function.
-
+ Compute a bytes representation of object *o*. *NULL* is returned on
+ failure and a bytes object on success. This is equivalent to the Python
+ expression ``bytes(o)``, when *o* is not an integer. Unlike ``bytes(o)``,
+ a TypeError is raised when *o* is an integer instead of a zero-initialized
+ bytes object.
.. c:function:: int PyObject_IsInstance(PyObject *inst, PyObject *cls)
@@ -184,10 +164,6 @@ Object Protocol
of the value of that attribute with *cls* will be used to determine the result
of this function.
- .. versionadded:: 2.1
-
- .. versionchanged:: 2.2
- Support for a tuple as the second argument added.
Subclass determination is done in a fairly straightforward way, but includes a
wrinkle that implementors of extensions to the class system may want to be aware
@@ -210,11 +186,6 @@ is considered sufficient for this determination.
``0``. If either *derived* or *cls* is not an actual class object (or tuple),
this function uses the generic algorithm described above.
- .. versionadded:: 2.1
-
- .. versionchanged:: 2.3
- Older versions of Python did not support a tuple as the second argument.
-
.. c:function:: int PyCallable_Check(PyObject *o)
@@ -224,40 +195,31 @@ is considered sufficient for this determination.
.. c:function:: PyObject* PyObject_Call(PyObject *callable_object, PyObject *args, PyObject *kw)
- .. index:: builtin: apply
-
Call a callable Python object *callable_object*, with arguments given by the
tuple *args*, and named arguments given by the dictionary *kw*. If no named
arguments are needed, *kw* may be *NULL*. *args* must not be *NULL*, use an
empty tuple if no arguments are needed. Returns the result of the call on
success, or *NULL* on failure. This is the equivalent of the Python expression
- ``apply(callable_object, args, kw)`` or ``callable_object(*args, **kw)``.
-
- .. versionadded:: 2.2
+ ``callable_object(*args, **kw)``.
.. c:function:: PyObject* PyObject_CallObject(PyObject *callable_object, PyObject *args)
- .. index:: builtin: apply
-
Call a callable Python object *callable_object*, with arguments given by the
tuple *args*. If no arguments are needed, then *args* may be *NULL*. Returns
the result of the call on success, or *NULL* on failure. This is the equivalent
- of the Python expression ``apply(callable_object, args)`` or
- ``callable_object(*args)``.
+ of the Python expression ``callable_object(*args)``.
.. c:function:: PyObject* PyObject_CallFunction(PyObject *callable, char *format, ...)
- .. index:: builtin: apply
-
Call a callable Python object *callable*, with a variable number of C arguments.
The C arguments are described using a :c:func:`Py_BuildValue` style format
string. The format may be *NULL*, indicating that no arguments are provided.
Returns the result of the call on success, or *NULL* on failure. This is the
- equivalent of the Python expression ``apply(callable, args)`` or
- ``callable(*args)``. Note that if you only pass :c:type:`PyObject \*` args,
- :c:func:`PyObject_CallFunctionObjArgs` is a faster alternative.
+ equivalent of the Python expression ``callable(*args)``. Note that if you only
+ pass :c:type:`PyObject \*` args, :c:func:`PyObject_CallFunctionObjArgs` is a
+ faster alternative.
.. c:function:: PyObject* PyObject_CallMethod(PyObject *o, char *method, char *format, ...)
@@ -278,8 +240,6 @@ is considered sufficient for this determination.
of parameters followed by *NULL*. Returns the result of the call on success, or
*NULL* on failure.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyObject_CallMethodObjArgs(PyObject *o, PyObject *name, ..., NULL)
@@ -289,26 +249,26 @@ is considered sufficient for this determination.
of parameters followed by *NULL*. Returns the result of the call on success, or
*NULL* on failure.
- .. versionadded:: 2.2
-
-.. c:function:: long PyObject_Hash(PyObject *o)
+.. c:function:: Py_hash_t PyObject_Hash(PyObject *o)
.. index:: builtin: hash
Compute and return the hash value of an object *o*. On failure, return ``-1``.
This is the equivalent of the Python expression ``hash(o)``.
+ .. versionchanged:: 3.2
+ The return type is now Py_hash_t. This is a signed integer the same size
+ as Py_ssize_t.
+
-.. c:function:: long PyObject_HashNotImplemented(PyObject *o)
+.. c:function:: Py_hash_t PyObject_HashNotImplemented(PyObject *o)
Set a :exc:`TypeError` indicating that ``type(o)`` is not hashable and return ``-1``.
This function receives special treatment when stored in a ``tp_hash`` slot,
allowing a type to explicitly indicate to the interpreter that it is not
hashable.
- .. versionadded:: 2.6
-
.. c:function:: int PyObject_IsTrue(PyObject *o)
@@ -342,8 +302,6 @@ is considered sufficient for this determination.
Return true if the object *o* is of type *type* or a subtype of *type*. Both
parameters must be non-*NULL*.
- .. versionadded:: 2.2
-
.. c:function:: Py_ssize_t PyObject_Length(PyObject *o)
Py_ssize_t PyObject_Size(PyObject *o)
@@ -354,10 +312,6 @@ is considered sufficient for this determination.
and mapping protocols, the sequence length is returned. On error, ``-1`` is
returned. This is the equivalent to the Python expression ``len(o)``.
- .. versionchanged:: 2.5
- These functions returned an :c:type:`int` type. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key)
@@ -377,14 +331,6 @@ is considered sufficient for this determination.
equivalent of the Python statement ``del o[key]``.
-.. c:function:: int PyObject_AsFileDescriptor(PyObject *o)
-
- Derives a file descriptor from a Python object. If the object is an integer or
- long integer, its value is returned. If not, the object's :meth:`fileno` method
- is called if it exists; the method must return an integer or long integer, which
- is returned as the file descriptor value. Returns ``-1`` on failure.
-
-
.. c:function:: PyObject* PyObject_Dir(PyObject *o)
This is equivalent to the Python expression ``dir(o)``, returning a (possibly
diff --git a/Doc/c-api/objimpl.rst b/Doc/c-api/objimpl.rst
index b335188..7023e51 100644
--- a/Doc/c-api/objimpl.rst
+++ b/Doc/c-api/objimpl.rst
@@ -1,6 +1,5 @@
.. highlightlang:: c
-
.. _newtypes:
*****************************
diff --git a/Doc/c-api/refcounting.rst b/Doc/c-api/refcounting.rst
index 49675a8..4f512ec 100644
--- a/Doc/c-api/refcounting.rst
+++ b/Doc/c-api/refcounting.rst
@@ -61,7 +61,6 @@ objects.
It is a good idea to use this macro whenever decrementing the value of a
variable that might be traversed during garbage collection.
- .. versionadded:: 2.4
The following functions are for runtime dynamic embedding of Python:
``Py_IncRef(PyObject *o)``, ``Py_DecRef(PyObject *o)``. They are
diff --git a/Doc/c-api/reflection.rst b/Doc/c-api/reflection.rst
index 59edbb3..9689365 100644
--- a/Doc/c-api/reflection.rst
+++ b/Doc/c-api/reflection.rst
@@ -34,12 +34,6 @@ Reflection
Return the line number that *frame* is currently executing.
-.. c:function:: int PyEval_GetRestricted()
-
- If there is a current frame and it is executing in restricted mode, return true,
- otherwise false.
-
-
.. c:function:: const char* PyEval_GetFuncName(PyObject *func)
Return the name of *func* if it is a function, class or instance object, else the
diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst
index 2b668a5..0297ba3 100644
--- a/Doc/c-api/sequence.rst
+++ b/Doc/c-api/sequence.rst
@@ -21,10 +21,6 @@ Sequence Protocol
For objects that do not provide sequence protocol, this is equivalent to the
Python expression ``len(o)``.
- .. versionchanged:: 2.5
- These functions returned an :c:type:`int` type. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PySequence_Concat(PyObject *o1, PyObject *o2)
@@ -37,10 +33,6 @@ Sequence Protocol
Return the result of repeating sequence object *o* *count* times, or *NULL* on
failure. This is the equivalent of the Python expression ``o * count``.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *count*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PySequence_InPlaceConcat(PyObject *o1, PyObject *o2)
@@ -55,30 +47,18 @@ Sequence Protocol
failure. The operation is done *in-place* when *o* supports it. This is the
equivalent of the Python expression ``o *= count``.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *count*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PySequence_GetItem(PyObject *o, Py_ssize_t i)
Return the *i*\ th element of *o*, or *NULL* on failure. This is the equivalent of
the Python expression ``o[i]``.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *i*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2)
Return the slice of sequence object *o* between *i1* and *i2*, or *NULL* on
failure. This is the equivalent of the Python expression ``o[i1:i2]``.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *i1* and *i2*. This might
- require changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v)
@@ -86,40 +66,24 @@ Sequence Protocol
is the equivalent of the Python statement ``o[i] = v``. This function *does
not* steal a reference to *v*.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *i*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PySequence_DelItem(PyObject *o, Py_ssize_t i)
Delete the *i*\ th element of object *o*. Returns ``-1`` on failure. This is the
equivalent of the Python statement ``del o[i]``.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *i*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, PyObject *v)
Assign the sequence object *v* to the slice in sequence object *o* from *i1* to
*i2*. This is the equivalent of the Python statement ``o[i1:i2] = v``.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *i1* and *i2*. This might
- require changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2)
Delete the slice in sequence object *o* from *i1* to *i2*. Returns ``-1`` on
failure. This is the equivalent of the Python statement ``del o[i1:i2]``.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *i1* and *i2*. This might
- require changes in your code for properly supporting 64-bit systems.
-
.. c:function:: Py_ssize_t PySequence_Count(PyObject *o, PyObject *value)
@@ -127,10 +91,6 @@ Sequence Protocol
of keys for which ``o[key] == value``. On failure, return ``-1``. This is
equivalent to the Python expression ``o.count(value)``.
- .. versionchanged:: 2.5
- This function returned an :c:type:`int` type. This might require changes
- in your code for properly supporting 64-bit systems.
-
.. c:function:: int PySequence_Contains(PyObject *o, PyObject *value)
@@ -144,10 +104,6 @@ Sequence Protocol
Return the first index *i* for which ``o[i] == value``. On error, return
``-1``. This is equivalent to the Python expression ``o.index(value)``.
- .. versionchanged:: 2.5
- This function returned an :c:type:`int` type. This might require changes
- in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PySequence_List(PyObject *o)
@@ -178,10 +134,6 @@ Sequence Protocol
Return the *i*\ th element of *o*, assuming that *o* was returned by
:c:func:`PySequence_Fast`, *o* is not *NULL*, and that *i* is within bounds.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *i*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject** PySequence_Fast_ITEMS(PyObject *o)
@@ -192,8 +144,6 @@ Sequence Protocol
So, only use the underlying array pointer in contexts where the sequence
cannot change.
- .. versionadded:: 2.4
-
.. c:function:: PyObject* PySequence_ITEM(PyObject *o, Py_ssize_t i)
@@ -202,12 +152,6 @@ Sequence Protocol
:c:func:`PySequence_Check` on *o* is true and without adjustment for negative
indices.
- .. versionadded:: 2.3
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *i*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o)
diff --git a/Doc/c-api/set.rst b/Doc/c-api/set.rst
index 41c4af4..66b47c4 100644
--- a/Doc/c-api/set.rst
+++ b/Doc/c-api/set.rst
@@ -12,8 +12,6 @@ Set Objects
object: set
object: frozenset
-.. versionadded:: 2.5
-
This section details the public API for :class:`set` and :class:`frozenset`
objects. Any functionality not listed below is best accessed using the either
the abstract object protocol (including :c:func:`PyObject_CallMethod`,
@@ -56,15 +54,11 @@ the constructor functions work with any iterable Python object.
Return true if *p* is a :class:`set` object or an instance of a subtype.
- .. versionadded:: 2.6
-
.. c:function:: int PyFrozenSet_Check(PyObject *p)
Return true if *p* is a :class:`frozenset` object or an instance of a
subtype.
- .. versionadded:: 2.6
-
.. c:function:: int PyAnySet_Check(PyObject *p)
Return true if *p* is a :class:`set` object, a :class:`frozenset` object, or an
@@ -99,10 +93,6 @@ the constructor functions work with any iterable Python object.
set on success or *NULL* on failure. Raise :exc:`TypeError` if *iterable* is
not actually iterable.
- .. versionchanged:: 2.6
- Now guaranteed to return a brand-new :class:`frozenset`. Formerly,
- frozensets of zero-length were a singleton. This got in the way of
- building-up new frozensets with :meth:`PySet_Add`.
The following functions and macros are available for instances of :class:`set`
or :class:`frozenset` or instances of their subtypes.
@@ -116,10 +106,6 @@ or :class:`frozenset` or instances of their subtypes.
``len(anyset)``. Raises a :exc:`PyExc_SystemError` if *anyset* is not a
:class:`set`, :class:`frozenset`, or an instance of a subtype.
- .. versionchanged:: 2.5
- This function returned an :c:type:`int`. This might require changes in
- your code for properly supporting 64-bit systems.
-
.. c:function:: Py_ssize_t PySet_GET_SIZE(PyObject *anyset)
@@ -137,16 +123,14 @@ or :class:`frozenset` or instances of their subtypes.
.. c:function:: int PySet_Add(PyObject *set, PyObject *key)
- Add *key* to a :class:`set` instance. Does not apply to :class:`frozenset`
- instances. Return 0 on success or -1 on failure. Raise a :exc:`TypeError` if
- the *key* is unhashable. Raise a :exc:`MemoryError` if there is no room to grow.
- Raise a :exc:`SystemError` if *set* is an not an instance of :class:`set` or its
+ Add *key* to a :class:`set` instance. Also works with :class:`frozenset`
+ instances (like :c:func:`PyTuple_SetItem` it can be used to fill-in the values
+ of brand new frozensets before they are exposed to other code). Return 0 on
+ success or -1 on failure. Raise a :exc:`TypeError` if the *key* is
+ unhashable. Raise a :exc:`MemoryError` if there is no room to grow. Raise a
+ :exc:`SystemError` if *set* is an not an instance of :class:`set` or its
subtype.
- .. versionchanged:: 2.6
- Now works with instances of :class:`frozenset` or its subtypes.
- Like :c:func:`PyTuple_SetItem` in that it can be used to fill-in the
- values of brand new frozensets before they are exposed to other code.
The following functions are available for instances of :class:`set` or its
subtypes but not for instances of :class:`frozenset` or its subtypes.
diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst
index f74230a..e157df2 100644
--- a/Doc/c-api/slice.rst
+++ b/Doc/c-api/slice.rst
@@ -8,10 +8,8 @@ Slice Objects
.. c:var:: PyTypeObject PySlice_Type
- .. index:: single: SliceType (in module types)
-
- The type object for slice objects. This is the same as ``slice`` and
- ``types.SliceType``.
+ The type object for slice objects. This is the same as :class:`slice` in the
+ Python layer.
.. c:function:: int PySlice_Check(PyObject *ob)
@@ -28,7 +26,7 @@ Slice Objects
the new object could not be allocated.
-.. c:function:: int PySlice_GetIndices(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)
+.. c:function:: int PySlice_GetIndices(PyObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)
Retrieve the start, stop and step indices from the slice object *slice*,
assuming a sequence of length *length*. Treats indices greater than
@@ -38,18 +36,14 @@ Slice Objects
the indices was not :const:`None` and failed to be converted to an integer,
in which case -1 is returned with an exception set).
- You probably do not want to use this function. If you want to use slice
- objects in versions of Python prior to 2.3, you would probably do well to
- incorporate the source of :c:func:`PySlice_GetIndicesEx`, suitably renamed,
- in the source of your extension.
+ You probably do not want to use this function.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *length* and an
- :c:type:`int *` type for *start*, *stop*, and *step*. This might require
- changes in your code for properly supporting 64-bit systems.
+ .. versionchanged:: 3.2
+ The parameter type for the *slice* parameter was ``PySliceObject*``
+ before.
-.. c:function:: int PySlice_GetIndicesEx(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength)
+.. c:function:: int PySlice_GetIndicesEx(PyObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength)
Usable replacement for :c:func:`PySlice_GetIndices`. Retrieve the start,
stop, and step indices from the slice object *slice* assuming a sequence of
@@ -59,10 +53,6 @@ Slice Objects
Returns 0 on success and -1 on error with exception set.
- .. versionadded:: 2.3
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *length* and an
- :c:type:`int *` type for *start*, *stop*, *step*, and *slicelength*. This
- might require changes in your code for properly supporting 64-bit
- systems.
+ .. versionchanged:: 3.2
+ The parameter type for the *slice* parameter was ``PySliceObject*``
+ before.
diff --git a/Doc/c-api/string.rst b/Doc/c-api/string.rst
deleted file mode 100644
index ecf7050..0000000
--- a/Doc/c-api/string.rst
+++ /dev/null
@@ -1,333 +0,0 @@
-.. highlightlang:: c
-
-.. _stringobjects:
-
-String/Bytes Objects
---------------------
-
-These functions raise :exc:`TypeError` when expecting a string parameter and are
-called with a non-string parameter.
-
-.. note::
-
- These functions have been renamed to PyBytes_* in Python 3.x. Unless
- otherwise noted, the PyBytes functions available in 3.x are aliased to their
- PyString_* equivalents to help porting.
-
-.. index:: object: string
-
-
-.. c:type:: PyStringObject
-
- This subtype of :c:type:`PyObject` represents a Python string object.
-
-
-.. c:var:: PyTypeObject PyString_Type
-
- .. index:: single: StringType (in module types)
-
- This instance of :c:type:`PyTypeObject` represents the Python string type; it is
- the same object as ``str`` and ``types.StringType`` in the Python layer. .
-
-
-.. c:function:: int PyString_Check(PyObject *o)
-
- Return true if the object *o* is a string object or an instance of a subtype of
- the string type.
-
- .. versionchanged:: 2.2
- Allowed subtypes to be accepted.
-
-
-.. c:function:: int PyString_CheckExact(PyObject *o)
-
- Return true if the object *o* is a string object, but not an instance of a
- subtype of the string type.
-
- .. versionadded:: 2.2
-
-
-.. c:function:: PyObject* PyString_FromString(const char *v)
-
- Return a new string object with a copy of the string *v* as value on success,
- and *NULL* on failure. The parameter *v* must not be *NULL*; it will not be
- checked.
-
-
-.. c:function:: PyObject* PyString_FromStringAndSize(const char *v, Py_ssize_t len)
-
- Return a new string object with a copy of the string *v* as value and length
- *len* on success, and *NULL* on failure. If *v* is *NULL*, the contents of the
- string are uninitialized.
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *len*. This might require
- changes in your code for properly supporting 64-bit systems.
-
-
-.. c:function:: PyObject* PyString_FromFormat(const char *format, ...)
-
- Take a C :c:func:`printf`\ -style *format* string and a variable number of
- arguments, calculate the size of the resulting Python string and return a string
- with the values formatted into it. The variable arguments must be C types and
- must correspond exactly to the format characters in the *format* string. The
- following format characters are allowed:
-
- .. % This should be exactly the same as the table in PyErr_Format.
- .. % One should just refer to the other.
- .. % The descriptions for %zd and %zu are wrong, but the truth is complicated
- .. % because not all compilers support the %z width modifier -- we fake it
- .. % when necessary via interpolating PY_FORMAT_SIZE_T.
- .. % Similar comments apply to the %ll width modifier and
- .. % PY_FORMAT_LONG_LONG.
- .. % %u, %lu, %zu should have "new in Python 2.5" blurbs.
-
- +-------------------+---------------+--------------------------------+
- | Format Characters | Type | Comment |
- +===================+===============+================================+
- | :attr:`%%` | *n/a* | The literal % character. |
- +-------------------+---------------+--------------------------------+
- | :attr:`%c` | int | A single character, |
- | | | represented as an C int. |
- +-------------------+---------------+--------------------------------+
- | :attr:`%d` | int | Exactly equivalent to |
- | | | ``printf("%d")``. |
- +-------------------+---------------+--------------------------------+
- | :attr:`%u` | unsigned int | Exactly equivalent to |
- | | | ``printf("%u")``. |
- +-------------------+---------------+--------------------------------+
- | :attr:`%ld` | long | Exactly equivalent to |
- | | | ``printf("%ld")``. |
- +-------------------+---------------+--------------------------------+
- | :attr:`%lu` | unsigned long | Exactly equivalent to |
- | | | ``printf("%lu")``. |
- +-------------------+---------------+--------------------------------+
- | :attr:`%lld` | long long | Exactly equivalent to |
- | | | ``printf("%lld")``. |
- +-------------------+---------------+--------------------------------+
- | :attr:`%llu` | unsigned | Exactly equivalent to |
- | | long long | ``printf("%llu")``. |
- +-------------------+---------------+--------------------------------+
- | :attr:`%zd` | Py_ssize_t | Exactly equivalent to |
- | | | ``printf("%zd")``. |
- +-------------------+---------------+--------------------------------+
- | :attr:`%zu` | size_t | Exactly equivalent to |
- | | | ``printf("%zu")``. |
- +-------------------+---------------+--------------------------------+
- | :attr:`%i` | int | Exactly equivalent to |
- | | | ``printf("%i")``. |
- +-------------------+---------------+--------------------------------+
- | :attr:`%x` | int | Exactly equivalent to |
- | | | ``printf("%x")``. |
- +-------------------+---------------+--------------------------------+
- | :attr:`%s` | char\* | A null-terminated C character |
- | | | array. |
- +-------------------+---------------+--------------------------------+
- | :attr:`%p` | void\* | The hex representation of a C |
- | | | pointer. Mostly equivalent to |
- | | | ``printf("%p")`` except that |
- | | | it is guaranteed to start with |
- | | | the literal ``0x`` regardless |
- | | | of what the platform's |
- | | | ``printf`` yields. |
- +-------------------+---------------+--------------------------------+
-
- An unrecognized format character causes all the rest of the format string to be
- copied as-is to the result string, and any extra arguments discarded.
-
- .. note::
-
- The `"%lld"` and `"%llu"` format specifiers are only available
- when :const:`HAVE_LONG_LONG` is defined.
-
- .. versionchanged:: 2.7
- Support for `"%lld"` and `"%llu"` added.
-
-
-.. c:function:: PyObject* PyString_FromFormatV(const char *format, va_list vargs)
-
- Identical to :c:func:`PyString_FromFormat` except that it takes exactly two
- arguments.
-
-
-.. c:function:: Py_ssize_t PyString_Size(PyObject *string)
-
- Return the length of the string in string object *string*.
-
- .. versionchanged:: 2.5
- This function returned an :c:type:`int` type. This might require changes
- in your code for properly supporting 64-bit systems.
-
-
-.. c:function:: Py_ssize_t PyString_GET_SIZE(PyObject *string)
-
- Macro form of :c:func:`PyString_Size` but without error checking.
-
- .. versionchanged:: 2.5
- This macro returned an :c:type:`int` type. This might require changes in
- your code for properly supporting 64-bit systems.
-
-
-.. c:function:: char* PyString_AsString(PyObject *string)
-
- Return a NUL-terminated representation of the contents of *string*. The pointer
- refers to the internal buffer of *string*, not a copy. The data must not be
- modified in any way, unless the string was just created using
- ``PyString_FromStringAndSize(NULL, size)``. It must not be deallocated. If
- *string* is a Unicode object, this function computes the default encoding of
- *string* and operates on that. If *string* is not a string object at all,
- :c:func:`PyString_AsString` returns *NULL* and raises :exc:`TypeError`.
-
-
-.. c:function:: char* PyString_AS_STRING(PyObject *string)
-
- Macro form of :c:func:`PyString_AsString` but without error checking. Only
- string objects are supported; no Unicode objects should be passed.
-
-
-.. c:function:: int PyString_AsStringAndSize(PyObject *obj, char **buffer, Py_ssize_t *length)
-
- Return a NUL-terminated representation of the contents of the object *obj*
- through the output variables *buffer* and *length*.
-
- The function accepts both string and Unicode objects as input. For Unicode
- objects it returns the default encoded version of the object. If *length* is
- *NULL*, the resulting buffer may not contain NUL characters; if it does, the
- function returns ``-1`` and a :exc:`TypeError` is raised.
-
- The buffer refers to an internal string buffer of *obj*, not a copy. The data
- must not be modified in any way, unless the string was just created using
- ``PyString_FromStringAndSize(NULL, size)``. It must not be deallocated. If
- *string* is a Unicode object, this function computes the default encoding of
- *string* and operates on that. If *string* is not a string object at all,
- :c:func:`PyString_AsStringAndSize` returns ``-1`` and raises :exc:`TypeError`.
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int *` type for *length*. This might
- require changes in your code for properly supporting 64-bit systems.
-
-
-.. c:function:: void PyString_Concat(PyObject **string, PyObject *newpart)
-
- Create a new string object in *\*string* containing the contents of *newpart*
- appended to *string*; the caller will own the new reference. The reference to
- the old value of *string* will be stolen. If the new string cannot be created,
- the old reference to *string* will still be discarded and the value of
- *\*string* will be set to *NULL*; the appropriate exception will be set.
-
-
-.. c:function:: void PyString_ConcatAndDel(PyObject **string, PyObject *newpart)
-
- Create a new string object in *\*string* containing the contents of *newpart*
- appended to *string*. This version decrements the reference count of *newpart*.
-
-
-.. c:function:: int _PyString_Resize(PyObject **string, Py_ssize_t newsize)
-
- A way to resize a string object even though it is "immutable". Only use this to
- build up a brand new string object; don't use this if the string may already be
- known in other parts of the code. It is an error to call this function if the
- refcount on the input string object is not one. Pass the address of an existing
- string object as an lvalue (it may be written into), and the new size desired.
- On success, *\*string* holds the resized string object and ``0`` is returned;
- the address in *\*string* may differ from its input value. If the reallocation
- fails, the original string object at *\*string* is deallocated, *\*string* is
- set to *NULL*, a memory exception is set, and ``-1`` is returned.
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *newsize*. This might
- require changes in your code for properly supporting 64-bit systems.
-
-.. c:function:: PyObject* PyString_Format(PyObject *format, PyObject *args)
-
- Return a new string object from *format* and *args*. Analogous to ``format %
- args``. The *args* argument must be a tuple.
-
-
-.. c:function:: void PyString_InternInPlace(PyObject **string)
-
- Intern the argument *\*string* in place. The argument must be the address of a
- pointer variable pointing to a Python string object. If there is an existing
- interned string that is the same as *\*string*, it sets *\*string* to it
- (decrementing the reference count of the old string object and incrementing the
- reference count of the interned string object), otherwise it leaves *\*string*
- alone and interns it (incrementing its reference count). (Clarification: even
- though there is a lot of talk about reference counts, think of this function as
- reference-count-neutral; you own the object after the call if and only if you
- owned it before the call.)
-
- .. note::
-
- This function is not available in 3.x and does not have a PyBytes alias.
-
-
-.. c:function:: PyObject* PyString_InternFromString(const char *v)
-
- A combination of :c:func:`PyString_FromString` and
- :c:func:`PyString_InternInPlace`, returning either a new string object that has
- been interned, or a new ("owned") reference to an earlier interned string object
- with the same value.
-
- .. note::
-
- This function is not available in 3.x and does not have a PyBytes alias.
-
-
-.. c:function:: PyObject* PyString_Decode(const char *s, Py_ssize_t size, const char *encoding, const char *errors)
-
- Create an object by decoding *size* bytes of the encoded buffer *s* using the
- codec registered for *encoding*. *encoding* and *errors* have the same meaning
- as the parameters of the same name in the :func:`unicode` built-in function.
- The codec to be used is looked up using the Python codec registry. Return
- *NULL* if an exception was raised by the codec.
-
- .. note::
-
- This function is not available in 3.x and does not have a PyBytes alias.
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
-
-.. c:function:: PyObject* PyString_AsDecodedObject(PyObject *str, const char *encoding, const char *errors)
-
- Decode a string object by passing it to the codec registered for *encoding* and
- return the result as Python object. *encoding* and *errors* have the same
- meaning as the parameters of the same name in the string :meth:`encode` method.
- The codec to be used is looked up using the Python codec registry. Return *NULL*
- if an exception was raised by the codec.
-
- .. note::
-
- This function is not available in 3.x and does not have a PyBytes alias.
-
-
-.. c:function:: PyObject* PyString_Encode(const char *s, Py_ssize_t size, const char *encoding, const char *errors)
-
- Encode the :c:type:`char` buffer of the given size by passing it to the codec
- registered for *encoding* and return a Python object. *encoding* and *errors*
- have the same meaning as the parameters of the same name in the string
- :meth:`encode` method. The codec to be used is looked up using the Python codec
- registry. Return *NULL* if an exception was raised by the codec.
-
- .. note::
-
- This function is not available in 3.x and does not have a PyBytes alias.
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
-
-.. c:function:: PyObject* PyString_AsEncodedObject(PyObject *str, const char *encoding, const char *errors)
-
- Encode a string object using the codec registered for *encoding* and return the
- result as Python object. *encoding* and *errors* have the same meaning as the
- parameters of the same name in the string :meth:`encode` method. The codec to be
- used is looked up using the Python codec registry. Return *NULL* if an exception
- was raised by the codec.
-
- .. note::
-
- This function is not available in 3.x and does not have a PyBytes alias.
diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst
index f5007ac..bb741fb 100644
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -36,6 +36,7 @@ the definition of all other Python objects.
These macros are used in the definition of :c:type:`PyObject` and
:c:type:`PyVarObject`:
+.. XXX need to document PEP 3123 changes here
.. c:macro:: PyObject_HEAD
@@ -98,6 +99,14 @@ These macros are used in the definition of :c:type:`PyObject` and
reference.
+.. c:type:: PyCFunctionWithKeywords
+
+ Type of the functions used to implement Python callables in C that take
+ keyword arguments: they take three :c:type:`PyObject\*` parameters and return
+ one such value. See :c:type:`PyCFunction` above for the meaning of the return
+ value.
+
+
.. c:type:: PyMethodDef
Structure used to describe a method of an extension type. This structure has
@@ -139,7 +148,7 @@ convention flags can be combined with a binding flag.
:c:type:`PyCFunction`. The function expects two :c:type:`PyObject\*` values.
The first one is the *self* object for methods; for module functions, it is
the module object. The second parameter (often called *args*) is a tuple
- object representing all arguments. This parameter is typically processed
+ object representing all arguments. This parameter is typically processed
using :c:func:`PyArg_ParseTuple` or :c:func:`PyArg_UnpackTuple`.
@@ -156,9 +165,9 @@ convention flags can be combined with a binding flag.
Methods without parameters don't need to check whether arguments are given if
they are listed with the :const:`METH_NOARGS` flag. They need to be of type
- :c:type:`PyCFunction`. The first parameter is typically named ``self`` and
- will hold a reference to the module or object instance. In all cases the
- second parameter will be *NULL*.
+ :c:type:`PyCFunction`. The first parameter is typically named *self* and will
+ hold a reference to the module or object instance. In all cases the second
+ parameter will be *NULL*.
.. data:: METH_O
@@ -169,15 +178,6 @@ convention flags can be combined with a binding flag.
:c:type:`PyObject\*` parameter representing the single argument.
-.. data:: METH_OLDARGS
-
- This calling convention is deprecated. The method must be of type
- :c:type:`PyCFunction`. The second argument is *NULL* if no arguments are
- given, a single object if exactly one argument is given, and a tuple of
- objects if more than one argument is given. There is no way for a function
- using this convention to distinguish between a call with multiple arguments
- and a call with a tuple as the only argument.
-
These two constants are not used to indicate the calling convention but the
binding when use with methods of classes. These may not be used for functions
defined for modules. At most one of these flags may be set for any given
@@ -193,8 +193,6 @@ method.
similar to what is created when using the :func:`classmethod` built-in
function.
- .. versionadded:: 2.3
-
.. data:: METH_STATIC
@@ -204,8 +202,6 @@ method.
instance of the type. This is used to create *static methods*, similar to
what is created when using the :func:`staticmethod` built-in function.
- .. versionadded:: 2.3
-
One other constant controls whether a method is loaded in place of another
definition with the same method name.
@@ -222,8 +218,6 @@ definition with the same method name.
slot. This is helpful because calls to PyCFunctions are optimized more
than wrapper object calls.
- .. versionadded:: 2.4
-
.. c:type:: PyMemberDef
@@ -288,11 +282,3 @@ definition with the same method name.
read-only access. Using :c:macro:`T_STRING` for :attr:`type` implies
:c:macro:`READONLY`. Only :c:macro:`T_OBJECT` and :c:macro:`T_OBJECT_EX`
members can be deleted. (They are set to *NULL*).
-
-
-.. c:function:: PyObject* Py_FindMethod(PyMethodDef table[], PyObject *ob, char *name)
-
- Return a bound method object for an extension type implemented in C. This
- can be useful in the implementation of a :attr:`tp_getattro` or
- :attr:`tp_getattr` handler that does not use the
- :c:func:`PyObject_GenericGetAttr` function.
diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst
index d354e9f..9760dca 100644
--- a/Doc/c-api/sys.rst
+++ b/Doc/c-api/sys.rst
@@ -61,12 +61,6 @@ accessible to C code. They all work with the current interpreter thread's
Return the object *name* from the :mod:`sys` module or *NULL* if it does
not exist, without setting an exception.
-.. c:function:: FILE *PySys_GetFile(char *name, FILE *def)
-
- Return the :c:type:`FILE*` associated with the object *name* in the
- :mod:`sys` module, or *def* if *name* is not in the module or is not associated
- with a :c:type:`FILE*`.
-
.. c:function:: int PySys_SetObject(char *name, PyObject *v)
Set *name* in the :mod:`sys` module to *v* unless *v* is *NULL*, in which
@@ -77,11 +71,15 @@ accessible to C code. They all work with the current interpreter thread's
Reset :data:`sys.warnoptions` to an empty list.
-.. c:function:: void PySys_AddWarnOption(char *s)
+.. c:function:: void PySys_AddWarnOption(wchar_t *s)
Append *s* to :data:`sys.warnoptions`.
-.. c:function:: void PySys_SetPath(char *path)
+.. c:function:: void PySys_AddWarnOptionUnicode(PyObject *unicode)
+
+ Append *unicode* to :data:`sys.warnoptions`.
+
+.. c:function:: void PySys_SetPath(wchar_t *path)
Set :data:`sys.path` to a list object of paths found in *path* which should
be a list of paths separated with the platform's search path delimiter
@@ -105,7 +103,38 @@ accessible to C code. They all work with the current interpreter thread's
.. c:function:: void PySys_WriteStderr(const char *format, ...)
- As above, but write to :data:`sys.stderr` or *stderr* instead.
+ As :c:func:`PySys_WriteStdout`, but write to :data:`sys.stderr` or *stderr*
+ instead.
+
+.. c:function:: void PySys_FormatStdout(const char *format, ...)
+
+ Function similar to PySys_WriteStdout() but format the message using
+ :c:func:`PyUnicode_FromFormatV` and don't truncate the message to an
+ arbitrary length.
+
+ .. versionadded:: 3.2
+
+.. c:function:: void PySys_FormatStderr(const char *format, ...)
+
+ As :c:func:`PySys_FormatStdout`, but write to :data:`sys.stderr` or *stderr*
+ instead.
+
+ .. versionadded:: 3.2
+
+.. c:function:: void PySys_AddXOption(const wchar_t *s)
+
+ Parse *s* as a set of :option:`-X` options and add them to the current
+ options mapping as returned by :c:func:`PySys_GetXOptions`.
+
+ .. versionadded:: 3.2
+
+.. c:function:: PyObject *PySys_GetXOptions()
+
+ Return the current dictionary of :option:`-X` options, similarly to
+ :data:`sys._xoptions`. On error, *NULL* is returned and an exception is
+ set.
+
+ .. versionadded:: 3.2
.. _processcontrol:
diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst
index 16de45f..3cbfe5b 100644
--- a/Doc/c-api/tuple.rst
+++ b/Doc/c-api/tuple.rst
@@ -15,10 +15,8 @@ Tuple Objects
.. c:var:: PyTypeObject PyTuple_Type
- .. index:: single: TupleType (in module types)
-
- This instance of :c:type:`PyTypeObject` represents the Python tuple type; it is
- the same object as ``tuple`` and ``types.TupleType`` in the Python layer..
+ This instance of :c:type:`PyTypeObject` represents the Python tuple type; it
+ is the same object as :class:`tuple` in the Python layer.
.. c:function:: int PyTuple_Check(PyObject *p)
@@ -26,26 +24,17 @@ Tuple Objects
Return true if *p* is a tuple object or an instance of a subtype of the tuple
type.
- .. versionchanged:: 2.2
- Allowed subtypes to be accepted.
-
.. c:function:: int PyTuple_CheckExact(PyObject *p)
Return true if *p* is a tuple object, but not an instance of a subtype of the
tuple type.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyTuple_New(Py_ssize_t len)
Return a new tuple object of size *len*, or *NULL* on failure.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *len*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyTuple_Pack(Py_ssize_t n, ...)
@@ -53,60 +42,34 @@ Tuple Objects
are initialized to the subsequent *n* C arguments pointing to Python objects.
``PyTuple_Pack(2, a, b)`` is equivalent to ``Py_BuildValue("(OO)", a, b)``.
- .. versionadded:: 2.4
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *n*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: Py_ssize_t PyTuple_Size(PyObject *p)
Take a pointer to a tuple object, and return the size of that tuple.
- .. versionchanged:: 2.5
- This function returned an :c:type:`int` type. This might require changes
- in your code for properly supporting 64-bit systems.
-
.. c:function:: Py_ssize_t PyTuple_GET_SIZE(PyObject *p)
Return the size of the tuple *p*, which must be non-*NULL* and point to a tuple;
no error checking is performed.
- .. versionchanged:: 2.5
- This function returned an :c:type:`int` type. This might require changes
- in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos)
Return the object at position *pos* in the tuple pointed to by *p*. If *pos* is
out of bounds, return *NULL* and sets an :exc:`IndexError` exception.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *pos*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos)
Like :c:func:`PyTuple_GetItem`, but does no checking of its arguments.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *pos*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high)
Take a slice of the tuple pointed to by *p* from *low* to *high* and return it
as a new tuple.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *low* and *high*. This might
- require changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o)
@@ -117,10 +80,6 @@ Tuple Objects
This function "steals" a reference to *o*.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *pos*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o)
@@ -131,10 +90,6 @@ Tuple Objects
This function "steals" a reference to *o*.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *pos*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize)
@@ -149,16 +104,7 @@ Tuple Objects
``*p`` is destroyed. On failure, returns ``-1`` and sets ``*p`` to *NULL*, and
raises :exc:`MemoryError` or :exc:`SystemError`.
- .. versionchanged:: 2.2
- Removed unused third parameter, *last_is_sticky*.
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *newsize*. This might
- require changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PyTuple_ClearFreeList()
Clear the free list. Return the total number of freed items.
-
- .. versionadded:: 2.6
diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst
index 22f7dd0..b3386ea 100644
--- a/Doc/c-api/type.rst
+++ b/Doc/c-api/type.rst
@@ -15,10 +15,8 @@ Type Objects
.. c:var:: PyObject* PyType_Type
- .. index:: single: TypeType (in module types)
-
- This is the type object for type objects; it is the same object as ``type`` and
- ``types.TypeType`` in the Python layer.
+ This is the type object for type objects; it is the same object as
+ :class:`type` in the Python layer.
.. c:function:: int PyType_Check(PyObject *o)
@@ -32,15 +30,19 @@ Type Objects
Return true if the object *o* is a type object, but not a subtype of the
standard type object. Return false in all other cases.
- .. versionadded:: 2.2
-
.. c:function:: unsigned int PyType_ClearCache()
Clear the internal lookup cache. Return the current version tag.
- .. versionadded:: 2.6
+.. c:function:: long PyType_GetFlags(PyTypeObject* type)
+ Return the :attr:`tp_flags` member of *type*. This function is primarily
+ meant for use with `Py_LIMITED_API`; the individual flag bits are
+ guaranteed to be stable across Python releases, but access to
+ :attr:`tp_flags` itself is not part of the limited API.
+
+ .. versionadded:: 3.2
.. c:function:: void PyType_Modified(PyTypeObject *type)
@@ -48,8 +50,6 @@ Type Objects
subtypes. This function must be called after any manual
modification of the attributes or base classes of the type.
- .. versionadded:: 2.6
-
.. c:function:: int PyType_HasFeature(PyObject *o, int feature)
@@ -62,28 +62,20 @@ Type Objects
Return true if the type object includes support for the cycle detector; this
tests the type flag :const:`Py_TPFLAGS_HAVE_GC`.
- .. versionadded:: 2.0
-
.. c:function:: int PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
Return true if *a* is a subtype of *b*.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
- .. versionadded:: 2.2
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *nitems*. This might require
- changes in your code for properly supporting 64-bit systems.
+ XXX: Document.
.. c:function:: PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
- .. versionadded:: 2.2
+ XXX: Document.
.. c:function:: int PyType_Ready(PyTypeObject *type)
@@ -92,5 +84,3 @@ Type Objects
their initialization. This function is responsible for adding inherited slots
from a type's base class. Return ``0`` on success, or return ``-1`` and sets an
exception on error.
-
- .. versionadded:: 2.2
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index 7c37786..68ca9ad 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -20,10 +20,10 @@ functionality. The fields of the type object are examined in detail in this
section. The fields will be described in the order in which they occur in the
structure.
-Typedefs: unaryfunc, binaryfunc, ternaryfunc, inquiry, coercion, intargfunc,
+Typedefs: unaryfunc, binaryfunc, ternaryfunc, inquiry, intargfunc,
intintargfunc, intobjargproc, intintobjargproc, objobjargproc, destructor,
freefunc, printfunc, getattrfunc, getattrofunc, setattrfunc, setattrofunc,
-cmpfunc, reprfunc, hashfunc
+reprfunc, hashfunc
The structure definition for :c:type:`PyTypeObject` can be found in
:file:`Include/object.h`. For convenience of reference, this repeats the
@@ -64,10 +64,6 @@ type objects) *must* have the :attr:`ob_size` field.
This field is not inherited by subtypes.
- .. versionchanged:: 2.5
- This field used to be an :c:type:`int` type. This might require changes
- in your code for properly supporting 64-bit systems.
-
.. c:member:: PyTypeObject* PyObject.ob_type
@@ -84,12 +80,10 @@ type objects) *must* have the :attr:`ob_size` field.
This should be done before any instances of the type are created.
:c:func:`PyType_Ready` checks if :attr:`ob_type` is *NULL*, and if so,
- initializes it: in Python 2.2, it is set to ``&PyType_Type``; in Python 2.2.1
- and later it is initialized to the :attr:`ob_type` field of the base class.
+ initializes it to the :attr:`ob_type` field of the base class.
:c:func:`PyType_Ready` will not change this field if it is non-zero.
- In Python 2.2, this field is not inherited by subtypes. In 2.2.1, and in 2.3
- and beyond, it is inherited by subtypes.
+ This field is inherited by subtypes.
.. c:member:: Py_ssize_t PyVarObject.ob_size
@@ -141,7 +135,7 @@ type objects) *must* have the :attr:`ob_size` field.
:attr:`ob_size` field, and the instance size is :attr:`tp_basicsize` plus N
times :attr:`tp_itemsize`, where N is the "length" of the object. The value of
N is typically stored in the instance's :attr:`ob_size` field. There are
- exceptions: for example, long ints use a negative :attr:`ob_size` to indicate a
+ exceptions: for example, ints use a negative :attr:`ob_size` to indicate a
negative number, and N is ``abs(ob_size)`` there. Also, the presence of an
:attr:`ob_size` field in the instance layout doesn't mean that the instance
structure is variable-length (for example, the structure for the list type has
@@ -154,8 +148,7 @@ type objects) *must* have the :attr:`ob_size` field.
:attr:`_ob_next` fields if they are present. This means that the only correct
way to get an initializer for the :attr:`tp_basicsize` is to use the
``sizeof`` operator on the struct used to declare the instance layout.
- The basic size does not include the GC header size (this is new in Python 2.2;
- in 2.1 and 2.0, the GC header size was included in :attr:`tp_basicsize`).
+ The basic size does not include the GC header size.
These fields are inherited separately by subtypes. If the base type has a
non-zero :attr:`tp_itemsize`, it is generally not safe to set
@@ -251,19 +244,9 @@ type objects) *must* have the :attr:`ob_size` field.
the subtype's :attr:`tp_setattr` and :attr:`tp_setattro` are both *NULL*.
-.. c:member:: cmpfunc PyTypeObject.tp_compare
-
- An optional pointer to the three-way comparison function.
-
- The signature is the same as for :c:func:`PyObject_Compare`. The function should
- return ``1`` if *self* greater than *other*, ``0`` if *self* is equal to
- *other*, and ``-1`` if *self* less than *other*. It should return ``-1`` and
- set an exception condition when an error occurred during the comparison.
+.. c:member:: void* PyTypeObject.tp_reserved
- This field is inherited by subtypes together with :attr:`tp_richcompare` and
- :attr:`tp_hash`: a subtypes inherits all three of :attr:`tp_compare`,
- :attr:`tp_richcompare`, and :attr:`tp_hash` when the subtype's
- :attr:`tp_compare`, :attr:`tp_richcompare`, and :attr:`tp_hash` are all *NULL*.
+ Reserved slot, formerly known as tp_compare.
.. c:member:: reprfunc PyTypeObject.tp_repr
@@ -323,10 +306,10 @@ type objects) *must* have the :attr:`ob_size` field.
An optional pointer to a function that implements the built-in function
:func:`hash`.
- The signature is the same as for :c:func:`PyObject_Hash`; it must return a C
- long. The value ``-1`` should not be returned as a normal return value; when an
- error occurs during the computation of the hash value, the function should set
- an exception and return ``-1``.
+ The signature is the same as for :c:func:`PyObject_Hash`; it must return a
+ value of the type Py_hash_t. The value ``-1`` should not be returned as a
+ normal return value; when an error occurs during the computation of the hash
+ value, the function should set an exception and return ``-1``.
This field can be set explicitly to :c:func:`PyObject_HashNotImplemented` to
block inheritance of the hash method from a parent type. This is interpreted
@@ -336,14 +319,13 @@ type objects) *must* have the :attr:`ob_size` field.
the Python level will result in the ``tp_hash`` slot being set to
:c:func:`PyObject_HashNotImplemented`.
- When this field is not set, two possibilities exist: if the :attr:`tp_compare`
- and :attr:`tp_richcompare` fields are both *NULL*, a default hash value based on
- the object's address is returned; otherwise, a :exc:`TypeError` is raised.
+ When this field is not set, an attempt to take the hash of the
+ object raises :exc:`TypeError`.
- This field is inherited by subtypes together with :attr:`tp_richcompare` and
- :attr:`tp_compare`: a subtypes inherits all three of :attr:`tp_compare`,
- :attr:`tp_richcompare`, and :attr:`tp_hash`, when the subtype's
- :attr:`tp_compare`, :attr:`tp_richcompare` and :attr:`tp_hash` are all *NULL*.
+ This field is inherited by subtypes together with
+ :attr:`tp_richcompare`: a subtype inherits both of
+ :attr:`tp_richcompare` and :attr:`tp_hash`, when the subtype's
+ :attr:`tp_richcompare` and :attr:`tp_hash` are both *NULL*.
.. c:member:: ternaryfunc PyTypeObject.tp_call
@@ -364,8 +346,8 @@ type objects) *must* have the :attr:`ob_size` field.
The signature is the same as for :c:func:`PyObject_Str`; it must return a string
or a Unicode object. This function should return a "friendly" string
- representation of the object, as this is the representation that will be used by
- the print statement.
+ representation of the object, as this is the representation that will be used,
+ among other things, by the :func:`print` function.
When this field is not set, :c:func:`PyObject_Repr` is called to return a string
representation.
@@ -427,9 +409,8 @@ type objects) *must* have the :attr:`ob_size` field.
structure. The :const:`Py_TPFLAGS_HAVE_GC` flag bit is inherited together with
the :attr:`tp_traverse` and :attr:`tp_clear` fields, i.e. if the
:const:`Py_TPFLAGS_HAVE_GC` flag bit is clear in the subtype and the
- :attr:`tp_traverse` and :attr:`tp_clear` fields in the subtype exist (as
- indicated by the :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag bit) and have *NULL*
- values.
+ :attr:`tp_traverse` and :attr:`tp_clear` fields in the subtype exist and have
+ *NULL* values.
The following bit masks are currently defined; these can be ORed together using
the ``|`` operator to form the value of the :attr:`tp_flags` field. The macro
@@ -437,81 +418,6 @@ type objects) *must* have the :attr:`ob_size` field.
checks whether ``tp->tp_flags & f`` is non-zero.
- .. data:: Py_TPFLAGS_HAVE_GETCHARBUFFER
-
- If this bit is set, the :c:type:`PyBufferProcs` struct referenced by
- :attr:`tp_as_buffer` has the :attr:`bf_getcharbuffer` field.
-
-
- .. data:: Py_TPFLAGS_HAVE_SEQUENCE_IN
-
- If this bit is set, the :c:type:`PySequenceMethods` struct referenced by
- :attr:`tp_as_sequence` has the :attr:`sq_contains` field.
-
-
- .. data:: Py_TPFLAGS_GC
-
- This bit is obsolete. The bit it used to name is no longer in use. The symbol
- is now defined as zero.
-
-
- .. data:: Py_TPFLAGS_HAVE_INPLACEOPS
-
- If this bit is set, the :c:type:`PySequenceMethods` struct referenced by
- :attr:`tp_as_sequence` and the :c:type:`PyNumberMethods` structure referenced by
- :attr:`tp_as_number` contain the fields for in-place operators. In particular,
- this means that the :c:type:`PyNumberMethods` structure has the fields
- :attr:`nb_inplace_add`, :attr:`nb_inplace_subtract`,
- :attr:`nb_inplace_multiply`, :attr:`nb_inplace_divide`,
- :attr:`nb_inplace_remainder`, :attr:`nb_inplace_power`,
- :attr:`nb_inplace_lshift`, :attr:`nb_inplace_rshift`, :attr:`nb_inplace_and`,
- :attr:`nb_inplace_xor`, and :attr:`nb_inplace_or`; and the
- :c:type:`PySequenceMethods` struct has the fields :attr:`sq_inplace_concat` and
- :attr:`sq_inplace_repeat`.
-
-
- .. data:: Py_TPFLAGS_CHECKTYPES
-
- If this bit is set, the binary and ternary operations in the
- :c:type:`PyNumberMethods` structure referenced by :attr:`tp_as_number` accept
- arguments of arbitrary object types, and do their own type conversions if
- needed. If this bit is clear, those operations require that all arguments have
- the current type as their type, and the caller is supposed to perform a coercion
- operation first. This applies to :attr:`nb_add`, :attr:`nb_subtract`,
- :attr:`nb_multiply`, :attr:`nb_divide`, :attr:`nb_remainder`, :attr:`nb_divmod`,
- :attr:`nb_power`, :attr:`nb_lshift`, :attr:`nb_rshift`, :attr:`nb_and`,
- :attr:`nb_xor`, and :attr:`nb_or`.
-
-
- .. data:: Py_TPFLAGS_HAVE_RICHCOMPARE
-
- If this bit is set, the type object has the :attr:`tp_richcompare` field, as
- well as the :attr:`tp_traverse` and the :attr:`tp_clear` fields.
-
-
- .. data:: Py_TPFLAGS_HAVE_WEAKREFS
-
- If this bit is set, the :attr:`tp_weaklistoffset` field is defined. Instances
- of a type are weakly referenceable if the type's :attr:`tp_weaklistoffset` field
- has a value greater than zero.
-
-
- .. data:: Py_TPFLAGS_HAVE_ITER
-
- If this bit is set, the type object has the :attr:`tp_iter` and
- :attr:`tp_iternext` fields.
-
-
- .. data:: Py_TPFLAGS_HAVE_CLASS
-
- If this bit is set, the type object has several new fields defined starting in
- Python 2.2: :attr:`tp_methods`, :attr:`tp_members`, :attr:`tp_getset`,
- :attr:`tp_base`, :attr:`tp_dict`, :attr:`tp_descr_get`, :attr:`tp_descr_set`,
- :attr:`tp_dictoffset`, :attr:`tp_init`, :attr:`tp_alloc`, :attr:`tp_new`,
- :attr:`tp_free`, :attr:`tp_is_gc`, :attr:`tp_bases`, :attr:`tp_mro`,
- :attr:`tp_cache`, :attr:`tp_subclasses`, and :attr:`tp_weaklist`.
-
-
.. data:: Py_TPFLAGS_HEAPTYPE
This bit is set when the type object itself is allocated on the heap. In this
@@ -548,19 +454,15 @@ type objects) *must* have the :attr:`ob_size` field.
destroyed using :c:func:`PyObject_GC_Del`. More information in section
:ref:`supporting-cycle-detection`. This bit also implies that the
GC-related fields :attr:`tp_traverse` and :attr:`tp_clear` are present in
- the type object; but those fields also exist when
- :const:`Py_TPFLAGS_HAVE_GC` is clear but
- :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` is set.
+ the type object.
.. data:: Py_TPFLAGS_DEFAULT
This is a bitmask of all the bits that pertain to the existence of certain
fields in the type object and its extension structures. Currently, it includes
- the following bits: :const:`Py_TPFLAGS_HAVE_GETCHARBUFFER`,
- :const:`Py_TPFLAGS_HAVE_SEQUENCE_IN`, :const:`Py_TPFLAGS_HAVE_INPLACEOPS`,
- :const:`Py_TPFLAGS_HAVE_RICHCOMPARE`, :const:`Py_TPFLAGS_HAVE_WEAKREFS`,
- :const:`Py_TPFLAGS_HAVE_ITER`, and :const:`Py_TPFLAGS_HAVE_CLASS`.
+ the following bits: :const:`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`,
+ :const:`Py_TPFLAGS_HAVE_VERSION_TAG`.
.. c:member:: char* PyTypeObject.tp_doc
@@ -571,9 +473,6 @@ type objects) *must* have the :attr:`ob_size` field.
This field is *not* inherited by subtypes.
-The following three fields only exist if the
-:const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag bit is set.
-
.. c:member:: traverseproc PyTypeObject.tp_traverse
@@ -586,7 +485,7 @@ The following three fields only exist if the
reference cycles. A typical implementation of a :attr:`tp_traverse` function
simply calls :c:func:`Py_VISIT` on each of the instance's members that are Python
objects. For example, this is function :c:func:`local_traverse` from the
- :mod:`thread` extension module::
+ :mod:`_thread` extension module::
static int
local_traverse(localobject *self, visitproc visit, void *arg)
@@ -612,8 +511,7 @@ The following three fields only exist if the
This field is inherited by subtypes together with :attr:`tp_clear` and the
:const:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :attr:`tp_traverse`, and
:attr:`tp_clear` are all inherited from the base type if they are all zero in
- the subtype *and* the subtype has the :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag
- bit set.
+ the subtype.
.. c:member:: inquiry PyTypeObject.tp_clear
@@ -668,8 +566,7 @@ The following three fields only exist if the
This field is inherited by subtypes together with :attr:`tp_traverse` and the
:const:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :attr:`tp_traverse`, and
:attr:`tp_clear` are all inherited from the base type if they are all zero in
- the subtype *and* the subtype has the :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag
- bit set.
+ the subtype.
.. c:member:: richcmpfunc PyTypeObject.tp_richcompare
@@ -688,10 +585,10 @@ The following three fields only exist if the
comparisons makes sense (e.g. ``==`` and ``!=``, but not ``<`` and
friends), directly raise :exc:`TypeError` in the rich comparison function.
- This field is inherited by subtypes together with :attr:`tp_compare` and
- :attr:`tp_hash`: a subtype inherits all three of :attr:`tp_compare`,
- :attr:`tp_richcompare`, and :attr:`tp_hash`, when the subtype's
- :attr:`tp_compare`, :attr:`tp_richcompare`, and :attr:`tp_hash` are all *NULL*.
+ This field is inherited by subtypes together with :attr:`tp_hash`:
+ a subtype inherits :attr:`tp_richcompare` and :attr:`tp_hash` when
+ the subtype's :attr:`tp_richcompare` and :attr:`tp_hash` are both
+ *NULL*.
The following constants are defined to be used as the third argument for
:attr:`tp_richcompare` and for :c:func:`PyObject_RichCompare`:
@@ -713,9 +610,6 @@ The following three fields only exist if the
+----------------+------------+
-The next field only exists if the :const:`Py_TPFLAGS_HAVE_WEAKREFS` flag bit is
-set.
-
.. c:member:: long PyTypeObject.tp_weaklistoffset
If the instances of this type are weakly referenceable, this field is greater
@@ -747,16 +641,11 @@ set.
:attr:`__weakref__`, the type inherits its :attr:`tp_weaklistoffset` from its
base type.
-The next two fields only exist if the :const:`Py_TPFLAGS_HAVE_ITER` flag bit is
-set.
-
-
.. c:member:: getiterfunc PyTypeObject.tp_iter
An optional pointer to a function that returns an iterator for the object. Its
presence normally signals that the instances of this type are iterable (although
- sequences may be iterable without this function, and classic instances always
- have this function, even if they don't define an :meth:`__iter__` method).
+ sequences may be iterable without this function).
This function has the same signature as :c:func:`PyObject_GetIter`.
@@ -768,9 +657,8 @@ set.
An optional pointer to a function that returns the next item in an iterator.
When the iterator is exhausted, it must return *NULL*; a :exc:`StopIteration`
exception may or may not be set. When another error occurs, it must return
- *NULL* too. Its presence normally signals that the instances of this type
- are iterators (although classic instances always have this function, even if
- they don't define a :meth:`next` method).
+ *NULL* too. Its presence signals that the instances of this type are
+ iterators.
Iterator types should also define the :attr:`tp_iter` function, and that
function should return the iterator instance itself (not a new iterator
@@ -780,9 +668,6 @@ set.
This field is inherited by subtypes.
-The next fields, up to and including :attr:`tp_weaklist`, only exist if the
-:const:`Py_TPFLAGS_HAVE_CLASS` flag bit is set.
-
.. c:member:: struct PyMethodDef* PyTypeObject.tp_methods
@@ -860,6 +745,11 @@ The next fields, up to and including :attr:`tp_weaklist`, only exist if the
This field is not inherited by subtypes (though the attributes defined in here
are inherited through a different mechanism).
+ .. warning::
+
+ It is not safe to use :c:func:`PyDict_SetItem` on or otherwise modify
+ :attr:`tp_dict` with the dictionary C-API.
+
.. c:member:: descrgetfunc PyTypeObject.tp_descr_get
@@ -918,7 +808,7 @@ The next fields, up to and including :attr:`tp_weaklist`, only exist if the
where :attr:`tp_basicsize`, :attr:`tp_itemsize` and :attr:`tp_dictoffset` are
taken from the type object, and :attr:`ob_size` is taken from the instance. The
- absolute value is taken because long ints use the sign of :attr:`ob_size` to
+ absolute value is taken because ints use the sign of :attr:`ob_size` to
store the sign of the number. (There's never a need to do this calculation
yourself; it is done for you by :c:func:`_PyObject_GetDictPtr`.)
@@ -962,10 +852,7 @@ The next fields, up to and including :attr:`tp_weaklist`, only exist if the
has returned an instance of the type. If the :attr:`tp_new` function returns an
instance of some other type that is not a subtype of the original type, no
:attr:`tp_init` function is called; if :attr:`tp_new` returns an instance of a
- subtype of the original type, the subtype's :attr:`tp_init` is called. (VERSION
- NOTE: described here is what is implemented in Python 2.2.1 and later. In
- Python 2.2, the :attr:`tp_init` of the type of the object returned by
- :attr:`tp_new` was always called, if not *NULL*.)
+ subtype of the original type, the subtype's :attr:`tp_init` is called.
This field is inherited by subtypes.
@@ -1024,26 +911,17 @@ The next fields, up to and including :attr:`tp_weaklist`, only exist if the
deferred to :attr:`tp_init`.
This field is inherited by subtypes, except it is not inherited by static types
- whose :attr:`tp_base` is *NULL* or ``&PyBaseObject_Type``. The latter exception
- is a precaution so that old extension types don't become callable simply by
- being linked with Python 2.2.
+ whose :attr:`tp_base` is *NULL* or ``&PyBaseObject_Type``.
.. c:member:: destructor PyTypeObject.tp_free
- An optional pointer to an instance deallocation function.
-
- The signature of this function has changed slightly: in Python 2.2 and 2.2.1,
- its signature is :c:type:`destructor`::
-
- void tp_free(PyObject *)
-
- In Python 2.3 and beyond, its signature is :c:type:`freefunc`::
+ An optional pointer to an instance deallocation function. Its signature is
+ :c:type:`freefunc`::
void tp_free(void *)
- The only initializer that is compatible with both versions is ``_PyObject_Del``,
- whose definition has suitably adapted in Python 2.3.
+ An initializer that is compatible with this signature is :c:func:`PyObject_Free`.
This field is inherited by static subtypes, but not by dynamic subtypes
(subtypes created by a class statement); in the latter, this field is set to a
@@ -1069,8 +947,7 @@ The next fields, up to and including :attr:`tp_weaklist`, only exist if the
:c:data:`PyType_Type`, defines this function to distinguish between statically
and dynamically allocated types.)
- This field is inherited by subtypes. (VERSION NOTE: in Python 2.2, it was not
- inherited. It is inherited in 2.2.1 and later versions.)
+ This field is inherited by subtypes.
.. c:member:: PyObject* PyTypeObject.tp_bases
@@ -1153,8 +1030,8 @@ Number Object Structures
.. c:type:: PyNumberMethods
This structure holds pointers to the functions which an object uses to
- implement the number protocol. Almost every function below is used by the
- function of similar name documented in the :ref:`number` section.
+ implement the number protocol. Each function is used by the function of
+ similar name documented in the :ref:`number` section.
Here is the structure definition::
@@ -1162,32 +1039,26 @@ Number Object Structures
binaryfunc nb_add;
binaryfunc nb_subtract;
binaryfunc nb_multiply;
- binaryfunc nb_divide;
binaryfunc nb_remainder;
binaryfunc nb_divmod;
ternaryfunc nb_power;
unaryfunc nb_negative;
unaryfunc nb_positive;
unaryfunc nb_absolute;
- inquiry nb_nonzero; /* Used by PyObject_IsTrue */
+ inquiry nb_bool;
unaryfunc nb_invert;
binaryfunc nb_lshift;
binaryfunc nb_rshift;
binaryfunc nb_and;
binaryfunc nb_xor;
binaryfunc nb_or;
- coercion nb_coerce; /* Used by the coerce() function */
unaryfunc nb_int;
- unaryfunc nb_long;
+ void *nb_reserved;
unaryfunc nb_float;
- unaryfunc nb_oct;
- unaryfunc nb_hex;
- /* Added in release 2.0 */
binaryfunc nb_inplace_add;
binaryfunc nb_inplace_subtract;
binaryfunc nb_inplace_multiply;
- binaryfunc nb_inplace_divide;
binaryfunc nb_inplace_remainder;
ternaryfunc nb_inplace_power;
binaryfunc nb_inplace_lshift;
@@ -1196,43 +1067,28 @@ Number Object Structures
binaryfunc nb_inplace_xor;
binaryfunc nb_inplace_or;
- /* Added in release 2.2 */
binaryfunc nb_floor_divide;
binaryfunc nb_true_divide;
binaryfunc nb_inplace_floor_divide;
binaryfunc nb_inplace_true_divide;
- /* Added in release 2.5 */
unaryfunc nb_index;
} PyNumberMethods;
+ .. note::
-Binary and ternary functions may receive different kinds of arguments, depending
-on the flag bit :const:`Py_TPFLAGS_CHECKTYPES`:
-
-- If :const:`Py_TPFLAGS_CHECKTYPES` is not set, the function arguments are
- guaranteed to be of the object's type; the caller is responsible for calling
- the coercion method specified by the :attr:`nb_coerce` member to convert the
- arguments:
-
- .. c:member:: coercion PyNumberMethods.nb_coerce
-
- This function is used by :c:func:`PyNumber_CoerceEx` and has the same
- signature. The first argument is always a pointer to an object of the
- defined type. If the conversion to a common "larger" type is possible, the
- function replaces the pointers with new references to the converted objects
- and returns ``0``. If the conversion is not possible, the function returns
- ``1``. If an error condition is set, it will return ``-1``.
+ Binary and ternary functions must check the type of all their operands,
+ and implement the necessary conversions (at least one of the operands is
+ an instance of the defined type). If the operation is not defined for the
+ given operands, binary and ternary functions must return
+ ``Py_NotImplemented``, if another error occurred they must return ``NULL``
+ and set an exception.
-- If the :const:`Py_TPFLAGS_CHECKTYPES` flag is set, binary and ternary
- functions must check the type of all their operands, and implement the
- necessary conversions (at least one of the operands is an instance of the
- defined type). This is the recommended way; with Python 3 coercion will
- disappear completely.
+ .. note::
-If the operation is not defined for the given operands, binary and ternary
-functions must return ``Py_NotImplemented``, if another error occurred they must
-return ``NULL`` and set an exception.
+ The :c:data:`nb_reserved` field should always be ``NULL``. It
+ was previously called :c:data:`nb_long`, and was renamed in
+ Python 3.0.1.
.. _mapping-structs:
@@ -1341,108 +1197,47 @@ Buffer Object Structures
========================
.. sectionauthor:: Greg J. Stein <greg@lyra.org>
+.. sectionauthor:: Benjamin Peterson
-The buffer interface exports a model where an object can expose its internal
-data as a set of chunks of data, where each chunk is specified as a
-pointer/length pair. These chunks are called :dfn:`segments` and are presumed
-to be non-contiguous in memory.
+The :ref:`buffer interface <bufferobjects>` exports a model where an object can expose its internal
+data.
If an object does not export the buffer interface, then its :attr:`tp_as_buffer`
member in the :c:type:`PyTypeObject` structure should be *NULL*. Otherwise, the
:attr:`tp_as_buffer` will point to a :c:type:`PyBufferProcs` structure.
-.. note::
-
- It is very important that your :c:type:`PyTypeObject` structure uses
- :const:`Py_TPFLAGS_DEFAULT` for the value of the :attr:`tp_flags` member rather
- than ``0``. This tells the Python runtime that your :c:type:`PyBufferProcs`
- structure contains the :attr:`bf_getcharbuffer` slot. Older versions of Python
- did not have this member, so a new Python interpreter using an old extension
- needs to be able to test for its presence before using it.
-
.. c:type:: PyBufferProcs
Structure used to hold the function pointers which define an implementation of
the buffer protocol.
- The first slot is :attr:`bf_getreadbuffer`, of type :c:type:`getreadbufferproc`.
- If this slot is *NULL*, then the object does not support reading from the
- internal data. This is non-sensical, so implementors should fill this in, but
- callers should test that the slot contains a non-*NULL* value.
-
- The next slot is :attr:`bf_getwritebuffer` having type
- :c:type:`getwritebufferproc`. This slot may be *NULL* if the object does not
- allow writing into its returned buffers.
-
- The third slot is :attr:`bf_getsegcount`, with type :c:type:`getsegcountproc`.
- This slot must not be *NULL* and is used to inform the caller how many segments
- the object contains. Simple objects such as :c:type:`PyString_Type` and
- :c:type:`PyBuffer_Type` objects contain a single segment.
-
- .. index:: single: PyType_HasFeature()
-
- The last slot is :attr:`bf_getcharbuffer`, of type :c:type:`getcharbufferproc`.
- This slot will only be present if the :const:`Py_TPFLAGS_HAVE_GETCHARBUFFER`
- flag is present in the :attr:`tp_flags` field of the object's
- :c:type:`PyTypeObject`. Before using this slot, the caller should test whether it
- is present by using the :c:func:`PyType_HasFeature` function. If the flag is
- present, :attr:`bf_getcharbuffer` may be *NULL*, indicating that the object's
- contents cannot be used as *8-bit characters*. The slot function may also raise
- an error if the object's contents cannot be interpreted as 8-bit characters.
- For example, if the object is an array which is configured to hold floating
- point values, an exception may be raised if a caller attempts to use
- :attr:`bf_getcharbuffer` to fetch a sequence of 8-bit characters. This notion of
- exporting the internal buffers as "text" is used to distinguish between objects
- that are binary in nature, and those which have character-based content.
-
- .. note::
-
- The current policy seems to state that these characters may be multi-byte
- characters. This implies that a buffer size of *N* does not mean there are *N*
- characters present.
-
-
-.. data:: Py_TPFLAGS_HAVE_GETCHARBUFFER
-
- Flag bit set in the type structure to indicate that the :attr:`bf_getcharbuffer`
- slot is known. This being set does not indicate that the object supports the
- buffer interface or that the :attr:`bf_getcharbuffer` slot is non-*NULL*.
-
-
-.. c:type:: Py_ssize_t (*readbufferproc) (PyObject *self, Py_ssize_t segment, void **ptrptr)
-
- Return a pointer to a readable segment of the buffer in ``*ptrptr``. This
- function is allowed to raise an exception, in which case it must return ``-1``.
- The *segment* which is specified must be zero or positive, and strictly less
- than the number of segments returned by the :attr:`bf_getsegcount` slot
- function. On success, it returns the length of the segment, and sets
- ``*ptrptr`` to a pointer to that memory.
-
-
-.. c:type:: Py_ssize_t (*writebufferproc) (PyObject *self, Py_ssize_t segment, void **ptrptr)
-
- Return a pointer to a writable memory buffer in ``*ptrptr``, and the length of
- that segment as the function return value. The memory buffer must correspond to
- buffer segment *segment*. Must return ``-1`` and set an exception on error.
- :exc:`TypeError` should be raised if the object only supports read-only buffers,
- and :exc:`SystemError` should be raised when *segment* specifies a segment that
- doesn't exist.
-
- .. Why doesn't it raise ValueError for this one?
- GJS: because you shouldn't be calling it with an invalid
- segment. That indicates a blatant programming error in the C code.
+ .. c:member:: getbufferproc bf_getbuffer
+ This should fill a :c:type:`Py_buffer` with the necessary data for
+ exporting the type. The signature of :data:`getbufferproc` is ``int
+ (PyObject *obj, Py_buffer *view, int flags)``. *obj* is the object to
+ export, *view* is the :c:type:`Py_buffer` struct to fill, and *flags* gives
+ the conditions the caller wants the memory under. (See
+ :c:func:`PyObject_GetBuffer` for all flags.) :c:member:`bf_getbuffer` is
+ responsible for filling *view* with the appropriate information.
+ (:c:func:`PyBuffer_FillView` can be used in simple cases.) See
+ :c:type:`Py_buffer`\s docs for what needs to be filled in.
-.. c:type:: Py_ssize_t (*segcountproc) (PyObject *self, Py_ssize_t *lenp)
- Return the number of memory segments which comprise the buffer. If *lenp* is
- not *NULL*, the implementation must report the sum of the sizes (in bytes) of
- all segments in ``*lenp``. The function cannot fail.
+ .. c:member:: releasebufferproc bf_releasebuffer
+ This should release the resources of the buffer. The signature of
+ :c:data:`releasebufferproc` is ``void (PyObject *obj, Py_buffer *view)``.
+ If the :c:data:`bf_releasebuffer` function is not provided (i.e. it is
+ *NULL*), then it does not ever need to be called.
-.. c:type:: Py_ssize_t (*charbufferproc) (PyObject *self, Py_ssize_t segment, const char **ptrptr)
+ The exporter of the buffer interface must make sure that any memory
+ pointed to in the :c:type:`Py_buffer` structure remains valid until
+ releasebuffer is called. Exporters will need to define a
+ :c:data:`bf_releasebuffer` function if they can re-allocate their memory,
+ strides, shape, suboffsets, or format variables which they might share
+ through the struct bufferinfo.
- Return the size of the segment *segment* that *ptrptr* is set to. ``*ptrptr``
- is set to the memory buffer. Returns ``-1`` on error.
+ See :c:func:`PyBuffer_Release`.
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index 73f6fe6..d1b57d9 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -5,12 +5,11 @@
Unicode Objects and Codecs
--------------------------
-.. sectionauthor:: Marc-Andre Lemburg <mal@lemburg.com>
+.. sectionauthor:: Marc-André Lemburg <mal@lemburg.com>
Unicode Objects
^^^^^^^^^^^^^^^
-
Unicode Type
""""""""""""
@@ -44,7 +43,7 @@ this in mind when writing extensions or interfaces.
.. c:var:: PyTypeObject PyUnicode_Type
This instance of :c:type:`PyTypeObject` represents the Python Unicode type. It
- is exposed to Python code as ``unicode`` and ``types.UnicodeType``.
+ is exposed to Python code as ``str``.
The following APIs are really C macros and can be used to do fast checks and to
access internal read-only data of Unicode objects:
@@ -55,37 +54,24 @@ access internal read-only data of Unicode objects:
Return true if the object *o* is a Unicode object or an instance of a Unicode
subtype.
- .. versionchanged:: 2.2
- Allowed subtypes to be accepted.
-
.. c:function:: int PyUnicode_CheckExact(PyObject *o)
Return true if the object *o* is a Unicode object, but not an instance of a
subtype.
- .. versionadded:: 2.2
-
.. c:function:: Py_ssize_t PyUnicode_GET_SIZE(PyObject *o)
Return the size of the object. *o* has to be a :c:type:`PyUnicodeObject` (not
checked).
- .. versionchanged:: 2.5
- This function returned an :c:type:`int` type. This might require changes
- in your code for properly supporting 64-bit systems.
-
.. c:function:: Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject *o)
Return the size of the object's internal buffer in bytes. *o* has to be a
:c:type:`PyUnicodeObject` (not checked).
- .. versionchanged:: 2.5
- This function returned an :c:type:`int` type. This might require changes
- in your code for properly supporting 64-bit systems.
-
.. c:function:: Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *o)
@@ -103,8 +89,6 @@ access internal read-only data of Unicode objects:
Clear the free list. Return the total number of freed items.
- .. versionadded:: 2.6
-
Unicode Character Properties
""""""""""""""""""""""""""""
@@ -163,6 +147,18 @@ the Python configuration.
Return 1 or 0 depending on whether *ch* is an alphanumeric character.
+
+.. c:function:: int Py_UNICODE_ISPRINTABLE(Py_UNICODE ch)
+
+ Return 1 or 0 depending on whether *ch* is a printable character.
+ Nonprintable characters are those characters defined in the Unicode character
+ database as "Other" or "Separator", excepting the ASCII space (0x20) which is
+ considered printable. (Note that printable characters in this context are
+ those which should not be escaped when :func:`repr` is invoked on a string.
+ It has no bearing on the handling of strings written to :data:`sys.stdout` or
+ :data:`sys.stderr`.)
+
+
These APIs can be used for fast direct character conversions:
@@ -215,10 +211,6 @@ APIs:
Therefore, modification of the resulting Unicode object is only allowed when *u*
is *NULL*.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size)
@@ -229,16 +221,12 @@ APIs:
*NULL*, the return value might be a shared object. Therefore, modification of
the resulting Unicode object is only allowed when *u* is *NULL*.
- .. versionadded:: 2.6
-
.. c:function:: PyObject *PyUnicode_FromString(const char *u)
Create a Unicode object from an UTF-8 encoded null-terminated char buffer
*u*.
- .. versionadded:: 2.6
-
.. c:function:: PyObject* PyUnicode_FromFormat(const char *format, ...)
@@ -246,11 +234,14 @@ APIs:
arguments, calculate the size of the resulting Python unicode string and return
a string with the values formatted into it. The variable arguments must be C
types and must correspond exactly to the format characters in the *format*
- string. The following format characters are allowed:
+ ASCII-encoded string. The following format characters are allowed:
+ .. % This should be exactly the same as the table in PyErr_Format.
.. % The descriptions for %zd and %zu are wrong, but the truth is complicated
.. % because not all compilers support the %z width modifier -- we fake it
.. % when necessary via interpolating PY_FORMAT_SIZE_T.
+ .. % Similar comments apply to the %ll width modifier and
+ .. % PY_FORMAT_LONG_LONG.
+-------------------+---------------------+--------------------------------+
| Format Characters | Type | Comment |
@@ -272,6 +263,12 @@ APIs:
| :attr:`%lu` | unsigned long | Exactly equivalent to |
| | | ``printf("%lu")``. |
+-------------------+---------------------+--------------------------------+
+ | :attr:`%lld` | long long | Exactly equivalent to |
+ | | | ``printf("%lld")``. |
+ +-------------------+---------------------+--------------------------------+
+ | :attr:`%llu` | unsigned long long | Exactly equivalent to |
+ | | | ``printf("%llu")``. |
+ +-------------------+---------------------+--------------------------------+
| :attr:`%zd` | Py_ssize_t | Exactly equivalent to |
| | | ``printf("%zd")``. |
+-------------------+---------------------+--------------------------------+
@@ -295,6 +292,9 @@ APIs:
| | | of what the platform's |
| | | ``printf`` yields. |
+-------------------+---------------------+--------------------------------+
+ | :attr:`%A` | PyObject\* | The result of calling |
+ | | | :func:`ascii`. |
+ +-------------------+---------------------+--------------------------------+
| :attr:`%U` | PyObject\* | A unicode object. |
+-------------------+---------------------+--------------------------------+
| :attr:`%V` | PyObject\*, char \* | A unicode object (which may be |
@@ -305,24 +305,35 @@ APIs:
| | | *NULL*). |
+-------------------+---------------------+--------------------------------+
| :attr:`%S` | PyObject\* | The result of calling |
- | | | :func:`PyObject_Unicode`. |
+ | | | :c:func:`PyObject_Str`. |
+-------------------+---------------------+--------------------------------+
| :attr:`%R` | PyObject\* | The result of calling |
- | | | :func:`PyObject_Repr`. |
+ | | | :c:func:`PyObject_Repr`. |
+-------------------+---------------------+--------------------------------+
An unrecognized format character causes all the rest of the format string to be
copied as-is to the result string, and any extra arguments discarded.
- .. versionadded:: 2.6
+ .. note::
+
+ The `"%lld"` and `"%llu"` format specifiers are only available
+ when :const:`HAVE_LONG_LONG` is defined.
+
+ .. versionchanged:: 3.2
+ Support for ``"%lld"`` and ``"%llu"`` added.
.. c:function:: PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs)
- Identical to :func:`PyUnicode_FromFormat` except that it takes exactly two
+ Identical to :c:func:`PyUnicode_FromFormat` except that it takes exactly two
arguments.
- .. versionadded:: 2.6
+.. c:function:: PyObject* PyUnicode_TransformDecimalToASCII(Py_UNICODE *s, Py_ssize_t size)
+
+ Create a Unicode object by replacing all decimal digits in
+ :c:type:`Py_UNICODE` buffer of the given *size* by ASCII digits 0--9
+ according to their decimal value. Return *NULL* if an exception
+ occurs.
.. c:function:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode)
@@ -334,24 +345,32 @@ APIs:
most C functions.
+.. c:function:: Py_UNICODE* PyUnicode_AsUnicodeCopy(PyObject *unicode)
+
+ Create a copy of a Unicode string ending with a nul character. Return *NULL*
+ and raise a :exc:`MemoryError` exception on memory allocation failure,
+ otherwise return a new allocated buffer (use :c:func:`PyMem_Free` to free
+ the buffer). Note that the resulting :c:type:`Py_UNICODE*` string may contain
+ embedded null characters, which would cause the string to be truncated when
+ used in most C functions.
+
+ .. versionadded:: 3.2
+
+
.. c:function:: Py_ssize_t PyUnicode_GetSize(PyObject *unicode)
Return the length of the Unicode object.
- .. versionchanged:: 2.5
- This function returned an :c:type:`int` type. This might require changes
- in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_FromEncodedObject(PyObject *obj, const char *encoding, const char *errors)
Coerce an encoded object *obj* to an Unicode object and return a reference with
incremented refcount.
- String and other char buffer compatible objects are decoded according to the
- given encoding and using the error handling defined by errors. Both can be
- *NULL* to have the interface use the default values (see the next section for
- details).
+ :class:`bytes`, :class:`bytearray` and other char buffer compatible objects
+ are decoded according to the given *encoding* and using the error handling
+ defined by *errors*. Both can be *NULL* to have the interface use the default
+ values (see the next section for details).
All other objects, including Unicode objects, cause a :exc:`TypeError` to be
set.
@@ -371,6 +390,77 @@ Support is optimized if Python's own :c:type:`Py_UNICODE` type is identical to
the system's :c:type:`wchar_t`.
+File System Encoding
+""""""""""""""""""""
+
+To encode and decode file names and other environment strings,
+:c:data:`Py_FileSystemEncoding` should be used as the encoding, and
+``"surrogateescape"`` should be used as the error handler (:pep:`383`). To
+encode file names during argument parsing, the ``"O&"`` converter should be
+used, passing :c:func:`PyUnicode_FSConverter` as the conversion function:
+
+.. c:function:: int PyUnicode_FSConverter(PyObject* obj, void* result)
+
+ ParseTuple converter: encode :class:`str` objects to :class:`bytes` using
+ :c:func:`PyUnicode_EncodeFSDefault`; :class:`bytes` objects are output as-is.
+ *result* must be a :c:type:`PyBytesObject*` which must be released when it is
+ no longer used.
+
+ .. versionadded:: 3.1
+
+
+To decode file names during argument parsing, the ``"O&"`` converter should be
+used, passing :c:func:`PyUnicode_FSDecoder` as the conversion function:
+
+.. c:function:: int PyUnicode_FSDecoder(PyObject* obj, void* result)
+
+ ParseTuple converter: decode :class:`bytes` objects to :class:`str` using
+ :c:func:`PyUnicode_DecodeFSDefaultAndSize`; :class:`str` objects are output
+ as-is. *result* must be a :c:type:`PyUnicodeObject*` which must be released
+ when it is no longer used.
+
+ .. versionadded:: 3.2
+
+
+.. c:function:: PyObject* PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size)
+
+ Decode a string using :c:data:`Py_FileSystemDefaultEncoding` and the
+ ``'surrogateescape'`` error handler, or ``'strict'`` on Windows.
+
+ If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the
+ locale encoding.
+
+ .. versionchanged:: 3.2
+ Use ``'strict'`` error handler on Windows.
+
+
+.. c:function:: PyObject* PyUnicode_DecodeFSDefault(const char *s)
+
+ Decode a null-terminated string using :c:data:`Py_FileSystemDefaultEncoding`
+ and the ``'surrogateescape'`` error handler, or ``'strict'`` on Windows.
+
+ If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the
+ locale encoding.
+
+ Use :c:func:`PyUnicode_DecodeFSDefaultAndSize` if you know the string length.
+
+ .. versionchanged:: 3.2
+ Use ``'strict'`` error handler on Windows.
+
+
+.. c:function:: PyObject* PyUnicode_EncodeFSDefault(PyObject *unicode)
+
+ Encode a Unicode object to :c:data:`Py_FileSystemDefaultEncoding` with the
+ ``'surrogateescape'`` error handler, or ``'strict'`` on Windows, and return
+ :class:`bytes`. Note that the resulting :class:`bytes` object may contain
+ null bytes.
+
+ If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the
+ locale encoding.
+
+ .. versionadded:: 3.2
+
+
wchar_t Support
"""""""""""""""
@@ -379,12 +469,10 @@ wchar_t Support
.. c:function:: PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size)
Create a Unicode object from the :c:type:`wchar_t` buffer *w* of the given *size*.
+ Passing -1 as the *size* indicates that the function must itself compute the length,
+ using wcslen.
Return *NULL* on failure.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size)
@@ -398,10 +486,21 @@ wchar_t Support
might contain null characters, which would cause the string to be truncated
when used with most C functions.
- .. versionchanged:: 2.5
- This function returned an :c:type:`int` type and used an :c:type:`int`
- type for *size*. This might require changes in your code for properly
- supporting 64-bit systems.
+
+.. c:function:: wchar_t* PyUnicode_AsWideCharString(PyObject *unicode, Py_ssize_t *size)
+
+ Convert the Unicode object to a wide character string. The output string
+ always ends with a nul character. If *size* is not *NULL*, write the number
+ of wide characters (excluding the trailing 0-termination character) into
+ *\*size*.
+
+ Returns a buffer allocated by :c:func:`PyMem_Alloc` (use
+ :c:func:`PyMem_Free` to free it) on success. On error, returns *NULL*,
+ *\*size* is undefined and raises a :exc:`MemoryError`. Note that the
+ resulting :c:type:`wchar_t*` string might contain null characters, which
+ would cause the string to be truncated when used with most C functions.
+
+ .. versionadded:: 3.2
.. _builtincodecs:
@@ -413,14 +512,16 @@ Python provides a set of built-in codecs which are written in C for speed. All o
these codecs are directly usable via the following functions.
Many of the following APIs take two arguments encoding and errors, and they
-have the same semantics as the ones of the built-in :func:`unicode` Unicode
-object constructor.
+have the same semantics as the ones of the built-in :func:`str` string object
+constructor.
-Setting encoding to *NULL* causes the default encoding to be used which is
-ASCII. The file system calls should use :c:data:`Py_FileSystemDefaultEncoding`
-as the encoding for file names. This variable should be treated as read-only: on
-some systems, it will be a pointer to a static string, on others, it will change
-at run-time (such as when the application invokes setlocale).
+Setting encoding to *NULL* causes the default encoding to be used
+which is ASCII. The file system calls should use
+:c:func:`PyUnicode_FSConverter` for encoding file names. This uses the
+variable :c:data:`Py_FileSystemDefaultEncoding` internally. This
+variable should be treated as read-only: on some systems, it will be a
+pointer to a static string, on others, it will change at run-time
+(such as when the application invokes setlocale).
Error handling is set by errors which may also be set to *NULL* meaning to use
the default handling defined for the codec. Default error handling for all
@@ -444,31 +545,23 @@ These are the generic codec APIs:
using the Python codec registry. Return *NULL* if an exception was raised by
the codec.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_Encode(const Py_UNICODE *s, Py_ssize_t size, const char *encoding, const char *errors)
Encode the :c:type:`Py_UNICODE` buffer *s* of the given *size* and return a Python
- string object. *encoding* and *errors* have the same meaning as the parameters
- of the same name in the Unicode :meth:`encode` method. The codec to be used is
- looked up using the Python codec registry. Return *NULL* if an exception was
- raised by the codec.
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
+ bytes object. *encoding* and *errors* have the same meaning as the
+ parameters of the same name in the Unicode :meth:`encode` method. The codec
+ to be used is looked up using the Python codec registry. Return *NULL* if an
+ exception was raised by the codec.
.. c:function:: PyObject* PyUnicode_AsEncodedString(PyObject *unicode, const char *encoding, const char *errors)
- Encode a Unicode object and return the result as Python string object.
- *encoding* and *errors* have the same meaning as the parameters of the same name
- in the Unicode :meth:`encode` method. The codec to be used is looked up using
- the Python codec registry. Return *NULL* if an exception was raised by the
- codec.
+ Encode a Unicode object and return the result as Python bytes object.
+ *encoding* and *errors* have the same meaning as the parameters of the same
+ name in the Unicode :meth:`encode` method. The codec to be used is looked up
+ using the Python codec registry. Return *NULL* if an exception was raised by
+ the codec.
UTF-8 Codecs
@@ -482,10 +575,6 @@ These are the UTF-8 codec APIs:
Create a Unicode object by decoding *size* bytes of the UTF-8 encoded string
*s*. Return *NULL* if an exception was raised by the codec.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed)
@@ -494,28 +583,19 @@ These are the UTF-8 codec APIs:
treated as an error. Those bytes will not be decoded and the number of bytes
that have been decoded will be stored in *consumed*.
- .. versionadded:: 2.4
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_EncodeUTF8(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
- Encode the :c:type:`Py_UNICODE` buffer *s* of the given *size* using UTF-8 and return a
- Python string object. Return *NULL* if an exception was raised by the codec.
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
+ Encode the :c:type:`Py_UNICODE` buffer *s* of the given *size* using UTF-8 and
+ return a Python bytes object. Return *NULL* if an exception was raised by
+ the codec.
.. c:function:: PyObject* PyUnicode_AsUTF8String(PyObject *unicode)
- Encode a Unicode object using UTF-8 and return the result as Python string
- object. Error handling is "strict". Return *NULL* if an exception was raised
- by the codec.
+ Encode a Unicode object using UTF-8 and return the result as Python bytes
+ object. Error handling is "strict". Return *NULL* if an exception was
+ raised by the codec.
UTF-32 Codecs
@@ -551,8 +631,6 @@ These are the UTF-32 codec APIs:
Return *NULL* if an exception was raised by the codec.
- .. versionadded:: 2.6
-
.. c:function:: PyObject* PyUnicode_DecodeUTF32Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed)
@@ -562,8 +640,6 @@ These are the UTF-32 codec APIs:
by four) as an error. Those bytes will not be decoded and the number of bytes
that have been decoded will be stored in *consumed*.
- .. versionadded:: 2.6
-
.. c:function:: PyObject* PyUnicode_EncodeUTF32(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder)
@@ -582,16 +658,12 @@ These are the UTF-32 codec APIs:
Return *NULL* if an exception was raised by the codec.
- .. versionadded:: 2.6
-
.. c:function:: PyObject* PyUnicode_AsUTF32String(PyObject *unicode)
- Return a Python string using the UTF-32 encoding in native byte order. The
- string always starts with a BOM mark. Error handling is "strict". Return
- *NULL* if an exception was raised by the codec.
-
- .. versionadded:: 2.6
+ Return a Python byte string using the UTF-32 encoding in native byte
+ order. The string always starts with a BOM mark. Error handling is "strict".
+ Return *NULL* if an exception was raised by the codec.
UTF-16 Codecs
@@ -626,10 +698,6 @@ These are the UTF-16 codec APIs:
Return *NULL* if an exception was raised by the codec.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_DecodeUTF16Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed)
@@ -639,17 +707,10 @@ These are the UTF-16 codec APIs:
split surrogate pair) as an error. Those bytes will not be decoded and the
number of bytes that have been decoded will be stored in *consumed*.
- .. versionadded:: 2.4
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size* and an :c:type:`int *`
- type for *consumed*. This might require changes in your code for
- properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_EncodeUTF16(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder)
- Return a Python string object holding the UTF-16 encoded value of the Unicode
+ Return a Python bytes object holding the UTF-16 encoded value of the Unicode
data in *s*. Output is written according to the following byte order::
byteorder == -1: little endian
@@ -665,16 +726,12 @@ These are the UTF-16 codec APIs:
Return *NULL* if an exception was raised by the codec.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_AsUTF16String(PyObject *unicode)
- Return a Python string using the UTF-16 encoding in native byte order. The
- string always starts with a BOM mark. Error handling is "strict". Return
- *NULL* if an exception was raised by the codec.
+ Return a Python byte string using the UTF-16 encoding in native byte
+ order. The string always starts with a BOM mark. Error handling is "strict".
+ Return *NULL* if an exception was raised by the codec.
UTF-7 Codecs
@@ -720,10 +777,6 @@ These are the "Unicode Escape" codec APIs:
Create a Unicode object by decoding *size* bytes of the Unicode-Escape encoded
string *s*. Return *NULL* if an exception was raised by the codec.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size)
@@ -731,10 +784,6 @@ These are the "Unicode Escape" codec APIs:
return a Python string object. Return *NULL* if an exception was raised by the
codec.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode)
@@ -754,10 +803,6 @@ These are the "Raw Unicode Escape" codec APIs:
Create a Unicode object by decoding *size* bytes of the Raw-Unicode-Escape
encoded string *s*. Return *NULL* if an exception was raised by the codec.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
@@ -765,10 +810,6 @@ These are the "Raw Unicode Escape" codec APIs:
and return a Python string object. Return *NULL* if an exception was raised by
the codec.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode)
@@ -789,26 +830,19 @@ ordinals and only these are accepted by the codecs during encoding.
Create a Unicode object by decoding *size* bytes of the Latin-1 encoded string
*s*. Return *NULL* if an exception was raised by the codec.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_EncodeLatin1(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
- Encode the :c:type:`Py_UNICODE` buffer of the given *size* using Latin-1 and return
- a Python string object. Return *NULL* if an exception was raised by the codec.
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
+ Encode the :c:type:`Py_UNICODE` buffer of the given *size* using Latin-1 and
+ return a Python bytes object. Return *NULL* if an exception was raised by
+ the codec.
.. c:function:: PyObject* PyUnicode_AsLatin1String(PyObject *unicode)
- Encode a Unicode object using Latin-1 and return the result as Python string
- object. Error handling is "strict". Return *NULL* if an exception was raised
- by the codec.
+ Encode a Unicode object using Latin-1 and return the result as Python bytes
+ object. Error handling is "strict". Return *NULL* if an exception was
+ raised by the codec.
ASCII Codecs
@@ -823,26 +857,19 @@ codes generate errors.
Create a Unicode object by decoding *size* bytes of the ASCII encoded string
*s*. Return *NULL* if an exception was raised by the codec.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_EncodeASCII(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
- Encode the :c:type:`Py_UNICODE` buffer of the given *size* using ASCII and return a
- Python string object. Return *NULL* if an exception was raised by the codec.
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
+ Encode the :c:type:`Py_UNICODE` buffer of the given *size* using ASCII and
+ return a Python bytes object. Return *NULL* if an exception was raised by
+ the codec.
.. c:function:: PyObject* PyUnicode_AsASCIIString(PyObject *unicode)
- Encode a Unicode object using ASCII and return the result as Python string
- object. Error handling is "strict". Return *NULL* if an exception was raised
- by the codec.
+ Encode a Unicode object using ASCII and return the result as Python bytes
+ object. Error handling is "strict". Return *NULL* if an exception was
+ raised by the codec.
Character Map Codecs
@@ -880,13 +907,6 @@ These are the mapping codec APIs:
Byte values greater that the length of the string and U+FFFE "characters" are
treated as "undefined mapping".
- .. versionchanged:: 2.4
- Allowed unicode string as mapping argument.
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_EncodeCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *mapping, const char *errors)
@@ -894,10 +914,6 @@ These are the mapping codec APIs:
*mapping* object and return a Python string object. Return *NULL* if an
exception was raised by the codec.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping)
@@ -921,9 +937,6 @@ The following codec API is special in that maps Unicode to Unicode.
and sequences work well. Unmapped character ordinals (ones which cause a
:exc:`LookupError`) are left untouched and are copied as-is.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
MBCS codecs for Windows
@@ -934,16 +947,11 @@ use the Win32 MBCS converters to implement the conversions. Note that MBCS (or
DBCS) is a class of encodings, not just one. The target encoding is defined by
the user settings on the machine running the codec.
-
.. c:function:: PyObject* PyUnicode_DecodeMBCS(const char *s, Py_ssize_t size, const char *errors)
Create a Unicode object by decoding *size* bytes of the MBCS encoded string *s*.
Return *NULL* if an exception was raised by the codec.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, int size, const char *errors, int *consumed)
@@ -952,29 +960,25 @@ the user settings on the machine running the codec.
trailing lead byte and the number of bytes that have been decoded will be stored
in *consumed*.
- .. versionadded:: 2.5
-
.. c:function:: PyObject* PyUnicode_EncodeMBCS(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
- Encode the :c:type:`Py_UNICODE` buffer of the given *size* using MBCS and return a
- Python string object. Return *NULL* if an exception was raised by the codec.
-
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *size*. This might require
- changes in your code for properly supporting 64-bit systems.
+ Encode the :c:type:`Py_UNICODE` buffer of the given *size* using MBCS and return
+ a Python bytes object. Return *NULL* if an exception was raised by the
+ codec.
.. c:function:: PyObject* PyUnicode_AsMBCSString(PyObject *unicode)
- Encode a Unicode object using MBCS and return the result as Python string
- object. Error handling is "strict". Return *NULL* if an exception was raised
- by the codec.
+ Encode a Unicode object using MBCS and return the result as Python bytes
+ object. Error handling is "strict". Return *NULL* if an exception was
+ raised by the codec.
Methods & Slots
"""""""""""""""
+
.. _unicodemethodsandslots:
Methods and Slot Functions
@@ -999,10 +1003,6 @@ They all return *NULL* or ``-1`` if an exception occurs.
separator. At most *maxsplit* splits will be done. If negative, no limit is
set. Separators are not included in the resulting list.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *maxsplit*. This might require
- changes in your code for properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend)
@@ -1039,11 +1039,6 @@ They all return *NULL* or ``-1`` if an exception occurs.
(*direction* == -1 means to do a prefix match, *direction* == 1 a suffix match),
0 otherwise. Return ``-1`` if an error occurred.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *start* and *end*. This
- might require changes in your code for properly supporting 64-bit
- systems.
-
.. c:function:: Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction)
@@ -1053,22 +1048,12 @@ They all return *NULL* or ``-1`` if an exception occurs.
``-1`` indicates that no match was found, and ``-2`` indicates that an error
occurred and an exception has been set.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *start* and *end*. This
- might require changes in your code for properly supporting 64-bit
- systems.
-
.. c:function:: Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end)
Return the number of non-overlapping occurrences of *substr* in
``str[start:end]``. Return ``-1`` if an error occurred.
- .. versionchanged:: 2.5
- This function returned an :c:type:`int` type and used an :c:type:`int`
- type for *start* and *end*. This might require changes in your code for
- properly supporting 64-bit systems.
-
.. c:function:: PyObject* PyUnicode_Replace(PyObject *str, PyObject *substr, PyObject *replstr, Py_ssize_t maxcount)
@@ -1076,10 +1061,6 @@ They all return *NULL* or ``-1`` if an exception occurs.
return the resulting Unicode object. *maxcount* == -1 means replace all
occurrences.
- .. versionchanged:: 2.5
- This function used an :c:type:`int` type for *maxcount*. This might
- require changes in your code for properly supporting 64-bit systems.
-
.. c:function:: int PyUnicode_Compare(PyObject *left, PyObject *right)
@@ -1087,6 +1068,14 @@ They all return *NULL* or ``-1`` if an exception occurs.
respectively.
+.. c:function:: int PyUnicode_CompareWithASCIIString(PyObject *uni, char *string)
+
+ Compare a unicode object, *uni*, with *string* and return -1, 0, 1 for less
+ than, equal, and greater than, respectively. It is best to pass only
+ ASCII-encoded strings, but the function interprets the input string as
+ ISO-8859-1 if it contains non-ASCII characters".
+
+
.. c:function:: int PyUnicode_RichCompare(PyObject *left, PyObject *right, int op)
Rich compare two unicode strings and return one of the following:
@@ -1116,3 +1105,25 @@ They all return *NULL* or ``-1`` if an exception occurs.
*element* has to coerce to a one element Unicode string. ``-1`` is returned if
there was an error.
+
+
+.. c:function:: void PyUnicode_InternInPlace(PyObject **string)
+
+ Intern the argument *\*string* in place. The argument must be the address of a
+ pointer variable pointing to a Python unicode string object. If there is an
+ existing interned string that is the same as *\*string*, it sets *\*string* to
+ it (decrementing the reference count of the old string object and incrementing
+ the reference count of the interned string object), otherwise it leaves
+ *\*string* alone and interns it (incrementing its reference count).
+ (Clarification: even though there is a lot of talk about reference counts, think
+ of this function as reference-count-neutral; you own the object after the call
+ if and only if you owned it before the call.)
+
+
+.. c:function:: PyObject* PyUnicode_InternFromString(const char *v)
+
+ A combination of :c:func:`PyUnicode_FromString` and
+ :c:func:`PyUnicode_InternInPlace`, returning either a new unicode string object
+ that has been interned, or a new ("owned") reference to an earlier interned
+ string object with the same value.
+
diff --git a/Doc/c-api/utilities.rst b/Doc/c-api/utilities.rst
index f43933b..d4484fb 100644
--- a/Doc/c-api/utilities.rst
+++ b/Doc/c-api/utilities.rst
@@ -1,6 +1,5 @@
.. highlightlang:: c
-
.. _utilities:
*********
diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst
index 4ce3b03..41cdd6b 100644
--- a/Doc/c-api/veryhigh.rst
+++ b/Doc/c-api/veryhigh.rst
@@ -25,16 +25,17 @@ are only passed to these functions if it is certain that they were created by
the same library that the Python runtime is using.
-.. c:function:: int Py_Main(int argc, char **argv)
+.. c:function:: int Py_Main(int argc, wchar_t **argv)
The main program for the standard interpreter. This is made available for
programs which embed Python. The *argc* and *argv* parameters should be
prepared exactly as those which are passed to a C program's :c:func:`main`
- function. It is important to note that the argument list may be modified (but
- the contents of the strings pointed to by the argument list are not). The return
- value will be ``0`` if the interpreter exits normally (ie, without an
- exception), ``1`` if the interpreter exits due to an exception, or ``2``
- if the parameter list does not represent a valid Python command line.
+ function (converted to wchar_t according to the user's locale). It is
+ important to note that the argument list may be modified (but the contents of
+ the strings pointed to by the argument list are not). The return value will
+ be ``0`` if the interpreter exits normally (i.e., without an exception),
+ ``1`` if the interpreter exits due to an exception, or ``2`` if the parameter
+ list does not represent a valid Python command line.
Note that if an otherwise unhandled :exc:`SystemExit` is raised, this
function will not return ``1``, but exit the process, as long as
@@ -64,8 +65,9 @@ the same library that the Python runtime is using.
If *fp* refers to a file associated with an interactive device (console or
terminal input or Unix pseudo-terminal), return the value of
:c:func:`PyRun_InteractiveLoop`, otherwise return the result of
- :c:func:`PyRun_SimpleFile`. If *filename* is *NULL*, this function uses
- ``"???"`` as the filename.
+ :c:func:`PyRun_SimpleFile`. *filename* is decoded from the filesystem
+ encoding (:func:`sys.getfilesystemencoding`). If *filename* is *NULL*, this
+ function uses ``"???"`` as the filename.
.. c:function:: int PyRun_SimpleString(const char *command)
@@ -108,9 +110,10 @@ the same library that the Python runtime is using.
.. c:function:: int PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, PyCompilerFlags *flags)
Similar to :c:func:`PyRun_SimpleStringFlags`, but the Python source code is read
- from *fp* instead of an in-memory string. *filename* should be the name of the
- file. If *closeit* is true, the file is closed before PyRun_SimpleFileExFlags
- returns.
+ from *fp* instead of an in-memory string. *filename* should be the name of
+ the file, it is decoded from the filesystem encoding
+ (:func:`sys.getfilesystemencoding`). If *closeit* is true, the file is
+ closed before PyRun_SimpleFileExFlags returns.
.. c:function:: int PyRun_InteractiveOne(FILE *fp, const char *filename)
@@ -123,7 +126,10 @@ the same library that the Python runtime is using.
Read and execute a single statement from a file associated with an
interactive device according to the *flags* argument. The user will be
- prompted using ``sys.ps1`` and ``sys.ps2``. Returns ``0`` when the input was
+ prompted using ``sys.ps1`` and ``sys.ps2``. *filename* is decoded from the
+ filesystem encoding (:func:`sys.getfilesystemencoding`).
+
+ Returns ``0`` when the input was
executed successfully, ``-1`` if there was an exception, or an error code
from the :file:`errcode.h` include file distributed as part of Python if
there was a parse error. (Note that :file:`errcode.h` is not included by
@@ -140,7 +146,8 @@ the same library that the Python runtime is using.
Read and execute statements from a file associated with an interactive device
until EOF is reached. The user will be prompted using ``sys.ps1`` and
- ``sys.ps2``. Returns ``0`` at EOF.
+ ``sys.ps2``. *filename* is decoded from the filesystem encoding
+ (:func:`sys.getfilesystemencoding`). Returns ``0`` at EOF.
.. c:function:: struct _node* PyParser_SimpleParseString(const char *str, int start)
@@ -162,7 +169,8 @@ the same library that the Python runtime is using.
Parse Python source code from *str* using the start token *start* according to
the *flags* argument. The result can be used to create a code object which can
be evaluated efficiently. This is useful if a code fragment must be evaluated
- many times.
+ many times. *filename* is decoded from the filesystem encoding
+ (:func:`sys.getfilesystemencoding`).
.. c:function:: struct _node* PyParser_SimpleParseFile(FILE *fp, const char *filename, int start)
@@ -215,7 +223,8 @@ the same library that the Python runtime is using.
.. c:function:: PyObject* PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, int closeit, PyCompilerFlags *flags)
Similar to :c:func:`PyRun_StringFlags`, but the Python source code is read from
- *fp* instead of an in-memory string. *filename* should be the name of the file.
+ *fp* instead of an in-memory string. *filename* should be the name of the file,
+ it is decoded from the filesystem encoding (:func:`sys.getfilesystemencoding`).
If *closeit* is true, the file is closed before :c:func:`PyRun_FileExFlags`
returns.
@@ -228,23 +237,38 @@ the same library that the Python runtime is using.
.. c:function:: PyObject* Py_CompileStringFlags(const char *str, const char *filename, int start, PyCompilerFlags *flags)
+ This is a simplified interface to :c:func:`Py_CompileStringExFlags` below, with
+ *optimize* set to ``-1``.
+
+
+.. c:function:: PyObject* Py_CompileStringExFlags(const char *str, const char *filename, int start, PyCompilerFlags *flags, int optimize)
+
Parse and compile the Python source code in *str*, returning the resulting code
object. The start token is given by *start*; this can be used to constrain the
code which can be compiled and should be :const:`Py_eval_input`,
:const:`Py_file_input`, or :const:`Py_single_input`. The filename specified by
*filename* is used to construct the code object and may appear in tracebacks or
- :exc:`SyntaxError` exception messages. This returns *NULL* if the code cannot
- be parsed or compiled.
+ :exc:`SyntaxError` exception messages, it is decoded from the filesystem
+ encoding (:func:`sys.getfilesystemencoding`). This returns *NULL* if the
+ code cannot be parsed or compiled.
+
+ The integer *optimize* specifies the optimization level of the compiler; a
+ value of ``-1`` selects the optimization level of the interpreter as given by
+ :option:`-O` options. Explicit levels are ``0`` (no optimization;
+ ``__debug__`` is true), ``1`` (asserts are removed, ``__debug__`` is false)
+ or ``2`` (docstrings are removed too).
+
+ .. versionadded:: 3.2
-.. c:function:: PyObject* PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
+.. c:function:: PyObject* PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals)
This is a simplified interface to :c:func:`PyEval_EvalCodeEx`, with just
the code object, and the dictionaries of global and local variables.
The other arguments are set to *NULL*.
-.. c:function:: PyObject* PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, PyObject **defs, int defcount, PyObject *closure)
+.. c:function:: PyObject* PyEval_EvalCodeEx(PyObject *co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, PyObject **defs, int defcount, PyObject *closure)
Evaluate a precompiled code object, given a particular environment for its
evaluation. This environment consists of dictionaries of global and local
diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst
index 243cfd1..6cb3e33 100644
--- a/Doc/c-api/weakref.rst
+++ b/Doc/c-api/weakref.rst
@@ -15,22 +15,16 @@ as much as it can.
Return true if *ob* is either a reference or proxy object.
- .. versionadded:: 2.2
-
.. c:function:: int PyWeakref_CheckRef(ob)
Return true if *ob* is a reference object.
- .. versionadded:: 2.2
-
.. c:function:: int PyWeakref_CheckProxy(ob)
Return true if *ob* is a proxy object.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyWeakref_NewRef(PyObject *ob, PyObject *callback)
@@ -43,8 +37,6 @@ as much as it can.
weakly-referencable object, or if *callback* is not callable, ``None``, or
*NULL*, this will return *NULL* and raise :exc:`TypeError`.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
@@ -57,17 +49,13 @@ as much as it can.
is not a weakly-referencable object, or if *callback* is not callable,
``None``, or *NULL*, this will return *NULL* and raise :exc:`TypeError`.
- .. versionadded:: 2.2
-
.. c:function:: PyObject* PyWeakref_GetObject(PyObject *ref)
Return the referenced object from a weak reference, *ref*. If the referent is
no longer live, returns :const:`Py_None`.
- .. versionadded:: 2.2
-
- .. warning::
+ .. note::
This function returns a **borrowed reference** to the referenced object.
This means that you should always call :c:func:`Py_INCREF` on the object
@@ -79,5 +67,3 @@ as much as it can.
Similar to :c:func:`PyWeakref_GetObject`, but implemented as a macro that does no
error checking.
-
- .. versionadded:: 2.2
diff --git a/Doc/conf.py b/Doc/conf.py
index b6d212d..555f281 100644
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Python documentation build configuration file
#
@@ -59,13 +58,19 @@ add_function_parentheses = True
# unit titles (such as .. function::).
add_module_names = True
+# By default, highlight as Python 3.
+highlight_language = 'python3'
+
# Options for HTML output
# -----------------------
-html_theme = 'default'
+html_theme = 'pydoctheme'
+html_theme_path = ['tools/sphinxext']
html_theme_options = {'collapsiblesidebar': True}
+html_short_title = '%s Documentation' % release
+
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
html_last_updated_fmt = '%b %d, %Y'
@@ -86,7 +91,7 @@ html_additional_pages = {
}
# Output an OpenSearch description file.
-html_use_opensearch = 'http://docs.python.org/'
+html_use_opensearch = 'http://docs.python.org/3.2'
# Additional static files.
html_static_path = ['tools/sphinxext/static']
diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat
index 1fc896f..b5dde33 100644
--- a/Doc/data/refcounts.dat
+++ b/Doc/data/refcounts.dat
@@ -344,10 +344,6 @@ PyErr_Format:PyObject*:exception:+1:
PyErr_Format:char*:format::
PyErr_Format::...::
-PyErr_Warn:int:::
-PyErr_Warn:PyObject*:category:0:
-PyErr_Warn:char*:message::
-
PyErr_WarnEx:int:::
PyErr_WarnEx:PyObject*:category:0:
PyErr_WarnEx:const char*:message::
@@ -380,6 +376,8 @@ PyEval_EvalCode:PyCodeObject*:co:0:
PyEval_EvalCode:PyObject*:globals:0:
PyEval_EvalCode:PyObject*:locals:0:
+PyException_GetTraceback:PyObject*::+1:
+
PyFile_AsFile:FILE*:::
PyFile_AsFile:PyFileObject*:p:0:
@@ -392,6 +390,15 @@ PyFile_FromFile:char*:name::
PyFile_FromFile:char*:mode::
PyFile_FromFile:int(*:close)::
+PyFile_FromFileEx:PyObject*::+1:
+PyFile_FromFileEx:FILE*:fp::
+PyFile_FromFileEx:char*:name::
+PyFile_FromFileEx:char*:mode::
+PyFile_FromFileEx:int(*:close)::
+PyFile_FromFileEx:int:buffering::
+PyFile_FromFileEx:char*:encoding::
+PyFile_FromFileEx:char*:newline::
+
PyFile_FromString:PyObject*::+1:
PyFile_FromString:char*:name::
PyFile_FromString:char*:mode::
@@ -435,7 +442,6 @@ PyFloat_FromDouble:double:v::
PyFloat_FromString:PyObject*::+1:
PyFloat_FromString:PyObject*:str:0:
-PyFloat_FromString:char**:pend:0:ignored
PyFrozenSet_New:PyObject*::+1:
PyFrozenSet_New:PyObject*:iterable:0:
@@ -638,9 +644,6 @@ PyLong_AsDouble:PyObject*:pylong:0:
PyLong_AsLong:long:::
PyLong_AsLong:PyObject*:pylong:0:
-PyLong_AsSsize_t:ssize_t:::
-PyLong_AsSsize_t:PyObject*:pylong:0:
-
PyLong_AsUnsignedLong:unsigned long:::
PyLong_AsUnsignedLong:PyObject*:pylong:0:
@@ -659,12 +662,6 @@ PyLong_FromLongLong:long long:v::
PyLong_FromUnsignedLongLong:PyObject*::+1:
PyLong_FromUnsignedLongLong:unsigned long long:v::
-PyLong_FromSize_t:PyObject*::+1:
-PyLong_FromSize_t:size_t:v::
-
-PyLong_FromSsize_t:PyObject*::+1:
-PyLong_FromSsize_t:ssize_t:v::
-
PyLong_FromString:PyObject*::+1:
PyLong_FromString:char*:str::
PyLong_FromString:char**:pend::
@@ -783,10 +780,6 @@ PyNumber_And:PyObject*:o2:0:
PyNumber_Check:PyObject*:o:0:
PyNumber_Check:int:::
-PyNumber_Coerce:int:::
-PyNumber_Coerce:PyObject**:p1:+1:
-PyNumber_Coerce:PyObject**:p2:+1:
-
PyNumber_Divide:PyObject*::+1:
PyNumber_Divide:PyObject*:o1:0:
PyNumber_Divide:PyObject*:o2:0:
@@ -855,9 +848,6 @@ PyNumber_InPlaceXor:PyObject*::+1:
PyNumber_InPlaceXor:PyObject*:v:0:
PyNumber_InPlaceXor:PyObject*:w:0:
-PyNumber_Int:PyObject*::+1:
-PyNumber_Int:PyObject*:o:0:
-
PyNumber_Invert:PyObject*::+1:
PyNumber_Invert:PyObject*:o:0:
@@ -1317,13 +1307,14 @@ PyString_AsEncodedString:const char*:errors::
PySys_AddWarnOption:void:::
PySys_AddWarnOption:char*:s::
-PySys_GetFile:FILE*:::
-PySys_GetFile:char*:name::
-PySys_GetFile:FILE*:def::
+PySys_AddXOption:void:::
+PySys_AddXOption:const wchar_t*:s::
PySys_GetObject:PyObject*::0:
PySys_GetObject:char*:name::
+PySys_GetXOptions:PyObject*::0:
+
PySys_SetArgv:int:::
PySys_SetArgv:int:argc::
PySys_SetArgv:char**:argv::
@@ -1482,21 +1473,6 @@ PyUnicode_FromEncodedObject:PyObject*:*obj:0:
PyUnicode_FromEncodedObject:const char*:encoding::
PyUnicode_FromEncodedObject:const char*:errors::
-PyUnicode_FromFormat:PyObject*::+1:
-PyUnicode_FromFormat:const char*:format::
-PyUnicode_FromFormat::...::
-
-PyUnicode_FromFormatV:PyObject*::+1:
-PyUnicode_FromFormatV:const char*:format::
-PyUnicode_FromFormatV:va_list:vargs::
-
-PyUnicode_FromString:PyObject*::+1:
-PyUnicode_FromString:const char*:u::
-
-PyUnicode_FromStringAndSize:PyObject*::+1:
-PyUnicode_FromStringAndSize:const char*:u::
-PyUnicode_FromStringAndSize:ssize_t:size::
-
PyUnicode_FromWideChar:PyObject*::+1:
PyUnicode_FromWideChar:const wchar_t*:w::
PyUnicode_FromWideChar:int:size::
@@ -1764,11 +1740,6 @@ Py_FdIsInteractive:char*:filename::
Py_Finalize:void:::
-Py_FindMethod:PyObject*::+1:
-Py_FindMethod:PyMethodDef[]:methods::
-Py_FindMethod:PyObject*:self:+1:
-Py_FindMethod:char*:name::
-
Py_GetBuildInfoconst:char*:::
Py_GetCompilerconst:char*:::
@@ -1819,9 +1790,6 @@ _PyImport_FixupExtension:char*:::
_PyImport_Init:void:::
-_PyObject_Del:void:::
-_PyObject_Del:PyObject*:op:0:
-
_PyObject_New:PyObject*::+1:
_PyObject_New:PyTypeObject*:type:0:
diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst
index 76567ad..74fba4a 100644
--- a/Doc/distutils/apiref.rst
+++ b/Doc/distutils/apiref.rst
@@ -115,7 +115,7 @@ setup script). Indirectly provides the :class:`distutils.dist.Distribution` and
args from *script* to :func:`setup`), or the contents of the config files or
command-line.
- *script_name* is a file that will be run with :func:`execfile` ``sys.argv[0]``
+ *script_name* is a file that will be read and run with :func:`exec`. ``sys.argv[0]``
will be replaced with *script* for the duration of the call. *script_args* is a
list of strings; if supplied, ``sys.argv[1:]`` will be replaced by *script_args*
for the duration of the call.
@@ -261,6 +261,11 @@ the full reference.
| | from the source extensions if | |
| | not provided. | |
+------------------------+--------------------------------+---------------------------+
+ | *optional* | specifies that a build failure | a boolean |
+ | | in the extension should not | |
+ | | abort the build process, but | |
+ | | simply skip the extension. | |
+ +------------------------+--------------------------------+---------------------------+
.. class:: Distribution
@@ -947,7 +952,7 @@ This module provides functions for operating on directories and trees of
directories.
-.. function:: mkpath(name[, mode=0777, verbose=0, dry_run=0])
+.. function:: mkpath(name[, mode=0o777, verbose=0, dry_run=0])
Create a directory and any missing ancestor directories. If the directory
already exists (or if *name* is the empty string, which means the current
@@ -958,7 +963,7 @@ directories.
directories actually created.
-.. function:: create_tree(base_dir, files[, mode=0777, verbose=0, dry_run=0])
+.. function:: create_tree(base_dir, files[, mode=0o777, verbose=0, dry_run=0])
Create all the empty directories under *base_dir* needed to put *files* there.
*base_dir* is just the a name of a directory which doesn't necessarily exist
@@ -973,8 +978,8 @@ directories.
Copy an entire directory tree *src* to a new location *dst*. Both *src* and
*dst* must be directory names. If *src* is not a directory, raise
:exc:`DistutilsFileError`. If *dst* does not exist, it is created with
- :func:`mkpath`. The end result of the copy is that every file in *src* is
- copied to *dst*, and directories under *src* are recursively copied to *dst*.
+ :func:`mkpath`. The end result of the copy is that every file in *src* is
+ copied to *dst*, and directories under *src* are recursively copied to *dst*.
Return the list of files that were copied or might have been copied, using their
output name. The return value is unaffected by *update* or *dry_run*: it is
simply the list of all files under *src*, with the names changed to be under
@@ -991,10 +996,9 @@ directories.
these files is available in answer D2 of the `NFS FAQ page
<http://nfs.sourceforge.net/#section_d>`_.
- .. versionchanged:: 2.7.4
+ .. versionchanged:: 3.2.4
NFS files are ignored.
-
.. function:: remove_tree(directory[, verbose=0, dry_run=0])
Recursively remove *directory* and all files and directories underneath it. Any
@@ -1201,9 +1205,9 @@ other utility module.
.. function:: byte_compile(py_files[, optimize=0, force=0, prefix=None, base_dir=None, verbose=1, dry_run=0, direct=None])
Byte-compile a collection of Python source files to either :file:`.pyc` or
- :file:`.pyo` files in the same directory. *py_files* is a list of files to
- compile; any files that don't end in :file:`.py` are silently skipped.
- *optimize* must be one of the following:
+ :file:`.pyo` files in a :file:`__pycache__` subdirectory (see :pep:`3147`).
+ *py_files* is a list of files to compile; any files that don't end in
+ :file:`.py` are silently skipped. *optimize* must be one of the following:
* ``0`` - don't optimize (generate :file:`.pyc`)
* ``1`` - normal optimization (like ``python -O``)
@@ -1228,6 +1232,11 @@ other utility module.
is used by the script generated in indirect mode; unless you know what you're
doing, leave it set to ``None``.
+ .. versionchanged:: 3.2.3
+ Create ``.pyc`` or ``.pyo`` files with an :func:`import magic tag
+ <imp.get_tag>` in their name, in a :file:`__pycache__` subdirectory
+ instead of files without tag in the current directory.
+
.. function:: rfc822_escape(header)
@@ -1313,7 +1322,6 @@ provides the following additional features:
the "negative alias" of :option:`--verbose`, then :option:`--quiet` on the
command line sets *verbose* to false.
-
.. function:: fancy_getopt(options, negative_opt, object, args)
Wrapper function. *options* is a list of ``(long_option, short_option,
@@ -1330,7 +1338,6 @@ provides the following additional features:
Wraps *text* to less than *width* wide.
-
.. class:: FancyGetopt([option_table=None])
The option_table is a list of 3-tuples: ``(long_option, short_option,
@@ -1888,6 +1895,27 @@ Subclasses of :class:`Command` must define the following methods.
:synopsis: Build the .py/.pyc files of a package
+.. class:: build_py
+
+.. class:: build_py_2to3
+
+ Alternative implementation of build_py which also runs the
+ 2to3 conversion library on each .py file that is going to be
+ installed. To use this in a setup.py file for a distribution
+ that is designed to run with both Python 2.x and 3.x, add::
+
+ try:
+ from distutils.command.build_py import build_py_2to3 as build_py
+ except ImportError:
+ from distutils.command.build_py import build_py
+
+ to your setup.py, and later::
+
+ cmdclass = {'build_py': build_py}
+
+ to the invocation of setup().
+
+
:mod:`distutils.command.build_scripts` --- Build the scripts of a package
=========================================================================
diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst
index 7a11459..d1ab7db 100644
--- a/Doc/distutils/builtdist.rst
+++ b/Doc/distutils/builtdist.rst
@@ -139,13 +139,13 @@ The following sections give details on the individual :command:`bdist_\*`
commands.
-.. _creating-dumb:
+.. .. _creating-dumb:
-Creating dumb built distributions
-=================================
+.. Creating dumb built distributions
+.. =================================
.. XXX Need to document absolute vs. prefix-relative packages here, but first
- I have to implement it!
+ I have to implement it!
.. _creating-rpms:
@@ -239,8 +239,7 @@ tedious and error-prone, so it's usually best to put them in the setup
configuration file, :file:`setup.cfg`\ ---see section :ref:`setup-config`. If
you distribute or package many Python module distributions, you might want to
put options that apply to all of them in your personal Distutils configuration
-file (:file:`~/.pydistutils.cfg`). If you want to temporarily disable
-this file, you can pass the --no-user-cfg option to setup.py.
+file (:file:`~/.pydistutils.cfg`).
There are three steps to building a binary RPM package, all of which are
handled automatically by the Distutils:
diff --git a/Doc/distutils/commandref.rst b/Doc/distutils/commandref.rst
index 7282961..6a2ac96 100644
--- a/Doc/distutils/commandref.rst
+++ b/Doc/distutils/commandref.rst
@@ -48,6 +48,50 @@ This command installs all (Python) scripts in the distribution.
.. % \label{clean-cmd}
+.. _sdist-cmd:
+
+Creating a source distribution: the :command:`sdist` command
+============================================================
+
+.. XXX fragment moved down from above: needs context!
+
+The manifest template commands are:
+
++-------------------------------------------+-----------------------------------------------+
+| Command | Description |
++===========================================+===============================================+
+| :command:`include pat1 pat2 ...` | include all files matching any of the listed |
+| | patterns |
++-------------------------------------------+-----------------------------------------------+
+| :command:`exclude pat1 pat2 ...` | exclude all files matching any of the listed |
+| | patterns |
++-------------------------------------------+-----------------------------------------------+
+| :command:`recursive-include dir pat1 pat2 | include all files under *dir* matching any of |
+| ...` | the listed patterns |
++-------------------------------------------+-----------------------------------------------+
+| :command:`recursive-exclude dir pat1 pat2 | exclude all files under *dir* matching any of |
+| ...` | the listed patterns |
++-------------------------------------------+-----------------------------------------------+
+| :command:`global-include pat1 pat2 ...` | include all files anywhere in the source tree |
+| | matching --- & any of the listed patterns |
++-------------------------------------------+-----------------------------------------------+
+| :command:`global-exclude pat1 pat2 ...` | exclude all files anywhere in the source tree |
+| | matching --- & any of the listed patterns |
++-------------------------------------------+-----------------------------------------------+
+| :command:`prune dir` | exclude all files under *dir* |
++-------------------------------------------+-----------------------------------------------+
+| :command:`graft dir` | include all files under *dir* |
++-------------------------------------------+-----------------------------------------------+
+
+The patterns here are Unix-style "glob" patterns: ``*`` matches any sequence of
+regular filename characters, ``?`` matches any single regular filename
+character, and ``[range]`` matches any of the characters in *range* (e.g.,
+``a-z``, ``a-zA-Z``, ``a-f0-9_.``). The definition of "regular filename
+character" is platform-specific: on Unix it is anything except slash; on Windows
+anything except backslash or colon.
+
+.. XXX Windows support not there yet
+
.. % \section{Creating a built distribution: the
.. % \protect\command{bdist} command family}
.. % \label{bdist-cmds}
diff --git a/Doc/distutils/examples.rst b/Doc/distutils/examples.rst
index b495928..b268486 100644
--- a/Doc/distutils/examples.rst
+++ b/Doc/distutils/examples.rst
@@ -233,9 +233,61 @@ With exactly the same source tree layout, this extension can be put in the
ext_modules=[Extension('foopkg.foo', ['foo.c'])],
)
+Checking a package
+==================
+
+The ``check`` command allows you to verify if your package meta-data
+meet the minimum requirements to build a distribution.
+
+To run it, just call it using your :file:`setup.py` script. If something is
+missing, ``check`` will display a warning.
+
+Let's take an example with a simple script::
+
+ from distutils.core import setup
+
+ setup(name='foobar')
+
+Running the ``check`` command will display some warnings::
+
+ $ python setup.py check
+ running check
+ warning: check: missing required meta-data: version, url
+ warning: check: missing meta-data: either (author and author_email) or
+ (maintainer and maintainer_email) must be supplied
+
+
+If you use the reStructuredText syntax in the ``long_description`` field and
+`docutils`_ is installed you can check if the syntax is fine with the
+``check`` command, using the ``restructuredtext`` option.
+
+For example, if the :file:`setup.py` script is changed like this::
+
+ from distutils.core import setup
+
+ desc = """\
+ My description
+ =============
+
+ This is the description of the ``foobar`` package.
+ """
+
+ setup(name='foobar', version='1', author='tarek',
+ author_email='tarek@ziade.org',
+ url='http://example.com', long_description=desc)
+
+Where the long description is broken, ``check`` will be able to detect it
+by using the :mod:`docutils` parser::
+
+ $ python setup.py check --restructuredtext
+ running check
+ warning: check: Title underline too short. (line 2)
+ warning: check: Could not finish the parsing.
+
.. % \section{Multiple extension modules}
.. % \label{multiple-ext}
.. % \section{Putting it all together}
+.. _docutils: http://docutils.sourceforge.net
diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst
index fc6184f..0ece646 100644
--- a/Doc/distutils/introduction.rst
+++ b/Doc/distutils/introduction.rst
@@ -84,7 +84,7 @@ terminal::
python setup.py sdist
-For Windows, open a command prompt windows (:menuselection:`Start -->
+For Windows, open a command prompt window (:menuselection:`Start -->
Accessories`) and change the command to::
setup.py sdist
@@ -193,7 +193,7 @@ modules using the Distutils:
module distribution
a collection of Python modules distributed together as a single downloadable
resource and meant to be installed *en masse*. Examples of some well-known
- module distributions are Numeric Python, PyXML, PIL (the Python Imaging
+ module distributions are NumPy, SciPy, PIL (the Python Imaging
Library), or mxBase. (This would be called a *package*, except that term is
already taken in the Python context: a single module distribution may contain
zero, one, or many Python packages.)
diff --git a/Doc/distutils/setupscript.rst b/Doc/distutils/setupscript.rst
index 165bfcd..8029243 100644
--- a/Doc/distutils/setupscript.rst
+++ b/Doc/distutils/setupscript.rst
@@ -334,6 +334,10 @@ Other options
There are still some other options which can be used to handle special cases.
+The :option:`optional` option is a boolean; if it is true,
+a build failure in the extension will not abort the build process, but
+instead simply not install the failing extension.
+
The :option:`extra_objects` option is a list of object files to be passed to the
linker. These files must not have extensions, as the default extension for the
compiler is used.
@@ -450,9 +454,10 @@ way. From the PyXML setup script::
scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val']
)
-.. versionchanged:: 2.7
- All the scripts will also be added to the ``MANIFEST``
- file if no template is provided. See :ref:`manifest`.
+.. versionchanged:: 3.1
+ All the scripts will also be added to the ``MANIFEST`` file if no template is
+ provided. See :ref:`manifest`.
+
.. _distutils-installing-package-data:
@@ -496,11 +501,10 @@ The corresponding call to :func:`setup` might be::
package_data={'mypkg': ['data/*.dat']},
)
-.. versionadded:: 2.4
-.. versionchanged:: 2.7
- All the files that match ``package_data`` will be added to the ``MANIFEST``
- file if no template is provided. See :ref:`manifest`.
+.. versionchanged:: 3.1
+ All the files that match ``package_data`` will be added to the ``MANIFEST``
+ file if no template is provided. See :ref:`manifest`.
.. _distutils-additional-files:
@@ -539,10 +543,9 @@ without specifying a target directory, but this is not recommended, and the
files directly in the target directory, an empty string should be given as the
directory.
-.. versionchanged:: 2.7
- All the files that match ``data_files`` will be added to the ``MANIFEST``
- file if no template is provided. See :ref:`manifest`.
-
+.. versionchanged:: 3.1
+ All the files that match ``data_files`` will be added to the ``MANIFEST``
+ file if no template is provided. See :ref:`manifest`.
.. _meta-data:
@@ -626,8 +629,6 @@ Notes:
'list of strings'
See below.
-None of the string values may be Unicode.
-
Encoding the version information is an art in itself. Python packages generally
adhere to the version format *major.minor[.patch][sub]*. The major number is 0
for initial, experimental releases of software. It is incremented for releases
diff --git a/Doc/distutils/sourcedist.rst b/Doc/distutils/sourcedist.rst
index b1695a2..1666436 100644
--- a/Doc/distutils/sourcedist.rst
+++ b/Doc/distutils/sourcedist.rst
@@ -26,16 +26,16 @@ to create a gzipped tarball and a zip file. The available formats are:
+===========+=========================+=========+
| ``zip`` | zip file (:file:`.zip`) | (1),(3) |
+-----------+-------------------------+---------+
-| ``gztar`` | gzip'ed tar file | \(2) |
+| ``gztar`` | gzip'ed tar file | (2),(4) |
| | (:file:`.tar.gz`) | |
+-----------+-------------------------+---------+
-| ``bztar`` | bzip2'ed tar file | |
+| ``bztar`` | bzip2'ed tar file | \(4) |
| | (:file:`.tar.bz2`) | |
+-----------+-------------------------+---------+
| ``ztar`` | compressed tar file | \(4) |
| | (:file:`.tar.Z`) | |
+-----------+-------------------------+---------+
-| ``tar`` | tar file (:file:`.tar`) | |
+| ``tar`` | tar file (:file:`.tar`) | \(4) |
+-----------+-------------------------+---------+
Notes:
@@ -51,15 +51,8 @@ Notes:
of the standard Python library since Python 1.6)
(4)
- requires the :program:`compress` program.
-
-When using any ``tar`` format (``gztar``, ``bztar``, ``ztar`` or
-``tar``) under Unix, you can specify the ``owner`` and ``group`` names
-that will be set for each member of the archive.
-
-For example, if you want all files of the archive to be owned by root::
-
- python setup.py sdist --owner=root --group=root
+ requires external utilities: :program:`tar` and possibly one of :program:`gzip`,
+ :program:`bzip2`, or :program:`compress`
.. _manifest:
@@ -75,10 +68,10 @@ source distribution:
:option:`packages` options
* all C source files mentioned in the :option:`ext_modules` or
- :option:`libraries` options
+ :option:`libraries` options (
- .. XXX Getting C library sources is currently broken -- no
- :meth:`get_source_files` method in :file:`build_clib.py`!
+ .. XXX getting C library sources currently broken---no
+ :meth:`get_source_files` method in :file:`build_clib.py`!
* scripts identified by the :option:`scripts` option
See :ref:`distutils-installing-scripts`.
@@ -110,74 +103,23 @@ per line, regular files (or symlinks to them) only. If you do supply your own
:file:`MANIFEST`, you must specify everything: the default set of files
described above does not apply in this case.
-.. versionchanged:: 2.7
+.. versionchanged:: 3.1
An existing generated :file:`MANIFEST` will be regenerated without
:command:`sdist` comparing its modification time to the one of
:file:`MANIFEST.in` or :file:`setup.py`.
-.. versionchanged:: 2.7.1
+.. versionchanged:: 3.1.3
:file:`MANIFEST` files start with a comment indicating they are generated.
Files without this comment are not overwritten or removed.
-.. versionchanged:: 2.7.3
+.. versionchanged:: 3.2.2
:command:`sdist` will read a :file:`MANIFEST` file if no :file:`MANIFEST.in`
- exists, like it did before 2.7.
-
-See :ref:`manifest_template` section for a syntax reference.
-
-
-.. _manifest-options:
-
-Manifest-related options
-========================
-
-The normal course of operations for the :command:`sdist` command is as follows:
+ exists, like it used to do.
-* if the manifest file (:file:`MANIFEST` by default) exists and the first line
- does not have a comment indicating it is generated from :file:`MANIFEST.in`,
- then it is used as is, unaltered
-
-* if the manifest file doesn't exist or has been previously automatically
- generated, read :file:`MANIFEST.in` and create the manifest
-
-* if neither :file:`MANIFEST` nor :file:`MANIFEST.in` exist, create a manifest
- with just the default file set
-
-* use the list of files now in :file:`MANIFEST` (either just generated or read
- in) to create the source distribution archive(s)
-
-There are a couple of options that modify this behaviour. First, use the
-:option:`--no-defaults` and :option:`--no-prune` to disable the standard
-"include" and "exclude" sets.
-
-Second, you might just want to (re)generate the manifest, but not create a
-source distribution::
-
- python setup.py sdist --manifest-only
-
-:option:`-o` is a shortcut for :option:`--manifest-only`.
-
-.. _manifest_template:
-
-The MANIFEST.in template
-========================
-
-A :file:`MANIFEST.in` file can be added in a project to define the list of
-files to include in the distribution built by the :command:`sdist` command.
-
-When :command:`sdist` is run, it will look for the :file:`MANIFEST.in` file
-and interpret it to generate the :file:`MANIFEST` file that contains the
-list of files that will be included in the package.
-
-This mechanism can be used when the default list of files is not enough.
-(See :ref:`manifest`).
-
-Principle
----------
The manifest template has one command per line, where each command specifies a
set of files to include or exclude from the source distribution. For an
-example, let's look at the Distutils' own manifest template::
+example, again we turn to the Distutils' own manifest template::
include *.txt
recursive-include examples *.txt *.py
@@ -189,7 +131,9 @@ matching :file:`\*.txt` or :file:`\*.py`, and exclude all directories matching
:file:`examples/sample?/build`. All of this is done *after* the standard
include set, so you can exclude files from the standard set with explicit
instructions in the manifest template. (Or, you can use the
-:option:`--no-defaults` option to disable the standard set entirely.)
+:option:`--no-defaults` option to disable the standard set entirely.) There are
+several other commands available in the manifest template mini-language; see
+section :ref:`sdist-cmd`.
The order of commands in the manifest template matters: initially, we have the
list of default files as described above, and each command in the template adds
@@ -243,40 +187,34 @@ should always be slash-separated; the Distutils will take care of converting
them to the standard representation on your platform. That way, the manifest
template is portable across operating systems.
-Commands
---------
-
-The manifest template commands are:
-
-+-------------------------------------------+-----------------------------------------------+
-| Command | Description |
-+===========================================+===============================================+
-| :command:`include pat1 pat2 ...` | include all files matching any of the listed |
-| | patterns |
-+-------------------------------------------+-----------------------------------------------+
-| :command:`exclude pat1 pat2 ...` | exclude all files matching any of the listed |
-| | patterns |
-+-------------------------------------------+-----------------------------------------------+
-| :command:`recursive-include dir pat1 pat2 | include all files under *dir* matching any of |
-| ...` | the listed patterns |
-+-------------------------------------------+-----------------------------------------------+
-| :command:`recursive-exclude dir pat1 pat2 | exclude all files under *dir* matching any of |
-| ...` | the listed patterns |
-+-------------------------------------------+-----------------------------------------------+
-| :command:`global-include pat1 pat2 ...` | include all files anywhere in the source tree |
-| | matching --- & any of the listed patterns |
-+-------------------------------------------+-----------------------------------------------+
-| :command:`global-exclude pat1 pat2 ...` | exclude all files anywhere in the source tree |
-| | matching --- & any of the listed patterns |
-+-------------------------------------------+-----------------------------------------------+
-| :command:`prune dir` | exclude all files under *dir* |
-+-------------------------------------------+-----------------------------------------------+
-| :command:`graft dir` | include all files under *dir* |
-+-------------------------------------------+-----------------------------------------------+
-
-The patterns here are Unix-style "glob" patterns: ``*`` matches any sequence of
-regular filename characters, ``?`` matches any single regular filename
-character, and ``[range]`` matches any of the characters in *range* (e.g.,
-``a-z``, ``a-zA-Z``, ``a-f0-9_.``). The definition of "regular filename
-character" is platform-specific: on Unix it is anything except slash; on Windows
-anything except backslash or colon.
+
+.. _manifest-options:
+
+Manifest-related options
+========================
+
+The normal course of operations for the :command:`sdist` command is as follows:
+
+* if the manifest file (:file:`MANIFEST` by default) exists and the first line
+ does not have a comment indicating it is generated from :file:`MANIFEST.in`,
+ then it is used as is, unaltered
+
+* if the manifest file doesn't exist or has been previously automatically
+ generated, read :file:`MANIFEST.in` and create the manifest
+
+* if neither :file:`MANIFEST` nor :file:`MANIFEST.in` exist, create a manifest
+ with just the default file set
+
+* use the list of files now in :file:`MANIFEST` (either just generated or read
+ in) to create the source distribution archive(s)
+
+There are a couple of options that modify this behaviour. First, use the
+:option:`--no-defaults` and :option:`--no-prune` to disable the standard
+"include" and "exclude" sets.
+
+Second, you might just want to (re)generate the manifest, but not create a source
+distribution::
+
+ python setup.py sdist --manifest-only
+
+:option:`-o` is a shortcut for :option:`--manifest-only`.
diff --git a/Doc/distutils/uploading.rst b/Doc/distutils/uploading.rst
index 12ee328..bfb392e 100644
--- a/Doc/distutils/uploading.rst
+++ b/Doc/distutils/uploading.rst
@@ -4,8 +4,6 @@
Uploading Packages to the Package Index
***************************************
-.. versionadded:: 2.5
-
The Python Package Index (PyPI) not only stores the package info, but also the
package data if the author of the package wishes to. The distutils command
:command:`upload` pushes the distribution files to PyPI.
@@ -69,8 +67,8 @@ In that case, :file:`README.txt` is a regular reStructuredText text file located
in the root of the package besides :file:`setup.py`.
To prevent registering broken reStructuredText content, you can use the
-:program:`rst2html` program that is provided by the :mod:`docutils` package
-and check the ``long_description`` from the command line::
+:program:`rst2html` program that is provided by the :mod:`docutils` package and
+check the ``long_description`` from the command line::
$ python setup.py --long-description | rst2html.py > output.html
diff --git a/Doc/extending/embedding.rst b/Doc/extending/embedding.rst
index ed2b5bf..d7cdee6 100644
--- a/Doc/extending/embedding.rst
+++ b/Doc/extending/embedding.rst
@@ -35,9 +35,6 @@ stdio file pointer and a file name (for identification in error messages only)
to :c:func:`PyRun_SimpleFile`. You can also call the lower-level operations
described in the previous chapters to construct and use Python objects.
-A simple demo of embedding Python can be found in the directory
-:file:`Demo/embed/` of the source distribution.
-
.. seealso::
@@ -64,7 +61,7 @@ perform some operation on a file. ::
Py_SetProgramName(argv[0]); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
- "print 'Today is',ctime(time())\n");
+ "print('Today is', ctime(time()))\n");
Py_Finalize();
return 0;
}
@@ -139,11 +136,12 @@ The code to run a function defined in a Python script is:
This code loads a Python script using ``argv[1]``, and calls the function named
in ``argv[2]``. Its integer arguments are the other values of the ``argv``
-array. If you compile and link this program (let's call the finished executable
-:program:`call`), and use it to execute a Python script, such as::
+array. If you :ref:`compile and link <compiling>` this program (let's call
+the finished executable :program:`call`), and use it to execute a Python
+script, such as::
def multiply(a,b):
- print "Will compute", a, "times", b
+ print("Will compute", a, "times", b)
c = 0
for i in range(0, a):
c = c + b
@@ -160,13 +158,13 @@ for data conversion between Python and C, and for error reporting. The
interesting part with respect to embedding Python starts with ::
Py_Initialize();
- pName = PyString_FromString(argv[1]);
+ pName = PyUnicode_FromString(argv[1]);
/* Error checking of pName left out */
pModule = PyImport_Import(pName);
After initializing the interpreter, the script is loaded using
:c:func:`PyImport_Import`. This routine needs a Python string as its argument,
-which is constructed using the :c:func:`PyString_FromString` data conversion
+which is constructed using the :c:func:`PyUnicode_FromString` data conversion
routine. ::
pFunc = PyObject_GetAttrString(pModule, argv[2]);
@@ -212,7 +210,7 @@ Python extension. For example::
{
if(!PyArg_ParseTuple(args, ":numargs"))
return NULL;
- return Py_BuildValue("i", numargs);
+ return PyLong_FromLong(numargs);
}
static PyMethodDef EmbMethods[] = {
@@ -221,18 +219,29 @@ Python extension. For example::
{NULL, NULL, 0, NULL}
};
+ static PyModuleDef EmbModule = {
+ PyModuleDef_HEAD_INIT, "emb", NULL, -1, EmbMethods,
+ NULL, NULL, NULL, NULL
+ };
+
+ static PyObject*
+ PyInit_emb(void)
+ {
+ return PyModule_Create(&EmbModule);
+ }
+
Insert the above code just above the :c:func:`main` function. Also, insert the
-following two statements directly after :c:func:`Py_Initialize`::
+following two statements before the call to :c:func:`Py_Initialize`::
numargs = argc;
- Py_InitModule("emb", EmbMethods);
+ PyImport_AppendInittab("emb", &PyInit_emb);
These two lines initialize the ``numargs`` variable, and make the
:func:`emb.numargs` function accessible to the embedded Python interpreter.
With these extensions, the Python script can do things like ::
import emb
- print "Number of arguments", emb.numargs()
+ print("Number of arguments", emb.numargs())
In a real application, the methods will expose an API of the application to
Python.
@@ -252,37 +261,53 @@ write the main program in C++, and use the C++ compiler to compile and link your
program. There is no need to recompile Python itself using C++.
-.. _link-reqs:
-
-Linking Requirements
-====================
-
-While the :program:`configure` script shipped with the Python sources will
-correctly build Python to export the symbols needed by dynamically linked
-extensions, this is not automatically inherited by applications which embed the
-Python library statically, at least on Unix. This is an issue when the
-application is linked to the static runtime library (:file:`libpython.a`) and
-needs to load dynamic extensions (implemented as :file:`.so` files).
+.. _compiling:
-The problem is that some entry points are defined by the Python runtime solely
-for extension modules to use. If the embedding application does not use any of
-these entry points, some linkers will not include those entries in the symbol
-table of the finished executable. Some additional options are needed to inform
-the linker not to remove these symbols.
-
-Determining the right options to use for any given platform can be quite
-difficult, but fortunately the Python configuration already has those values.
-To retrieve them from an installed Python interpreter, start an interactive
-interpreter and have a short session like this::
+Compiling and Linking under Unix-like systems
+=============================================
- >>> import distutils.sysconfig
- >>> distutils.sysconfig.get_config_var('LINKFORSHARED')
+It is not necessarily trivial to find the right flags to pass to your
+compiler (and linker) in order to embed the Python interpreter into your
+application, particularly because Python needs to load library modules
+implemented as C dynamic extensions (:file:`.so` files) linked against
+it.
+
+To find out the required compiler and linker flags, you can execute the
+:file:`python{X.Y}-config` script which is generated as part of the
+installation process (a :file:`python3-config` script may also be
+available). This script has several options, of which the following will
+be directly useful to you:
+
+* ``pythonX.Y-config --cflags`` will give you the recommended flags when
+ compiling::
+
+ $ /opt/bin/python3.2-config --cflags
+ -I/opt/include/python3.2m -I/opt/include/python3.2m -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes
+
+* ``pythonX.Y-config --ldflags`` will give you the recommended flags when
+ linking::
+
+ $ /opt/bin/python3.2-config --ldflags
+ -I/opt/lib/python3.2/config-3.2m -lpthread -ldl -lutil -lm -lpython3.2m -Xlinker -export-dynamic
+
+.. note::
+ To avoid confusion between several Python installations (and especially
+ between the system Python and your own compiled Python), it is recommended
+ that you use the absolute path to :file:`python{X.Y}-config`, as in the above
+ example.
+
+If this procedure doesn't work for you (it is not guaranteed to work for
+all Unix-like platforms; however, we welcome :ref:`bug reports <reporting-bugs>`)
+you will have to read your system's documentation about dynamic linking and/or
+examine Python's :file:`Makefile` (use :func:`sysconfig.get_makefile_filename`
+to find its location) and compilation
+options. In this case, the :mod:`sysconfig` module is a useful tool to
+programmatically extract the configuration values that you will want to
+combine together::
+
+ >>> import sysconfig
+ >>> sysconfig.get_config_var('LINKFORSHARED')
'-Xlinker -export-dynamic'
-.. index:: module: distutils.sysconfig
-
-The contents of the string presented will be the options that should be used.
-If the string is empty, there's no need to add any additional options. The
-:const:`LINKFORSHARED` definition corresponds to the variable of the same name
-in Python's top-level :file:`Makefile`.
+.. XXX similar documentation for Windows missing
diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst
index eb18a46..7fd9f72 100644
--- a/Doc/extending/extending.rst
+++ b/Doc/extending/extending.rst
@@ -81,7 +81,7 @@ shortly how it ends up being called)::
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
- return Py_BuildValue("i", sts);
+ return PyLong_FromLong(sts);
}
There is a straightforward translation from the argument list in Python (for
@@ -120,10 +120,9 @@ inside the interpreter; if this variable is *NULL* no exception has occurred. A
second global variable stores the "associated value" of the exception (the
second argument to :keyword:`raise`). A third variable contains the stack
traceback in case the error originated in Python code. These three variables
-are the C equivalents of the Python variables ``sys.exc_type``,
-``sys.exc_value`` and ``sys.exc_traceback`` (see the section on module
-:mod:`sys` in the Python Library Reference). It is important to know about them
-to understand how errors are passed around.
+are the C equivalents of the result in Python of :meth:`sys.exc_info` (see the
+section on module :mod:`sys` in the Python Library Reference). It is important
+to know about them to understand how errors are passed around.
The Python API defines a number of functions to set various types of exceptions.
@@ -171,7 +170,7 @@ error on to the interpreter but wants to handle it completely by itself
Every failing :c:func:`malloc` call must be turned into an exception --- the
direct caller of :c:func:`malloc` (or :c:func:`realloc`) must call
:c:func:`PyErr_NoMemory` and return a failure indicator itself. All the
-object-creating functions (for example, :c:func:`PyInt_FromLong`) already do
+object-creating functions (for example, :c:func:`PyLong_FromLong`) already do
this, so this note is only relevant to those who call :c:func:`malloc` directly.
Also note that, with the important exception of :c:func:`PyArg_ParseTuple` and
@@ -197,21 +196,22 @@ usually declare a static object variable at the beginning of your file::
static PyObject *SpamError;
-and initialize it in your module's initialization function (:c:func:`initspam`)
+and initialize it in your module's initialization function (:c:func:`PyInit_spam`)
with an exception object (leaving out the error checking for now)::
PyMODINIT_FUNC
- initspam(void)
+ PyInit_spam(void)
{
PyObject *m;
- m = Py_InitModule("spam", SpamMethods);
+ m = PyModule_Create(&spammodule);
if (m == NULL)
- return;
+ return NULL;
SpamError = PyErr_NewException("spam.error", NULL, NULL);
Py_INCREF(SpamError);
PyModule_AddObject(m, "error", SpamError);
+ return m;
}
Note that the Python name for the exception object is :exc:`spam.error`. The
@@ -274,12 +274,9 @@ the string we just got from :c:func:`PyArg_ParseTuple`::
sts = system(command);
Our :func:`spam.system` function must return the value of :c:data:`sts` as a
-Python object. This is done using the function :c:func:`Py_BuildValue`, which is
-something like the inverse of :c:func:`PyArg_ParseTuple`: it takes a format
-string and an arbitrary number of C values, and returns a new Python object.
-More info on :c:func:`Py_BuildValue` is given later. ::
+Python object. This is done using the function :c:func:`PyLong_FromLong`. ::
- return Py_BuildValue("i", sts);
+ return PyLong_FromLong(sts);
In this case, it will return an integer object. (Yes, even integers are objects
on the heap in Python!)
@@ -324,53 +321,68 @@ parameters to be passed in as a tuple acceptable for parsing via
The :const:`METH_KEYWORDS` bit may be set in the third field if keyword
arguments should be passed to the function. In this case, the C function should
-accept a third ``PyObject *`` parameter which will be a dictionary of keywords.
+accept a third ``PyObject \*`` parameter which will be a dictionary of keywords.
Use :c:func:`PyArg_ParseTupleAndKeywords` to parse the arguments to such a
function.
-The method table must be passed to the interpreter in the module's
+The method table must be referenced in the module definition structure::
+
+ static struct PyModuleDef spammodule = {
+ PyModuleDef_HEAD_INIT,
+ "spam", /* name of module */
+ spam_doc, /* module documentation, may be NULL */
+ -1, /* size of per-interpreter state of the module,
+ or -1 if the module keeps state in global variables. */
+ SpamMethods
+ };
+
+This structure, in turn, must be passed to the interpreter in the module's
initialization function. The initialization function must be named
-:c:func:`initname`, where *name* is the name of the module, and should be the
+:c:func:`PyInit_name`, where *name* is the name of the module, and should be the
only non-\ ``static`` item defined in the module file::
PyMODINIT_FUNC
- initspam(void)
+ PyInit_spam(void)
{
- (void) Py_InitModule("spam", SpamMethods);
+ return PyModule_Create(&spammodule);
}
-Note that PyMODINIT_FUNC declares the function as ``void`` return type,
-declares any special linkage declarations required by the platform, and for C++
+Note that PyMODINIT_FUNC declares the function as ``PyObject *`` return type,
+declares any special linkage declarations required by the platform, and for C++
declares the function as ``extern "C"``.
When the Python program imports module :mod:`spam` for the first time,
-:c:func:`initspam` is called. (See below for comments about embedding Python.)
-It calls :c:func:`Py_InitModule`, which creates a "module object" (which is
-inserted in the dictionary ``sys.modules`` under the key ``"spam"``), and
+:c:func:`PyInit_spam` is called. (See below for comments about embedding Python.)
+It calls :c:func:`PyModule_Create`, which returns a module object, and
inserts built-in function objects into the newly created module based upon the
-table (an array of :c:type:`PyMethodDef` structures) that was passed as its
-second argument. :c:func:`Py_InitModule` returns a pointer to the module object
-that it creates (which is unused here). It may abort with a fatal error for
+table (an array of :c:type:`PyMethodDef` structures) found in the module definition.
+:c:func:`PyModule_Create` returns a pointer to the module object
+that it creates. It may abort with a fatal error for
certain errors, or return *NULL* if the module could not be initialized
-satisfactorily.
+satisfactorily. The init function must return the module object to its caller,
+so that it then gets inserted into ``sys.modules``.
-When embedding Python, the :c:func:`initspam` function is not called
-automatically unless there's an entry in the :c:data:`_PyImport_Inittab` table.
-The easiest way to handle this is to statically initialize your
-statically-linked modules by directly calling :c:func:`initspam` after the call
-to :c:func:`Py_Initialize`::
+When embedding Python, the :c:func:`PyInit_spam` function is not called
+automatically unless there's an entry in the :c:data:`PyImport_Inittab` table.
+To add the module to the initialization table, use :c:func:`PyImport_AppendInittab`,
+optionally followed by an import of the module::
int
main(int argc, char *argv[])
{
+ /* Add a built-in module, before Py_Initialize */
+ PyImport_AppendInittab("spam", PyInit_spam);
+
/* Pass argv[0] to the Python interpreter */
Py_SetProgramName(argv[0]);
/* Initialize the Python interpreter. Required. */
Py_Initialize();
- /* Add a static module */
- initspam();
+ /* Optionally import the module; alternatively,
+ import can be deferred until the embedded script
+ imports it. */
+ PyImport_ImportModule("spam");
An example may be found in the file :file:`Demo/embed/demo.c` in the Python
source distribution.
@@ -381,11 +393,7 @@ source distribution.
multiple interpreters within a process (or following a :c:func:`fork` without an
intervening :c:func:`exec`) can create problems for some extension modules.
Extension module authors should exercise caution when initializing internal data
- structures. Note also that the :func:`reload` function can be used with
- extension modules, and will call the module initialization function
- (:c:func:`initspam` in the example), but will not load the module again if it was
- loaded from a dynamically loadable object file (:file:`.so` on Unix,
- :file:`.dll` on Windows).
+ structures.
A more substantial example module is included in the Python source distribution
as :file:`Modules/xxmodule.c`. This file may be used as a template or simply
@@ -596,11 +604,16 @@ Note that any Python object references which are provided to the caller are
Some example calls::
+ #define PY_SSIZE_T_CLEAN /* Make "s#" use Py_ssize_t rather than int. */
+ #include <Python.h>
+
+::
+
int ok;
int i, j;
long k, l;
const char *s;
- int size;
+ Py_ssize_t size;
ok = PyArg_ParseTuple(args, ""); /* No arguments */
/* Python call: f() */
@@ -722,13 +735,18 @@ Philbrick (philbrick@hks.com)::
{NULL, NULL, 0, NULL} /* sentinel */
};
-::
+ static struct PyModuleDef keywdargmodule = {
+ PyModuleDef_HEAD_INIT,
+ "keywdarg",
+ NULL,
+ -1,
+ keywdarg_methods
+ };
- void
- initkeywdarg(void)
+ PyMODINIT_FUNC
+ PyInit_keywdarg(void)
{
- /* Create the module and add the functions */
- Py_InitModule("keywdarg", keywdarg_methods);
+ return PyModule_Create(&keywdargmodule);
}
@@ -761,8 +779,10 @@ Examples (to the left the call, to the right the resulting Python value)::
Py_BuildValue("i", 123) 123
Py_BuildValue("iii", 123, 456, 789) (123, 456, 789)
Py_BuildValue("s", "hello") 'hello'
+ Py_BuildValue("y", "hello") b'hello'
Py_BuildValue("ss", "hello", "world") ('hello', 'world')
Py_BuildValue("s#", "hello", 4) 'hell'
+ Py_BuildValue("y#", "hello", 4) b'hell'
Py_BuildValue("()") ()
Py_BuildValue("(i)", 123) (123,)
Py_BuildValue("(ii)", 123, 456) (123, 456)
@@ -849,10 +869,9 @@ to run the detector (the :func:`collect` function), as well as configuration
interfaces and the ability to disable the detector at runtime. The cycle
detector is considered an optional component; though it is included by default,
it can be disabled at build time using the :option:`--without-cycle-gc` option
-to the :program:`configure` script on Unix platforms (including Mac OS X) or by
-removing the definition of ``WITH_CYCLE_GC`` in the :file:`pyconfig.h` header on
-other platforms. If the cycle detector is disabled in this way, the :mod:`gc`
-module will not be available.
+to the :program:`configure` script on Unix platforms (including Mac OS X). If
+the cycle detector is disabled in this way, the :mod:`gc` module will not be
+available.
.. _refcountsinpython:
@@ -908,10 +927,10 @@ reference or not.
Most functions that return a reference to an object pass on ownership with the
reference. In particular, all functions whose function it is to create a new
-object, such as :c:func:`PyInt_FromLong` and :c:func:`Py_BuildValue`, pass
+object, such as :c:func:`PyLong_FromLong` and :c:func:`Py_BuildValue`, pass
ownership to the receiver. Even if the object is not actually new, you still
receive ownership of a new reference to that object. For instance,
-:c:func:`PyInt_FromLong` maintains a cache of popular values and can return a
+:c:func:`PyLong_FromLong` maintains a cache of popular values and can return a
reference to a cached item.
Many functions that extract objects from other objects also transfer ownership
@@ -961,7 +980,7 @@ an unrelated object while borrowing a reference to a list item. For instance::
{
PyObject *item = PyList_GetItem(list, 0);
- PyList_SetItem(list, 1, PyInt_FromLong(0L));
+ PyList_SetItem(list, 1, PyLong_FromLong(0L));
PyObject_Print(item, stdout, 0); /* BUG! */
}
@@ -993,7 +1012,7 @@ increment the reference count. The correct version of the function reads::
PyObject *item = PyList_GetItem(list, 0);
Py_INCREF(item);
- PyList_SetItem(list, 1, PyInt_FromLong(0L));
+ PyList_SetItem(list, 1, PyLong_FromLong(0L));
PyObject_Print(item, stdout, 0);
Py_DECREF(item);
}
@@ -1178,7 +1197,7 @@ The function :c:func:`spam_system` is modified in a trivial way::
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = PySpam_System(command);
- return Py_BuildValue("i", sts);
+ return PyLong_FromLong(sts);
}
In the beginning of the module, right after the line ::
@@ -1195,15 +1214,15 @@ exporting module, not a client module. Finally, the module's initialization
function must take care of initializing the C API pointer array::
PyMODINIT_FUNC
- initspam(void)
+ PyInit_spam(void)
{
PyObject *m;
static void *PySpam_API[PySpam_API_pointers];
PyObject *c_api_object;
- m = Py_InitModule("spam", SpamMethods);
+ m = PyModule_Create(&spammodule);
if (m == NULL)
- return;
+ return NULL;
/* Initialize the C API pointer array */
PySpam_API[PySpam_System_NUM] = (void *)PySpam_System;
@@ -1213,10 +1232,11 @@ function must take care of initializing the C API pointer array::
if (c_api_object != NULL)
PyModule_AddObject(m, "_C_API", c_api_object);
+ return m;
}
Note that ``PySpam_API`` is declared ``static``; otherwise the pointer
-array would disappear when :func:`initspam` terminates!
+array would disappear when :func:`PyInit_spam` terminates!
The bulk of the work is in the header file :file:`spammodule.h`, which looks
like this::
@@ -1274,16 +1294,17 @@ All that a client module must do in order to have access to the function
:c:func:`import_spam` in its initialization function::
PyMODINIT_FUNC
- initclient(void)
+ PyInit_client(void)
{
PyObject *m;
- m = Py_InitModule("client", ClientMethods);
+ m = PyModule_Create(&clientmodule);
if (m == NULL)
- return;
+ return NULL;
if (import_spam() < 0)
- return;
+ return NULL;
/* additional initialization can happen here */
+ return m;
}
The main disadvantage of this approach is that the file :file:`spammodule.h` is
diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst
index 269c8fd..3001415 100644
--- a/Doc/extending/newtypes.rst
+++ b/Doc/extending/newtypes.rst
@@ -19,14 +19,6 @@ strings and lists in core Python.
This is not hard; the code for all extension types follows a pattern, but there
are some details that you need to understand before you can get started.
-.. note::
-
- The way new types are defined changed dramatically (and for the better) in
- Python 2.2. This document documents how to define new types for Python 2.2 and
- later. If you need to support older versions of Python, you will need to refer
- to `older versions of this documentation
- <http://www.python.org/doc/versions/>`_.
-
.. _dnt-basics:
@@ -69,37 +61,36 @@ probably will! (On Windows, MSVC is known to call this an error and refuse to
compile the code.)
For contrast, let's take a look at the corresponding definition for standard
-Python integers::
+Python floats::
typedef struct {
PyObject_HEAD
- long ob_ival;
- } PyIntObject;
+ double ob_fval;
+ } PyFloatObject;
Moving on, we come to the crunch --- the type object. ::
static PyTypeObject noddy_NoddyType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "noddy.Noddy", /*tp_name*/
- sizeof(noddy_NoddyObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- 0, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "noddy.Noddy", /* tp_name */
+ sizeof(noddy_NoddyObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
"Noddy objects", /* tp_doc */
};
@@ -111,23 +102,16 @@ it's common practice to not specify them explicitly unless you need them.
This is so important that we're going to pick the top of it apart still
further::
- PyObject_HEAD_INIT(NULL)
+ PyVarObject_HEAD_INIT(NULL, 0)
This line is a bit of a wart; what we'd like to write is::
- PyObject_HEAD_INIT(&PyType_Type)
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
as the type of a type object is "type", but this isn't strictly conforming C and
some compilers complain. Fortunately, this member will be filled in for us by
:c:func:`PyType_Ready`. ::
- 0, /* ob_size */
-
-The :attr:`ob_size` field of the header is not used; its presence in the type
-structure is a historical artifact that is maintained for binary compatibility
-with extension modules compiled for older versions of Python. Always set this
-field to zero. ::
-
"noddy.Noddy", /* tp_name */
The name of our type. This will appear in the default textual representation of
@@ -169,7 +153,7 @@ for now.
Skipping a number of type methods that we don't provide, we set the class flags
to :const:`Py_TPFLAGS_DEFAULT`. ::
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
All types should include this constant in their flags. It enables all of the
members defined by the current version of Python.
@@ -200,7 +184,7 @@ All the other type methods are *NULL*, so we'll go over them later --- that's
for a later section!
Everything else in the file should be familiar, except for some code in
-:c:func:`initnoddy`::
+:c:func:`PyInit_noddy`::
if (PyType_Ready(&noddy_NoddyType) < 0)
return;
@@ -280,7 +264,7 @@ allocation and deallocation. At a minimum, we need a deallocation method::
{
Py_XDECREF(self->first);
Py_XDECREF(self->last);
- self->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
}
which is assigned to the :attr:`tp_dealloc` member::
@@ -530,8 +514,8 @@ object being created or used, so all we need to do is to add the
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
-We rename :c:func:`initnoddy` to :c:func:`initnoddy2` and update the module name
-passed to :c:func:`Py_InitModule3`.
+We rename :c:func:`PyInit_noddy` to :c:func:`PyInit_noddy2` and update the module
+name in the :c:type:`PyModuleDef` struct.
Finally, we update our :file:`setup.py` file to build the new module::
@@ -733,9 +717,8 @@ For each subobject that can participate in cycles, we need to call the
*arg* passed to the traversal method. It returns an integer value that must be
returned if it is non-zero.
-Python 2.4 and higher provide a :c:func:`Py_VISIT` macro that automates calling
-visit functions. With :c:func:`Py_VISIT`, :c:func:`Noddy_traverse` can be
-simplified::
+Python provides a :c:func:`Py_VISIT` macro that automates calling visit
+functions. With :c:func:`Py_VISIT`, :c:func:`Noddy_traverse` can be simplified::
static int
Noddy_traverse(Noddy *self, visitproc visit, void *arg)
@@ -775,7 +758,7 @@ to use it::
Noddy_dealloc(Noddy* self)
{
Noddy_clear(self);
- self->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
}
Notice the use of a temporary variable in :c:func:`Noddy_clear`. We use the
@@ -788,9 +771,9 @@ collection is run, our :attr:`tp_traverse` handler could get called. We can't
take a chance of having :c:func:`Noddy_traverse` called when a member's reference
count has dropped to zero and its value hasn't been set to *NULL*.
-Python 2.4 and higher provide a :c:func:`Py_CLEAR` that automates the careful
-decrementing of reference counts. With :c:func:`Py_CLEAR`, the
-:c:func:`Noddy_clear` function can be simplified::
+Python provides a :c:func:`Py_CLEAR` that automates the careful decrementing of
+reference counts. With :c:func:`Py_CLEAR`, the :c:func:`Noddy_clear` function can
+be simplified::
static int
Noddy_clear(Noddy *self)
@@ -802,7 +785,7 @@ decrementing of reference counts. With :c:func:`Py_CLEAR`, the
Finally, we add the :const:`Py_TPFLAGS_HAVE_GC` flag to the class flags::
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
That's pretty much it. If we had written custom :attr:`tp_alloc` or
:attr:`tp_free` slots, we'd need to modify them for cyclic-garbage collection.
@@ -825,11 +808,11 @@ increases an internal counter. ::
>>> import shoddy
>>> s = shoddy.Shoddy(range(3))
>>> s.extend(s)
- >>> print len(s)
+ >>> print(len(s))
6
- >>> print s.increment()
+ >>> print(s.increment())
1
- >>> print s.increment()
+ >>> print(s.increment())
2
.. literalinclude:: ../includes/shoddy.c
@@ -873,20 +856,21 @@ fill that field directly with the :c:func:`PyList_Type`; it can be done later in
the module's :c:func:`init` function. ::
PyMODINIT_FUNC
- initshoddy(void)
+ PyInit_shoddy(void)
{
PyObject *m;
ShoddyType.tp_base = &PyList_Type;
if (PyType_Ready(&ShoddyType) < 0)
- return;
+ return NULL;
- m = Py_InitModule3("shoddy", NULL, "Shoddy module");
+ m = PyModule_Create(&shoddymodule);
if (m == NULL)
- return;
+ return NULL;
Py_INCREF(&ShoddyType);
PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType);
+ return m;
}
Before calling :c:func:`PyType_Ready`, the type structure must have the
@@ -968,7 +952,7 @@ needs to be freed here as well. Here is an example of this function::
newdatatype_dealloc(newdatatypeobject * obj)
{
free(obj->obj_UnderlyingDatatypePtr);
- obj->ob_type->tp_free(obj);
+ Py_TYPE(obj)->tp_free(obj);
}
.. index::
@@ -1011,7 +995,7 @@ done. This can be done using the :c:func:`PyErr_Fetch` and
Py_DECREF(self->my_callback);
}
- obj->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(obj)->tp_free((PyObject*)self);
}
@@ -1022,21 +1006,14 @@ Object Presentation
builtin: repr
builtin: str
-In Python, there are three ways to generate a textual representation of an
-object: the :func:`repr` function (or equivalent back-tick syntax), the
-:func:`str` function, and the :keyword:`print` statement. For most objects, the
-:keyword:`print` statement is equivalent to the :func:`str` function, but it is
-possible to special-case printing to a :c:type:`FILE\*` if necessary; this should
-only be done if efficiency is identified as a problem and profiling suggests
-that creating a temporary string object to be written to a file is too
-expensive.
+In Python, there are two ways to generate a textual representation of an object:
+the :func:`repr` function, and the :func:`str` function. (The :func:`print`
+function just calls :func:`str`.) These handlers are both optional.
-These handlers are all optional, and most types at most need to implement the
-:attr:`tp_str` and :attr:`tp_repr` handlers. ::
+::
reprfunc tp_repr;
reprfunc tp_str;
- printfunc tp_print;
The :attr:`tp_repr` handler should return a string object containing a
representation of the instance for which it is called. Here is a simple
@@ -1069,34 +1046,6 @@ Here is a simple example::
obj->obj_UnderlyingDatatypePtr->size);
}
-The print function will be called whenever Python needs to "print" an instance
-of the type. For example, if 'node' is an instance of type TreeNode, then the
-print function is called when Python code calls::
-
- print node
-
-There is a flags argument and one flag, :const:`Py_PRINT_RAW`, and it suggests
-that you print without string quotes and possibly without interpreting escape
-sequences.
-
-The print function receives a file object as an argument. You will likely want
-to write to that file object.
-
-Here is a sample print function::
-
- static int
- newdatatype_print(newdatatypeobject *obj, FILE *fp, int flags)
- {
- if (flags & Py_PRINT_RAW) {
- fprintf(fp, "<{newdatatype object--size: %d}>",
- obj->obj_UnderlyingDatatypePtr->size);
- }
- else {
- fprintf(fp, "\"<{newdatatype object--size: %d}>\"",
- obj->obj_UnderlyingDatatypePtr->size);
- }
- return 0;
- }
Attribute Management
@@ -1117,8 +1066,8 @@ sense for the implementation's convenience. ::
getattrfunc tp_getattr; /* char * version */
setattrfunc tp_setattr;
/* ... */
- getattrofunc tp_getattrofunc; /* PyObject * version */
- setattrofunc tp_setattrofunc;
+ getattrofunc tp_getattro; /* PyObject * version */
+ setattrofunc tp_setattro;
If accessing attributes of an object is always a simple operation (this will be
explained shortly), there are generic implementations which can be used to
@@ -1133,8 +1082,6 @@ not been updated to use some of the new generic mechanism that is available.
Generic Attribute Management
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. versionadded:: 2.2
-
Most extension types only use *simple* attributes. So, what makes the
attributes simple? There are only a couple of conditions that must be met:
@@ -1209,8 +1156,6 @@ combined using bitwise-OR.
+===========================+==============================================+
| :const:`READONLY` | Never writable. |
+---------------------------+----------------------------------------------+
-| :const:`RO` | Shorthand for :const:`READONLY`. |
-+---------------------------+----------------------------------------------+
| :const:`READ_RESTRICTED` | Not readable in restricted mode. |
+---------------------------+----------------------------------------------+
| :const:`WRITE_RESTRICTED` | Not writable in restricted mode. |
@@ -1220,7 +1165,6 @@ combined using bitwise-OR.
.. index::
single: READONLY
- single: RO
single: READ_RESTRICTED
single: WRITE_RESTRICTED
single: RESTRICTED
@@ -1251,9 +1195,7 @@ For simplicity, only the :c:type:`char\*` version will be demonstrated here; the
type of the name parameter is the only difference between the :c:type:`char\*`
and :c:type:`PyObject\*` flavors of the interface. This example effectively does
the same thing as the generic example above, but does not use the generic
-support added in Python 2.2. The value in showing this is two-fold: it
-demonstrates how basic attribute management can be done in a way that is
-portable to older versions of Python, and explains how the handler functions are
+support added in Python 2.2. It explains how the handler functions are
called, so that if you do need to extend their functionality, you'll understand
what needs to be done.
@@ -1261,27 +1203,20 @@ The :attr:`tp_getattr` handler is called when the object requires an attribute
look-up. It is called in the same situations where the :meth:`__getattr__`
method of a class would be called.
-A likely way to handle this is (1) to implement a set of functions (such as
-:c:func:`newdatatype_getSize` and :c:func:`newdatatype_setSize` in the example
-below), (2) provide a method table listing these functions, and (3) provide a
-getattr function that returns the result of a lookup in that table. The method
-table uses the same structure as the :attr:`tp_methods` field of the type
-object.
-
Here is an example::
- static PyMethodDef newdatatype_methods[] = {
- {"getSize", (PyCFunction)newdatatype_getSize, METH_VARARGS,
- "Return the current size."},
- {"setSize", (PyCFunction)newdatatype_setSize, METH_VARARGS,
- "Set the size."},
- {NULL, NULL, 0, NULL} /* sentinel */
- };
-
static PyObject *
newdatatype_getattr(newdatatypeobject *obj, char *name)
{
- return Py_FindMethod(newdatatype_methods, (PyObject *)obj, name);
+ if (strcmp(name, "data") == 0)
+ {
+ return PyInt_FromLong(obj->data);
+ }
+
+ PyErr_Format(PyExc_AttributeError,
+ "'%.50s' object has no attribute '%.400s'",
+ tp->tp_name, name);
+ return NULL;
}
The :attr:`tp_setattr` handler is called when the :meth:`__setattr__` or
@@ -1297,49 +1232,53 @@ example that simply raises an exception; if this were really all you wanted, the
return -1;
}
-
Object Comparison
-----------------
::
- cmpfunc tp_compare;
+ richcmpfunc tp_richcompare;
-The :attr:`tp_compare` handler is called when comparisons are needed and the
-object does not implement the specific rich comparison method which matches the
-requested comparison. (It is always used if defined and the
-:c:func:`PyObject_Compare` or :c:func:`PyObject_Cmp` functions are used, or if
-:func:`cmp` is used from Python.) It is analogous to the :meth:`__cmp__` method.
-This function should return ``-1`` if *obj1* is less than *obj2*, ``0`` if they
-are equal, and ``1`` if *obj1* is greater than *obj2*. (It was previously
-allowed to return arbitrary negative or positive integers for less than and
-greater than, respectively; as of Python 2.2, this is no longer allowed. In the
-future, other return values may be assigned a different meaning.)
+The :attr:`tp_richcompare` handler is called when comparisons are needed. It is
+analogous to the :ref:`rich comparison methods <richcmpfuncs>`, like
+:meth:`__lt__`, and also called by :c:func:`PyObject_RichCompare` and
+:c:func:`PyObject_RichCompareBool`.
-A :attr:`tp_compare` handler may raise an exception. In this case it should
-return a negative value. The caller has to test for the exception using
-:c:func:`PyErr_Occurred`.
+This function is called with two Python objects and the operator as arguments,
+where the operator is one of ``Py_EQ``, ``Py_NE``, ``Py_LE``, ``Py_GT``,
+``Py_LT`` or ``Py_GT``. It should compare the two objects with respect to the
+specified operator and return ``Py_True`` or ``Py_False`` if the comparison is
+successful, ``Py_NotImplemented`` to indicate that comparison is not
+implemented and the other object's comparison method should be tried, or *NULL*
+if an exception was set.
-Here is a sample implementation::
+Here is a sample implementation, for a datatype that is considered equal if the
+size of an internal pointer is equal::
static int
- newdatatype_compare(newdatatypeobject * obj1, newdatatypeobject * obj2)
+ newdatatype_richcmp(PyObject *obj1, PyObject *obj2, int op)
{
- long result;
+ PyObject *result;
+ int c, size1, size2;
- if (obj1->obj_UnderlyingDatatypePtr->size <
- obj2->obj_UnderlyingDatatypePtr->size) {
- result = -1;
- }
- else if (obj1->obj_UnderlyingDatatypePtr->size >
- obj2->obj_UnderlyingDatatypePtr->size) {
- result = 1;
- }
- else {
- result = 0;
+ /* code to make sure that both arguments are of type
+ newdatatype omitted */
+
+ size1 = obj1->obj_UnderlyingDatatypePtr->size;
+ size2 = obj2->obj_UnderlyingDatatypePtr->size;
+
+ switch (op) {
+ case Py_LT: c = size1 < size2; break;
+ case Py_LE: c = size1 <= size2; break;
+ case Py_EQ: c = size1 == size2; break;
+ case Py_NE: c = size1 != size2; break;
+ case Py_GT: c = size1 > size2; break;
+ case Py_GE: c = size1 >= size2; break;
}
+ result = c ? Py_True : Py_False;
+ Py_INCREF(result);
return result;
- }
+ }
Abstract Protocol Support
@@ -1435,7 +1374,6 @@ Here is a desultory example of the implementation of the call function. ::
XXX some fields need to be added here... ::
- /* Added in release 2.2 */
/* Iterators */
getiterfunc tp_iter;
iternextfunc tp_iternext;
@@ -1494,7 +1432,7 @@ type is defined with the following structure::
The statically-declared type object for instances is defined this way::
PyTypeObject PyInstance_Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
0,
"module.instance",
@@ -1547,10 +1485,10 @@ provide. They are in :file:`object.h` in the Python include directory that
comes with the source distribution of Python.
In order to learn how to implement any specific method for your new data type,
-do the following: Download and unpack the Python source distribution. Go the
-:file:`Objects` directory, then search the C source files for ``tp_`` plus the
-function you want (for example, ``tp_print`` or ``tp_compare``). You will find
-examples of the function you want to implement.
+do the following: Download and unpack the Python source distribution. Go to
+the :file:`Objects` directory, then search the C source files for ``tp_`` plus
+the function you want (for example, ``tp_richcompare``). You will find examples
+of the function you want to implement.
When you need to verify that an object is an instance of the type you are
implementing, use the :c:func:`PyObject_TypeCheck` function. A sample of its use
diff --git a/Doc/extending/windows.rst b/Doc/extending/windows.rst
index 66b518d..3fd5e57 100644
--- a/Doc/extending/windows.rst
+++ b/Doc/extending/windows.rst
@@ -107,10 +107,6 @@ described here are distributed with the Python sources in the
to avoid confusion with a system library :file:`spam.dll` to which your module
could be a Python interface.
- .. versionchanged:: 2.5
- Previously, file names like :file:`spam.dll` (in release mode) or
- :file:`spam_d.dll` (in debug mode) were also recognized.
-
Now your options are:
#. Copy :file:`example.sln` and :file:`example.vcproj`, rename them to
@@ -173,13 +169,13 @@ described here are distributed with the Python sources in the
If your module creates a new type, you may have trouble with this line::
- PyObject_HEAD_INIT(&PyType_Type)
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
Static type object initializers in extension modules may cause
compiles to fail with an error message like "initializer not a
constant". This shows up when building DLL under MSVC. Change it to::
- PyObject_HEAD_INIT(NULL)
+ PyVarObject_HEAD_INIT(NULL, 0)
and add the following to the module initialization function::
diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst
index 25c72db..7c5116d 100644
--- a/Doc/faq/design.rst
+++ b/Doc/faq/design.rst
@@ -43,56 +43,45 @@ Why am I getting strange results with simple arithmetic operations?
See the next question.
-Why are floating point calculations so inaccurate?
+Why are floating-point calculations so inaccurate?
--------------------------------------------------
-People are often very surprised by results like this::
+Users are often surprised by results like this::
- >>> 1.2 - 1.0
- 0.199999999999999996
+ >>> 1.2 - 1.0
+ 0.199999999999999996
-and think it is a bug in Python. It's not. This has nothing to do with Python,
-but with how the underlying C platform handles floating point numbers, and
-ultimately with the inaccuracies introduced when writing down numbers as a
-string of a fixed number of digits.
-
-The internal representation of floating point numbers uses a fixed number of
-binary digits to represent a decimal number. Some decimal numbers can't be
-represented exactly in binary, resulting in small roundoff errors.
+and think it is a bug in Python. It's not. This has little to do with Python,
+and much more to do with how the underlying platform handles floating-point
+numbers.
-In decimal math, there are many numbers that can't be represented with a fixed
-number of decimal digits, e.g. 1/3 = 0.3333333333.......
+The :class:`float` type in CPython uses a C ``double`` for storage. A
+:class:`float` object's value is stored in binary floating-point with a fixed
+precision (typically 53 bits) and Python uses C operations, which in turn rely
+on the hardware implementation in the processor, to perform floating-point
+operations. This means that as far as floating-point operations are concerned,
+Python behaves like many popular languages including C and Java.
-In base 2, 1/2 = 0.1, 1/4 = 0.01, 1/8 = 0.001, etc. .2 equals 2/10 equals 1/5,
-resulting in the binary fractional number 0.001100110011001...
+Many numbers that can be written easily in decimal notation cannot be expressed
+exactly in binary floating-point. For example, after::
-Floating point numbers only have 32 or 64 bits of precision, so the digits are
-cut off at some point, and the resulting number is 0.199999999999999996 in
-decimal, not 0.2.
+ >>> x = 1.2
-A floating point number's ``repr()`` function prints as many digits are
-necessary to make ``eval(repr(f)) == f`` true for any float f. The ``str()``
-function prints fewer digits and this often results in the more sensible number
-that was probably intended::
+the value stored for ``x`` is a (very good) approximation to the decimal value
+``1.2``, but is not exactly equal to it. On a typical machine, the actual
+stored value is::
- >>> 1.1 - 0.9
- 0.20000000000000007
- >>> print 1.1 - 0.9
- 0.2
+ 1.0011001100110011001100110011001100110011001100110011 (binary)
-One of the consequences of this is that it is error-prone to compare the result
-of some computation to a float with ``==``. Tiny inaccuracies may mean that
-``==`` fails. Instead, you have to check that the difference between the two
-numbers is less than a certain threshold::
+which is exactly::
- epsilon = 0.0000000000001 # Tiny allowed error
- expected_result = 0.4
+ 1.1999999999999999555910790149937383830547332763671875 (decimal)
- if expected_result-epsilon <= computation() <= expected_result+epsilon:
- ...
+The typical precision of 53 bits provides Python floats with 15-16
+decimal digits of accuracy.
-Please see the chapter on :ref:`floating point arithmetic <tut-fp-issues>` in
-the Python tutorial for more information.
+For a fuller explanation, please see the :ref:`floating point arithmetic
+<tut-fp-issues>` chapter in the Python tutorial.
Why are Python strings immutable?
@@ -210,8 +199,8 @@ have to remember to change two places in your program -- the second occurrence
is hidden at the bottom of the loop.
The best approach is to use iterators, making it possible to loop through
-objects using the ``for`` statement. For example, in the current version of
-Python file objects support the iterator protocol, so you can now write simply::
+objects using the ``for`` statement. For example, :term:`file objects
+<file object>` support the iterator protocol, so you can write simply::
for line in f:
... # do something with line...
@@ -272,26 +261,13 @@ a string method, since in that case it is easy to see that ::
"1, 2, 4, 8, 16".split(", ")
is an instruction to a string literal to return the substrings delimited by the
-given separator (or, by default, arbitrary runs of white space). In this case a
-Unicode string returns a list of Unicode strings, an ASCII string returns a list
-of ASCII strings, and everyone is happy.
+given separator (or, by default, arbitrary runs of white space).
:meth:`~str.join` is a string method because in using it you are telling the
separator string to iterate over a sequence of strings and insert itself between
adjacent elements. This method can be used with any argument which obeys the
rules for sequence objects, including any new classes you might define yourself.
-
-Because this is a string method it can work for Unicode strings as well as plain
-ASCII strings. If ``join()`` were a method of the sequence types then the
-sequence types would have to decide which type of string to return depending on
-the type of the separator.
-
-.. XXX remove next paragraph eventually
-
-If none of these arguments persuade you, then for the moment you can continue to
-use the ``join()`` function from the string module, which allows you to write ::
-
- string.join(['1', '2', '4', '8', '16'], ", ")
+Similar methods exist for bytes and bytearray objects.
How fast are exceptions?
@@ -315,10 +291,9 @@ time. If that wasn't the case, you coded it like this::
else:
value = mydict[key] = getvalue(key)
-.. note::
-
- In Python 2.0 and higher, you can code this as ``value =
- mydict.setdefault(key, getvalue(key))``.
+For this specific case, you could also use ``value = dict.setdefault(key,
+getvalue(key))``, but only if the ``getvalue()`` call is cheap enough because it
+is evaluated in all cases.
Why isn't there a switch or case statement in Python?
@@ -394,11 +369,24 @@ is exactly the same type of object that a lambda form yields) is assigned!
Can Python be compiled to machine code, C or some other language?
-----------------------------------------------------------------
-Not easily. Python's high level data types, dynamic typing of objects and
-run-time invocation of the interpreter (using :func:`eval` or :keyword:`exec`)
-together mean that a "compiled" Python program would probably consist mostly of
-calls into the Python run-time system, even for seemingly simple operations like
-``x+1``.
+Practical answer:
+
+`Cython <http://cython.org/>`_ and `Pyrex <http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/>`_
+compile a modified version of Python with optional annotations into C
+extensions. `Weave <http://www.scipy.org/Weave>`_ makes it easy to
+intermingle Python and C code in various ways to increase performance.
+`Nuitka <http://www.nuitka.net/>`_ is an up-and-coming compiler of Python
+into C++ code, aiming to support the full Python language.
+
+Theoretical answer:
+
+ .. XXX not sure what to make of this
+
+Not trivially. Python's high level data types, dynamic typing of objects and
+run-time invocation of the interpreter (using :func:`eval` or :func:`exec`)
+together mean that a naïvely "compiled" Python program would probably consist
+mostly of calls into the Python run-time system, even for seemingly simple
+operations like ``x+1``.
Several projects described in the Python newsgroup or at past `Python
conferences <http://python.org/community/workshops/>`_ have shown that this
@@ -409,102 +397,64 @@ speedups of 1000x are feasible for small demo programs. See the proceedings
from the `1997 Python conference
<http://python.org/workshops/1997-10/proceedings/>`_ for more information.)
-Internally, Python source code is always translated into a bytecode
-representation, and this bytecode is then executed by the Python virtual
-machine. In order to avoid the overhead of repeatedly parsing and translating
-modules that rarely change, this byte code is written into a file whose name
-ends in ".pyc" whenever a module is parsed. When the corresponding .py file is
-changed, it is parsed and translated again and the .pyc file is rewritten.
-
-There is no performance difference once the .pyc file has been loaded, as the
-bytecode read from the .pyc file is exactly the same as the bytecode created by
-direct translation. The only difference is that loading code from a .pyc file
-is faster than parsing and translating a .py file, so the presence of
-precompiled .pyc files improves the start-up time of Python scripts. If
-desired, the Lib/compileall.py module can be used to create valid .pyc files for
-a given set of modules.
-
-Note that the main script executed by Python, even if its filename ends in .py,
-is not compiled to a .pyc file. It is compiled to bytecode, but the bytecode is
-not saved to a file. Usually main scripts are quite short, so this doesn't cost
-much speed.
-
-.. XXX check which of these projects are still alive
-
-There are also several programs which make it easier to intermingle Python and C
-code in various ways to increase performance. See, for example, `Psyco
-<http://psyco.sourceforge.net/>`_, `Pyrex
-<http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/>`_, `PyInline
-<http://pyinline.sourceforge.net/>`_, `Py2Cmod
-<http://sourceforge.net/projects/py2cmod/>`_, and `Weave
-<http://www.scipy.org/Weave>`_.
-
How does Python manage memory?
------------------------------
The details of Python memory management depend on the implementation. The
-standard C implementation of Python uses reference counting to detect
-inaccessible objects, and another mechanism to collect reference cycles,
+standard implementation of Python, :term:`CPython`, uses reference counting to
+detect inaccessible objects, and another mechanism to collect reference cycles,
periodically executing a cycle detection algorithm which looks for inaccessible
cycles and deletes the objects involved. The :mod:`gc` module provides functions
to perform a garbage collection, obtain debugging statistics, and tune the
collector's parameters.
-Jython relies on the Java runtime so the JVM's garbage collector is used. This
-difference can cause some subtle porting problems if your Python code depends on
-the behavior of the reference counting implementation.
+Other implementations (such as `Jython <http://www.jython.org>`_ or
+`PyPy <http://www.pypy.org>`_), however, can rely on a different mechanism
+such as a full-blown garbage collector. This difference can cause some
+subtle porting problems if your Python code depends on the behavior of the
+reference counting implementation.
+
+In some Python implementations, the following code (which is fine in CPython)
+will probably run out of file descriptors::
+
+ for file in very_long_list_of_files:
+ f = open(file)
+ c = f.read(1)
-.. XXX relevant for Python 2.6?
+Indeed, using CPython's reference counting and destructor scheme, each new
+assignment to *f* closes the previous file. With a traditional GC, however,
+those file objects will only get collected (and closed) at varying and possibly
+long intervals.
-Sometimes objects get stuck in tracebacks temporarily and hence are not
-deallocated when you might expect. Clear the tracebacks with::
+If you want to write code that will work with any Python implementation,
+you should explicitly close the file or use the :keyword:`with` statement;
+this will work regardless of memory management scheme::
- import sys
- sys.exc_clear()
- sys.exc_traceback = sys.last_traceback = None
+ for file in very_long_list_of_files:
+ with open(file) as f:
+ c = f.read(1)
-Tracebacks are used for reporting errors, implementing debuggers and related
-things. They contain a portion of the program state extracted during the
-handling of an exception (usually the most recent exception).
-In the absence of circularities and tracebacks, Python programs do not need to
-manage memory explicitly.
+Why doesn't CPython use a more traditional garbage collection scheme?
+---------------------------------------------------------------------
-Why doesn't Python use a more traditional garbage collection scheme? For one
-thing, this is not a C standard feature and hence it's not portable. (Yes, we
-know about the Boehm GC library. It has bits of assembler code for *most*
-common platforms, not for all of them, and although it is mostly transparent, it
-isn't completely transparent; patches are required to get Python to work with
-it.)
+For one thing, this is not a C standard feature and hence it's not portable.
+(Yes, we know about the Boehm GC library. It has bits of assembler code for
+*most* common platforms, not for all of them, and although it is mostly
+transparent, it isn't completely transparent; patches are required to get
+Python to work with it.)
Traditional GC also becomes a problem when Python is embedded into other
applications. While in a standalone Python it's fine to replace the standard
malloc() and free() with versions provided by the GC library, an application
embedding Python may want to have its *own* substitute for malloc() and free(),
-and may not want Python's. Right now, Python works with anything that
+and may not want Python's. Right now, CPython works with anything that
implements malloc() and free() properly.
-In Jython, the following code (which is fine in CPython) will probably run out
-of file descriptors long before it runs out of memory::
- for file in very_long_list_of_files:
- f = open(file)
- c = f.read(1)
-
-Using the current reference counting and destructor scheme, each new assignment
-to f closes the previous file. Using GC, this is not guaranteed. If you want
-to write code that will work with any Python implementation, you should
-explicitly close the file or use the :keyword:`with` statement; this will work
-regardless of GC::
-
- for file in very_long_list_of_files:
- with open(file) as f:
- c = f.read(1)
-
-
-Why isn't all memory freed when Python exits?
----------------------------------------------
+Why isn't all memory freed when CPython exits?
+----------------------------------------------
Objects referenced from the global namespaces of Python modules are not always
deallocated when Python exits. This may happen if there are circular
@@ -597,7 +547,7 @@ Some unacceptable solutions that have been proposed:
construct a new list with the same value it won't be found; e.g.::
mydict = {[1, 2]: '12'}
- print mydict[[1, 2]]
+ print(mydict[[1, 2]])
would raise a KeyError exception because the id of the ``[1, 2]`` used in the
second line differs from that in the first line. In other words, dictionary
@@ -664,10 +614,10 @@ order to remind you of that fact, it does not return the sorted list. This way,
you won't be fooled into accidentally overwriting a list when you need a sorted
copy but also need to keep the unsorted version around.
-In Python 2.4 a new built-in function -- :func:`sorted` -- has been added.
-This function creates a new list from a provided iterable, sorts it and returns
-it. For example, here's how to iterate over the keys of a dictionary in sorted
-order::
+If you want to return a new list, use the built-in :func:`sorted` function
+instead. This function creates a new list from a provided iterable, sorts
+it and returns it. For example, here's how to iterate over the keys of a
+dictionary in sorted order::
for key in sorted(mydict):
... # do whatever with mydict[key]...
@@ -846,7 +796,7 @@ For instance, take the following incomplete snippet::
def foo(a):
with a:
- print x
+ print(x)
The snippet assumes that "a" must have a member attribute called "x". However,
there is nothing in Python that tells the interpreter this. What should happen
@@ -880,12 +830,12 @@ The colon is required primarily to enhance readability (one of the results of
the experimental ABC language). Consider this::
if a == b
- print a
+ print(a)
versus ::
if a == b:
- print a
+ print(a)
Notice how the second one is slightly easier to read. Notice further how a
colon sets off the example in this FAQ answer; it's a standard usage in English.
diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst
index b79d716..7c684a0 100644
--- a/Doc/faq/extending.rst
+++ b/Doc/faq/extending.rst
@@ -7,6 +7,9 @@ Extending/Embedding FAQ
.. highlight:: c
+.. XXX need review for Python 3.
+
+
Can I create my own functions in C?
-----------------------------------
@@ -34,18 +37,13 @@ Writing C is hard; are there any alternatives?
There are a number of alternatives to writing your own C extensions, depending
on what you're trying to do.
-.. XXX make sure these all work; mention Cython
-
-If you need more speed, `Psyco <http://psyco.sourceforge.net/>`_ generates x86
-assembly code from Python bytecode. You can use Psyco to compile the most
-time-critical functions in your code, and gain a significant improvement with
-very little effort, as long as you're running on a machine with an
-x86-compatible processor.
+.. XXX make sure these all work
-`Pyrex <http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/>`_ is a compiler
-that accepts a slightly modified form of Python and generates the corresponding
-C code. Pyrex makes it possible to write an extension without having to learn
-Python's C API.
+`Cython <http://cython.org>`_ and its relative `Pyrex
+<http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/>`_ are compilers
+that accept a slightly modified form of Python and generate the corresponding
+C code. Cython and Pyrex make it possible to write an extension without having
+to learn Python's C API.
If you need to interface to some C or C++ library for which no Python extension
currently exists, you can try wrapping the library's data types and functions
@@ -101,12 +99,7 @@ many other useful protocols.
How do I use Py_BuildValue() to create a tuple of arbitrary length?
-------------------------------------------------------------------
-You can't. Use ``t = PyTuple_New(n)`` instead, and fill it with objects using
-``PyTuple_SetItem(t, i, o)`` -- note that this "eats" a reference count of
-``o``, so you have to :c:func:`Py_INCREF` it. Lists have similar functions
-``PyList_New(n)`` and ``PyList_SetItem(l, i, o)``. Note that you *must* set all
-the tuple items to some value before you pass the tuple to Python code --
-``PyTuple_New(n)`` initializes them to NULL, which isn't a valid Python value.
+You can't. Use :c:func:`PyTuple_Pack` instead.
How do I call an object's method from C?
@@ -149,21 +142,30 @@ this object to :data:`sys.stdout` and :data:`sys.stderr`. Call print_error, or
just allow the standard traceback mechanism to work. Then, the output will go
wherever your ``write()`` method sends it.
-The easiest way to do this is to use the StringIO class in the standard library.
+The easiest way to do this is to use the :class:`io.StringIO` class::
-Sample code and use for catching stdout:
+ >>> import io, sys
+ >>> sys.stdout = io.StringIO()
+ >>> print('foo')
+ >>> print('hello world!')
+ >>> sys.stderr.write(sys.stdout.getvalue())
+ foo
+ hello world!
- >>> class StdoutCatcher:
+A custom object to do the same would look like this::
+
+ >>> import io, sys
+ >>> class StdoutCatcher(io.TextIOBase):
... def __init__(self):
- ... self.data = ''
+ ... self.data = []
... def write(self, stuff):
- ... self.data = self.data + stuff
+ ... self.data.append(stuff)
...
>>> import sys
>>> sys.stdout = StdoutCatcher()
- >>> print 'foo'
- >>> print 'hello world!'
- >>> sys.stderr.write(sys.stdout.data)
+ >>> print('foo')
+ >>> print('hello world!')
+ >>> sys.stderr.write(''.join(sys.stdout.data))
foo
hello world!
@@ -376,7 +378,7 @@ complete example using the GNU readline library (you may want to ignore
if (ps1 == prompt || /* ">>> " or */
'\n' == code[i + j - 1]) /* "... " and double '\n' */
{ /* so execute it */
- dum = PyEval_EvalCode ((PyCodeObject *)src, glb, loc);
+ dum = PyEval_EvalCode (src, glb, loc);
Py_XDECREF (dum);
Py_XDECREF (src);
free (code);
@@ -468,12 +470,9 @@ checking the value of sys.maxunicode:
>>> import sys
>>> if sys.maxunicode > 65535:
- ... print 'UCS4 build'
+ ... print('UCS4 build')
... else:
- ... print 'UCS2 build'
+ ... print('UCS2 build')
The only way to solve this problem is to use extension modules compiled with a
Python binary built using the same size for Unicode characters.
-
-
-
diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst
index df43196..9f26dc9 100644
--- a/Doc/faq/general.rst
+++ b/Doc/faq/general.rst
@@ -19,7 +19,7 @@ It has interfaces to many system calls and libraries, as well as to various
window systems, and is extensible in C or C++. It is also usable as an
extension language for applications that need a programmable interface.
Finally, Python is portable: it runs on many Unix variants, on the Mac, and on
-PCs under MS-DOS, Windows, Windows NT, and OS/2.
+Windows 2000 and later.
To find out more, start with :ref:`tutorial-index`. The `Beginner's Guide to
Python <http://wiki.python.org/moin/BeginnersGuide>`_ links to other
@@ -469,38 +469,3 @@ http://www.python.org/editors/ for a full list of Python editing environments.
If you want to discuss Python's use in education, you may be interested in
joining `the edu-sig mailing list
<http://python.org/community/sigs/current/edu-sig>`_.
-
-
-Upgrading Python
-================
-
-What is this bsddb185 module my application keeps complaining about?
---------------------------------------------------------------------
-
-.. XXX remove this question?
-
-Starting with Python2.3, the distribution includes the `PyBSDDB package
-<http://pybsddb.sf.net/>` as a replacement for the old bsddb module. It
-includes functions which provide backward compatibility at the API level, but
-requires a newer version of the underlying `Berkeley DB
-<http://www.sleepycat.com>`_ library. Files created with the older bsddb module
-can't be opened directly using the new module.
-
-Using your old version of Python and a pair of scripts which are part of Python
-2.3 (db2pickle.py and pickle2db.py, in the Tools/scripts directory) you can
-convert your old database files to the new format. Using your old Python
-version, run the db2pickle.py script to convert it to a pickle, e.g.::
-
- python2.2 <pathto>/db2pickley.py database.db database.pck
-
-Rename your database file::
-
- mv database.db olddatabase.db
-
-Now convert the pickle file to a new format database::
-
- python <pathto>/pickle2db.py database.db database.pck
-
-The precise commands you use will vary depending on the particulars of your
-installation. For full details about operation of these two scripts check the
-doc string at the start of each one.
diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst
index 50a30b0..f697cd3 100644
--- a/Doc/faq/gui.rst
+++ b/Doc/faq/gui.rst
@@ -6,10 +6,18 @@ Graphic User Interface FAQ
.. contents::
+.. XXX need review for Python 3.
+
+
+General GUI Questions
+=====================
+
What platform-independent GUI toolkits exist for Python?
========================================================
-Depending on what platform(s) you are aiming at, there are several.
+Depending on what platform(s) you are aiming at, there are several. Some
+of them haven't been ported to Python 3 yet. At least `Tkinter`_ and `Qt`_
+are known to be Python 3-compatible.
.. XXX check links
@@ -17,10 +25,12 @@ Tkinter
-------
Standard builds of Python include an object-oriented interface to the Tcl/Tk
-widget set, called Tkinter. This is probably the easiest to install and use.
-For more info about Tk, including pointers to the source, see the Tcl/Tk home
-page at http://www.tcl.tk. Tcl/Tk is fully portable to the MacOS, Windows, and
-Unix platforms.
+widget set, called :ref:`tkinter <Tkinter>`. This is probably the easiest to
+install (since it comes included with most
+`binary distributions <http://www.python.org/download/>`_ of Python) and use.
+For more info about Tk, including pointers to the source, see the
+`Tcl/Tk home page <http://www.tcl.tk>`_. Tcl/Tk is fully portable to the
+MacOS, Windows, and Unix platforms.
wxWidgets
---------
@@ -45,19 +55,25 @@ well as in freeware or shareware.
Qt
---
-There are bindings available for the Qt toolkit (`PyQt
-<http://www.riverbankcomputing.co.uk/software/pyqt/>`_) and for KDE (`PyKDE <http://www.riverbankcomputing.co.uk/software/pykde/intro>`__). If
-you're writing open source software, you don't need to pay for PyQt, but if you
-want to write proprietary applications, you must buy a PyQt license from
-`Riverbank Computing <http://www.riverbankcomputing.co.uk>`_ and (up to Qt 4.4;
-Qt 4.5 upwards is licensed under the LGPL license) a Qt license from `Trolltech
-<http://www.trolltech.com>`_.
+There are bindings available for the Qt toolkit (using either `PyQt
+<http://www.riverbankcomputing.co.uk/software/pyqt/>`_ or `PySide
+<http://www.pyside.org/>`_) and for KDE (`PyKDE <http://www.riverbankcomputing.co.uk/software/pykde/intro>`__).
+PyQt is currently more mature than PySide, but you must buy a PyQt license from
+`Riverbank Computing <http://www.riverbankcomputing.co.uk/software/pyqt/license>`_
+if you want to write proprietary applications. PySide is free for all applications.
+
+Qt 4.5 upwards is licensed under the LGPL license; also, commercial licenses
+are available from `Nokia <http://qt.nokia.com/>`_.
Gtk+
----
-PyGtk bindings for the `Gtk+ toolkit <http://www.gtk.org>`_ have been
-implemented by James Henstridge; see <http://www.pygtk.org>.
+The `GObject introspection bindings <https://live.gnome.org/PyGObject>`_
+for Python allow you to write GTK+ 3 applications. There is also a
+`Python GTK+ 3 Tutorial <http://python-gtk-3-tutorial.readthedocs.org/en/latest/>`_.
+
+The older PyGtk bindings for the `Gtk+ 2 toolkit <http://www.gtk.org>`_ have
+been implemented by James Henstridge; see <http://www.pygtk.org>.
FLTK
----
@@ -161,6 +177,3 @@ The most common cause is that the widget to which the binding applies doesn't
have "keyboard focus". Check out the Tk documentation for the focus command.
Usually a widget is given the keyboard focus by clicking in it (but not for
labels; see the takefocus option).
-
-
-
diff --git a/Doc/faq/installed.rst b/Doc/faq/installed.rst
index 390c85a..efec9bf 100644
--- a/Doc/faq/installed.rst
+++ b/Doc/faq/installed.rst
@@ -24,14 +24,14 @@ there are several possible ways it could have gotten there.
it; you'll have to figure out who's been using the machine and might have
installed it.
* A third-party application installed on the machine might have been written in
- Python and included a Python installation. For a home computer, the most
- common such application is `PySol <http://pysolfc.sourceforge.net/>`_, a
- solitaire game that includes over 1000 different games and variations.
+ Python and included a Python installation. There are many such applications,
+ from GUI programs to network servers and administrative scripts.
* Some Windows machines also have Python installed. At this writing we're aware
of computers from Hewlett-Packard and Compaq that include Python. Apparently
some of HP/Compaq's administrative tools are written in Python.
-* All Apple computers running Mac OS X have Python installed; it's included in
- the base installation.
+* Many Unix-compatible operating systems, such as Mac OS X and some Linux
+ distributions, have Python installed by default; it's included in the base
+ installation.
Can I delete Python?
diff --git a/Doc/faq/library.rst b/Doc/faq/library.rst
index 7b340b2..7385c59 100644
--- a/Doc/faq/library.rst
+++ b/Doc/faq/library.rst
@@ -38,7 +38,7 @@ There are (at least) three kinds of modules in Python:
type::
import sys
- print sys.builtin_module_names
+ print(sys.builtin_module_names)
How do I make a Python script executable on Unix?
@@ -91,7 +91,7 @@ Is there a curses/termcap package for Python?
.. XXX curses *is* built by default, isn't it?
-For Unix variants the standard Python source distribution comes with a curses
+For Unix variants: The standard Python source distribution comes with a curses
module in the :source:`Modules` subdirectory, though it's not compiled by default.
(Note that this is not available in the Windows distribution -- there is no
curses module for Windows.)
@@ -187,8 +187,11 @@ How do I get a single keypress at a time?
-----------------------------------------
For Unix variants there are several solutions. It's straightforward to do this
-using curses, but curses is a fairly large module to learn. Here's a solution
-without curses::
+using curses, but curses is a fairly large module to learn.
+
+.. XXX this doesn't work out of the box, some IO expert needs to check why
+
+ Here's a solution without curses::
import termios, fcntl, sys, os
fd = sys.stdin.fileno()
@@ -202,23 +205,24 @@ without curses::
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
try:
- while 1:
+ while True:
try:
c = sys.stdin.read(1)
- print "Got character", repr(c)
- except IOError: pass
+ print("Got character", repr(c))
+ except IOError:
+ pass
finally:
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
-You need the :mod:`termios` and the :mod:`fcntl` module for any of this to work,
-and I've only tried it on Linux, though it should work elsewhere. In this code,
-characters are read and printed one at a time.
+ You need the :mod:`termios` and the :mod:`fcntl` module for any of this to
+ work, and I've only tried it on Linux, though it should work elsewhere. In
+ this code, characters are read and printed one at a time.
-:func:`termios.tcsetattr` turns off stdin's echoing and disables canonical mode.
-:func:`fcntl.fnctl` is used to obtain stdin's file descriptor flags and modify
-them for non-blocking mode. Since reading stdin when it is empty results in an
-:exc:`IOError`, this error is caught and ignored.
+ :func:`termios.tcsetattr` turns off stdin's echoing and disables canonical
+ mode. :func:`fcntl.fnctl` is used to obtain stdin's file descriptor flags
+ and modify them for non-blocking mode. Since reading stdin when it is empty
+ results in an :exc:`IOError`, this error is caught and ignored.
Threads
@@ -227,11 +231,9 @@ Threads
How do I program using threads?
-------------------------------
-.. XXX it's _thread in py3k
-
-Be sure to use the :mod:`threading` module and not the :mod:`thread` module.
+Be sure to use the :mod:`threading` module and not the :mod:`_thread` module.
The :mod:`threading` module builds convenient abstractions on top of the
-low-level primitives provided by the :mod:`thread` module.
+low-level primitives provided by the :mod:`_thread` module.
Aahz has a set of slides from his threading tutorial that are helpful; see
http://www.pythoncraft.com/OSCON2001/.
@@ -249,13 +251,13 @@ all the threads to finish::
import threading, time
def thread_task(name, n):
- for i in range(n): print name, i
+ for i in range(n): print(name, i)
for i in range(10):
T = threading.Thread(target=thread_task, args=(str(i), i))
T.start()
- time.sleep(10) # <----------------------------!
+ time.sleep(10) # <---------------------------!
But now (on many platforms) the threads don't run in parallel, but appear to run
sequentially, one at a time! The reason is that the OS thread scheduler doesn't
@@ -264,8 +266,8 @@ start a new thread until the previous thread is blocked.
A simple fix is to add a tiny sleep to the start of the run function::
def thread_task(name, n):
- time.sleep(0.001) # <---------------------!
- for i in range(n): print name, i
+ time.sleep(0.001) # <--------------------!
+ for i in range(n): print(name, i)
for i in range(10):
T = threading.Thread(target=thread_task, args=(str(i), i))
@@ -275,7 +277,7 @@ A simple fix is to add a tiny sleep to the start of the run function::
Instead of trying to guess a good delay value for :func:`time.sleep`,
it's better to use some kind of semaphore mechanism. One idea is to use the
-:mod:`Queue` module to create a queue object, let each thread append a token to
+:mod:`queue` module to create a queue object, let each thread append a token to
the queue when it finishes, and let the main thread read as many tokens from the
queue as there are threads.
@@ -283,36 +285,40 @@ queue as there are threads.
How do I parcel out work among a bunch of worker threads?
---------------------------------------------------------
-Use the :mod:`Queue` module to create a queue containing a list of jobs. The
-:class:`~Queue.Queue` class maintains a list of objects and has a ``.put(obj)``
-method that adds items to the queue and a ``.get()`` method to return them.
-The class will take care of the locking necessary to ensure that each job is
-handed out exactly once.
+The easiest way is to use the new :mod:`concurrent.futures` module,
+especially the :mod:`~concurrent.futures.ThreadPoolExecutor` class.
+
+Or, if you want fine control over the dispatching algorithm, you can write
+your own logic manually. Use the :mod:`queue` module to create a queue
+containing a list of jobs. The :class:`~queue.Queue` class maintains a
+list of objects and has a ``.put(obj)`` method that adds items to the queue and
+a ``.get()`` method to return them. The class will take care of the locking
+necessary to ensure that each job is handed out exactly once.
Here's a trivial example::
- import threading, Queue, time
+ import threading, queue, time
# The worker thread gets jobs off the queue. When the queue is empty, it
# assumes there will be no more work and exits.
# (Realistically workers will run until terminated.)
def worker():
- print 'Running worker'
+ print('Running worker')
time.sleep(0.1)
while True:
try:
arg = q.get(block=False)
- except Queue.Empty:
- print 'Worker', threading.currentThread(),
- print 'queue empty'
+ except queue.Empty:
+ print('Worker', threading.currentThread(), end=' ')
+ print('queue empty')
break
else:
- print 'Worker', threading.currentThread(),
- print 'running with argument', arg
+ print('Worker', threading.currentThread(), end=' ')
+ print('running with argument', arg)
time.sleep(0.5)
# Create queue
- q = Queue.Queue()
+ q = queue.Queue()
# Start a pool of 5 workers
for i in range(5):
@@ -324,7 +330,7 @@ Here's a trivial example::
q.put(i)
# Give threads time to run
- print 'Main thread sleeping'
+ print('Main thread sleeping')
time.sleep(5)
When run, this will produce the following output:
@@ -337,25 +343,25 @@ When run, this will produce the following output:
Running worker
Running worker
Main thread sleeping
- Worker <Thread(worker 1, started)> running with argument 0
- Worker <Thread(worker 2, started)> running with argument 1
- Worker <Thread(worker 3, started)> running with argument 2
- Worker <Thread(worker 4, started)> running with argument 3
- Worker <Thread(worker 5, started)> running with argument 4
- Worker <Thread(worker 1, started)> running with argument 5
+ Worker <Thread(worker 1, started 130283832797456)> running with argument 0
+ Worker <Thread(worker 2, started 130283824404752)> running with argument 1
+ Worker <Thread(worker 3, started 130283816012048)> running with argument 2
+ Worker <Thread(worker 4, started 130283807619344)> running with argument 3
+ Worker <Thread(worker 5, started 130283799226640)> running with argument 4
+ Worker <Thread(worker 1, started 130283832797456)> running with argument 5
...
-Consult the module's documentation for more details; the :class:`~Queue.Queue`
+Consult the module's documentation for more details; the :class:`~queue.Queue``
class provides a featureful interface.
What kinds of global value mutation are thread-safe?
----------------------------------------------------
-A :term:`global interpreter lock` (GIL) is used internally to ensure that only
-one thread runs in the Python VM at a time. In general, Python offers to switch
+A :term:`global interpreter lock` (GIL) is used internally to ensure that only one
+thread runs in the Python VM at a time. In general, Python offers to switch
among threads only between bytecode instructions; how frequently it switches can
-be set via :func:`sys.setcheckinterval`. Each bytecode instruction and
+be set via :func:`sys.setswitchinterval`. Each bytecode instruction and
therefore all the C implementation code reached from each instruction is
therefore atomic from the point of view of a Python program.
@@ -395,7 +401,6 @@ lists. When in doubt, use a mutex!
Can't we get rid of the Global Interpreter Lock?
------------------------------------------------
-.. XXX mention multiprocessing
.. XXX link to dbeazley's talk about GIL?
The :term:`global interpreter lock` (GIL) is often seen as a hindrance to Python's
@@ -405,22 +410,25 @@ Python program effectively only uses one CPU, due to the insistence that
Back in the days of Python 1.5, Greg Stein actually implemented a comprehensive
patch set (the "free threading" patches) that removed the GIL and replaced it
-with fine-grained locking. Unfortunately, even on Windows (where locks are very
-efficient) this ran ordinary Python code about twice as slow as the interpreter
-using the GIL. On Linux the performance loss was even worse because pthread
-locks aren't as efficient.
-
-Since then, the idea of getting rid of the GIL has occasionally come up but
-nobody has found a way to deal with the expected slowdown, and users who don't
-use threads would not be happy if their code ran at half the speed. Greg's
-free threading patch set has not been kept up-to-date for later Python versions.
+with fine-grained locking. Adam Olsen recently did a similar experiment
+in his `python-safethread <http://code.google.com/p/python-safethread/>`_
+project. Unfortunately, both experiments exhibited a sharp drop in single-thread
+performance (at least 30% slower), due to the amount of fine-grained locking
+necessary to compensate for the removal of the GIL.
This doesn't mean that you can't make good use of Python on multi-CPU machines!
You just have to be creative with dividing the work up between multiple
-*processes* rather than multiple *threads*. Judicious use of C extensions will
-also help; if you use a C extension to perform a time-consuming task, the
-extension can release the GIL while the thread of execution is in the C code and
-allow other threads to get some work done.
+*processes* rather than multiple *threads*. The
+:class:`~concurrent.futures.ProcessPoolExecutor` class in the new
+:mod:`concurrent.futures` module provides an easy way of doing so; the
+:mod:`multiprocessing` module provides a lower-level API in case you want
+more control over dispatching of tasks.
+
+Judicious use of C extensions will also help; if you use a C extension to
+perform a time-consuming task, the extension can release the GIL while the
+thread of execution is in the C code and allow other threads to get some work
+done. Some standard library modules such as :mod:`zlib` and :mod:`hashlib`
+already do this.
It has been suggested that the GIL should be a per-interpreter-state lock rather
than truly global; interpreters then wouldn't be able to share objects.
@@ -447,7 +455,7 @@ How do I delete a file? (And other file questions...)
-----------------------------------------------------
Use ``os.remove(filename)`` or ``os.unlink(filename)``; for documentation, see
-the :mod:`os` module. The two functions are identical; :func:`unlink` is simply
+the :mod:`os` module. The two functions are identical; :func:`~os.unlink` is simply
the name of the Unix system call for this function.
To remove a directory, use :func:`os.rmdir`; use :func:`os.mkdir` to create one.
@@ -458,7 +466,7 @@ contents, use :func:`shutil.rmtree`.
To rename a file, use ``os.rename(old_path, new_path)``.
-To truncate a file, open it using ``f = open(filename, "r+")``, and use
+To truncate a file, open it using ``f = open(filename, "rb+")``, and use
``f.truncate(offset)``; offset defaults to the current seek position. There's
also ``os.ftruncate(fd, offset)`` for files opened with :func:`os.open`, where
*fd* is the file descriptor (a small integer).
@@ -487,9 +495,9 @@ in big-endian format from a file::
import struct
- f = open(filename, "rb") # Open in binary mode for portability
- s = f.read(8)
- x, y, z = struct.unpack(">hhl", s)
+ with open(filename, "rb") as f:
+ s = f.read(8)
+ x, y, z = struct.unpack(">hhl", s)
The '>' in the format string forces big-endian data; the letter 'h' reads one
"short integer" (2 bytes), and 'l' reads one "long integer" (4 bytes) from the
@@ -498,6 +506,13 @@ string.
For data that is more regular (e.g. a homogeneous list of ints or floats),
you can also use the :mod:`array` module.
+.. note::
+ To read and write binary data, it is mandatory to open the file in
+ binary mode (here, passing ``"rb"`` to :func:`open`). If you use
+ ``"r"`` instead (the default), the file will be open in text mode
+ and ``f.read()`` will return :class:`str` objects rather than
+ :class:`bytes` objects.
+
I can't seem to use os.read() on a pipe created with os.popen(); why?
---------------------------------------------------------------------
@@ -509,81 +524,83 @@ Thus, to read *n* bytes from a pipe *p* created with :func:`os.popen`, you need
use ``p.read(n)``.
-How do I run a subprocess with pipes connected to both input and output?
-------------------------------------------------------------------------
-
-.. XXX update to use subprocess
-
-Use the :mod:`popen2` module. For example::
-
- import popen2
- fromchild, tochild = popen2.popen2("command")
- tochild.write("input\n")
- tochild.flush()
- output = fromchild.readline()
-
-Warning: in general it is unwise to do this because you can easily cause a
-deadlock where your process is blocked waiting for output from the child while
-the child is blocked waiting for input from you. This can be caused by the
-parent expecting the child to output more text than it does or by data being
-stuck in stdio buffers due to lack of flushing. The Python parent
-can of course explicitly flush the data it sends to the child before it reads
-any output, but if the child is a naive C program it may have been written to
-never explicitly flush its output, even if it is interactive, since flushing is
-normally automatic.
-
-Note that a deadlock is also possible if you use :func:`popen3` to read stdout
-and stderr. If one of the two is too large for the internal buffer (increasing
-the buffer size does not help) and you ``read()`` the other one first, there is
-a deadlock, too.
-
-Note on a bug in popen2: unless your program calls ``wait()`` or ``waitpid()``,
-finished child processes are never removed, and eventually calls to popen2 will
-fail because of a limit on the number of child processes. Calling
-:func:`os.waitpid` with the :data:`os.WNOHANG` option can prevent this; a good
-place to insert such a call would be before calling ``popen2`` again.
-
-In many cases, all you really need is to run some data through a command and get
-the result back. Unless the amount of data is very large, the easiest way to do
-this is to write it to a temporary file and run the command with that temporary
-file as input. The standard module :mod:`tempfile` exports a
-:func:`~tempfile.mktemp` function to generate unique temporary file names. ::
-
- import tempfile
- import os
-
- class Popen3:
- """
- This is a deadlock-safe version of popen that returns
- an object with errorlevel, out (a string) and err (a string).
- (capturestderr may not work under windows.)
- Example: print Popen3('grep spam','\n\nhere spam\n\n').out
- """
- def __init__(self,command,input=None,capturestderr=None):
- outfile=tempfile.mktemp()
- command="( %s ) > %s" % (command,outfile)
- if input:
- infile=tempfile.mktemp()
- open(infile,"w").write(input)
- command=command+" <"+infile
- if capturestderr:
- errfile=tempfile.mktemp()
- command=command+" 2>"+errfile
- self.errorlevel=os.system(command) >> 8
- self.out=open(outfile,"r").read()
- os.remove(outfile)
- if input:
- os.remove(infile)
- if capturestderr:
- self.err=open(errfile,"r").read()
- os.remove(errfile)
-
-Note that many interactive programs (e.g. vi) don't work well with pipes
-substituted for standard input and output. You will have to use pseudo ttys
-("ptys") instead of pipes. Or you can use a Python interface to Don Libes'
-"expect" library. A Python extension that interfaces to expect is called "expy"
-and available from http://expectpy.sourceforge.net. A pure Python solution that
-works like expect is `pexpect <http://pypi.python.org/pypi/pexpect/>`_.
+.. XXX update to use subprocess. See the :ref:`subprocess-replacements` section.
+
+ How do I run a subprocess with pipes connected to both input and output?
+ ------------------------------------------------------------------------
+
+ Use the :mod:`popen2` module. For example::
+
+ import popen2
+ fromchild, tochild = popen2.popen2("command")
+ tochild.write("input\n")
+ tochild.flush()
+ output = fromchild.readline()
+
+ Warning: in general it is unwise to do this because you can easily cause a
+ deadlock where your process is blocked waiting for output from the child
+ while the child is blocked waiting for input from you. This can be caused
+ by the parent expecting the child to output more text than it does or
+ by data being stuck in stdio buffers due to lack of flushing.
+ The Python parent can of course explicitly flush the data it sends to the
+ child before it reads any output, but if the child is a naive C program it
+ may have been written to never explicitly flush its output, even if it is
+ interactive, since flushing is normally automatic.
+
+ Note that a deadlock is also possible if you use :func:`popen3` to read
+ stdout and stderr. If one of the two is too large for the internal buffer
+ (increasing the buffer size does not help) and you ``read()`` the other one
+ first, there is a deadlock, too.
+
+ Note on a bug in popen2: unless your program calls ``wait()`` or
+ ``waitpid()``, finished child processes are never removed, and eventually
+ calls to popen2 will fail because of a limit on the number of child
+ processes. Calling :func:`os.waitpid` with the :data:`os.WNOHANG` option can
+ prevent this; a good place to insert such a call would be before calling
+ ``popen2`` again.
+
+ In many cases, all you really need is to run some data through a command and
+ get the result back. Unless the amount of data is very large, the easiest
+ way to do this is to write it to a temporary file and run the command with
+ that temporary file as input. The standard module :mod:`tempfile` exports a
+ :func:`~tempfile.mktemp` function to generate unique temporary file names. ::
+
+ import tempfile
+ import os
+
+ class Popen3:
+ """
+ This is a deadlock-safe version of popen that returns
+ an object with errorlevel, out (a string) and err (a string).
+ (capturestderr may not work under windows.)
+ Example: print(Popen3('grep spam','\n\nhere spam\n\n').out)
+ """
+ def __init__(self,command,input=None,capturestderr=None):
+ outfile=tempfile.mktemp()
+ command="( %s ) > %s" % (command,outfile)
+ if input:
+ infile=tempfile.mktemp()
+ open(infile,"w").write(input)
+ command=command+" <"+infile
+ if capturestderr:
+ errfile=tempfile.mktemp()
+ command=command+" 2>"+errfile
+ self.errorlevel=os.system(command) >> 8
+ self.out=open(outfile,"r").read()
+ os.remove(outfile)
+ if input:
+ os.remove(infile)
+ if capturestderr:
+ self.err=open(errfile,"r").read()
+ os.remove(errfile)
+
+ Note that many interactive programs (e.g. vi) don't work well with pipes
+ substituted for standard input and output. You will have to use pseudo ttys
+ ("ptys") instead of pipes. Or you can use a Python interface to Don Libes'
+ "expect" library. A Python extension that interfaces to expect is called
+ "expy" and available from http://expectpy.sourceforge.net. A pure Python
+ solution that works like expect is `pexpect
+ <http://pypi.python.org/pypi/pexpect/>`_.
How do I access the serial (RS232) port?
@@ -601,28 +618,29 @@ For Unix, see a Usenet post by Mitch Chapman:
Why doesn't closing sys.stdout (stdin, stderr) really close it?
---------------------------------------------------------------
-Python file objects are a high-level layer of abstraction on top of C streams,
-which in turn are a medium-level layer of abstraction on top of (among other
-things) low-level C file descriptors.
+Python :term:`file objects <file object>` are a high-level layer of
+abstraction on low-level C file descriptors.
-For most file objects you create in Python via the built-in ``file``
-constructor, ``f.close()`` marks the Python file object as being closed from
-Python's point of view, and also arranges to close the underlying C stream.
-This also happens automatically in ``f``'s destructor, when ``f`` becomes
-garbage.
+For most file objects you create in Python via the built-in :func:`open`
+function, ``f.close()`` marks the Python file object as being closed from
+Python's point of view, and also arranges to close the underlying C file
+descriptor. This also happens automatically in ``f``'s destructor, when
+``f`` becomes garbage.
But stdin, stdout and stderr are treated specially by Python, because of the
special status also given to them by C. Running ``sys.stdout.close()`` marks
the Python-level file object as being closed, but does *not* close the
-associated C stream.
+associated C file descriptor.
+
+To close the underlying C file descriptor for one of these three, you should
+first be sure that's what you really want to do (e.g., you may confuse
+extension modules trying to do I/O). If it is, use :func:`os.close`::
-To close the underlying C stream for one of these three, you should first be
-sure that's what you really want to do (e.g., you may confuse extension modules
-trying to do I/O). If it is, use os.close::
+ os.close(stdin.fileno())
+ os.close(stdout.fileno())
+ os.close(stderr.fileno())
- os.close(0) # close C's stdin stream
- os.close(1) # close C's stdout stream
- os.close(2) # close C's stderr stream
+Or you can use the numeric constants 0, 1 and 2, respectively.
Network/Internet Programming
@@ -650,38 +668,30 @@ How can I mimic CGI form submission (METHOD=POST)?
I would like to retrieve web pages that are the result of POSTing a form. Is
there existing code that would let me do this easily?
-Yes. Here's a simple example that uses httplib::
+Yes. Here's a simple example that uses urllib.request::
#!/usr/local/bin/python
- import httplib, sys, time
+ import urllib.request
### build the query string
qs = "First=Josephine&MI=Q&Last=Public"
### connect and send the server a path
- httpobj = httplib.HTTP('www.some-server.out-there', 80)
- httpobj.putrequest('POST', '/cgi-bin/some-cgi-script')
- ### now generate the rest of the HTTP headers...
- httpobj.putheader('Accept', '*/*')
- httpobj.putheader('Connection', 'Keep-Alive')
- httpobj.putheader('Content-type', 'application/x-www-form-urlencoded')
- httpobj.putheader('Content-length', '%d' % len(qs))
- httpobj.endheaders()
- httpobj.send(qs)
- ### find out what the server said in response...
- reply, msg, hdrs = httpobj.getreply()
- if reply != 200:
- sys.stdout.write(httpobj.getfile().read())
+ req = urllib.request.urlopen('http://www.some-server.out-there'
+ '/cgi-bin/some-cgi-script', data=qs)
+ msg, hdrs = req.read(), req.info()
Note that in general for percent-encoded POST operations, query strings must be
-quoted using :func:`urllib.urlencode`. For example, to send
+quoted using :func:`urllib.parse.urlencode`. For example, to send
``name=Guy Steele, Jr.``::
- >>> import urllib
- >>> urllib.urlencode({'name': 'Guy Steele, Jr.'})
+ >>> import urllib.parse
+ >>> urllib.parse.urlencode({'name': 'Guy Steele, Jr.'})
'name=Guy+Steele%2C+Jr.'
+.. seealso:: :ref:`urllib-howto` for extensive examples.
+
What module should I use to help with generating HTML?
------------------------------------------------------
@@ -702,9 +712,9 @@ work on any host that supports an SMTP listener. ::
import sys, smtplib
- fromaddr = raw_input("From: ")
- toaddrs = raw_input("To: ").split(',')
- print "Enter message, end with ^D:"
+ fromaddr = input("From: ")
+ toaddrs = input("To: ").split(',')
+ print("Enter message, end with ^D:")
msg = ''
while True:
line = sys.stdin.readline()
@@ -722,23 +732,24 @@ varies between systems; sometimes it is ``/usr/lib/sendmail``, sometimes
``/usr/sbin/sendmail``. The sendmail manual page will help you out. Here's
some sample code::
- SENDMAIL = "/usr/sbin/sendmail" # sendmail location
+ SENDMAIL = "/usr/sbin/sendmail" # sendmail location
import os
p = os.popen("%s -t -i" % SENDMAIL, "w")
p.write("To: receiver@example.com\n")
p.write("Subject: test\n")
- p.write("\n") # blank line separating headers from body
+ p.write("\n") # blank line separating headers from body
p.write("Some text\n")
p.write("some more text\n")
sts = p.close()
if sts != 0:
- print "Sendmail exit status", sts
+ print("Sendmail exit status", sts)
How do I avoid blocking in the connect() method of a socket?
------------------------------------------------------------
-The select module is commonly used to help with asynchronous I/O on sockets.
+The :mod:`select` module is commonly used to help with asynchronous I/O on
+sockets.
To prevent the TCP connect from blocking, you can set the socket to non-blocking
mode. Then when you do the ``connect()``, you will either connect immediately
@@ -749,9 +760,15 @@ have to check what's returned on your system.
You can use the ``connect_ex()`` method to avoid creating an exception. It will
just return the errno value. To poll, you can call ``connect_ex()`` again later
--- 0 or ``errno.EISCONN`` indicate that you're connected -- or you can pass this
+-- ``0`` or ``errno.EISCONN`` indicate that you're connected -- or you can pass this
socket to select to check if it's writable.
+.. note::
+ The :mod:`asyncore` module presents a framework-like approach to the problem
+ of writing non-blocking networking code.
+ The third-party `Twisted <http://twistedmatrix.com/>`_ library is
+ a popular and feature-rich alternative.
+
Databases
=========
@@ -761,11 +778,10 @@ Are there any interfaces to database packages in Python?
Yes.
-.. XXX remove bsddb in py3k, fix other module names
-
-Python 2.3 includes the :mod:`bsddb` package which provides an interface to the
-BerkeleyDB library. Interfaces to disk-based hashes such as :mod:`DBM <dbm>`
-and :mod:`GDBM <gdbm>` are also included with standard Python.
+Interfaces to disk-based hashes such as :mod:`DBM <dbm.ndbm>` and :mod:`GDBM
+<dbm.gnu>` are also included with standard Python. There is also the
+:mod:`sqlite3` module, which provides a lightweight disk-based relational
+database.
Support for most relational databases is available. See the
`DatabaseProgramming wiki page
@@ -778,61 +794,7 @@ How do you implement persistent objects in Python?
The :mod:`pickle` library module solves this in a very general way (though you
still can't store things like open files, sockets or windows), and the
:mod:`shelve` library module uses pickle and (g)dbm to create persistent
-mappings containing arbitrary Python objects. For better performance, you can
-use the :mod:`cPickle` module.
-
-A more awkward way of doing things is to use pickle's little sister, marshal.
-The :mod:`marshal` module provides very fast ways to store noncircular basic
-Python types to files and strings, and back again. Although marshal does not do
-fancy things like store instances or handle shared references properly, it does
-run extremely fast. For example, loading a half megabyte of data may take less
-than a third of a second. This often beats doing something more complex and
-general such as using gdbm with pickle/shelve.
-
-
-Why is cPickle so slow?
------------------------
-
-.. XXX update this, default protocol is 2/3
-
-By default :mod:`pickle` uses a relatively old and slow format for backward
-compatibility. You can however specify other protocol versions that are
-faster::
-
- largeString = 'z' * (100 * 1024)
- myPickle = cPickle.dumps(largeString, protocol=1)
-
-
-If my program crashes with a bsddb (or anydbm) database open, it gets corrupted. How come?
-------------------------------------------------------------------------------------------
-
-Databases opened for write access with the bsddb module (and often by the anydbm
-module, since it will preferentially use bsddb) must explicitly be closed using
-the ``.close()`` method of the database. The underlying library caches database
-contents which need to be converted to on-disk form and written.
-
-If you have initialized a new bsddb database but not written anything to it
-before the program crashes, you will often wind up with a zero-length file and
-encounter an exception the next time the file is opened.
-
-
-I tried to open Berkeley DB file, but bsddb produces bsddb.error: (22, 'Invalid argument'). Help! How can I restore my data?
-----------------------------------------------------------------------------------------------------------------------------
-
-Don't panic! Your data is probably intact. The most frequent cause for the error
-is that you tried to open an earlier Berkeley DB file with a later version of
-the Berkeley DB library.
-
-Many Linux systems now have all three versions of Berkeley DB available. If you
-are migrating from version 1 to a newer version use db_dump185 to dump a plain
-text version of the database. If you are migrating from version 2 to version 3
-use db2_dump to create a plain text version of the database. In either case,
-use db_load to create a new native database for the latest version installed on
-your computer. If you have version 3 of Berkeley DB installed, you should be
-able to use db2_load to create a native version 2 database.
-
-You should move away from Berkeley DB version 1 files because the hash file code
-contains known bugs that can corrupt your data.
+mappings containing arbitrary Python objects.
Mathematics and Numerics
diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst
index edee68a..aac8e81 100644
--- a/Doc/faq/programming.rst
+++ b/Doc/faq/programming.rst
@@ -115,167 +115,6 @@ Yes. The coding style required for standard library modules is documented as
:pep:`8`.
-My program is too slow. How do I speed it up?
----------------------------------------------
-
-That's a tough one, in general. There are many tricks to speed up Python code;
-consider rewriting parts in C as a last resort.
-
-In some cases it's possible to automatically translate Python to C or x86
-assembly language, meaning that you don't have to modify your code to gain
-increased speed.
-
-.. XXX seems to have overlap with other questions!
-
-`Pyrex <http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/>`_ can compile a
-slightly modified version of Python code into a C extension, and can be used on
-many different platforms.
-
-`Psyco <http://psyco.sourceforge.net>`_ is a just-in-time compiler that
-translates Python code into x86 assembly language. If you can use it, Psyco can
-provide dramatic speedups for critical functions.
-
-The rest of this answer will discuss various tricks for squeezing a bit more
-speed out of Python code. *Never* apply any optimization tricks unless you know
-you need them, after profiling has indicated that a particular function is the
-heavily executed hot spot in the code. Optimizations almost always make the
-code less clear, and you shouldn't pay the costs of reduced clarity (increased
-development time, greater likelihood of bugs) unless the resulting performance
-benefit is worth it.
-
-There is a page on the wiki devoted to `performance tips
-<http://wiki.python.org/moin/PythonSpeed/PerformanceTips>`_.
-
-Guido van Rossum has written up an anecdote related to optimization at
-http://www.python.org/doc/essays/list2str.html.
-
-One thing to notice is that function and (especially) method calls are rather
-expensive; if you have designed a purely OO interface with lots of tiny
-functions that don't do much more than get or set an instance variable or call
-another method, you might consider using a more direct way such as directly
-accessing instance variables. Also see the standard module :mod:`profile` which
-makes it possible to find out where your program is spending most of its time
-(if you have some patience -- the profiling itself can slow your program down by
-an order of magnitude).
-
-Remember that many standard optimization heuristics you may know from other
-programming experience may well apply to Python. For example it may be faster
-to send output to output devices using larger writes rather than smaller ones in
-order to reduce the overhead of kernel system calls. Thus CGI scripts that
-write all output in "one shot" may be faster than those that write lots of small
-pieces of output.
-
-Also, be sure to use Python's core features where appropriate. For example,
-slicing allows programs to chop up lists and other sequence objects in a single
-tick of the interpreter's mainloop using highly optimized C implementations.
-Thus to get the same effect as::
-
- L2 = []
- for i in range(3):
- L2.append(L1[i])
-
-it is much shorter and far faster to use ::
-
- L2 = list(L1[:3]) # "list" is redundant if L1 is a list.
-
-Note that the functionally-oriented built-in functions such as :func:`map`,
-:func:`zip`, and friends can be a convenient accelerator for loops that
-perform a single task. For example to pair the elements of two lists
-together::
-
- >>> zip([1, 2, 3], [4, 5, 6])
- [(1, 4), (2, 5), (3, 6)]
-
-or to compute a number of sines::
-
- >>> map(math.sin, (1, 2, 3, 4))
- [0.841470984808, 0.909297426826, 0.14112000806, -0.756802495308]
-
-The operation completes very quickly in such cases.
-
-Other examples include the ``join()`` and ``split()`` :ref:`methods
-of string objects <string-methods>`.
-For example if s1..s7 are large (10K+) strings then
-``"".join([s1,s2,s3,s4,s5,s6,s7])`` may be far faster than the more obvious
-``s1+s2+s3+s4+s5+s6+s7``, since the "summation" will compute many
-subexpressions, whereas ``join()`` does all the copying in one pass. For
-manipulating strings, use the ``replace()`` and the ``format()`` :ref:`methods
-on string objects <string-methods>`. Use regular expressions only when you're
-not dealing with constant string patterns. You may still use :ref:`the old %
-operations <string-formatting>` ``string % tuple`` and ``string % dictionary``.
-
-Be sure to use the :meth:`list.sort` built-in method to do sorting, and see the
-`sorting mini-HOWTO <http://wiki.python.org/moin/HowTo/Sorting>`_ for examples
-of moderately advanced usage. :meth:`list.sort` beats other techniques for
-sorting in all but the most extreme circumstances.
-
-Another common trick is to "push loops into functions or methods." For example
-suppose you have a program that runs slowly and you use the profiler to
-determine that a Python function ``ff()`` is being called lots of times. If you
-notice that ``ff()``::
-
- def ff(x):
- ... # do something with x computing result...
- return result
-
-tends to be called in loops like::
-
- list = map(ff, oldlist)
-
-or::
-
- for x in sequence:
- value = ff(x)
- ... # do something with value...
-
-then you can often eliminate function call overhead by rewriting ``ff()`` to::
-
- def ffseq(seq):
- resultseq = []
- for x in seq:
- ... # do something with x computing result...
- resultseq.append(result)
- return resultseq
-
-and rewrite the two examples to ``list = ffseq(oldlist)`` and to::
-
- for value in ffseq(sequence):
- ... # do something with value...
-
-Single calls to ``ff(x)`` translate to ``ffseq([x])[0]`` with little penalty.
-Of course this technique is not always appropriate and there are other variants
-which you can figure out.
-
-You can gain some performance by explicitly storing the results of a function or
-method lookup into a local variable. A loop like::
-
- for key in token:
- dict[key] = dict.get(key, 0) + 1
-
-resolves ``dict.get`` every iteration. If the method isn't going to change, a
-slightly faster implementation is::
-
- dict_get = dict.get # look up the method once
- for key in token:
- dict[key] = dict_get(key, 0) + 1
-
-Default arguments can be used to determine values once, at compile time instead
-of at run time. This can only be done for functions or objects which will not
-be changed during program execution, such as replacing ::
-
- def degree_sin(deg):
- return math.sin(deg * math.pi / 180.0)
-
-with ::
-
- def degree_sin(deg, factor=math.pi/180.0, sin=math.sin):
- return sin(deg * factor)
-
-Because this trick uses default arguments for terms which should not be changed,
-it should only be used when you are not concerned with presenting a possibly
-confusing API to your users.
-
-
Core Language
=============
@@ -290,7 +129,7 @@ This code:
>>> x = 10
>>> def bar():
- ... print x
+ ... print(x)
>>> bar()
10
@@ -298,7 +137,7 @@ works, but this code:
>>> x = 10
>>> def foo():
- ... print x
+ ... print(x)
... x += 1
results in an UnboundLocalError:
@@ -312,7 +151,7 @@ This is because when you make an assignment to a variable in a scope, that
variable becomes local to that scope and shadows any similarly named variable
in the outer scope. Since the last statement in foo assigns a new value to
``x``, the compiler recognizes it as a local variable. Consequently when the
-earlier ``print x`` attempts to print the uninitialized local variable and
+earlier ``print(x)`` attempts to print the uninitialized local variable and
an error results.
In the example above you can access the outer scope variable by declaring it
@@ -321,7 +160,7 @@ global:
>>> x = 10
>>> def foobar():
... global x
- ... print x
+ ... print(x)
... x += 1
>>> foobar()
10
@@ -330,7 +169,22 @@ This explicit declaration is required in order to remind you that (unlike the
superficially analogous situation with class and instance variables) you are
actually modifying the value of the variable in the outer scope:
- >>> print x
+ >>> print(x)
+ 11
+
+You can do a similar thing in a nested scope using the :keyword:`nonlocal`
+keyword:
+
+ >>> def foo():
+ ... x = 10
+ ... def bar():
+ ... nonlocal x
+ ... print(x)
+ ... x += 1
+ ... bar()
+ ... print(x)
+ >>> foo()
+ 10
11
@@ -374,7 +228,7 @@ main.py::
import config
import mod
- print config.x
+ print(config.x)
Note that using a module is also the basis for implementing the Singleton design
pattern, for the same reason.
@@ -386,7 +240,7 @@ What are the "best practices" for using import in a module?
In general, don't use ``from modulename import *``. Doing so clutters the
importer's namespace. Some people avoid this idiom even with the few modules
that were designed to be imported in this manner. Modules designed in this
-manner include :mod:`Tkinter`, and :mod:`threading`.
+manner include :mod:`tkinter`, and :mod:`threading`.
Import modules at the top of a file. Doing so makes it clear what other modules
your code requires and avoids questions of whether the module name is in scope.
@@ -402,9 +256,8 @@ It's good practice if you import modules in the following order:
Never use relative package imports. If you're writing code that's in the
``package.sub.m1`` module and want to import ``package.sub.m2``, do not just
-write ``import m2``, even though it's legal. Write ``from package.sub import
-m2`` instead. Relative imports can lead to a module being initialized twice,
-leading to confusing bugs. See :pep:`328` for details.
+write ``from . import m2``, even though it's legal. Write ``from package.sub
+import m2`` instead. See :pep:`328` for details.
It is sometimes necessary to move imports to a function or class to avoid
problems with circular imports. Gordon McMillan says:
@@ -459,15 +312,6 @@ calling another function by using ``*`` and ``**``::
...
g(x, *args, **kwargs)
-In the unlikely case that you care about Python versions older than 2.0, use
-:func:`apply`::
-
- def f(x, *args, **kwargs):
- ...
- kwargs['width'] = '14.3c'
- ...
- apply(g, (x,)+args, kwargs)
-
.. index::
single: argument; difference from parameter
@@ -511,7 +355,7 @@ desired effect in a number of ways.
x, y = 'old-value', 99
x, y = func2(x, y)
- print x, y # output: new-value 100
+ print(x, y) # output: new-value 100
This is almost always the clearest solution.
@@ -525,7 +369,7 @@ desired effect in a number of ways.
args = ['old-value', 99]
func1(args)
- print args[0], args[1] # output: new-value 100
+ print(args[0], args[1]) # output: new-value 100
4) By passing in a dictionary that gets mutated::
@@ -535,7 +379,7 @@ desired effect in a number of ways.
args = {'a':' old-value', 'b': 99}
func3(args)
- print args['a'], args['b']
+ print(args['a'], args['b'])
5) Or bundle up values in a class instance::
@@ -550,7 +394,7 @@ desired effect in a number of ways.
args = callByRef(a='old-value', b=99)
func4(args)
- print args.a, args.b
+ print(args.a, args.b)
There's almost never a good reason to get this complicated.
@@ -656,10 +500,10 @@ callable. Consider the following code::
a = B()
b = a
- print b
- <__main__.A instance at 0x16D07CC>
- print a
- <__main__.A instance at 0x16D07CC>
+ print(b)
+ <__main__.A object at 0x16D07CC>
+ print(a)
+ <__main__.A object at 0x16D07CC>
Arguably the class has a name: even though it is bound to two names and invoked
through the name B the created instance is still reported as an instance of
@@ -707,61 +551,21 @@ are not truly operators but syntactic delimiters in assignment statements.
Is there an equivalent of C's "?:" ternary operator?
----------------------------------------------------
-Yes, this feature was added in Python 2.5. The syntax would be as follows::
+Yes, there is. The syntax is as follows::
[on_true] if [expression] else [on_false]
x, y = 50, 25
-
small = x if x < y else y
-For versions previous to 2.5 the answer would be 'No'.
-
-.. XXX remove rest?
-
-In many cases you can mimic ``a ? b : c`` with ``a and b or c``, but there's a
-flaw: if *b* is zero (or empty, or ``None`` -- anything that tests false) then
-*c* will be selected instead. In many cases you can prove by looking at the
-code that this can't happen (e.g. because *b* is a constant or has a type that
-can never be false), but in general this can be a problem.
+Before this syntax was introduced in Python 2.5, a common idiom was to use
+logical operators::
-Tim Peters (who wishes it was Steve Majewski) suggested the following solution:
-``(a and [b] or [c])[0]``. Because ``[b]`` is a singleton list it is never
-false, so the wrong path is never taken; then applying ``[0]`` to the whole
-thing gets the *b* or *c* that you really wanted. Ugly, but it gets you there
-in the rare cases where it is really inconvenient to rewrite your code using
-'if'.
+ [expression] and [on_true] or [on_false]
-The best course is usually to write a simple ``if...else`` statement. Another
-solution is to implement the ``?:`` operator as a function::
-
- def q(cond, on_true, on_false):
- if cond:
- if not isfunction(on_true):
- return on_true
- else:
- return on_true()
- else:
- if not isfunction(on_false):
- return on_false
- else:
- return on_false()
-
-In most cases you'll pass b and c directly: ``q(a, b, c)``. To avoid evaluating
-b or c when they shouldn't be, encapsulate them within a lambda function, e.g.:
-``q(a, lambda: b, lambda: c)``.
-
-It has been asked *why* Python has no if-then-else expression. There are
-several answers: many languages do just fine without one; it can easily lead to
-less readable code; no sufficiently "Pythonic" syntax has been discovered; a
-search of the standard library found remarkably few places where using an
-if-then-else expression would make the code more understandable.
-
-In 2002, :pep:`308` was written proposing several possible syntaxes and the
-community was asked to vote on the issue. The vote was inconclusive. Most
-people liked one of the syntaxes, but also hated other syntaxes; many votes
-implied that people preferred no ternary operator rather than having a syntax
-they hated.
+However, this idiom is unsafe, as it can give wrong results when *on_true*
+has a false boolean value. Therefore, it is always better to use
+the ``... if ... else ...`` form.
Is it possible to write obfuscated one-liners in Python?
@@ -770,22 +574,24 @@ Is it possible to write obfuscated one-liners in Python?
Yes. Usually this is done by nesting :keyword:`lambda` within
:keyword:`lambda`. See the following three examples, due to Ulf Bartelt::
+ from functools import reduce
+
# Primes < 1000
- print filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0,
- map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000)))
+ print(list(filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0,
+ map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000)))))
# First 10 Fibonacci numbers
- print map(lambda x,f=lambda x,f:(f(x-1,f)+f(x-2,f)) if x>1 else 1: f(x,f),
- range(10))
+ print(list(map(lambda x,f=lambda x,f:(f(x-1,f)+f(x-2,f)) if x>1 else 1:
+ f(x,f), range(10))))
# Mandelbrot set
- print (lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,
+ print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,
Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM,
Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,
i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y
>=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr(
64+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))):L(Iu+y*(Io-Iu)/Sy),range(Sy
- ))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24)
+ ))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24))
# \___ ___/ \___ ___/ | | |__ lines on screen
# V V | |______ columns on screen
# | | |__________ maximum of "iterations"
@@ -839,12 +645,6 @@ is positive, there are many, and in virtually all of them it's more useful for
ago? ``-190 % 12 == 2`` is useful; ``-190 % 12 == -10`` is a bug waiting to
bite.
-.. note::
-
- On Python 2, ``a / b`` returns the same as ``a // b`` if
- ``__future__.division`` is not in effect. This is also known as "classic"
- division.
-
How do I convert a string to a number?
--------------------------------------
@@ -867,8 +667,8 @@ unwanted side effects. For example, someone could pass
directory.
:func:`eval` also has the effect of interpreting numbers as Python expressions,
-so that e.g. ``eval('09')`` gives a syntax error because Python regards numbers
-starting with '0' as octal (base 8).
+so that e.g. ``eval('09')`` gives a syntax error because Python does not allow
+leading '0' in a decimal number (except '0').
How do I convert a number to a string?
@@ -877,33 +677,38 @@ How do I convert a number to a string?
To convert, e.g., the number 144 to the string '144', use the built-in type
constructor :func:`str`. If you want a hexadecimal or octal representation, use
the built-in functions :func:`hex` or :func:`oct`. For fancy formatting, see
-the :ref:`formatstrings` section, e.g. ``"{:04d}".format(144)`` yields
-``'0144'`` and ``"{:.3f}".format(1/3)`` yields ``'0.333'``. You may also use
-:ref:`the % operator <string-formatting>` on strings. See the library reference
-manual for details.
+the :ref:`string-formatting` section, e.g. ``"{:04d}".format(144)`` yields
+``'0144'`` and ``"{:.3f}".format(1/3)`` yields ``'0.333'``.
How do I modify a string in place?
----------------------------------
-You can't, because strings are immutable. If you need an object with this
-ability, try converting the string to a list or use the array module::
+You can't, because strings are immutable. In most situations, you should
+simply construct a new string from the various parts you want to assemble
+it from. However, if you need an object with the ability to modify in-place
+unicode data, try using a :class:`io.StringIO` object or the :mod:`array`
+module::
>>> s = "Hello, world"
- >>> a = list(s)
- >>> print a
- ['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd']
- >>> a[7:] = list("there!")
- >>> ''.join(a)
+ >>> sio = io.StringIO(s)
+ >>> sio.getvalue()
+ 'Hello, world'
+ >>> sio.seek(7)
+ 7
+ >>> sio.write("there!")
+ 6
+ >>> sio.getvalue()
'Hello, there!'
>>> import array
- >>> a = array.array('c', s)
- >>> print a
- array('c', 'Hello, world')
- >>> a[0] = 'y' ; print a
- array('c', 'yello world')
- >>> a.tostring()
+ >>> a = array.array('u', s)
+ >>> print(a)
+ array('u', 'Hello, world')
+ >>> a[0] = 'y'
+ >>> print(a)
+ array('u', 'yello world')
+ >>> a.tounicode()
'yello, world'
@@ -951,7 +756,7 @@ There are various techniques.
* Use :func:`locals` or :func:`eval` to resolve the function name::
def myFunc():
- print "hello"
+ print("hello")
fname = "myFunc"
@@ -968,11 +773,11 @@ There are various techniques.
Is there an equivalent to Perl's chomp() for removing trailing newlines from strings?
-------------------------------------------------------------------------------------
-Starting with Python 2.2, you can use ``S.rstrip("\r\n")`` to remove all
-occurrences of any line terminator from the end of the string ``S`` without
-removing other trailing whitespace. If the string ``S`` represents more than
-one line, with several empty lines at the end, the line terminators for all the
-blank lines will be removed::
+You can use ``S.rstrip("\r\n")`` to remove all occurrences of any line
+terminator from the end of the string ``S`` without removing other trailing
+whitespace. If the string ``S`` represents more than one line, with several
+empty lines at the end, the line terminators for all the blank lines will
+be removed::
>>> lines = ("line 1 \r\n"
... "\r\n"
@@ -983,15 +788,6 @@ blank lines will be removed::
Since this is typically only desired when reading text one line at a time, using
``S.rstrip()`` this way works well.
-For older versions of Python, there are two partial substitutes:
-
-- If you want to remove all trailing whitespace, use the ``rstrip()`` method of
- string objects. This removes all trailing whitespace, not just a single
- newline.
-
-- Otherwise, if there is only one line in the string ``S``, use
- ``S.splitlines()[0]``.
-
Is there a scanf() or sscanf() equivalent?
------------------------------------------
@@ -1008,45 +804,98 @@ For more complicated input parsing, regular expressions are more powerful
than C's :c:func:`sscanf` and better suited for the task.
-What does 'UnicodeError: ASCII [decoding,encoding] error: ordinal not in range(128)' mean?
-------------------------------------------------------------------------------------------
+What does 'UnicodeDecodeError' or 'UnicodeEncodeError' error mean?
+-------------------------------------------------------------------
-This error indicates that your Python installation can handle only 7-bit ASCII
-strings. There are a couple ways to fix or work around the problem.
+See the :ref:`unicode-howto`.
-If your programs must handle data in arbitrary character set encodings, the
-environment the application runs in will generally identify the encoding of the
-data it is handing you. You need to convert the input to Unicode data using
-that encoding. For example, a program that handles email or web input will
-typically find character set encoding information in Content-Type headers. This
-can then be used to properly convert input data to Unicode. Assuming the string
-referred to by ``value`` is encoded as UTF-8::
- value = unicode(value, "utf-8")
+Performance
+===========
-will return a Unicode object. If the data is not correctly encoded as UTF-8,
-the above call will raise a :exc:`UnicodeError` exception.
+My program is too slow. How do I speed it up?
+---------------------------------------------
-If you only want strings converted to Unicode which have non-ASCII data, you can
-try converting them first assuming an ASCII encoding, and then generate Unicode
-objects if that fails::
+That's a tough one, in general. First, here are a list of things to
+remember before diving further:
+
+* Performance characteristics vary across Python implementations. This FAQ
+ focusses on :term:`CPython`.
+* Behaviour can vary across operating systems, especially when talking about
+ I/O or multi-threading.
+* You should always find the hot spots in your program *before* attempting to
+ optimize any code (see the :mod:`profile` module).
+* Writing benchmark scripts will allow you to iterate quickly when searching
+ for improvements (see the :mod:`timeit` module).
+* It is highly recommended to have good code coverage (through unit testing
+ or any other technique) before potentially introducing regressions hidden
+ in sophisticated optimizations.
+
+That being said, there are many tricks to speed up Python code. Here are
+some general principles which go a long way towards reaching acceptable
+performance levels:
+
+* Making your algorithms faster (or changing to faster ones) can yield
+ much larger benefits than trying to sprinkle micro-optimization tricks
+ all over your code.
+
+* Use the right data structures. Study documentation for the :ref:`bltin-types`
+ and the :mod:`collections` module.
+
+* When the standard library provides a primitive for doing something, it is
+ likely (although not guaranteed) to be faster than any alternative you
+ may come up with. This is doubly true for primitives written in C, such
+ as builtins and some extension types. For example, be sure to use
+ either the :meth:`list.sort` built-in method or the related :func:`sorted`
+ function to do sorting (and see the
+ `sorting mini-HOWTO <http://wiki.python.org/moin/HowTo/Sorting>`_ for examples
+ of moderately advanced usage).
+
+* Abstractions tend to create indirections and force the interpreter to work
+ more. If the levels of indirection outweigh the amount of useful work
+ done, your program will be slower. You should avoid excessive abstraction,
+ especially under the form of tiny functions or methods (which are also often
+ detrimental to readability).
+
+If you have reached the limit of what pure Python can allow, there are tools
+to take you further away. For example, `Cython <http://cython.org>`_ can
+compile a slightly modified version of Python code into a C extension, and
+can be used on many different platforms. Cython can take advantage of
+compilation (and optional type annotations) to make your code significantly
+faster than when interpreted. If you are confident in your C programming
+skills, you can also :ref:`write a C extension module <extending-index>`
+yourself.
+
+.. seealso::
+ The wiki page devoted to `performance tips
+ <http://wiki.python.org/moin/PythonSpeed/PerformanceTips>`_.
+
+.. _efficient_string_concatenation:
+
+What is the most efficient way to concatenate many strings together?
+--------------------------------------------------------------------
- try:
- x = unicode(value, "ascii")
- except UnicodeError:
- value = unicode(value, "utf-8")
- else:
- # value was valid ASCII data
- pass
+:class:`str` and :class:`bytes` objects are immutable, therefore concatenating
+many strings together is inefficient as each concatenation creates a new
+object. In the general case, the total runtime cost is quadratic in the
+total string length.
+
+To accumulate many :class:`str` objects, the recommended idiom is to place
+them into a list and call :meth:`str.join` at the end::
-It's possible to set a default encoding in a file called ``sitecustomize.py``
-that's part of the Python library. However, this isn't recommended because
-changing the Python-wide default encoding may cause third-party extension
-modules to fail.
+ chunks = []
+ for s in my_strings:
+ chunks.append(s)
+ result = ''.join(chunks)
-Note that on Windows, there is an encoding known as "mbcs", which uses an
-encoding specific to your current locale. In many cases, and particularly when
-working with COM, this may be an appropriate default encoding to use.
+(another reasonably efficient idiom is to use :class:`io.StringIO`)
+
+To accumulate many :class:`bytes` objects, the recommended idiom is to extend
+a :class:`bytearray` object using in-place concatenation (the ``+=`` operator)::
+
+ result = bytearray()
+ for b in my_bytes_objects:
+ result += b
Sequences (Tuples/Lists)
@@ -1118,15 +967,8 @@ list, deleting duplicates as you go::
else:
last = mylist[i]
-If all elements of the list may be used as dictionary keys (i.e. they are all
-hashable) this is often faster ::
-
- d = {}
- for x in mylist:
- d[x] = 1
- mylist = list(d.keys())
-
-In Python 2.5 and later, the following is possible instead::
+If all elements of the list may be used as set keys (i.e. they are all
+:term:`hashable`) this is often faster ::
mylist = list(set(mylist))
@@ -1206,14 +1048,6 @@ Use a list comprehension::
result = [obj.method() for obj in mylist]
-More generically, you can try the following function::
-
- def method_map(objects, method, arguments):
- """method_map([a,b], "meth", (1,2)) gives [a.meth(1,2), b.meth(1,2)]"""
- nobjects = len(objects)
- methods = map(getattr, objects, [method]*nobjects)
- return map(apply, methods, [arguments]*nobjects)
-
Dictionaries
============
@@ -1272,7 +1106,7 @@ each string::
tmp2.sort()
Isorted = [x[1] for x in tmp2]
-Note that Isorted may also be computed by ::
+For versions prior to 3.0, Isorted may also be computed by ::
def intfield(s):
return int(s[10:15])
@@ -1290,19 +1124,20 @@ is slower than the Schwartzian Transform.
How can I sort one list by values from another list?
----------------------------------------------------
-Merge them into a single list of tuples, sort the resulting list, and then pick
+Merge them into an iterator of tuples, sort the resulting list, and then pick
out the element you want. ::
>>> list1 = ["what", "I'm", "sorting", "by"]
>>> list2 = ["something", "else", "to", "sort"]
>>> pairs = zip(list1, list2)
+ >>> pairs = sorted(pairs)
>>> pairs
- [('what', 'something'), ("I'm", 'else'), ('sorting', 'to'), ('by', 'sort')]
- >>> pairs.sort()
- >>> result = [ x[1] for x in pairs ]
+ [("I'm", 'else'), ('by', 'sort'), ('sorting', 'to'), ('what', 'something')]
+ >>> result = [x[1] for x in pairs]
>>> result
['else', 'sort', 'to', 'something']
+
An alternative for the last step is::
>>> result = []
@@ -1365,7 +1200,7 @@ Use the built-in function ``isinstance(obj, cls)``. You can check if an object
is an instance of any of a number of classes by providing a tuple instead of a
single class, e.g. ``isinstance(obj, (class1, class2, ...))``, and can also
check whether an object is one of Python's built-in types, e.g.
-``isinstance(obj, str)`` or ``isinstance(obj, (int, long, float, complex))``.
+``isinstance(obj, str)`` or ``isinstance(obj, (int, float, complex))``.
Note that most programs do not use :func:`isinstance` on user-defined classes
very often. If you are developing the classes yourself, a more proper
@@ -1444,17 +1279,17 @@ local state for self without causing an infinite recursion.
How do I call a method defined in a base class from a derived class that overrides it?
--------------------------------------------------------------------------------------
-If you're using new-style classes, use the built-in :func:`super` function::
+Use the built-in :func:`super` function::
class Derived(Base):
def meth (self):
super(Derived, self).meth()
-If you're using classic classes: For a class definition such as ``class
-Derived(Base): ...`` you can call method ``meth()`` defined in ``Base`` (or one
-of ``Base``'s base classes) as ``Base.meth(self, arguments...)``. Here,
-``Base.meth`` is an unbound method, so you need to provide the ``self``
-argument.
+For version prior to 3.0, you may be using classic classes: For a class
+definition such as ``class Derived(Base): ...`` you can call method ``meth()``
+defined in ``Base`` (or one of ``Base``'s base classes) as ``Base.meth(self,
+arguments...)``. Here, ``Base.meth`` is an unbound method, so you need to
+provide the ``self`` argument.
How can I organize my code to make it easier to change the base class?
@@ -1503,15 +1338,7 @@ not::
C.count = 314
-Static methods are possible since Python 2.2::
-
- class C:
- def static(arg1, arg2, arg3):
- # No 'self' parameter!
- ...
- static = staticmethod(static)
-
-With Python 2.4's decorators, this can also be written as ::
+Static methods are possible::
class C:
@staticmethod
@@ -1550,9 +1377,9 @@ default arguments. For example::
class C:
def __init__(self, i=None):
if i is None:
- print "No arguments"
+ print("No arguments")
else:
- print "Argument is", i
+ print("Argument is", i)
This is not entirely equivalent, but close enough in practice.
@@ -1611,11 +1438,13 @@ which allows you to point to objects without incrementing their reference count.
Tree data structures, for instance, should use weak references for their parent
and sibling references (if they need them!).
-If the object has ever been a local variable in a function that caught an
-expression in an except clause, chances are that a reference to the object still
-exists in that function's stack frame as contained in the stack trace.
-Normally, calling :func:`sys.exc_clear` will take care of this by clearing the
-last recorded exception.
+.. XXX relevant for Python 3?
+
+ If the object has ever been a local variable in a function that caught an
+ expression in an except clause, chances are that a reference to the object
+ still exists in that function's stack frame as contained in the stack trace.
+ Normally, calling :func:`sys.exc_clear` will take care of this by clearing
+ the last recorded exception.
Finally, if your :meth:`__del__` method raises an exception, a warning message
is printed to :data:`sys.stderr`.
@@ -1683,7 +1512,7 @@ provide a command-line interface or a self-test, and only execute this code
after checking ``__name__``::
def main():
- print 'Running test...'
+ print('Running test...')
...
if __name__ == '__main__':
@@ -1772,8 +1601,9 @@ consisting of many modules where each one imports the same basic module, the
basic module would be parsed and re-parsed many times. To force rereading of a
changed module, do this::
+ import imp
import modname
- reload(modname)
+ imp.reload(modname)
Warning: this technique is not 100% fool-proof. In particular, modules
containing statements like ::
@@ -1785,17 +1615,18 @@ module contains class definitions, existing class instances will *not* be
updated to use the new class definition. This can result in the following
paradoxical behaviour:
+ >>> import imp
>>> import cls
>>> c = cls.C() # Create an instance of C
- >>> reload(cls)
- <module 'cls' from 'cls.pyc'>
+ >>> imp.reload(cls)
+ <module 'cls' from 'cls.py'>
>>> isinstance(c, cls.C) # isinstance is false?!?
False
-The nature of the problem is made clear if you print out the class objects:
-
- >>> c.__class__
- <class cls.C at 0x7352a0>
- >>> cls.C
- <class cls.C at 0x4198d0>
+The nature of the problem is made clear if you print out the "identity" of the
+class objects:
+ >>> hex(id(c.__class__))
+ '0x7352a0'
+ >>> hex(id(cls.C))
+ '0x4198d0'
diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst
index 0abe2e9..0a85a40 100644
--- a/Doc/faq/windows.rst
+++ b/Doc/faq/windows.rst
@@ -8,6 +8,10 @@ Python on Windows FAQ
.. contents::
+.. XXX need review for Python 3.
+ XXX need review for Windows Vista/Seven?
+
+
How do I run a Python program under Windows?
--------------------------------------------
@@ -60,7 +64,7 @@ return.::
You should then see something like::
- Python 2.7.3 (default, Apr 10 2012, 22.71:26) [MSC v.1500 32 bit (Intel)] on win32
+ Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
@@ -69,7 +73,7 @@ Python statements or expressions interactively and have them executed or
evaluated while you wait. This is one of Python's strongest features. Check it
by entering a few expressions of your choice and seeing the results::
- >>> print "Hello"
+ >>> print("Hello")
Hello
>>> "Hello" * 3
HelloHelloHello
@@ -80,7 +84,7 @@ key down while you enter a Z, then hit the "Enter" key to get back to your
Windows command prompt.
You may also find that you have a Start-menu entry such as :menuselection:`Start
---> Programs --> Python 2.7 --> Python (command line)` that results in you
+--> Programs --> Python 3.3 --> Python (command line)` that results in you
seeing the ``>>>`` prompt in a new window. If so, the window will disappear
after you enter the Ctrl-Z character; Windows is running a single "python"
command in the window, and closes it when you terminate the interpreter.
@@ -117,19 +121,19 @@ then the command ::
dir C:\py*
will probably tell you where it is installed; the usual location is something
-like ``C:\Python27``. Otherwise you will be reduced to a search of your whole
+like ``C:\Python33``. Otherwise you will be reduced to a search of your whole
disk ... use :menuselection:`Tools --> Find` or hit the :guilabel:`Search`
button and look for "python.exe". Supposing you discover that Python is
-installed in the ``C:\Python27`` directory (the default at the time of writing),
+installed in the ``C:\Python33`` directory (the default at the time of writing),
you should make sure that entering the command ::
- c:\Python27\python
+ c:\Python33\python
starts up the interpreter as above (and don't forget you'll need a "CTRL-Z" and
an "Enter" to get out of it). Once you have verified the directory, you can
add it to the system path to make it easier to start Python by just running
the ``python`` command. This is currently an option in the installer as of
-CPython 2.7.
+CPython 3.3.
More information about environment variables can be found on the
:ref:`Using Python on Windows <setting-envvars>` page.
@@ -196,7 +200,7 @@ Embedding the Python interpreter in a Windows app can be summarized as follows:
be a DLL to handle importing modules that are themselves DLL's. (This is the
first key undocumented fact.) Instead, link to :file:`python{NN}.dll`; it is
typically installed in ``C:\Windows\System``. *NN* is the Python version, a
- number such as "27" for Python 2.7.
+ number such as "33" for Python 3.3.
You can link to Python in two different ways. Load-time linking means
linking against :file:`python{NN}.lib`, while run-time linking means linking
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index 392a60c..164c017 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -30,13 +30,14 @@ Glossary
Abstract base classes complement :term:`duck-typing` by
providing a way to define interfaces when other techniques like
:func:`hasattr` would be clumsy or subtly wrong (for example with
- :ref:`magic methods <new-style-special-lookup>`). ABCs introduce virtual
+ :ref:`magic methods <special-lookup>`). ABCs introduce virtual
subclasses, which are classes that don't inherit from a class but are
still recognized by :func:`isinstance` and :func:`issubclass`; see the
:mod:`abc` module documentation. Python comes with many built-in ABCs for
data structures (in the :mod:`collections` module), numbers (in the
- :mod:`numbers` module), and streams (in the :mod:`io` module). You can
- create your own ABCs with the :mod:`abc` module.
+ :mod:`numbers` module), streams (in the :mod:`io` module), import finders
+ and loaders (in the :mod:`importlib.abc` module). You can create your own
+ ABCs with the :mod:`abc` module.
argument
A value passed to a :term:`function` (or :term:`method`) when calling the
@@ -64,9 +65,9 @@ Glossary
Syntactically, any expression can be used to represent an argument; the
evaluated value is assigned to the local variable.
- See also the :term:`parameter` glossary entry and the FAQ question on
+ See also the :term:`parameter` glossary entry, the FAQ question on
:ref:`the difference between arguments and parameters
- <faq-argument-vs-parameter>`.
+ <faq-argument-vs-parameter>`, and :pep:`362`.
attribute
A value associated with an object which is referenced by name using
@@ -96,20 +97,13 @@ Glossary
normally contain method definitions which operate on instances of the
class.
- classic class
- Any class which does not inherit from :class:`object`. See
- :term:`new-style class`. Classic classes have been removed in Python 3.
-
coercion
The implicit conversion of an instance of one type to another during an
operation which involves two arguments of the same type. For example,
``int(3.15)`` converts the floating point number to the integer ``3``, but
in ``3+4.5``, each argument is of a different type (one int, one float),
and both must be converted to the same type before they can be added or it
- will raise a ``TypeError``. Coercion between two operands can be
- performed with the ``coerce`` built-in function; thus, ``3+4.5`` is
- equivalent to calling ``operator.add(*coerce(3, 4.5))`` and results in
- ``operator.add(3.0, 4.5)``. Without coercion, all arguments of even
+ will raise a ``TypeError``. Without coercion, all arguments of even
compatible types would have to be normalized to the same value by the
programmer, e.g., ``float(3)+4.5`` rather than just ``3+4.5``.
@@ -157,21 +151,21 @@ Glossary
:ref:`class definitions <class>` for more about decorators.
descriptor
- Any *new-style* object which defines the methods :meth:`__get__`,
- :meth:`__set__`, or :meth:`__delete__`. When a class attribute is a
- descriptor, its special binding behavior is triggered upon attribute
- lookup. Normally, using *a.b* to get, set or delete an attribute looks up
- the object named *b* in the class dictionary for *a*, but if *b* is a
- descriptor, the respective descriptor method gets called. Understanding
- descriptors is a key to a deep understanding of Python because they are
- the basis for many features including functions, methods, properties,
- class methods, static methods, and reference to super classes.
+ Any object which defines the methods :meth:`__get__`, :meth:`__set__`, or
+ :meth:`__delete__`. When a class attribute is a descriptor, its special
+ binding behavior is triggered upon attribute lookup. Normally, using
+ *a.b* to get, set or delete an attribute looks up the object named *b* in
+ the class dictionary for *a*, but if *b* is a descriptor, the respective
+ descriptor method gets called. Understanding descriptors is a key to a
+ deep understanding of Python because they are the basis for many features
+ including functions, methods, properties, class methods, static methods,
+ and reference to super classes.
For more information about descriptors' methods, see :ref:`descriptors`.
dictionary
An associative array, where arbitrary keys are mapped to values. The
- keys can be any object with :meth:`__hash__` and :meth:`__eq__` methods.
+ keys can be any object with :meth:`__hash__` and :meth:`__eq__` methods.
Called a hash in Perl.
docstring
@@ -207,8 +201,8 @@ Glossary
names, attribute access, operators or function calls which all return a
value. In contrast to many other languages, not all language constructs
are expressions. There are also :term:`statement`\s which cannot be used
- as expressions, such as :keyword:`print` or :keyword:`if`. Assignments
- are also statements, not expressions.
+ as expressions, such as :keyword:`if`. Assignments are also statements,
+ not expressions.
extension module
A module written in C or C++, using Python's C API to interact with the
@@ -234,7 +228,8 @@ Glossary
finder
An object that tries to find the :term:`loader` for a module. It must
implement a method named :meth:`find_module`. See :pep:`302` for
- details.
+ details and :class:`importlib.abc.Finder` for an
+ :term:`abstract base class`.
floor division
Mathematical division that rounds down to nearest integer. The floor
@@ -251,16 +246,11 @@ Glossary
__future__
A pseudo-module which programmers can use to enable new language features
- which are not compatible with the current interpreter. For example, the
- expression ``11/4`` currently evaluates to ``2``. If the module in which
- it is executed had enabled *true division* by executing::
-
- from __future__ import division
+ which are not compatible with the current interpreter.
- the expression ``11/4`` would evaluate to ``2.75``. By importing the
- :mod:`__future__` module and evaluating its variables, you can see when a
- new feature was first added to the language and when it will become the
- default::
+ By importing the :mod:`__future__` module and evaluating its variables,
+ you can see when a new feature was first added to the language and when it
+ becomes the default::
>>> import __future__
>>> __future__.division
@@ -321,8 +311,8 @@ Glossary
hashable
An object is *hashable* if it has a hash value which never changes during
its lifetime (it needs a :meth:`__hash__` method), and can be compared to
- other objects (it needs an :meth:`__eq__` or :meth:`__cmp__` method).
- Hashable objects which compare equal must have the same hash value.
+ other objects (it needs an :meth:`__eq__` method). Hashable objects which
+ compare equal must have the same hash value.
Hashability makes an object usable as a dictionary key and a set member,
because these data structures use the hash value internally.
@@ -344,18 +334,6 @@ Glossary
role in places where a constant hash value is needed, for example as a key
in a dictionary.
- integer division
- Mathematical division discarding any remainder. For example, the
- expression ``11/4`` currently evaluates to ``2`` in contrast to the
- ``2.75`` returned by float division. Also called *floor division*.
- When dividing two integers the outcome will always be another integer
- (having the floor function applied to it). However, if one of the operands
- is another numeric type (such as a :class:`float`), the result will be
- coerced (see :term:`coercion`) to a common type. For example, an integer
- divided by a float will result in a float value, possibly with a decimal
- fraction. Integer division can be forced by using the ``//`` operator
- instead of the ``/`` operator. See also :term:`__future__`.
-
importer
An object that both finds and loads a module; both a
:term:`finder` and :term:`loader` object.
@@ -395,11 +373,12 @@ Glossary
iterator
An object representing a stream of data. Repeated calls to the iterator's
- :meth:`next` method return successive items in the stream. When no more
- data are available a :exc:`StopIteration` exception is raised instead. At
- this point, the iterator object is exhausted and any further calls to its
- :meth:`next` method just raise :exc:`StopIteration` again. Iterators are
- required to have an :meth:`__iter__` method that returns the iterator
+ :meth:`~iterator.__next__` method (or passing it to the built-in function
+ :func:`next`) return successive items in the stream. When no more data
+ are available a :exc:`StopIteration` exception is raised instead. At this
+ point, the iterator object is exhausted and any further calls to its
+ :meth:`__next__` method just raise :exc:`StopIteration` again. Iterators
+ are required to have an :meth:`__iter__` method that returns the iterator
object itself so every iterator is also iterable and may be used in most
places where other iterables are accepted. One notable exception is code
which attempts multiple iteration passes. A container object (such as a
@@ -457,7 +436,7 @@ Glossary
list comprehension
A compact way to process all or part of the elements in a sequence and
- return a list with the results. ``result = ["0x%02x" % x for x in
+ return a list with the results. ``result = ['{:#04x}'.format(x) for x in
range(256) if x % 2 == 0]`` generates a list of strings containing
even hex numbers (0x..) in the range from 0 to 255. The :keyword:`if`
clause is optional. If omitted, all elements in ``range(256)`` are
@@ -466,7 +445,8 @@ Glossary
loader
An object that loads a module. It must define a method named
:meth:`load_module`. A loader is typically returned by a
- :term:`finder`. See :pep:`302` for details.
+ :term:`finder`. See :pep:`302` for details and
+ :class:`importlib.abc.Loader` for an :term:`abstract base class`.
mapping
A container object that supports arbitrary key lookups and implements the
@@ -525,28 +505,27 @@ Glossary
dictionaries. There are the local, global and built-in namespaces as well
as nested namespaces in objects (in methods). Namespaces support
modularity by preventing naming conflicts. For instance, the functions
- :func:`__builtin__.open` and :func:`os.open` are distinguished by their
+ :func:`builtins.open` and :func:`os.open` are distinguished by their
namespaces. Namespaces also aid readability and maintainability by making
it clear which module implements a function. For instance, writing
- :func:`random.seed` or :func:`itertools.izip` makes it clear that those
+ :func:`random.seed` or :func:`itertools.islice` makes it clear that those
functions are implemented by the :mod:`random` and :mod:`itertools`
modules, respectively.
nested scope
The ability to refer to a variable in an enclosing definition. For
instance, a function defined inside another function can refer to
- variables in the outer function. Note that nested scopes work only for
- reference and not for assignment which will always write to the innermost
- scope. In contrast, local variables both read and write in the innermost
- scope. Likewise, global variables read and write to the global namespace.
+ variables in the outer function. Note that nested scopes by default work
+ only for reference and not for assignment. Local variables both read and
+ write in the innermost scope. Likewise, global variables read and write
+ to the global namespace. The :keyword:`nonlocal` allows writing to outer
+ scopes.
new-style class
- Any class which inherits from :class:`object`. This includes all built-in
- types like :class:`list` and :class:`dict`. Only new-style classes can
- use Python's newer, versatile features like :attr:`__slots__`,
- descriptors, properties, and :meth:`__getattribute__`.
-
- More information can be found in :ref:`newstyle`.
+ Old name for the flavor of classes now used for all class objects. In
+ earlier Python versions, only new-style classes could use Python's newer,
+ versatile features like :attr:`__slots__`, descriptors, properties,
+ :meth:`__getattribute__`, class methods, and static methods.
object
Any data with state (attributes or value) and defined behavior
@@ -556,7 +535,7 @@ Glossary
parameter
A named entity in a :term:`function` (or method) definition that
specifies an :term:`argument` (or in some cases, arguments) that the
- function can accept. There are four types of parameters:
+ function can accept. There are five types of parameters:
* :dfn:`positional-or-keyword`: specifies an argument that can be passed
either :term:`positionally <argument>` or as a :term:`keyword argument
@@ -570,6 +549,14 @@ Glossary
parameters. However, some built-in functions have positional-only
parameters (e.g. :func:`abs`).
+ * :dfn:`keyword-only`: specifies an argument that can be supplied only
+ by keyword. Keyword-only parameters can be defined by including a
+ single var-positional parameter or bare ``*`` in the parameter list
+ of the function definition before them, for example *kw_only1* and
+ *kw_only2* in the following::
+
+ def func(arg, *, kw_only1, kw_only2): ...
+
* :dfn:`var-positional`: specifies that an arbitrary sequence of
positional arguments can be provided (in addition to any positional
arguments already accepted by other parameters). Such a parameter can
@@ -589,7 +576,8 @@ Glossary
See also the :term:`argument` glossary entry, the FAQ question on
:ref:`the difference between arguments and parameters
- <faq-argument-vs-parameter>`, and the :ref:`function` section.
+ <faq-argument-vs-parameter>`, the :class:`inspect.Parameter` class, the
+ :ref:`function` section, and :pep:`362`.
positional argument
See :term:`argument`.
@@ -608,12 +596,12 @@ Glossary
people unfamiliar with Python sometimes use a numerical counter instead::
for i in range(len(food)):
- print food[i]
+ print(food[i])
As opposed to the cleaner, Pythonic method::
for piece in food:
- print piece
+ print(piece)
reference count
The number of references to an object. When the reference count of an
@@ -624,18 +612,18 @@ Glossary
reference count for a particular object.
__slots__
- A declaration inside a :term:`new-style class` that saves memory by
- pre-declaring space for instance attributes and eliminating instance
- dictionaries. Though popular, the technique is somewhat tricky to get
- right and is best reserved for rare cases where there are large numbers of
- instances in a memory-critical application.
+ A declaration inside a class that saves memory by pre-declaring space for
+ instance attributes and eliminating instance dictionaries. Though
+ popular, the technique is somewhat tricky to get right and is best
+ reserved for rare cases where there are large numbers of instances in a
+ memory-critical application.
sequence
An :term:`iterable` which supports efficient element access using integer
indices via the :meth:`__getitem__` special method and defines a
- :meth:`len` method that returns the length of the sequence.
+ :meth:`__len__` method that returns the length of the sequence.
Some built-in sequence types are :class:`list`, :class:`str`,
- :class:`tuple`, and :class:`unicode`. Note that :class:`dict` also
+ :class:`tuple`, and :class:`bytes`. Note that :class:`dict` also
supports :meth:`__getitem__` and :meth:`__len__`, but is considered a
mapping rather than a sequence because the lookups use arbitrary
:term:`immutable` keys rather than integers.
@@ -644,8 +632,7 @@ Glossary
An object usually containing a portion of a :term:`sequence`. A slice is
created using the subscript notation, ``[]`` with colons between numbers
when several are given, such as in ``variable_name[1:3:5]``. The bracket
- (subscript) notation uses :class:`slice` objects internally (or in older
- versions, :meth:`__getslice__` and :meth:`__setslice__`).
+ (subscript) notation uses :class:`slice` objects internally.
special method
A method that is called implicitly by Python to execute a certain
@@ -658,14 +645,6 @@ Glossary
an :term:`expression` or a one of several constructs with a keyword, such
as :keyword:`if`, :keyword:`while` or :keyword:`for`.
- struct sequence
- A tuple with named elements. Struct sequences expose an interface similiar
- to :term:`named tuple` in that elements can either be accessed either by
- index or as an attribute. However, they do not have any of the named tuple
- methods like :meth:`~collections.somenamedtuple._make` or
- :meth:`~collections.somenamedtuple._asdict`. Examples of struct sequences
- include :data:`sys.float_info` and the return value of :func:`os.stat`.
-
triple-quoted string
A string which is bound by three instances of either a quotation mark
(") or an apostrophe ('). While they don't provide any functionality
@@ -688,10 +667,10 @@ Glossary
:func:`str.splitlines` for an additional use.
view
- The objects returned from :meth:`dict.viewkeys`, :meth:`dict.viewvalues`,
- and :meth:`dict.viewitems` are called dictionary views. They are lazy
- sequences that will see changes in the underlying dictionary. To force
- the dictionary view to become a full list use ``list(dictview)``. See
+ The objects returned from :meth:`dict.keys`, :meth:`dict.values`, and
+ :meth:`dict.items` are called dictionary views. They are lazy sequences
+ that will see changes in the underlying dictionary. To force the
+ dictionary view to become a full list use ``list(dictview)``. See
:ref:`dict-views`.
virtual machine
diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst
index 449f7cd..50e1a94 100644
--- a/Doc/howto/argparse.rst
+++ b/Doc/howto/argparse.rst
@@ -79,16 +79,16 @@ Following is a result of running the code:
.. code-block:: sh
- $ python prog.py
- $ python prog.py --help
+ $ python3 prog.py
+ $ python3 prog.py --help
usage: prog.py [-h]
optional arguments:
-h, --help show this help message and exit
- $ python prog.py --verbose
+ $ python3 prog.py --verbose
usage: prog.py [-h]
prog.py: error: unrecognized arguments: --verbose
- $ python prog.py foo
+ $ python3 prog.py foo
usage: prog.py [-h]
prog.py: error: unrecognized arguments: foo
@@ -115,16 +115,16 @@ An example::
parser = argparse.ArgumentParser()
parser.add_argument("echo")
args = parser.parse_args()
- print args.echo
+ print(args.echo)
And running the code:
.. code-block:: sh
- $ python prog.py
+ $ python3 prog.py
usage: prog.py [-h] echo
prog.py: error: the following arguments are required: echo
- $ python prog.py --help
+ $ python3 prog.py --help
usage: prog.py [-h] echo
positional arguments:
@@ -132,7 +132,7 @@ And running the code:
optional arguments:
-h, --help show this help message and exit
- $ python prog.py foo
+ $ python3 prog.py foo
foo
Here is what's happening:
@@ -160,13 +160,13 @@ by reading the source code. So, let's make it a bit more useful::
parser = argparse.ArgumentParser()
parser.add_argument("echo", help="echo the string you use here")
args = parser.parse_args()
- print args.echo
+ print(args.echo)
And we get:
.. code-block:: sh
- $ python prog.py -h
+ $ python3 prog.py -h
usage: prog.py [-h] echo
positional arguments:
@@ -181,16 +181,16 @@ Now, how about doing something even more useful::
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number")
args = parser.parse_args()
- print args.square**2
+ print(args.square**2)
Following is a result of running the code:
.. code-block:: sh
- $ python prog.py 4
+ $ python3 prog.py 4
Traceback (most recent call last):
File "prog.py", line 5, in <module>
- print args.square**2
+ print(args.square**2)
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
That didn't go so well. That's because :mod:`argparse` treats the options we
@@ -202,15 +202,15 @@ give it as strings, unless we tell it otherwise. So, let's tell
parser.add_argument("square", help="display a square of a given number",
type=int)
args = parser.parse_args()
- print args.square**2
+ print(args.square**2)
Following is a result of running the code:
.. code-block:: sh
- $ python prog.py 4
+ $ python3 prog.py 4
16
- $ python prog.py four
+ $ python3 prog.py four
usage: prog.py [-h] square
prog.py: error: argument square: invalid int value: 'four'
@@ -229,23 +229,23 @@ have a look on how to add optional ones::
parser.add_argument("--verbosity", help="increase output verbosity")
args = parser.parse_args()
if args.verbosity:
- print "verbosity turned on"
+ print("verbosity turned on")
And the output:
.. code-block:: sh
- $ python prog.py --verbosity 1
+ $ python3 prog.py --verbosity 1
verbosity turned on
- $ python prog.py
- $ python prog.py --help
+ $ python3 prog.py
+ $ python3 prog.py --help
usage: prog.py [-h] [--verbosity VERBOSITY]
optional arguments:
-h, --help show this help message and exit
--verbosity VERBOSITY
increase output verbosity
- $ python prog.py --verbosity
+ $ python3 prog.py --verbosity
usage: prog.py [-h] [--verbosity VERBOSITY]
prog.py: error: argument --verbosity: expected one argument
@@ -275,18 +275,18 @@ Let's modify the code accordingly::
action="store_true")
args = parser.parse_args()
if args.verbose:
- print "verbosity turned on"
+ print("verbosity turned on")
And the output:
.. code-block:: sh
- $ python prog.py --verbose
+ $ python3 prog.py --verbose
verbosity turned on
- $ python prog.py --verbose 1
+ $ python3 prog.py --verbose 1
usage: prog.py [-h] [--verbose]
prog.py: error: unrecognized arguments: 1
- $ python prog.py --help
+ $ python3 prog.py --help
usage: prog.py [-h] [--verbose]
optional arguments:
@@ -321,15 +321,15 @@ versions of the options. It's quite simple::
action="store_true")
args = parser.parse_args()
if args.verbose:
- print "verbosity turned on"
+ print("verbosity turned on")
And here goes:
.. code-block:: sh
- $ python prog.py -v
+ $ python3 prog.py -v
verbosity turned on
- $ python prog.py --help
+ $ python3 prog.py --help
usage: prog.py [-h] [-v]
optional arguments:
@@ -353,22 +353,22 @@ Our program keeps growing in complexity::
args = parser.parse_args()
answer = args.square**2
if args.verbose:
- print "the square of {} equals {}".format(args.square, answer)
+ print("the square of {} equals {}".format(args.square, answer))
else:
- print answer
+ print(answer)
And now the output:
.. code-block:: sh
- $ python prog.py
+ $ python3 prog.py
usage: prog.py [-h] [-v] square
prog.py: error: the following arguments are required: square
- $ python prog.py 4
+ $ python3 prog.py 4
16
- $ python prog.py 4 --verbose
+ $ python3 prog.py 4 --verbose
the square of 4 equals 16
- $ python prog.py --verbose 4
+ $ python3 prog.py --verbose 4
the square of 4 equals 16
* We've brought back a positional argument, hence the complaint.
@@ -387,26 +387,26 @@ multiple verbosity values, and actually get to use them::
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
- print "the square of {} equals {}".format(args.square, answer)
+ print("the square of {} equals {}".format(args.square, answer))
elif args.verbosity == 1:
- print "{}^2 == {}".format(args.square, answer)
+ print("{}^2 == {}".format(args.square, answer))
else:
- print answer
+ print(answer)
And the output:
.. code-block:: sh
- $ python prog.py 4
+ $ python3 prog.py 4
16
- $ python prog.py 4 -v
+ $ python3 prog.py 4 -v
usage: prog.py [-h] [-v VERBOSITY] square
prog.py: error: argument -v/--verbosity: expected one argument
- $ python prog.py 4 -v 1
+ $ python3 prog.py 4 -v 1
4^2 == 16
- $ python prog.py 4 -v 2
+ $ python3 prog.py 4 -v 2
the square of 4 equals 16
- $ python prog.py 4 -v 3
+ $ python3 prog.py 4 -v 3
16
These all look good except the last one, which exposes a bug in our program.
@@ -421,20 +421,20 @@ Let's fix it by restricting the values the ``--verbosity`` option can accept::
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
- print "the square of {} equals {}".format(args.square, answer)
+ print("the square of {} equals {}".format(args.square, answer))
elif args.verbosity == 1:
- print "{}^2 == {}".format(args.square, answer)
+ print("{}^2 == {}".format(args.square, answer))
else:
- print answer
+ print(answer)
And the output:
.. code-block:: sh
- $ python prog.py 4 -v 3
+ $ python3 prog.py 4 -v 3
usage: prog.py [-h] [-v {0,1,2}] square
prog.py: error: argument -v/--verbosity: invalid choice: 3 (choose from 0, 1, 2)
- $ python prog.py 4 -h
+ $ python3 prog.py 4 -h
usage: prog.py [-h] [-v {0,1,2}] square
positional arguments:
@@ -461,29 +461,29 @@ verbosity argument (check the output of ``python --help``)::
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
- print "the square of {} equals {}".format(args.square, answer)
+ print("the square of {} equals {}".format(args.square, answer))
elif args.verbosity == 1:
- print "{}^2 == {}".format(args.square, answer)
+ print("{}^2 == {}".format(args.square, answer))
else:
- print answer
+ print(answer)
We have introduced another action, "count",
to count the number of occurences of a specific optional arguments:
.. code-block:: sh
- $ python prog.py 4
+ $ python3 prog.py 4
16
- $ python prog.py 4 -v
+ $ python3 prog.py 4 -v
4^2 == 16
- $ python prog.py 4 -vv
+ $ python3 prog.py 4 -vv
the square of 4 equals 16
- $ python prog.py 4 --verbosity --verbosity
+ $ python3 prog.py 4 --verbosity --verbosity
the square of 4 equals 16
- $ python prog.py 4 -v 1
+ $ python3 prog.py 4 -v 1
usage: prog.py [-h] [-v] square
prog.py: error: unrecognized arguments: 1
- $ python prog.py 4 -h
+ $ python3 prog.py 4 -h
usage: prog.py [-h] [-v] square
positional arguments:
@@ -492,7 +492,7 @@ to count the number of occurences of a specific optional arguments:
optional arguments:
-h, --help show this help message and exit
-v, --verbosity increase output verbosity
- $ python prog.py 4 -vvv
+ $ python3 prog.py 4 -vvv
16
* Yes, it's now more of a flag (similar to ``action="store_true"``) in the
@@ -529,21 +529,21 @@ Let's fix::
# bugfix: replace == with >=
if args.verbosity >= 2:
- print "the square of {} equals {}".format(args.square, answer)
+ print("the square of {} equals {}".format(args.square, answer))
elif args.verbosity >= 1:
- print "{}^2 == {}".format(args.square, answer)
+ print("{}^2 == {}".format(args.square, answer))
else:
- print answer
+ print(answer)
And this is what it gives:
.. code-block:: sh
- $ python prog.py 4 -vvv
+ $ python3 prog.py 4 -vvv
the square of 4 equals 16
- $ python prog.py 4 -vvvv
+ $ python3 prog.py 4 -vvvv
the square of 4 equals 16
- $ python prog.py 4
+ $ python3 prog.py 4
Traceback (most recent call last):
File "prog.py", line 11, in <module>
if args.verbosity >= 2:
@@ -565,11 +565,11 @@ Let's fix that bug::
args = parser.parse_args()
answer = args.square**2
if args.verbosity >= 2:
- print "the square of {} equals {}".format(args.square, answer)
+ print("the square of {} equals {}".format(args.square, answer))
elif args.verbosity >= 1:
- print "{}^2 == {}".format(args.square, answer)
+ print("{}^2 == {}".format(args.square, answer))
else:
- print answer
+ print(answer)
We've just introduced yet another keyword, ``default``.
We've set it to ``0`` in order to make it comparable to the other int values.
@@ -582,7 +582,7 @@ And:
.. code-block:: sh
- $ python prog.py 4
+ $ python3 prog.py 4
16
You can go quite far just with what we've learned so far,
@@ -605,20 +605,20 @@ not just squares::
args = parser.parse_args()
answer = args.x**args.y
if args.verbosity >= 2:
- print "{} to the power {} equals {}".format(args.x, args.y, answer)
+ print("{} to the power {} equals {}".format(args.x, args.y, answer))
elif args.verbosity >= 1:
- print "{}^{} == {}".format(args.x, args.y, answer)
+ print("{}^{} == {}".format(args.x, args.y, answer))
else:
- print answer
+ print(answer)
Output:
.. code-block:: sh
- $ python prog.py
+ $ python3 prog.py
usage: prog.py [-h] [-v] x y
prog.py: error: the following arguments are required: x, y
- $ python prog.py -h
+ $ python3 prog.py -h
usage: prog.py [-h] [-v] x y
positional arguments:
@@ -628,7 +628,7 @@ Output:
optional arguments:
-h, --help show this help message and exit
-v, --verbosity
- $ python prog.py 4 2 -v
+ $ python3 prog.py 4 2 -v
4^2 == 16
@@ -644,20 +644,20 @@ to display *more* text instead::
args = parser.parse_args()
answer = args.x**args.y
if args.verbosity >= 2:
- print "Running '{}'".format(__file__)
+ print("Running '{}'".format(__file__))
if args.verbosity >= 1:
- print "{}^{} ==".format(args.x, args.y),
- print answer
+ print("{}^{} == ".format(args.x, args.y), end="")
+ print(answer)
Output:
.. code-block:: sh
- $ python prog.py 4 2
+ $ python3 prog.py 4 2
16
- $ python prog.py 4 2 -v
+ $ python3 prog.py 4 2 -v
4^2 == 16
- $ python prog.py 4 2 -vv
+ $ python3 prog.py 4 2 -vv
Running 'prog.py'
4^2 == 16
@@ -685,27 +685,27 @@ which will be the opposite of the ``--verbose`` one::
answer = args.x**args.y
if args.quiet:
- print answer
+ print(answer)
elif args.verbose:
- print "{} to the power {} equals {}".format(args.x, args.y, answer)
+ print("{} to the power {} equals {}".format(args.x, args.y, answer))
else:
- print "{}^{} == {}".format(args.x, args.y, answer)
+ print("{}^{} == {}".format(args.x, args.y, answer))
Our program is now simpler, and we've lost some functionality for the sake of
demonstration. Anyways, here's the output:
.. code-block:: sh
- $ python prog.py 4 2
+ $ python3 prog.py 4 2
4^2 == 16
- $ python prog.py 4 2 -q
+ $ python3 prog.py 4 2 -q
16
- $ python prog.py 4 2 -v
+ $ python3 prog.py 4 2 -v
4 to the power 2 equals 16
- $ python prog.py 4 2 -vq
+ $ python3 prog.py 4 2 -vq
usage: prog.py [-h] [-v | -q] x y
prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose
- $ python prog.py 4 2 -v --quiet
+ $ python3 prog.py 4 2 -v --quiet
usage: prog.py [-h] [-v | -q] x y
prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose
@@ -728,11 +728,11 @@ your program, just in case they don't know::
answer = args.x**args.y
if args.quiet:
- print answer
+ print(answer)
elif args.verbose:
- print "{} to the power {} equals {}".format(args.x, args.y, answer)
+ print("{} to the power {} equals {}".format(args.x, args.y, answer))
else:
- print "{}^{} == {}".format(args.x, args.y, answer)
+ print("{}^{} == {}".format(args.x, args.y, answer))
Note that slight difference in the usage text. Note the ``[-v | -q]``,
which tells us that we can either use ``-v`` or ``-q``,
@@ -740,7 +740,7 @@ but not both at the same time:
.. code-block:: sh
- $ python prog.py --help
+ $ python3 prog.py --help
usage: prog.py [-h] [-v | -q] x y
calculate X to the power of Y
diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst
index 1fc10c7..1b14ceb 100644
--- a/Doc/howto/curses.rst
+++ b/Doc/howto/curses.rst
@@ -379,7 +379,7 @@ value returned to constants such as :const:`curses.KEY_PPAGE`,
:const:`curses.KEY_HOME`, or :const:`curses.KEY_LEFT`. Usually the main loop of
your program will look something like this::
- while 1:
+ while True:
c = stdscr.getch()
if c == ord('p'): PrintDocument()
elif c == ord('q'): break # Exit the while()
diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst
index ce4b6bb..1616f67 100644
--- a/Doc/howto/descriptor.rst
+++ b/Doc/howto/descriptor.rst
@@ -163,11 +163,11 @@ descriptor is useful for monitoring just a few chosen attributes::
self.name = name
def __get__(self, obj, objtype):
- print 'Retrieving', self.name
+ print('Retrieving', self.name)
return self.val
def __set__(self, obj, val):
- print 'Updating' , self.name
+ print('Updating', self.name)
self.val = val
>>> class MyClass(object):
@@ -357,12 +357,12 @@ calls are unexciting::
>>> class E(object):
def f(x):
- print x
+ print(x)
f = staticmethod(f)
- >>> print E.f(3)
+ >>> print(E.f(3))
3
- >>> print E().f(3)
+ >>> print(E().f(3))
3
Using the non-data descriptor protocol, a pure Python version of
@@ -386,9 +386,9 @@ for whether the caller is an object or a class::
return klass.__name__, x
f = classmethod(f)
- >>> print E.f(3)
+ >>> print(E.f(3))
('E', 3)
- >>> print E().f(3)
+ >>> print(E().f(3))
('E', 3)
diff --git a/Doc/howto/doanddont.rst b/Doc/howto/doanddont.rst
deleted file mode 100644
index 98dbad1..0000000
--- a/Doc/howto/doanddont.rst
+++ /dev/null
@@ -1,327 +0,0 @@
-************************************
- Idioms and Anti-Idioms in Python
-************************************
-
-:Author: Moshe Zadka
-
-This document is placed in the public domain.
-
-
-.. topic:: Abstract
-
- This document can be considered a companion to the tutorial. It shows how to use
- Python, and even more importantly, how *not* to use Python.
-
-
-Language Constructs You Should Not Use
-======================================
-
-While Python has relatively few gotchas compared to other languages, it still
-has some constructs which are only useful in corner cases, or are plain
-dangerous.
-
-
-from module import \*
----------------------
-
-
-Inside Function Definitions
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``from module import *`` is *invalid* inside function definitions. While many
-versions of Python do not check for the invalidity, it does not make it more
-valid, no more than having a smart lawyer makes a man innocent. Do not use it
-like that ever. Even in versions where it was accepted, it made the function
-execution slower, because the compiler could not be certain which names were
-local and which were global. In Python 2.1 this construct causes warnings, and
-sometimes even errors.
-
-
-At Module Level
-^^^^^^^^^^^^^^^
-
-While it is valid to use ``from module import *`` at module level it is usually
-a bad idea. For one, this loses an important property Python otherwise has ---
-you can know where each toplevel name is defined by a simple "search" function
-in your favourite editor. You also open yourself to trouble in the future, if
-some module grows additional functions or classes.
-
-One of the most awful questions asked on the newsgroup is why this code::
-
- f = open("www")
- f.read()
-
-does not work. Of course, it works just fine (assuming you have a file called
-"www".) But it does not work if somewhere in the module, the statement ``from
-os import *`` is present. The :mod:`os` module has a function called
-:func:`open` which returns an integer. While it is very useful, shadowing a
-builtin is one of its least useful properties.
-
-Remember, you can never know for sure what names a module exports, so either
-take what you need --- ``from module import name1, name2``, or keep them in the
-module and access on a per-need basis --- ``import module;print module.name``.
-
-
-When It Is Just Fine
-^^^^^^^^^^^^^^^^^^^^
-
-There are situations in which ``from module import *`` is just fine:
-
-* The interactive prompt. For example, ``from math import *`` makes Python an
- amazing scientific calculator.
-
-* When extending a module in C with a module in Python.
-
-* When the module advertises itself as ``from import *`` safe.
-
-
-Unadorned :keyword:`exec`, :func:`execfile` and friends
--------------------------------------------------------
-
-The word "unadorned" refers to the use without an explicit dictionary, in which
-case those constructs evaluate code in the *current* environment. This is
-dangerous for the same reasons ``from import *`` is dangerous --- it might step
-over variables you are counting on and mess up things for the rest of your code.
-Simply do not do that.
-
-Bad examples::
-
- >>> for name in sys.argv[1:]:
- >>> exec "%s=1" % name
- >>> def func(s, **kw):
- >>> for var, val in kw.items():
- >>> exec "s.%s=val" % var # invalid!
- >>> execfile("handler.py")
- >>> handle()
-
-Good examples::
-
- >>> d = {}
- >>> for name in sys.argv[1:]:
- >>> d[name] = 1
- >>> def func(s, **kw):
- >>> for var, val in kw.items():
- >>> setattr(s, var, val)
- >>> d={}
- >>> execfile("handle.py", d, d)
- >>> handle = d['handle']
- >>> handle()
-
-
-from module import name1, name2
--------------------------------
-
-This is a "don't" which is much weaker than the previous "don't"s but is still
-something you should not do if you don't have good reasons to do that. The
-reason it is usually a bad idea is because you suddenly have an object which lives
-in two separate namespaces. When the binding in one namespace changes, the
-binding in the other will not, so there will be a discrepancy between them. This
-happens when, for example, one module is reloaded, or changes the definition of
-a function at runtime.
-
-Bad example::
-
- # foo.py
- a = 1
-
- # bar.py
- from foo import a
- if something():
- a = 2 # danger: foo.a != a
-
-Good example::
-
- # foo.py
- a = 1
-
- # bar.py
- import foo
- if something():
- foo.a = 2
-
-
-except:
--------
-
-Python has the ``except:`` clause, which catches all exceptions. Since *every*
-error in Python raises an exception, using ``except:`` can make many
-programming errors look like runtime problems, which hinders the debugging
-process.
-
-The following code shows a great example of why this is bad::
-
- try:
- foo = opne("file") # misspelled "open"
- except:
- sys.exit("could not open file!")
-
-The second line triggers a :exc:`NameError`, which is caught by the except
-clause. The program will exit, and the error message the program prints will
-make you think the problem is the readability of ``"file"`` when in fact
-the real error has nothing to do with ``"file"``.
-
-A better way to write the above is ::
-
- try:
- foo = opne("file")
- except IOError:
- sys.exit("could not open file")
-
-When this is run, Python will produce a traceback showing the :exc:`NameError`,
-and it will be immediately apparent what needs to be fixed.
-
-.. index:: bare except, except; bare
-
-Because ``except:`` catches *all* exceptions, including :exc:`SystemExit`,
-:exc:`KeyboardInterrupt`, and :exc:`GeneratorExit` (which is not an error and
-should not normally be caught by user code), using a bare ``except:`` is almost
-never a good idea. In situations where you need to catch all "normal" errors,
-such as in a framework that runs callbacks, you can catch the base class for
-all normal exceptions, :exc:`Exception`. Unfortunately in Python 2.x it is
-possible for third-party code to raise exceptions that do not inherit from
-:exc:`Exception`, so in Python 2.x there are some cases where you may have to
-use a bare ``except:`` and manually re-raise the exceptions you don't want
-to catch.
-
-
-Exceptions
-==========
-
-Exceptions are a useful feature of Python. You should learn to raise them
-whenever something unexpected occurs, and catch them only where you can do
-something about them.
-
-The following is a very popular anti-idiom ::
-
- def get_status(file):
- if not os.path.exists(file):
- print "file not found"
- sys.exit(1)
- return open(file).readline()
-
-Consider the case where the file gets deleted between the time the call to
-:func:`os.path.exists` is made and the time :func:`open` is called. In that
-case the last line will raise an :exc:`IOError`. The same thing would happen
-if *file* exists but has no read permission. Since testing this on a normal
-machine on existent and non-existent files makes it seem bugless, the test
-results will seem fine, and the code will get shipped. Later an unhandled
-:exc:`IOError` (or perhaps some other :exc:`EnvironmentError`) escapes to the
-user, who gets to watch the ugly traceback.
-
-Here is a somewhat better way to do it. ::
-
- def get_status(file):
- try:
- return open(file).readline()
- except EnvironmentError as err:
- print "Unable to open file: {}".format(err)
- sys.exit(1)
-
-In this version, *either* the file gets opened and the line is read (so it
-works even on flaky NFS or SMB connections), or an error message is printed
-that provides all the available information on why the open failed, and the
-application is aborted.
-
-However, even this version of :func:`get_status` makes too many assumptions ---
-that it will only be used in a short running script, and not, say, in a long
-running server. Sure, the caller could do something like ::
-
- try:
- status = get_status(log)
- except SystemExit:
- status = None
-
-But there is a better way. You should try to use as few ``except`` clauses in
-your code as you can --- the ones you do use will usually be inside calls which
-should always succeed, or a catch-all in a main function.
-
-So, an even better version of :func:`get_status()` is probably ::
-
- def get_status(file):
- return open(file).readline()
-
-The caller can deal with the exception if it wants (for example, if it tries
-several files in a loop), or just let the exception filter upwards to *its*
-caller.
-
-But the last version still has a serious problem --- due to implementation
-details in CPython, the file would not be closed when an exception is raised
-until the exception handler finishes; and, worse, in other implementations
-(e.g., Jython) it might not be closed at all regardless of whether or not
-an exception is raised.
-
-The best version of this function uses the ``open()`` call as a context
-manager, which will ensure that the file gets closed as soon as the
-function returns::
-
- def get_status(file):
- with open(file) as fp:
- return fp.readline()
-
-
-Using the Batteries
-===================
-
-Every so often, people seem to be writing stuff in the Python library again,
-usually poorly. While the occasional module has a poor interface, it is usually
-much better to use the rich standard library and data types that come with
-Python than inventing your own.
-
-A useful module very few people know about is :mod:`os.path`. It always has the
-correct path arithmetic for your operating system, and will usually be much
-better than whatever you come up with yourself.
-
-Compare::
-
- # ugh!
- return dir+"/"+file
- # better
- return os.path.join(dir, file)
-
-More useful functions in :mod:`os.path`: :func:`basename`, :func:`dirname` and
-:func:`splitext`.
-
-There are also many useful built-in functions people seem not to be aware of
-for some reason: :func:`min` and :func:`max` can find the minimum/maximum of
-any sequence with comparable semantics, for example, yet many people write
-their own :func:`max`/:func:`min`. Another highly useful function is
-:func:`reduce` which can be used to repeatly apply a binary operation to a
-sequence, reducing it to a single value. For example, compute a factorial
-with a series of multiply operations::
-
- >>> n = 4
- >>> import operator
- >>> reduce(operator.mul, range(1, n+1))
- 24
-
-When it comes to parsing numbers, note that :func:`float`, :func:`int` and
-:func:`long` all accept string arguments and will reject ill-formed strings
-by raising an :exc:`ValueError`.
-
-
-Using Backslash to Continue Statements
-======================================
-
-Since Python treats a newline as a statement terminator, and since statements
-are often more than is comfortable to put in one line, many people do::
-
- if foo.bar()['first'][0] == baz.quux(1, 2)[5:9] and \
- calculate_number(10, 20) != forbulate(500, 360):
- pass
-
-You should realize that this is dangerous: a stray space after the ``\`` would
-make this line wrong, and stray spaces are notoriously hard to see in editors.
-In this case, at least it would be a syntax error, but if the code was::
-
- value = foo.bar()['first'][0]*baz.quux(1, 2)[5:9] \
- + calculate_number(10, 20)*forbulate(500, 360)
-
-then it would just be subtly wrong.
-
-It is usually much better to use the implicit continuation inside parenthesis:
-
-This version is bulletproof::
-
- value = (foo.bar()['first'][0]*baz.quux(1, 2)[5:9]
- + calculate_number(10, 20)*forbulate(500, 360))
-
diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst
index 836ec6d..ebbb229 100644
--- a/Doc/howto/functional.rst
+++ b/Doc/howto/functional.rst
@@ -44,14 +44,15 @@ Programming languages support decomposing problems in several different ways:
functional languages include the ML family (Standard ML, OCaml, and other
variants) and Haskell.
-The designers of some computer languages choose to emphasize one particular
-approach to programming. This often makes it difficult to write programs that
-use a different approach. Other languages are multi-paradigm languages that
-support several different approaches. Lisp, C++, and Python are
-multi-paradigm; you can write programs or libraries that are largely
-procedural, object-oriented, or functional in all of these languages. In a
-large program, different sections might be written using different approaches;
-the GUI might be object-oriented while the processing logic is procedural or
+The designers of some computer languages choose to emphasize one
+particular approach to programming. This often makes it difficult to
+write programs that use a different approach. Other languages are
+multi-paradigm languages that support several different approaches.
+Lisp, C++, and Python are multi-paradigm; you can write programs or
+libraries that are largely procedural, object-oriented, or functional
+in all of these languages. In a large program, different sections
+might be written using different approaches; the GUI might be
+object-oriented while the processing logic is procedural or
functional, for example.
In a functional program, input flows through a set of functions. Each function
@@ -65,9 +66,9 @@ output must only depend on its input.
Some languages are very strict about purity and don't even have assignment
statements such as ``a=3`` or ``c = a + b``, but it's difficult to avoid all
side effects. Printing to the screen or writing to a disk file are side
-effects, for example. For example, in Python a ``print`` statement or a
-``time.sleep(1)`` both return no useful value; they're only called for their
-side effects of sending some text to the screen or pausing execution for a
+effects, for example. For example, in Python a call to the :func:`print` or
+:func:`time.sleep` function both return no useful value; they're only called for
+their side effects of sending some text to the screen or pausing execution for a
second.
Python programs written in functional style usually won't go to the extreme of
@@ -180,47 +181,48 @@ foundation for writing functional-style programs: iterators.
An iterator is an object representing a stream of data; this object returns the
data one element at a time. A Python iterator must support a method called
-``next()`` that takes no arguments and always returns the next element of the
-stream. If there are no more elements in the stream, ``next()`` must raise the
-``StopIteration`` exception. Iterators don't have to be finite, though; it's
-perfectly reasonable to write an iterator that produces an infinite stream of
-data.
+:meth:`~iterator.__next__` that takes no arguments and always returns the next
+element of the stream. If there are no more elements in the stream,
+:meth:`~iterator.__next__` must raise the :exc:`StopIteration` exception.
+Iterators don't have to be finite, though; it's perfectly reasonable to write
+an iterator that produces an infinite stream of data.
The built-in :func:`iter` function takes an arbitrary object and tries to return
an iterator that will return the object's contents or elements, raising
:exc:`TypeError` if the object doesn't support iteration. Several of Python's
built-in data types support iteration, the most common being lists and
-dictionaries. An object is called an **iterable** object if you can get an
-iterator for it.
+dictionaries. An object is called :term:`iterable` if you can get an iterator
+for it.
You can experiment with the iteration interface manually:
>>> L = [1,2,3]
>>> it = iter(L)
- >>> print it
+ >>> it #doctest: +ELLIPSIS
<...iterator object at ...>
- >>> it.next()
+ >>> it.__next__() # same as next(it)
1
- >>> it.next()
+ >>> next(it)
2
- >>> it.next()
+ >>> next(it)
3
- >>> it.next()
+ >>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
StopIteration
>>>
Python expects iterable objects in several different contexts, the most
-important being the ``for`` statement. In the statement ``for X in Y``, Y must
-be an iterator or some object for which ``iter()`` can create an iterator.
-These two statements are equivalent::
+important being the :keyword:`for` statement. In the statement ``for X in Y``,
+Y must be an iterator or some object for which :func:`iter` can create an
+iterator. These two statements are equivalent::
+
for i in iter(obj):
- print i
+ print(i)
for i in obj:
- print i
+ print(i)
Iterators can be materialized as lists or tuples by using the :func:`list` or
:func:`tuple` constructor functions:
@@ -244,16 +246,16 @@ Built-in functions such as :func:`max` and :func:`min` can take a single
iterator argument and will return the largest or smallest element. The ``"in"``
and ``"not in"`` operators also support iterators: ``X in iterator`` is true if
X is found in the stream returned by the iterator. You'll run into obvious
-problems if the iterator is infinite; ``max()``, ``min()``
+problems if the iterator is infinite; :func:`max`, :func:`min`
will never return, and if the element X never appears in the stream, the
``"in"`` and ``"not in"`` operators won't return either.
Note that you can only go forward in an iterator; there's no way to get the
previous element, reset the iterator, or make a copy of it. Iterator objects
can optionally provide these additional capabilities, but the iterator protocol
-only specifies the ``next()`` method. Functions may therefore consume all of
-the iterator's output, and if you need to do something different with the same
-stream, you'll have to create a new iterator.
+only specifies the :meth:`~iterator.__next__` method. Functions may therefore
+consume all of the iterator's output, and if you need to do something different
+with the same stream, you'll have to create a new iterator.
@@ -265,16 +267,12 @@ sequence type, such as strings, will automatically support creation of an
iterator.
Calling :func:`iter` on a dictionary returns an iterator that will loop over the
-dictionary's keys:
-
-.. not a doctest since dict ordering varies across Pythons
-
-::
+dictionary's keys::
>>> m = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6,
... 'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}
- >>> for key in m:
- ... print key, m[key]
+ >>> for key in m: #doctest: +SKIP
+ ... print(key, m[key])
Mar 3
Feb 2
Aug 8
@@ -291,10 +289,10 @@ dictionary's keys:
Note that the order is essentially random, because it's based on the hash
ordering of the objects in the dictionary.
-Applying ``iter()`` to a dictionary always loops over the keys, but dictionaries
-have methods that return other iterators. If you want to iterate over keys,
-values, or key/value pairs, you can explicitly call the ``iterkeys()``,
-``itervalues()``, or ``iteritems()`` methods to get an appropriate iterator.
+Applying :func:`iter` to a dictionary always loops over the keys, but
+dictionaries have methods that return other iterators. If you want to iterate
+over values or key/value pairs, you can explicitly call the
+:meth:`~dict.values` or :meth:`~dict.items` methods to get an appropriate iterator.
The :func:`dict` constructor can accept an iterator that returns a finite stream
of ``(key, value)`` tuples:
@@ -303,9 +301,9 @@ of ``(key, value)`` tuples:
>>> dict(iter(L))
{'Italy': 'Rome', 'US': 'Washington DC', 'France': 'Paris'}
-Files also support iteration by calling the ``readline()`` method until there
-are no more lines in the file. This means you can read each line of a file like
-this::
+Files also support iteration by calling the :meth:`~io.TextIOBase.readline`
+method until there are no more lines in the file. This means you can read each
+line of a file like this::
for line in file:
# do something for each line
@@ -314,9 +312,9 @@ this::
Sets can take their contents from an iterable and let you iterate over the set's
elements::
- S = set((2, 3, 5, 7, 11, 13))
+ S = {2, 3, 5, 7, 11, 13}
for i in S:
- print i
+ print(i)
@@ -408,12 +406,9 @@ clauses, the length of the resulting output will be equal to the product of the
lengths of all the sequences. If you have two lists of length 3, the output
list is 9 elements long:
-.. doctest::
- :options: +NORMALIZE_WHITESPACE
-
>>> seq1 = 'abc'
>>> seq2 = (1,2,3)
- >>> [(x,y) for x in seq1 for y in seq2]
+ >>> [(x, y) for x in seq1 for y in seq2] #doctest: +NORMALIZE_WHITESPACE
[('a', 1), ('a', 2), ('a', 3),
('b', 1), ('b', 2), ('b', 3),
('c', 1), ('c', 2), ('c', 3)]
@@ -423,9 +418,9 @@ creating a tuple, it must be surrounded with parentheses. The first list
comprehension below is a syntax error, while the second one is correct::
# Syntax error
- [ x,y for x in seq1 for y in seq2]
+ [x, y for x in seq1 for y in seq2]
# Correct
- [ (x,y) for x in seq1 for y in seq2]
+ [(x, y) for x in seq1 for y in seq2]
Generators
@@ -446,15 +441,13 @@ is what generators provide; they can be thought of as resumable functions.
Here's the simplest example of a generator function:
-.. testcode::
-
- def generate_ints(N):
- for i in range(N):
- yield i
+ >>> def generate_ints(N):
+ ... for i in range(N):
+ ... yield i
-Any function containing a ``yield`` keyword is a generator function; this is
-detected by Python's :term:`bytecode` compiler which compiles the function
-specially as a result.
+Any function containing a :keyword:`yield` keyword is a generator function;
+this is detected by Python's :term:`bytecode` compiler which compiles the
+function specially as a result.
When you call a generator function, it doesn't return a single value; instead it
returns a generator object that supports the iterator protocol. On executing
@@ -462,20 +455,21 @@ the ``yield`` expression, the generator outputs the value of ``i``, similar to a
``return`` statement. The big difference between ``yield`` and a ``return``
statement is that on reaching a ``yield`` the generator's state of execution is
suspended and local variables are preserved. On the next call to the
-generator's ``.next()`` method, the function will resume executing.
+generator's :meth:`~generator.__next__` method, the function will resume
+executing.
Here's a sample usage of the ``generate_ints()`` generator:
>>> gen = generate_ints(3)
- >>> gen
+ >>> gen #doctest: +ELLIPSIS
<generator object generate_ints at ...>
- >>> gen.next()
+ >>> next(gen)
0
- >>> gen.next()
+ >>> next(gen)
1
- >>> gen.next()
+ >>> next(gen)
2
- >>> gen.next()
+ >>> next(gen)
Traceback (most recent call last):
File "stdin", line 1, in ?
File "stdin", line 2, in generate_ints
@@ -489,17 +483,19 @@ value, and signals the end of the procession of values; after executing a
``return`` the generator cannot return any further values. ``return`` with a
value, such as ``return 5``, is a syntax error inside a generator function. The
end of the generator's results can also be indicated by raising
-``StopIteration`` manually, or by just letting the flow of execution fall off
+:exc:`StopIteration` manually, or by just letting the flow of execution fall off
the bottom of the function.
You could achieve the effect of generators manually by writing your own class
and storing all the local variables of the generator as instance variables. For
example, returning a list of integers could be done by setting ``self.count`` to
-0, and having the ``next()`` method increment ``self.count`` and return it.
+0, and having the :meth:`~iterator.__next__` method increment ``self.count`` and
+return it.
However, for a moderately complicated generator, writing a corresponding class
can be much messier.
-The test suite included with Python's library, ``test_generators.py``, contains
+The test suite included with Python's library,
+:source:`Lib/test/test_generators.py`, contains
a number of more interesting examples. Here's one generator that implements an
in-order traversal of a tree using generators recursively. ::
@@ -542,23 +538,23 @@ when you're doing something with the returned value, as in the above example.
The parentheses aren't always necessary, but it's easier to always add them
instead of having to remember when they're needed.
-(PEP 342 explains the exact rules, which are that a ``yield``-expression must
+(:pep:`342` explains the exact rules, which are that a ``yield``-expression must
always be parenthesized except when it occurs at the top-level expression on the
right-hand side of an assignment. This means you can write ``val = yield i``
but have to use parentheses when there's an operation, as in ``val = (yield i)
+ 12``.)
-Values are sent into a generator by calling its ``send(value)`` method. This
-method resumes the generator's code and the ``yield`` expression returns the
-specified value. If the regular ``next()`` method is called, the ``yield``
-returns ``None``.
+Values are sent into a generator by calling its :meth:`send(value)
+<generator.send>` method. This method resumes the generator's code and the
+``yield`` expression returns the specified value. If the regular
+:meth:`~generator.__next__` method is called, the ``yield`` returns ``None``.
Here's a simple counter that increments by 1 and allows changing the value of
the internal counter.
.. testcode::
- def counter (maximum):
+ def counter(maximum):
i = 0
while i < maximum:
val = (yield i)
@@ -570,37 +566,40 @@ the internal counter.
And here's an example of changing the counter:
- >>> it = counter(10)
- >>> print it.next()
+ >>> it = counter(10) #doctest: +SKIP
+ >>> next(it) #doctest: +SKIP
0
- >>> print it.next()
+ >>> next(it) #doctest: +SKIP
1
- >>> print it.send(8)
+ >>> it.send(8) #doctest: +SKIP
8
- >>> print it.next()
+ >>> next(it) #doctest: +SKIP
9
- >>> print it.next()
+ >>> next(it) #doctest: +SKIP
Traceback (most recent call last):
File "t.py", line 15, in ?
- print it.next()
+ it.next()
StopIteration
Because ``yield`` will often be returning ``None``, you should always check for
this case. Don't just use its value in expressions unless you're sure that the
-``send()`` method will be the only method used resume your generator function.
+:meth:`~generator.send` method will be the only method used resume your
+generator function.
-In addition to ``send()``, there are two other new methods on generators:
+In addition to :meth:`~generator.send`, there are two other methods on
+generators:
-* ``throw(type, value=None, traceback=None)`` is used to raise an exception
- inside the generator; the exception is raised by the ``yield`` expression
- where the generator's execution is paused.
+* :meth:`throw(type, value=None, traceback=None) <generator.throw>` is used to
+ raise an exception inside the generator; the exception is raised by the
+ ``yield`` expression where the generator's execution is paused.
-* ``close()`` raises a :exc:`GeneratorExit` exception inside the generator to
- terminate the iteration. On receiving this exception, the generator's code
- must either raise :exc:`GeneratorExit` or :exc:`StopIteration`; catching the
- exception and doing anything else is illegal and will trigger a
- :exc:`RuntimeError`. ``close()`` will also be called by Python's garbage
- collector when the generator is garbage-collected.
+* :meth:`~generator.close` raises a :exc:`GeneratorExit` exception inside the
+ generator to terminate the iteration. On receiving this exception, the
+ generator's code must either raise :exc:`GeneratorExit` or
+ :exc:`StopIteration`; catching the exception and doing anything else is
+ illegal and will trigger a :exc:`RuntimeError`. :meth:`~generator.close`
+ will also be called by Python's garbage collector when the generator is
+ garbage-collected.
If you need to run cleanup code when a :exc:`GeneratorExit` occurs, I suggest
using a ``try: ... finally:`` suite instead of catching :exc:`GeneratorExit`.
@@ -619,99 +618,46 @@ Built-in functions
Let's look in more detail at built-in functions often used with iterators.
-Two of Python's built-in functions, :func:`map` and :func:`filter`, are somewhat
-obsolete; they duplicate the features of list comprehensions but return actual
-lists instead of iterators.
+Two of Python's built-in functions, :func:`map` and :func:`filter` duplicate the
+features of generator expressions:
-``map(f, iterA, iterB, ...)`` returns a list containing ``f(iterA[0], iterB[0]),
-f(iterA[1], iterB[1]), f(iterA[2], iterB[2]), ...``.
+:func:`map(f, iterA, iterB, ...) <map>` returns an iterator over the sequence
+ ``f(iterA[0], iterB[0]), f(iterA[1], iterB[1]), f(iterA[2], iterB[2]), ...``.
>>> def upper(s):
... return s.upper()
- >>> map(upper, ['sentence', 'fragment'])
+ >>> list(map(upper, ['sentence', 'fragment']))
['SENTENCE', 'FRAGMENT']
-
>>> [upper(s) for s in ['sentence', 'fragment']]
['SENTENCE', 'FRAGMENT']
-As shown above, you can achieve the same effect with a list comprehension. The
-:func:`itertools.imap` function does the same thing but can handle infinite
-iterators; it'll be discussed later, in the section on the :mod:`itertools` module.
+You can of course achieve the same effect with a list comprehension.
-``filter(predicate, iter)`` returns a list that contains all the sequence
-elements that meet a certain condition, and is similarly duplicated by list
-comprehensions. A **predicate** is a function that returns the truth value of
-some condition; for use with :func:`filter`, the predicate must take a single
-value.
+:func:`filter(predicate, iter) <filter>` returns an iterator over all the
+sequence elements that meet a certain condition, and is similarly duplicated by
+list comprehensions. A **predicate** is a function that returns the truth
+value of some condition; for use with :func:`filter`, the predicate must take a
+single value.
>>> def is_even(x):
... return (x % 2) == 0
- >>> filter(is_even, range(10))
+ >>> list(filter(is_even, range(10)))
[0, 2, 4, 6, 8]
+
This can also be written as a list comprehension:
- >>> [x for x in range(10) if is_even(x)]
+ >>> list(x for x in range(10) if is_even(x))
[0, 2, 4, 6, 8]
-:func:`filter` also has a counterpart in the :mod:`itertools` module,
-:func:`itertools.ifilter`, that returns an iterator and can therefore handle
-infinite sequences just as :func:`itertools.imap` can.
-
-``reduce(func, iter, [initial_value])`` doesn't have a counterpart in the
-:mod:`itertools` module because it cumulatively performs an operation on all the
-iterable's elements and therefore can't be applied to infinite iterables.
-``func`` must be a function that takes two elements and returns a single value.
-:func:`reduce` takes the first two elements A and B returned by the iterator and
-calculates ``func(A, B)``. It then requests the third element, C, calculates
-``func(func(A, B), C)``, combines this result with the fourth element returned,
-and continues until the iterable is exhausted. If the iterable returns no
-values at all, a :exc:`TypeError` exception is raised. If the initial value is
-supplied, it's used as a starting point and ``func(initial_value, A)`` is the
-first calculation.
-
- >>> import operator
- >>> reduce(operator.concat, ['A', 'BB', 'C'])
- 'ABBC'
- >>> reduce(operator.concat, [])
- Traceback (most recent call last):
- ...
- TypeError: reduce() of empty sequence with no initial value
- >>> reduce(operator.mul, [1,2,3], 1)
- 6
- >>> reduce(operator.mul, [], 1)
- 1
-
-If you use :func:`operator.add` with :func:`reduce`, you'll add up all the
-elements of the iterable. This case is so common that there's a special
-built-in called :func:`sum` to compute it:
-
- >>> reduce(operator.add, [1,2,3,4], 0)
- 10
- >>> sum([1,2,3,4])
- 10
- >>> sum([])
- 0
-
-For many uses of :func:`reduce`, though, it can be clearer to just write the
-obvious :keyword:`for` loop::
-
- # Instead of:
- product = reduce(operator.mul, [1,2,3], 1)
- # You can write:
- product = 1
- for i in [1,2,3]:
- product *= i
-
-
-``enumerate(iter)`` counts off the elements in the iterable, returning 2-tuples
-containing the count and each element.
+:func:`enumerate(iter) <enumerate>` counts off the elements in the iterable,
+returning 2-tuples containing the count and each element. ::
>>> for item in enumerate(['subject', 'verb', 'object']):
- ... print item
+ ... print(item)
(0, 'subject')
(1, 'verb')
(2, 'object')
@@ -722,30 +668,30 @@ indexes at which certain conditions are met::
f = open('data.txt', 'r')
for i, line in enumerate(f):
if line.strip() == '':
- print 'Blank line at line #%i' % i
+ print('Blank line at line #%i' % i)
-``sorted(iterable, [cmp=None], [key=None], [reverse=False])`` collects all the
+:func:`sorted(iterable, key=None, reverse=False) <sorted>` collects all the
elements of the iterable into a list, sorts the list, and returns the sorted
-result. The ``cmp``, ``key``, and ``reverse`` arguments are passed through to
-the constructed list's ``.sort()`` method. ::
+result. The *key*, and *reverse* arguments are passed through to the
+constructed list's :meth:`~list.sort` method. ::
>>> import random
>>> # Generate 8 random numbers between [0, 10000)
>>> rand_list = random.sample(range(10000), 8)
- >>> rand_list
+ >>> rand_list #doctest: +SKIP
[769, 7953, 9828, 6431, 8442, 9878, 6213, 2207]
- >>> sorted(rand_list)
+ >>> sorted(rand_list) #doctest: +SKIP
[769, 2207, 6213, 6431, 7953, 8442, 9828, 9878]
- >>> sorted(rand_list, reverse=True)
+ >>> sorted(rand_list, reverse=True) #doctest: +SKIP
[9878, 9828, 8442, 7953, 6431, 6213, 2207, 769]
-(For a more detailed discussion of sorting, see the Sorting mini-HOWTO in the
-Python wiki at http://wiki.python.org/moin/HowTo/Sorting.)
+(For a more detailed discussion of sorting, see the :ref:`sortinghowto`.)
+
-The ``any(iter)`` and ``all(iter)`` built-ins look at the truth values of an
-iterable's contents. :func:`any` returns True if any element in the iterable is
-a true value, and :func:`all` returns True if all of the elements are true
-values:
+The :func:`any(iter) <any>` and :func:`all(iter) <all>` built-ins look at the
+truth values of an iterable's contents. :func:`any` returns True if any element
+in the iterable is a true value, and :func:`all` returns True if all of the
+elements are true values:
>>> any([0,1,0])
True
@@ -761,88 +707,27 @@ values:
True
-Small functions and the lambda expression
-=========================================
-
-When writing functional-style programs, you'll often need little functions that
-act as predicates or that combine elements in some way.
-
-If there's a Python built-in or a module function that's suitable, you don't
-need to define a new function at all::
-
- stripped_lines = [line.strip() for line in lines]
- existing_files = filter(os.path.exists, file_list)
-
-If the function you need doesn't exist, you need to write it. One way to write
-small functions is to use the ``lambda`` statement. ``lambda`` takes a number
-of parameters and an expression combining these parameters, and creates a small
-function that returns the value of the expression::
-
- lowercase = lambda x: x.lower()
-
- print_assign = lambda name, value: name + '=' + str(value)
-
- adder = lambda x, y: x+y
-
-An alternative is to just use the ``def`` statement and define a function in the
-usual way::
-
- def lowercase(x):
- return x.lower()
-
- def print_assign(name, value):
- return name + '=' + str(value)
-
- def adder(x,y):
- return x + y
-
-Which alternative is preferable? That's a style question; my usual course is to
-avoid using ``lambda``.
-
-One reason for my preference is that ``lambda`` is quite limited in the
-functions it can define. The result has to be computable as a single
-expression, which means you can't have multiway ``if... elif... else``
-comparisons or ``try... except`` statements. If you try to do too much in a
-``lambda`` statement, you'll end up with an overly complicated expression that's
-hard to read. Quick, what's the following code doing?
-
-::
-
- total = reduce(lambda a, b: (0, a[1] + b[1]), items)[1]
-
-You can figure it out, but it takes time to disentangle the expression to figure
-out what's going on. Using a short nested ``def`` statements makes things a
-little bit better::
-
- def combine (a, b):
- return 0, a[1] + b[1]
-
- total = reduce(combine, items)[1]
-
-But it would be best of all if I had simply used a ``for`` loop::
-
- total = 0
- for a, b in items:
- total += b
-
-Or the :func:`sum` built-in and a generator expression::
+:func:`zip(iterA, iterB, ...) <zip>` takes one element from each iterable and
+returns them in a tuple::
- total = sum(b for a,b in items)
+ zip(['a', 'b', 'c'], (1, 2, 3)) =>
+ ('a', 1), ('b', 2), ('c', 3)
-Many uses of :func:`reduce` are clearer when written as ``for`` loops.
+It doesn't construct an in-memory list and exhaust all the input iterators
+before returning; instead tuples are constructed and returned only if they're
+requested. (The technical term for this behaviour is `lazy evaluation
+<http://en.wikipedia.org/wiki/Lazy_evaluation>`__.)
-Fredrik Lundh once suggested the following set of rules for refactoring uses of
-``lambda``:
+This iterator is intended to be used with iterables that are all of the same
+length. If the iterables are of different lengths, the resulting stream will be
+the same length as the shortest iterable. ::
-1) Write a lambda function.
-2) Write a comment explaining what the heck that lambda does.
-3) Study the comment for a while, and think of a name that captures the essence
- of the comment.
-4) Convert the lambda to a def statement, using that name.
-5) Remove the comment.
+ zip(['a', 'b'], (1, 2, 3)) =>
+ ('a', 1), ('b', 2)
-I really like these rules, but you're free to disagree
-about whether this lambda-free style is better.
+You should avoid doing this, though, because an element may be taken from the
+longer iterators and discarded. This means you can't go on to use the iterators
+further because you risk skipping a discarded element.
The itertools module
@@ -862,65 +747,44 @@ The module's functions fall into a few broad classes:
Creating new iterators
----------------------
-``itertools.count(n)`` returns an infinite stream of integers, increasing by 1
-each time. You can optionally supply the starting number, which defaults to 0::
+:func:`itertools.count(n) <itertools.count>` returns an infinite stream of
+integers, increasing by 1 each time. You can optionally supply the starting
+number, which defaults to 0::
itertools.count() =>
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...
itertools.count(10) =>
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, ...
-``itertools.cycle(iter)`` saves a copy of the contents of a provided iterable
-and returns a new iterator that returns its elements from first to last. The
-new iterator will repeat these elements infinitely. ::
+:func:`itertools.cycle(iter) <itertools.cycle>` saves a copy of the contents of
+a provided iterable and returns a new iterator that returns its elements from
+first to last. The new iterator will repeat these elements infinitely. ::
itertools.cycle([1,2,3,4,5]) =>
1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ...
-``itertools.repeat(elem, [n])`` returns the provided element ``n`` times, or
-returns the element endlessly if ``n`` is not provided. ::
+:func:`itertools.repeat(elem, [n]) <itertools.repeat>` returns the provided
+element *n* times, or returns the element endlessly if *n* is not provided. ::
itertools.repeat('abc') =>
abc, abc, abc, abc, abc, abc, abc, abc, abc, abc, ...
itertools.repeat('abc', 5) =>
abc, abc, abc, abc, abc
-``itertools.chain(iterA, iterB, ...)`` takes an arbitrary number of iterables as
-input, and returns all the elements of the first iterator, then all the elements
-of the second, and so on, until all of the iterables have been exhausted. ::
+:func:`itertools.chain(iterA, iterB, ...) <itertools.chain>` takes an arbitrary
+number of iterables as input, and returns all the elements of the first
+iterator, then all the elements of the second, and so on, until all of the
+iterables have been exhausted. ::
itertools.chain(['a', 'b', 'c'], (1, 2, 3)) =>
a, b, c, 1, 2, 3
-``itertools.izip(iterA, iterB, ...)`` takes one element from each iterable and
-returns them in a tuple::
-
- itertools.izip(['a', 'b', 'c'], (1, 2, 3)) =>
- ('a', 1), ('b', 2), ('c', 3)
-
-It's similar to the built-in :func:`zip` function, but doesn't construct an
-in-memory list and exhaust all the input iterators before returning; instead
-tuples are constructed and returned only if they're requested. (The technical
-term for this behaviour is `lazy evaluation
-<http://en.wikipedia.org/wiki/Lazy_evaluation>`__.)
-
-This iterator is intended to be used with iterables that are all of the same
-length. If the iterables are of different lengths, the resulting stream will be
-the same length as the shortest iterable. ::
-
- itertools.izip(['a', 'b'], (1, 2, 3)) =>
- ('a', 1), ('b', 2)
-
-You should avoid doing this, though, because an element may be taken from the
-longer iterators and discarded. This means you can't go on to use the iterators
-further because you risk skipping a discarded element.
-
-``itertools.islice(iter, [start], stop, [step])`` returns a stream that's a
-slice of the iterator. With a single ``stop`` argument, it will return the
-first ``stop`` elements. If you supply a starting index, you'll get
-``stop-start`` elements, and if you supply a value for ``step``, elements will
-be skipped accordingly. Unlike Python's string and list slicing, you can't use
-negative values for ``start``, ``stop``, or ``step``. ::
+:func:`itertools.islice(iter, [start], stop, [step]) <itertools.islice>` returns
+a stream that's a slice of the iterator. With a single *stop* argument, it
+will return the first *stop* elements. If you supply a starting index, you'll
+get *stop-start* elements, and if you supply a value for *step*, elements
+will be skipped accordingly. Unlike Python's string and list slicing, you can't
+use negative values for *start*, *stop*, or *step*. ::
itertools.islice(range(10), 8) =>
0, 1, 2, 3, 4, 5, 6, 7
@@ -929,9 +793,10 @@ negative values for ``start``, ``stop``, or ``step``. ::
itertools.islice(range(10), 2, 8, 2) =>
2, 4, 6
-``itertools.tee(iter, [n])`` replicates an iterator; it returns ``n``
-independent iterators that will all return the contents of the source iterator.
-If you don't supply a value for ``n``, the default is 2. Replicating iterators
+:func:`itertools.tee(iter, [n]) <itertools.tee>` replicates an iterator; it
+returns *n* independent iterators that will all return the contents of the
+source iterator.
+If you don't supply a value for *n*, the default is 2. Replicating iterators
requires saving some of the contents of the source iterator, so this can consume
significant memory if the iterator is large and one of the new iterators is
consumed more than the others. ::
@@ -949,28 +814,21 @@ consumed more than the others. ::
Calling functions on elements
-----------------------------
-Two functions are used for calling other functions on the contents of an
-iterable.
-
-``itertools.imap(f, iterA, iterB, ...)`` returns a stream containing
-``f(iterA[0], iterB[0]), f(iterA[1], iterB[1]), f(iterA[2], iterB[2]), ...``::
+The :mod:`operator` module contains a set of functions corresponding to Python's
+operators. Some examples are :func:`operator.add(a, b) <operator.add>` (adds
+two values), :func:`operator.ne(a, b) <operator.ne>` (same as ``a != b``), and
+:func:`operator.attrgetter('id') <operator.attrgetter>`
+(returns a callable that fetches the ``.id`` attribute).
- itertools.imap(operator.add, [5, 6, 5], [1, 2, 3]) =>
- 6, 8, 8
-
-The ``operator`` module contains a set of functions corresponding to Python's
-operators. Some examples are ``operator.add(a, b)`` (adds two values),
-``operator.ne(a, b)`` (same as ``a!=b``), and ``operator.attrgetter('id')``
-(returns a callable that fetches the ``"id"`` attribute).
-
-``itertools.starmap(func, iter)`` assumes that the iterable will return a stream
-of tuples, and calls ``f()`` using these tuples as the arguments::
+:func:`itertools.starmap(func, iter) <itertools.starmap>` assumes that the
+iterable will return a stream of tuples, and calls *func* using these tuples as
+the arguments::
itertools.starmap(os.path.join,
- [('/usr', 'bin', 'java'), ('/bin', 'python'),
- ('/usr', 'bin', 'perl'),('/usr', 'bin', 'ruby')])
+ [('/bin', 'python'), ('/usr', 'bin', 'java'),
+ ('/usr', 'bin', 'perl'), ('/usr', 'bin', 'ruby')])
=>
- /usr/bin/java, /bin/python, /usr/bin/perl, /usr/bin/ruby
+ /bin/python, /usr/bin/java, /usr/bin/perl, /usr/bin/ruby
Selecting elements
@@ -979,29 +837,18 @@ Selecting elements
Another group of functions chooses a subset of an iterator's elements based on a
predicate.
-``itertools.ifilter(predicate, iter)`` returns all the elements for which the
-predicate returns true::
-
- def is_even(x):
- return (x % 2) == 0
+:func:`itertools.filterfalse(predicate, iter) <itertools.filterfalse>` is the
+opposite, returning all elements for which the predicate returns false::
- itertools.ifilter(is_even, itertools.count()) =>
- 0, 2, 4, 6, 8, 10, 12, 14, ...
-
-``itertools.ifilterfalse(predicate, iter)`` is the opposite, returning all
-elements for which the predicate returns false::
-
- itertools.ifilterfalse(is_even, itertools.count()) =>
+ itertools.filterfalse(is_even, itertools.count()) =>
1, 3, 5, 7, 9, 11, 13, 15, ...
-``itertools.takewhile(predicate, iter)`` returns elements for as long as the
-predicate returns true. Once the predicate returns false, the iterator will
-signal the end of its results.
-
-::
+:func:`itertools.takewhile(predicate, iter) <itertools.takewhile>` returns
+elements for as long as the predicate returns true. Once the predicate returns
+false, the iterator will signal the end of its results. ::
def less_than_10(x):
- return (x < 10)
+ return x < 10
itertools.takewhile(less_than_10, itertools.count()) =>
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
@@ -1009,10 +856,9 @@ signal the end of its results.
itertools.takewhile(is_even, itertools.count()) =>
0
-``itertools.dropwhile(predicate, iter)`` discards elements while the predicate
-returns true, and then returns the rest of the iterable's results.
-
-::
+:func:`itertools.dropwhile(predicate, iter) <itertools.dropwhile>` discards
+elements while the predicate returns true, and then returns the rest of the
+iterable's results. ::
itertools.dropwhile(less_than_10, itertools.count()) =>
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, ...
@@ -1024,14 +870,14 @@ returns true, and then returns the rest of the iterable's results.
Grouping elements
-----------------
-The last function I'll discuss, ``itertools.groupby(iter, key_func=None)``, is
-the most complicated. ``key_func(elem)`` is a function that can compute a key
-value for each element returned by the iterable. If you don't supply a key
-function, the key is simply each element itself.
+The last function I'll discuss, :func:`itertools.groupby(iter, key_func=None)
+<itertools.groupby>`, is the most complicated. ``key_func(elem)`` is a function
+that can compute a key value for each element returned by the iterable. If you
+don't supply a key function, the key is simply each element itself.
-``groupby()`` collects all the consecutive elements from the underlying iterable
-that have the same key value, and returns a stream of 2-tuples containing a key
-value and an iterator for the elements with that key.
+:func:`~itertools.groupby` collects all the consecutive elements from the
+underlying iterable that have the same key value, and returns a stream of
+2-tuples containing a key value and an iterator for the elements with that key.
::
@@ -1041,8 +887,8 @@ value and an iterator for the elements with that key.
...
]
- def get_state ((city, state)):
- return state
+ def get_state(city_state):
+ return city_state[1]
itertools.groupby(city_list, get_state) =>
('AL', iterator-1),
@@ -1057,9 +903,9 @@ value and an iterator for the elements with that key.
iterator-3 =>
('Flagstaff', 'AZ'), ('Phoenix', 'AZ'), ('Tucson', 'AZ')
-``groupby()`` assumes that the underlying iterable's contents will already be
-sorted based on the key. Note that the returned iterators also use the
-underlying iterable, so you have to consume the results of iterator-1 before
+:func:`~itertools.groupby` assumes that the underlying iterable's contents will
+already be sorted based on the key. Note that the returned iterators also use
+the underlying iterable, so you have to consume the results of iterator-1 before
requesting iterator-2 and its corresponding key.
@@ -1077,22 +923,71 @@ Consider a Python function ``f(a, b, c)``; you may wish to create a new function
``g(b, c)`` that's equivalent to ``f(1, b, c)``; you're filling in a value for
one of ``f()``'s parameters. This is called "partial function application".
-The constructor for ``partial`` takes the arguments ``(function, arg1, arg2,
-... kwarg1=value1, kwarg2=value2)``. The resulting object is callable, so you
-can just call it to invoke ``function`` with the filled-in arguments.
+The constructor for :func:`~functools.partial` takes the arguments
+``(function, arg1, arg2, ..., kwarg1=value1, kwarg2=value2)``. The resulting
+object is callable, so you can just call it to invoke ``function`` with the
+filled-in arguments.
Here's a small but realistic example::
import functools
- def log (message, subsystem):
- "Write the contents of 'message' to the specified subsystem."
- print '%s: %s' % (subsystem, message)
+ def log(message, subsystem):
+ """Write the contents of 'message' to the specified subsystem."""
+ print('%s: %s' % (subsystem, message))
...
server_log = functools.partial(log, subsystem='server')
server_log('Unable to open socket')
+:func:`functools.reduce(func, iter, [initial_value]) <functools.reduce>`
+cumulatively performs an operation on all the iterable's elements and,
+therefore, can't be applied to infinite iterables. *func* must be a function
+that takes two elements and returns a single value. :func:`functools.reduce`
+takes the first two elements A and B returned by the iterator and calculates
+``func(A, B)``. It then requests the third element, C, calculates
+``func(func(A, B), C)``, combines this result with the fourth element returned,
+and continues until the iterable is exhausted. If the iterable returns no
+values at all, a :exc:`TypeError` exception is raised. If the initial value is
+supplied, it's used as a starting point and ``func(initial_value, A)`` is the
+first calculation. ::
+
+ >>> import operator, functools
+ >>> functools.reduce(operator.concat, ['A', 'BB', 'C'])
+ 'ABBC'
+ >>> functools.reduce(operator.concat, [])
+ Traceback (most recent call last):
+ ...
+ TypeError: reduce() of empty sequence with no initial value
+ >>> functools.reduce(operator.mul, [1,2,3], 1)
+ 6
+ >>> functools.reduce(operator.mul, [], 1)
+ 1
+
+If you use :func:`operator.add` with :func:`functools.reduce`, you'll add up all the
+elements of the iterable. This case is so common that there's a special
+built-in called :func:`sum` to compute it:
+
+ >>> import functools
+ >>> functools.reduce(operator.add, [1,2,3,4], 0)
+ 10
+ >>> sum([1,2,3,4])
+ 10
+ >>> sum([])
+ 0
+
+For many uses of :func:`functools.reduce`, though, it can be clearer to just
+write the obvious :keyword:`for` loop::
+
+ import functools
+ # Instead of:
+ product = functools.reduce(operator.mul, [1,2,3], 1)
+
+ # You can write:
+ product = 1
+ for i in [1,2,3]:
+ product *= i
+
The operator module
-------------------
@@ -1104,8 +999,7 @@ that perform a single operation.
Some of the functions in this module are:
-* Math operations: ``add()``, ``sub()``, ``mul()``, ``div()``, ``floordiv()``,
- ``abs()``, ...
+* Math operations: ``add()``, ``sub()``, ``mul()``, ``floordiv()``, ``abs()``, ...
* Logical operations: ``not_()``, ``truth()``.
* Bitwise operations: ``and_()``, ``or_()``, ``invert()``.
* Comparisons: ``eq()``, ``ne()``, ``lt()``, ``le()``, ``gt()``, and ``ge()``.
@@ -1114,6 +1008,85 @@ Some of the functions in this module are:
Consult the operator module's documentation for a complete list.
+Small functions and the lambda expression
+=========================================
+
+When writing functional-style programs, you'll often need little functions that
+act as predicates or that combine elements in some way.
+
+If there's a Python built-in or a module function that's suitable, you don't
+need to define a new function at all::
+
+ stripped_lines = [line.strip() for line in lines]
+ existing_files = filter(os.path.exists, file_list)
+
+If the function you need doesn't exist, you need to write it. One way to write
+small functions is to use the :keyword:`lambda` statement. ``lambda`` takes a
+number of parameters and an expression combining these parameters, and creates
+an anonymous function that returns the value of the expression::
+
+ adder = lambda x, y: x+y
+
+ print_assign = lambda name, value: name + '=' + str(value)
+
+An alternative is to just use the ``def`` statement and define a function in the
+usual way::
+
+ def adder(x, y):
+ return x + y
+
+ def print_assign(name, value):
+ return name + '=' + str(value)
+
+Which alternative is preferable? That's a style question; my usual course is to
+avoid using ``lambda``.
+
+One reason for my preference is that ``lambda`` is quite limited in the
+functions it can define. The result has to be computable as a single
+expression, which means you can't have multiway ``if... elif... else``
+comparisons or ``try... except`` statements. If you try to do too much in a
+``lambda`` statement, you'll end up with an overly complicated expression that's
+hard to read. Quick, what's the following code doing? ::
+
+ import functools
+ total = functools.reduce(lambda a, b: (0, a[1] + b[1]), items)[1]
+
+You can figure it out, but it takes time to disentangle the expression to figure
+out what's going on. Using a short nested ``def`` statements makes things a
+little bit better::
+
+ import functools
+ def combine(a, b):
+ return 0, a[1] + b[1]
+
+ total = functools.reduce(combine, items)[1]
+
+But it would be best of all if I had simply used a ``for`` loop::
+
+ total = 0
+ for a, b in items:
+ total += b
+
+Or the :func:`sum` built-in and a generator expression::
+
+ total = sum(b for a,b in items)
+
+Many uses of :func:`functools.reduce` are clearer when written as ``for`` loops.
+
+Fredrik Lundh once suggested the following set of rules for refactoring uses of
+``lambda``:
+
+1. Write a lambda function.
+2. Write a comment explaining what the heck that lambda does.
+3. Study the comment for a while, and think of a name that captures the essence
+ of the comment.
+4. Convert the lambda to a def statement, using that name.
+5. Remove the comment.
+
+I really like these rules, but you're free to disagree
+about whether this lambda-free style is better.
+
+
Revision History and Acknowledgements
=====================================
@@ -1169,7 +1142,6 @@ Text Processing".
Mertz also wrote a 3-part series of articles on functional programming
for IBM's DeveloperWorks site; see
-
`part 1 <http://www.ibm.com/developerworks/linux/library/l-prog/index.html>`__,
`part 2 <http://www.ibm.com/developerworks/linux/library/l-prog2/index.html>`__, and
`part 3 <http://www.ibm.com/developerworks/linux/library/l-prog3/index.html>`__,
@@ -1231,7 +1203,6 @@ features in Python 2.5.
Built-in functions
map
filter
- reduce
.. comment
@@ -1244,6 +1215,6 @@ features in Python 2.5.
for elem in slice[:-1]:
sys.stdout.write(str(elem))
sys.stdout.write(', ')
- print elem[-1]
+ print(elem[-1])
diff --git a/Doc/howto/index.rst b/Doc/howto/index.rst
index 6706f89..a11d3da 100644
--- a/Doc/howto/index.rst
+++ b/Doc/howto/index.rst
@@ -18,7 +18,6 @@ Currently, the HOWTOs are:
cporting.rst
curses.rst
descriptor.rst
- doanddont.rst
functional.rst
logging.rst
logging-cookbook.rst
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
index 0937812..370c757 100644
--- a/Doc/howto/logging-cookbook.rst
+++ b/Doc/howto/logging-cookbook.rst
@@ -262,6 +262,70 @@ configuration::
print('complete')
+Dealing with handlers that block
+--------------------------------
+
+.. currentmodule:: logging.handlers
+
+Sometimes you have to get your logging handlers to do their work without
+blocking the thread you're logging from. This is common in Web applications,
+though of course it also occurs in other scenarios.
+
+A common culprit which demonstrates sluggish behaviour is the
+:class:`SMTPHandler`: sending emails can take a long time, for a
+number of reasons outside the developer's control (for example, a poorly
+performing mail or network infrastructure). But almost any network-based
+handler can block: Even a :class:`SocketHandler` operation may do a
+DNS query under the hood which is too slow (and this query can be deep in the
+socket library code, below the Python layer, and outside your control).
+
+One solution is to use a two-part approach. For the first part, attach only a
+:class:`QueueHandler` to those loggers which are accessed from
+performance-critical threads. They simply write to their queue, which can be
+sized to a large enough capacity or initialized with no upper bound to their
+size. The write to the queue will typically be accepted quickly, though you
+will probably need to catch the :exc:`queue.Full` exception as a precaution
+in your code. If you are a library developer who has performance-critical
+threads in their code, be sure to document this (together with a suggestion to
+attach only ``QueueHandlers`` to your loggers) for the benefit of other
+developers who will use your code.
+
+The second part of the solution is :class:`QueueListener`, which has been
+designed as the counterpart to :class:`QueueHandler`. A
+:class:`QueueListener` is very simple: it's passed a queue and some handlers,
+and it fires up an internal thread which listens to its queue for LogRecords
+sent from ``QueueHandlers`` (or any other source of ``LogRecords``, for that
+matter). The ``LogRecords`` are removed from the queue and passed to the
+handlers for processing.
+
+The advantage of having a separate :class:`QueueListener` class is that you
+can use the same instance to service multiple ``QueueHandlers``. This is more
+resource-friendly than, say, having threaded versions of the existing handler
+classes, which would eat up one thread per handler for no particular benefit.
+
+An example of using these two classes follows (imports omitted)::
+
+ que = queue.Queue(-1) # no limit on size
+ queue_handler = QueueHandler(que)
+ handler = logging.StreamHandler()
+ listener = QueueListener(que, handler)
+ root = logging.getLogger()
+ root.addHandler(queue_handler)
+ formatter = logging.Formatter('%(threadName)s: %(message)s')
+ handler.setFormatter(formatter)
+ listener.start()
+ # The log output will display the thread which generated
+ # the event (the main thread) rather than the internal
+ # thread which monitors the internal queue. This is what
+ # you want to happen.
+ root.warning('Look out!')
+ listener.stop()
+
+which, when run, will produce::
+
+ MainThread: Look out!
+
+
.. _network-logging:
Sending and receiving logging events across a network
@@ -295,17 +359,17 @@ the receiving end. A simple way of doing this is attaching a
logger2.warning('Jail zesty vixen who grabbed pay from quack.')
logger2.error('The five boxing wizards jump quickly.')
-At the receiving end, you can set up a receiver using the :mod:`SocketServer`
+At the receiving end, you can set up a receiver using the :mod:`socketserver`
module. Here is a basic working example::
import pickle
import logging
import logging.handlers
- import SocketServer
+ import socketserver
import struct
- class LogRecordStreamHandler(SocketServer.StreamRequestHandler):
+ class LogRecordStreamHandler(socketserver.StreamRequestHandler):
"""Handler for a streaming logging request.
This basically logs the record using whatever logging policy is
@@ -347,7 +411,7 @@ module. Here is a basic working example::
# cycles and network bandwidth!
logger.handle(record)
- class LogRecordSocketReceiver(SocketServer.ThreadingTCPServer):
+ class LogRecordSocketReceiver(socketserver.ThreadingTCPServer):
"""
Simple TCP socket-based logging receiver suitable for testing.
"""
@@ -357,7 +421,7 @@ module. Here is a basic working example::
def __init__(self, host='localhost',
port=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
handler=LogRecordStreamHandler):
- SocketServer.ThreadingTCPServer.__init__(self, (host, port), handler)
+ socketserver.ThreadingTCPServer.__init__(self, (host, port), handler)
self.abort = 0
self.timeout = 1
self.logname = None
@@ -626,6 +690,223 @@ http://bugs.python.org/issue3770).
.. currentmodule:: logging.handlers
+Alternatively, you can use a ``Queue`` and a :class:`QueueHandler` to send
+all logging events to one of the processes in your multi-process application.
+The following example script demonstrates how you can do this; in the example
+a separate listener process listens for events sent by other processes and logs
+them according to its own logging configuration. Although the example only
+demonstrates one way of doing it (for example, you may want to use a listener
+thread rather than a separate listener process -- the implementation would be
+analogous) it does allow for completely different logging configurations for
+the listener and the other processes in your application, and can be used as
+the basis for code meeting your own specific requirements::
+
+ # You'll need these imports in your own code
+ import logging
+ import logging.handlers
+ import multiprocessing
+
+ # Next two import lines for this demo only
+ from random import choice, random
+ import time
+
+ #
+ # Because you'll want to define the logging configurations for listener and workers, the
+ # listener and worker process functions take a configurer parameter which is a callable
+ # for configuring logging for that process. These functions are also passed the queue,
+ # which they use for communication.
+ #
+ # In practice, you can configure the listener however you want, but note that in this
+ # simple example, the listener does not apply level or filter logic to received records.
+ # In practice, you would probably want to do this logic in the worker processes, to avoid
+ # sending events which would be filtered out between processes.
+ #
+ # The size of the rotated files is made small so you can see the results easily.
+ def listener_configurer():
+ root = logging.getLogger()
+ h = logging.handlers.RotatingFileHandler('mptest.log', 'a', 300, 10)
+ f = logging.Formatter('%(asctime)s %(processName)-10s %(name)s %(levelname)-8s %(message)s')
+ h.setFormatter(f)
+ root.addHandler(h)
+
+ # This is the listener process top-level loop: wait for logging events
+ # (LogRecords)on the queue and handle them, quit when you get a None for a
+ # LogRecord.
+ def listener_process(queue, configurer):
+ configurer()
+ while True:
+ try:
+ record = queue.get()
+ if record is None: # We send this as a sentinel to tell the listener to quit.
+ break
+ logger = logging.getLogger(record.name)
+ logger.handle(record) # No level or filter logic applied - just do it!
+ except (KeyboardInterrupt, SystemExit):
+ raise
+ except:
+ import sys, traceback
+ print('Whoops! Problem:', file=sys.stderr)
+ traceback.print_exc(file=sys.stderr)
+
+ # Arrays used for random selections in this demo
+
+ LEVELS = [logging.DEBUG, logging.INFO, logging.WARNING,
+ logging.ERROR, logging.CRITICAL]
+
+ LOGGERS = ['a.b.c', 'd.e.f']
+
+ MESSAGES = [
+ 'Random message #1',
+ 'Random message #2',
+ 'Random message #3',
+ ]
+
+ # The worker configuration is done at the start of the worker process run.
+ # Note that on Windows you can't rely on fork semantics, so each process
+ # will run the logging configuration code when it starts.
+ def worker_configurer(queue):
+ h = logging.handlers.QueueHandler(queue) # Just the one handler needed
+ root = logging.getLogger()
+ root.addHandler(h)
+ root.setLevel(logging.DEBUG) # send all messages, for demo; no other level or filter logic applied.
+
+ # This is the worker process top-level loop, which just logs ten events with
+ # random intervening delays before terminating.
+ # The print messages are just so you know it's doing something!
+ def worker_process(queue, configurer):
+ configurer(queue)
+ name = multiprocessing.current_process().name
+ print('Worker started: %s' % name)
+ for i in range(10):
+ time.sleep(random())
+ logger = logging.getLogger(choice(LOGGERS))
+ level = choice(LEVELS)
+ message = choice(MESSAGES)
+ logger.log(level, message)
+ print('Worker finished: %s' % name)
+
+ # Here's where the demo gets orchestrated. Create the queue, create and start
+ # the listener, create ten workers and start them, wait for them to finish,
+ # then send a None to the queue to tell the listener to finish.
+ def main():
+ queue = multiprocessing.Queue(-1)
+ listener = multiprocessing.Process(target=listener_process,
+ args=(queue, listener_configurer))
+ listener.start()
+ workers = []
+ for i in range(10):
+ worker = multiprocessing.Process(target=worker_process,
+ args=(queue, worker_configurer))
+ workers.append(worker)
+ worker.start()
+ for w in workers:
+ w.join()
+ queue.put_nowait(None)
+ listener.join()
+
+ if __name__ == '__main__':
+ main()
+
+A variant of the above script keeps the logging in the main process, in a
+separate thread::
+
+ import logging
+ import logging.config
+ import logging.handlers
+ from multiprocessing import Process, Queue
+ import random
+ import threading
+ import time
+
+ def logger_thread(q):
+ while True:
+ record = q.get()
+ if record is None:
+ break
+ logger = logging.getLogger(record.name)
+ logger.handle(record)
+
+
+ def worker_process(q):
+ qh = logging.handlers.QueueHandler(q)
+ root = logging.getLogger()
+ root.setLevel(logging.DEBUG)
+ root.addHandler(qh)
+ levels = [logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR,
+ logging.CRITICAL]
+ loggers = ['foo', 'foo.bar', 'foo.bar.baz',
+ 'spam', 'spam.ham', 'spam.ham.eggs']
+ for i in range(100):
+ lvl = random.choice(levels)
+ logger = logging.getLogger(random.choice(loggers))
+ logger.log(lvl, 'Message no. %d', i)
+
+ if __name__ == '__main__':
+ q = Queue()
+ d = {
+ 'version': 1,
+ 'formatters': {
+ 'detailed': {
+ 'class': 'logging.Formatter',
+ 'format': '%(asctime)s %(name)-15s %(levelname)-8s %(processName)-10s %(message)s'
+ }
+ },
+ 'handlers': {
+ 'console': {
+ 'class': 'logging.StreamHandler',
+ 'level': 'INFO',
+ },
+ 'file': {
+ 'class': 'logging.FileHandler',
+ 'filename': 'mplog.log',
+ 'mode': 'w',
+ 'formatter': 'detailed',
+ },
+ 'foofile': {
+ 'class': 'logging.FileHandler',
+ 'filename': 'mplog-foo.log',
+ 'mode': 'w',
+ 'formatter': 'detailed',
+ },
+ 'errors': {
+ 'class': 'logging.FileHandler',
+ 'filename': 'mplog-errors.log',
+ 'mode': 'w',
+ 'level': 'ERROR',
+ 'formatter': 'detailed',
+ },
+ },
+ 'loggers': {
+ 'foo': {
+ 'handlers' : ['foofile']
+ }
+ },
+ 'root': {
+ 'level': 'DEBUG',
+ 'handlers': ['console', 'file', 'errors']
+ },
+ }
+ workers = []
+ for i in range(5):
+ wp = Process(target=worker_process, name='worker %d' % (i + 1), args=(q,))
+ workers.append(wp)
+ wp.start()
+ logging.config.dictConfig(d)
+ lp = threading.Thread(target=logger_thread, args=(q,))
+ lp.start()
+ # At this point, the main process could do some useful work of its own
+ # Once it's done that, it can wait for the workers to terminate...
+ for wp in workers:
+ wp.join()
+ # And now tell the logging thread to finish up, too
+ q.put(None)
+ lp.join()
+
+This variant shows how you can e.g. apply configuration for particular loggers
+- e.g. the ``foo`` logger has a special handler which stores all events in the
+``foo`` subsystem in a file ``mplog-foo.log``. This will be used by the logging
+machinery in the main process (even though the logging events are generated in
+the worker processes) to direct the messages to the appropriate destinations.
Using file rotation
-------------------
@@ -683,6 +964,295 @@ and each time it reaches the size limit it is renamed with the suffix
Obviously this example sets the log length much too small as an extreme
example. You would want to set *maxBytes* to an appropriate value.
+.. _format-styles:
+
+Use of alternative formatting styles
+------------------------------------
+
+When logging was added to the Python standard library, the only way of
+formatting messages with variable content was to use the %-formatting
+method. Since then, Python has gained two new formatting approaches:
+:class:`string.Template` (added in Python 2.4) and :meth:`str.format`
+(added in Python 2.6).
+
+Logging (as of 3.2) provides improved support for these two additional
+formatting styles. The :class:`Formatter` class been enhanced to take an
+additional, optional keyword parameter named ``style``. This defaults to
+``'%'``, but other possible values are ``'{'`` and ``'$'``, which correspond
+to the other two formatting styles. Backwards compatibility is maintained by
+default (as you would expect), but by explicitly specifying a style parameter,
+you get the ability to specify format strings which work with
+:meth:`str.format` or :class:`string.Template`. Here's an example console
+session to show the possibilities:
+
+.. code-block:: pycon
+
+ >>> import logging
+ >>> root = logging.getLogger()
+ >>> root.setLevel(logging.DEBUG)
+ >>> handler = logging.StreamHandler()
+ >>> bf = logging.Formatter('{asctime} {name} {levelname:8s} {message}',
+ ... style='{')
+ >>> handler.setFormatter(bf)
+ >>> root.addHandler(handler)
+ >>> logger = logging.getLogger('foo.bar')
+ >>> logger.debug('This is a DEBUG message')
+ 2010-10-28 15:11:55,341 foo.bar DEBUG This is a DEBUG message
+ >>> logger.critical('This is a CRITICAL message')
+ 2010-10-28 15:12:11,526 foo.bar CRITICAL This is a CRITICAL message
+ >>> df = logging.Formatter('$asctime $name ${levelname} $message',
+ ... style='$')
+ >>> handler.setFormatter(df)
+ >>> logger.debug('This is a DEBUG message')
+ 2010-10-28 15:13:06,924 foo.bar DEBUG This is a DEBUG message
+ >>> logger.critical('This is a CRITICAL message')
+ 2010-10-28 15:13:11,494 foo.bar CRITICAL This is a CRITICAL message
+ >>>
+
+Note that the formatting of logging messages for final output to logs is
+completely independent of how an individual logging message is constructed.
+That can still use %-formatting, as shown here::
+
+ >>> logger.error('This is an%s %s %s', 'other,', 'ERROR,', 'message')
+ 2010-10-28 15:19:29,833 foo.bar ERROR This is another, ERROR, message
+ >>>
+
+Logging calls (``logger.debug()``, ``logger.info()`` etc.) only take
+positional parameters for the actual logging message itself, with keyword
+parameters used only for determining options for how to handle the actual
+logging call (e.g. the ``exc_info`` keyword parameter to indicate that
+traceback information should be logged, or the ``extra`` keyword parameter
+to indicate additional contextual information to be added to the log). So
+you cannot directly make logging calls using :meth:`str.format` or
+:class:`string.Template` syntax, because internally the logging package
+uses %-formatting to merge the format string and the variable arguments.
+There would no changing this while preserving backward compatibility, since
+all logging calls which are out there in existing code will be using %-format
+strings.
+
+There is, however, a way that you can use {}- and $- formatting to construct
+your individual log messages. Recall that for a message you can use an
+arbitrary object as a message format string, and that the logging package will
+call ``str()`` on that object to get the actual format string. Consider the
+following two classes::
+
+ class BraceMessage(object):
+ def __init__(self, fmt, *args, **kwargs):
+ self.fmt = fmt
+ self.args = args
+ self.kwargs = kwargs
+
+ def __str__(self):
+ return self.fmt.format(*self.args, **self.kwargs)
+
+ class DollarMessage(object):
+ def __init__(self, fmt, **kwargs):
+ self.fmt = fmt
+ self.kwargs = kwargs
+
+ def __str__(self):
+ from string import Template
+ return Template(self.fmt).substitute(**self.kwargs)
+
+Either of these can be used in place of a format string, to allow {}- or
+$-formatting to be used to build the actual "message" part which appears in the
+formatted log output in place of "%(message)s" or "{message}" or "$message".
+It's a little unwieldy to use the class names whenever you want to log
+something, but it's quite palatable if you use an alias such as __ (double
+underscore – not to be confused with _, the single underscore used as a
+synonym/alias for :func:`gettext.gettext` or its brethren).
+
+The above classes are not included in Python, though they're easy enough to
+copy and paste into your own code. They can be used as follows (assuming that
+they're declared in a module called ``wherever``):
+
+.. code-block:: pycon
+
+ >>> from wherever import BraceMessage as __
+ >>> print(__('Message with {0} {name}', 2, name='placeholders'))
+ Message with 2 placeholders
+ >>> class Point: pass
+ ...
+ >>> p = Point()
+ >>> p.x = 0.5
+ >>> p.y = 0.5
+ >>> print(__('Message with coordinates: ({point.x:.2f}, {point.y:.2f})',
+ ... point=p))
+ Message with coordinates: (0.50, 0.50)
+ >>> from wherever import DollarMessage as __
+ >>> print(__('Message with $num $what', num=2, what='placeholders'))
+ Message with 2 placeholders
+ >>>
+
+While the above examples use ``print()`` to show how the formatting works, you
+would of course use ``logger.debug()`` or similar to actually log using this
+approach.
+
+One thing to note is that you pay no significant performance penalty with this
+approach: the actual formatting happens not when you make the logging call, but
+when (and if) the logged message is actually about to be output to a log by a
+handler. So the only slightly unusual thing which might trip you up is that the
+parentheses go around the format string and the arguments, not just the format
+string. That's because the __ notation is just syntax sugar for a constructor
+call to one of the XXXMessage classes.
+
+
+.. currentmodule:: logging
+
+.. _custom-logrecord:
+
+Customising ``LogRecord``
+-------------------------
+
+Every logging event is represented by a :class:`LogRecord` instance.
+When an event is logged and not filtered out by a logger's level, a
+:class:`LogRecord` is created, populated with information about the event and
+then passed to the handlers for that logger (and its ancestors, up to and
+including the logger where further propagation up the hierarchy is disabled).
+Before Python 3.2, there were only two places where this creation was done:
+
+* :meth:`Logger.makeRecord`, which is called in the normal process of
+ logging an event. This invoked :class:`LogRecord` directly to create an
+ instance.
+* :func:`makeLogRecord`, which is called with a dictionary containing
+ attributes to be added to the LogRecord. This is typically invoked when a
+ suitable dictionary has been received over the network (e.g. in pickle form
+ via a :class:`~handlers.SocketHandler`, or in JSON form via an
+ :class:`~handlers.HTTPHandler`).
+
+This has usually meant that if you need to do anything special with a
+:class:`LogRecord`, you've had to do one of the following.
+
+* Create your own :class:`Logger` subclass, which overrides
+ :meth:`Logger.makeRecord`, and set it using :func:`~logging.setLoggerClass`
+ before any loggers that you care about are instantiated.
+* Add a :class:`Filter` to a logger or handler, which does the
+ necessary special manipulation you need when its
+ :meth:`~Filter.filter` method is called.
+
+The first approach would be a little unwieldy in the scenario where (say)
+several different libraries wanted to do different things. Each would attempt
+to set its own :class:`Logger` subclass, and the one which did this last would
+win.
+
+The second approach works reasonably well for many cases, but does not allow
+you to e.g. use a specialized subclass of :class:`LogRecord`. Library
+developers can set a suitable filter on their loggers, but they would have to
+remember to do this every time they introduced a new logger (which they would
+do simply by adding new packages or modules and doing ::
+
+ logger = logging.getLogger(__name__)
+
+at module level). It's probably one too many things to think about. Developers
+could also add the filter to a :class:`~logging.NullHandler` attached to their
+top-level logger, but this would not be invoked if an application developer
+attached a handler to a lower-level library logger – so output from that
+handler would not reflect the intentions of the library developer.
+
+In Python 3.2 and later, :class:`~logging.LogRecord` creation is done through a
+factory, which you can specify. The factory is just a callable you can set with
+:func:`~logging.setLogRecordFactory`, and interrogate with
+:func:`~logging.getLogRecordFactory`. The factory is invoked with the same
+signature as the :class:`~logging.LogRecord` constructor, as :class:`LogRecord`
+is the default setting for the factory.
+
+This approach allows a custom factory to control all aspects of LogRecord
+creation. For example, you could return a subclass, or just add some additional
+attributes to the record once created, using a pattern similar to this::
+
+ old_factory = logging.getLogRecordFactory()
+
+ def record_factory(*args, **kwargs):
+ record = old_factory(*args, **kwargs)
+ record.custom_attribute = 0xdecafbad
+ return record
+
+ logging.setLogRecordFactory(record_factory)
+
+This pattern allows different libraries to chain factories together, and as
+long as they don't overwrite each other's attributes or unintentionally
+overwrite the attributes provided as standard, there should be no surprises.
+However, it should be borne in mind that each link in the chain adds run-time
+overhead to all logging operations, and the technique should only be used when
+the use of a :class:`Filter` does not provide the desired result.
+
+
+.. _zeromq-handlers:
+
+Subclassing QueueHandler - a ZeroMQ example
+-------------------------------------------
+
+You can use a :class:`QueueHandler` subclass to send messages to other kinds
+of queues, for example a ZeroMQ 'publish' socket. In the example below,the
+socket is created separately and passed to the handler (as its 'queue')::
+
+ import zmq # using pyzmq, the Python binding for ZeroMQ
+ import json # for serializing records portably
+
+ ctx = zmq.Context()
+ sock = zmq.Socket(ctx, zmq.PUB) # or zmq.PUSH, or other suitable value
+ sock.bind('tcp://*:5556') # or wherever
+
+ class ZeroMQSocketHandler(QueueHandler):
+ def enqueue(self, record):
+ data = json.dumps(record.__dict__)
+ self.queue.send(data)
+
+ handler = ZeroMQSocketHandler(sock)
+
+
+Of course there are other ways of organizing this, for example passing in the
+data needed by the handler to create the socket::
+
+ class ZeroMQSocketHandler(QueueHandler):
+ def __init__(self, uri, socktype=zmq.PUB, ctx=None):
+ self.ctx = ctx or zmq.Context()
+ socket = zmq.Socket(self.ctx, socktype)
+ socket.bind(uri)
+ QueueHandler.__init__(self, socket)
+
+ def enqueue(self, record):
+ data = json.dumps(record.__dict__)
+ self.queue.send(data)
+
+ def close(self):
+ self.queue.close()
+
+
+Subclassing QueueListener - a ZeroMQ example
+--------------------------------------------
+
+You can also subclass :class:`QueueListener` to get messages from other kinds
+of queues, for example a ZeroMQ 'subscribe' socket. Here's an example::
+
+ class ZeroMQSocketListener(QueueListener):
+ def __init__(self, uri, *handlers, **kwargs):
+ self.ctx = kwargs.get('ctx') or zmq.Context()
+ socket = zmq.Socket(self.ctx, zmq.SUB)
+ socket.setsockopt(zmq.SUBSCRIBE, '') # subscribe to everything
+ socket.connect(uri)
+
+ def dequeue(self):
+ msg = self.queue.recv()
+ return logging.makeLogRecord(json.loads(msg))
+
+
+.. seealso::
+
+ Module :mod:`logging`
+ API reference for the logging module.
+
+ Module :mod:`logging.config`
+ Configuration API for the logging module.
+
+ Module :mod:`logging.handlers`
+ Useful handlers included with the logging module.
+
+ :ref:`A basic logging tutorial <logging-basic-tutorial>`
+
+ :ref:`A more advanced logging tutorial <logging-advanced-tutorial>`
+
+
An example dictionary-based configuration
-----------------------------------------
@@ -746,6 +1316,235 @@ For more information about this configuration, you can see the `relevant
section <https://docs.djangoproject.com/en/1.3/topics/logging/#configuring-logging>`_
of the Django documentation.
+A more elaborate multiprocessing example
+----------------------------------------
+
+The following working example shows how logging can be used with multiprocessing
+using configuration files. The configurations are fairly simple, but serve to
+illustrate how more complex ones could be implemented in a real multiprocessing
+scenario.
+
+In the example, the main process spawns a listener process and some worker
+processes. Each of the main process, the listener and the workers have three
+separate configurations (the workers all share the same configuration). We can
+see logging in the main process, how the workers log to a QueueHandler and how
+the listener implements a QueueListener and a more complex logging
+configuration, and arranges to dispatch events received via the queue to the
+handlers specified in the configuration. Note that these configurations are
+purely illustrative, but you should be able to adapt this example to your own
+scenario.
+
+Here's the script - the docstrings and the comments hopefully explain how it
+works::
+
+ import logging
+ import logging.config
+ import logging.handlers
+ from multiprocessing import Process, Queue, Event, current_process
+ import os
+ import random
+ import time
+
+ class MyHandler(object):
+ """
+ A simple handler for logging events. It runs in the listener process and
+ dispatches events to loggers based on the name in the received record,
+ which then get dispatched, by the logging system, to the handlers
+ configured for those loggers.
+ """
+ def handle(self, record):
+ logger = logging.getLogger(record.name)
+ # The process name is transformed just to show that it's the listener
+ # doing the logging to files and console
+ record.processName = '%s (for %s)' % (current_process().name, record.processName)
+ logger.handle(record)
+
+ def listener_process(q, stop_event, config):
+ """
+ This could be done in the main process, but is just done in a separate
+ process for illustrative purposes.
+
+ This initialises logging according to the specified configuration,
+ starts the listener and waits for the main process to signal completion
+ via the event. The listener is then stopped, and the process exits.
+ """
+ logging.config.dictConfig(config)
+ listener = logging.handlers.QueueListener(q, MyHandler())
+ listener.start()
+ if os.name == 'posix':
+ # On POSIX, the setup logger will have been configured in the
+ # parent process, but should have been disabled following the
+ # dictConfig call.
+ # On Windows, since fork isn't used, the setup logger won't
+ # exist in the child, so it would be created and the message
+ # would appear - hence the "if posix" clause.
+ logger = logging.getLogger('setup')
+ logger.critical('Should not appear, because of disabled logger ...')
+ stop_event.wait()
+ listener.stop()
+
+ def worker_process(config):
+ """
+ A number of these are spawned for the purpose of illustration. In
+ practice, they could be a heterogenous bunch of processes rather than
+ ones which are identical to each other.
+
+ This initialises logging according to the specified configuration,
+ and logs a hundred messages with random levels to randomly selected
+ loggers.
+
+ A small sleep is added to allow other processes a chance to run. This
+ is not strictly needed, but it mixes the output from the different
+ processes a bit more than if it's left out.
+ """
+ logging.config.dictConfig(config)
+ levels = [logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR,
+ logging.CRITICAL]
+ loggers = ['foo', 'foo.bar', 'foo.bar.baz',
+ 'spam', 'spam.ham', 'spam.ham.eggs']
+ if os.name == 'posix':
+ # On POSIX, the setup logger will have been configured in the
+ # parent process, but should have been disabled following the
+ # dictConfig call.
+ # On Windows, since fork isn't used, the setup logger won't
+ # exist in the child, so it would be created and the message
+ # would appear - hence the "if posix" clause.
+ logger = logging.getLogger('setup')
+ logger.critical('Should not appear, because of disabled logger ...')
+ for i in range(100):
+ lvl = random.choice(levels)
+ logger = logging.getLogger(random.choice(loggers))
+ logger.log(lvl, 'Message no. %d', i)
+ time.sleep(0.01)
+
+ def main():
+ q = Queue()
+ # The main process gets a simple configuration which prints to the console.
+ config_initial = {
+ 'version': 1,
+ 'formatters': {
+ 'detailed': {
+ 'class': 'logging.Formatter',
+ 'format': '%(asctime)s %(name)-15s %(levelname)-8s %(processName)-10s %(message)s'
+ }
+ },
+ 'handlers': {
+ 'console': {
+ 'class': 'logging.StreamHandler',
+ 'level': 'INFO',
+ },
+ },
+ 'root': {
+ 'level': 'DEBUG',
+ 'handlers': ['console']
+ },
+ }
+ # The worker process configuration is just a QueueHandler attached to the
+ # root logger, which allows all messages to be sent to the queue.
+ # We disable existing loggers to disable the "setup" logger used in the
+ # parent process. This is needed on POSIX because the logger will
+ # be there in the child following a fork().
+ config_worker = {
+ 'version': 1,
+ 'disable_existing_loggers': True,
+ 'handlers': {
+ 'queue': {
+ 'class': 'logging.handlers.QueueHandler',
+ 'queue': q,
+ },
+ },
+ 'root': {
+ 'level': 'DEBUG',
+ 'handlers': ['queue']
+ },
+ }
+ # The listener process configuration shows that the full flexibility of
+ # logging configuration is available to dispatch events to handlers however
+ # you want.
+ # We disable existing loggers to disable the "setup" logger used in the
+ # parent process. This is needed on POSIX because the logger will
+ # be there in the child following a fork().
+ config_listener = {
+ 'version': 1,
+ 'disable_existing_loggers': True,
+ 'formatters': {
+ 'detailed': {
+ 'class': 'logging.Formatter',
+ 'format': '%(asctime)s %(name)-15s %(levelname)-8s %(processName)-10s %(message)s'
+ },
+ 'simple': {
+ 'class': 'logging.Formatter',
+ 'format': '%(name)-15s %(levelname)-8s %(processName)-10s %(message)s'
+ }
+ },
+ 'handlers': {
+ 'console': {
+ 'class': 'logging.StreamHandler',
+ 'level': 'INFO',
+ 'formatter': 'simple',
+ },
+ 'file': {
+ 'class': 'logging.FileHandler',
+ 'filename': 'mplog.log',
+ 'mode': 'w',
+ 'formatter': 'detailed',
+ },
+ 'foofile': {
+ 'class': 'logging.FileHandler',
+ 'filename': 'mplog-foo.log',
+ 'mode': 'w',
+ 'formatter': 'detailed',
+ },
+ 'errors': {
+ 'class': 'logging.FileHandler',
+ 'filename': 'mplog-errors.log',
+ 'mode': 'w',
+ 'level': 'ERROR',
+ 'formatter': 'detailed',
+ },
+ },
+ 'loggers': {
+ 'foo': {
+ 'handlers' : ['foofile']
+ }
+ },
+ 'root': {
+ 'level': 'DEBUG',
+ 'handlers': ['console', 'file', 'errors']
+ },
+ }
+ # Log some initial events, just to show that logging in the parent works
+ # normally.
+ logging.config.dictConfig(config_initial)
+ logger = logging.getLogger('setup')
+ logger.info('About to create workers ...')
+ workers = []
+ for i in range(5):
+ wp = Process(target=worker_process, name='worker %d' % (i + 1),
+ args=(config_worker,))
+ workers.append(wp)
+ wp.start()
+ logger.info('Started worker: %s', wp.name)
+ logger.info('About to create listener ...')
+ stop_event = Event()
+ lp = Process(target=listener_process, name='listener',
+ args=(q, stop_event, config_listener))
+ lp.start()
+ logger.info('Started listener')
+ # We now hang around for the workers to finish their work.
+ for wp in workers:
+ wp.join()
+ # Workers all done, listening can now stop.
+ # Logging in the parent still works normally.
+ logger.info('Telling listener to stop ...')
+ stop_event.set()
+ lp.join()
+ logger.info('All done.')
+
+ if __name__ == '__main__':
+ main()
+
+
Inserting a BOM into messages sent to a SysLogHandler
-----------------------------------------------------
@@ -755,14 +1554,14 @@ following structure: an optional pure-ASCII component, followed by a UTF-8 Byte
Order Mark (BOM), followed by Unicode encoded using UTF-8. (See the `relevant
section of the specification <http://tools.ietf.org/html/rfc5424#section-6>`_.)
-In Python 2.6 and 2.7, code was added to
+In Python 3.1, code was added to
:class:`~logging.handlers.SysLogHandler` to insert a BOM into the message, but
unfortunately, it was implemented incorrectly, with the BOM appearing at the
beginning of the message and hence not allowing any pure-ASCII component to
appear before it.
As this behaviour is broken, the incorrect BOM insertion code is being removed
-from Python 2.7.4 and later. However, it is not being replaced, and if you
+from Python 3.2.4 and later. However, it is not being replaced, and if you
want to produce RFC 5424-compliant messages which include a BOM, an optional
pure-ASCII sequence before it and arbitrary Unicode after it, encoded using
UTF-8, then you need to do the following:
@@ -771,10 +1570,10 @@ UTF-8, then you need to do the following:
:class:`~logging.handlers.SysLogHandler` instance, with a format string
such as::
- u'ASCII section\ufeffUnicode section'
+ 'ASCII section\ufeffUnicode section'
- The Unicode code point ``u'\feff```, when encoded using UTF-8, will be
- encoded as a UTF-8 BOM -- the byte-string ``'\xef\xbb\xbf'``.
+ The Unicode code point ``'\feff```, when encoded using UTF-8, will be
+ encoded as a UTF-8 BOM -- the byte-string ``b'\xef\xbb\xbf'``.
#. Replace the ASCII section with whatever placeholders you like, but make sure
that the data that appears in there after substitution is always ASCII (that
@@ -784,9 +1583,8 @@ UTF-8, then you need to do the following:
which appears there after substitution contains characters outside the ASCII
range, that's fine -- it will be encoded using UTF-8.
-If the formatted message is Unicode, it *will* be encoded using UTF-8 encoding
-by ``SysLogHandler``. If you follow the above rules, you should be able to
-produce RFC 5424-compliant messages. If you don't, logging may not complain,
-but your messages will not be RFC 5424-compliant, and your syslog daemon may
-complain.
+The formatted message *will* be encoded using UTF-8 encoding by
+``SysLogHandler``. If you follow the above rules, you should be able to produce
+RFC 5424-compliant messages. If you don't, logging may not complain, but your
+messages will not be RFC 5424-compliant, and your syslog daemon may complain.
diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst
index 79e4dc9..44b2f59 100644
--- a/Doc/howto/logging.rst
+++ b/Doc/howto/logging.rst
@@ -353,10 +353,10 @@ root logger's name is printed as 'root' in the logged output.
It is, of course, possible to log messages to different destinations. Support
is included in the package for writing log messages to files, HTTP GET/POST
-locations, email via SMTP, generic sockets, or OS-specific logging mechanisms
-such as syslog or the Windows NT event log. Destinations are served by
-:dfn:`handler` classes. You can create your own log destination class if you
-have special requirements not met by any of the built-in handler classes.
+locations, email via SMTP, generic sockets, queues, or OS-specific logging
+mechanisms such as syslog or the Windows NT event log. Destinations are served
+by :dfn:`handler` classes. You can create your own log destination class if
+you have special requirements not met by any of the built-in handler classes.
By default, no destination is set for any logging messages. You can specify
a destination (such as console or file) by using :func:`basicConfig` as in the
@@ -412,10 +412,10 @@ With the logger object configured, the following methods create log messages:
:meth:`Logger.error`, and :meth:`Logger.critical` all create log records with
a message and a level that corresponds to their respective method names. The
message is actually a format string, which may contain the standard string
- substitution syntax of :const:`%s`, :const:`%d`, :const:`%f`, and so on. The
+ substitution syntax of ``%s``, ``%d``, ``%f``, and so on. The
rest of their arguments is a list of objects that correspond with the
- substitution fields in the message. With regard to :const:`**kwargs`, the
- logging methods care only about a keyword of :const:`exc_info` and use it to
+ substitution fields in the message. With regard to ``**kwargs``, the
+ logging methods care only about a keyword of ``exc_info`` and use it to
determine whether to log exception information.
* :meth:`Logger.exception` creates a log message similar to
@@ -496,20 +496,29 @@ Formatters
Formatter objects configure the final order, structure, and contents of the log
message. Unlike the base :class:`logging.Handler` class, application code may
instantiate formatter classes, although you could likely subclass the formatter
-if your application needs special behavior. The constructor takes two
-optional arguments -- a message format string and a date format string.
+if your application needs special behavior. The constructor takes three
+optional arguments -- a message format string, a date format string and a style
+indicator.
-.. method:: logging.Formatter.__init__(fmt=None, datefmt=None)
+.. method:: logging.Formatter.__init__(fmt=None, datefmt=None, style='%')
If there is no message format string, the default is to use the
raw message. If there is no date format string, the default date format is::
%Y-%m-%d %H:%M:%S
-with the milliseconds tacked on at the end.
+with the milliseconds tacked on at the end. The ``style`` is one of `%`, '{'
+or '$'. If one of these is not specified, then '%' will be used.
-The message format string uses ``%(<dictionary key>)s`` styled string
-substitution; the possible keys are documented in :ref:`logrecord-attributes`.
+If the ``style`` is '%', the message format string uses
+``%(<dictionary key>)s`` styled string substitution; the possible keys are
+documented in :ref:`logrecord-attributes`. If the style is '{', the message
+format string is assumed to be compatible with :meth:`str.format` (using
+keyword arguments), while if the style is '$' then the message format string
+should conform to what is expected by :meth:`string.Template.substitute`.
+
+.. versionchanged:: 3.2
+ Added the ``style`` parameter.
The following message format string will log the time in a human-readable
format, the severity of the message, and the contents of the message, in that
@@ -657,6 +666,7 @@ noncoders to easily modify the logging properties.
which may not be what you want - in which case, provide the key
explicitly with a value of ``False``.
+
.. currentmodule:: logging
Note that the class names referenced in config files need to be either relative
@@ -667,7 +677,7 @@ import mechanisms. Thus, you could use either
and module ``mymodule``, where ``mypackage`` is available on the Python import
path).
-In Python 2.7, a new means of configuring logging has been introduced, using
+In Python 3.2, a new means of configuring logging has been introduced, using
dictionaries to hold configuration information. This provides a superset of the
functionality of the config-file-based approach outlined above, and is the
recommended configuration method for new applications and deployments. Because
@@ -712,7 +722,7 @@ where a logging event needs to be output, but no handlers can be found to
output the event. The behaviour of the logging package in these
circumstances is dependent on the Python version.
-For Python 2.x, the behaviour is as follows:
+For versions of Python prior to 3.2, the behaviour is as follows:
* If *logging.raiseExceptions* is *False* (production mode), the event is
silently dropped.
@@ -720,6 +730,19 @@ For Python 2.x, the behaviour is as follows:
* If *logging.raiseExceptions* is *True* (development mode), a message
'No handlers could be found for logger X.Y.Z' is printed once.
+In Python 3.2 and later, the behaviour is as follows:
+
+* The event is output using a 'handler of last resort', stored in
+ ``logging.lastResort``. This internal handler is not associated with any
+ logger, and acts like a :class:`~logging.StreamHandler` which writes the
+ event description message to the current value of ``sys.stderr`` (therefore
+ respecting any redirections which may be in effect). No formatting is
+ done on the message - just the bare event description message is printed.
+ The handler's level is set to ``WARNING``, so all events at this and
+ greater severities will be output.
+
+To obtain the pre-3.2 behaviour, ``logging.lastResort`` can be set to *None*.
+
.. _library-config:
Configuring Logging for a Library
@@ -743,7 +766,7 @@ configured then logging calls made in library code will send output to those
handlers, as normal.
A do-nothing handler is included in the logging package:
-:class:`~logging.NullHandler` (since Python 2.7). An instance of this handler
+:class:`~logging.NullHandler` (since Python 3.1). An instance of this handler
could be added to the top-level logger of the logging namespace used by the
library (*if* you want to prevent your library's logged events being output to
``sys.stderr`` in the absence of logging configuration). If all logging by a
@@ -887,15 +910,21 @@ provided:
name. This handler is only useful on Unix-like systems; Windows does not
support the underlying mechanism used.
+#. :class:`~handlers.QueueHandler` instances send messages to a queue, such as
+ those implemented in the :mod:`queue` or :mod:`multiprocessing` modules.
+
#. :class:`NullHandler` instances do nothing with error messages. They are used
by library developers who want to use logging, but want to avoid the 'No
handlers could be found for logger XXX' message which can be displayed if
the library user has not configured logging. See :ref:`library-config` for
more information.
-.. versionadded:: 2.7
+.. versionadded:: 3.1
The :class:`NullHandler` class.
+.. versionadded:: 3.2
+ The :class:`~handlers.QueueHandler` class.
+
The :class:`NullHandler`, :class:`StreamHandler` and :class:`FileHandler`
classes are defined in the core logging package. The other handlers are
defined in a sub- module, :mod:`logging.handlers`. (There is also another
diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst
index 3eca496..a2e4173 100644
--- a/Doc/howto/pyporting.rst
+++ b/Doc/howto/pyporting.rst
@@ -505,6 +505,18 @@ Otherwise it might very well be worth your time and effort to port your tests
to :mod:`unittest`.
+Update `map` for imbalanced input sequences
+'''''''''''''''''''''''''''''''''''''''''''
+
+With Python 2, `map` would pad input sequences of unequal length with
+`None` values, returning a sequence as long as the longest input sequence.
+
+With Python 3, if the input sequences to `map` are of unequal length, `map`
+will stop at the termination of the shortest of the sequences. For full
+compatibility with `map` from Python 2.x, also wrap the sequences in
+:func:`itertools.zip_longest`, e.g. ``map(func, *sequences)`` becomes
+``list(map(func, itertools.zip_longest(*sequences)))``.
+
Eliminate ``-3`` Warnings
-------------------------
diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst
index 2f552e3..9adfa85 100644
--- a/Doc/howto/regex.rst
+++ b/Doc/howto/regex.rst
@@ -23,11 +23,6 @@
Introduction
============
-The :mod:`re` module was added in Python 1.5, and provides Perl-style regular
-expression patterns. Earlier versions of Python came with the :mod:`regex`
-module, which provided Emacs-style patterns. The :mod:`regex` module was
-removed completely in Python 2.5.
-
Regular expressions (called REs, or regexes, or regex patterns) are essentially
a tiny, highly specialized programming language embedded inside Python and made
available through the :mod:`re` module. Using this little language, you specify
@@ -113,7 +108,7 @@ Some of the special sequences beginning with ``'\'`` represent predefined sets
of characters that are often useful, such as the set of digits, the set of
letters, or the set of anything that isn't whitespace. The following predefined
special sequences are a subset of those available. The equivalent classes are
-for byte string patterns. For a complete list of sequences and expanded class
+for bytes patterns. For a complete list of sequences and expanded class
definitions for Unicode string patterns, see the last part of
:ref:`Regular Expression Syntax <re-syntax>`.
@@ -364,8 +359,8 @@ containing information about the match: where it starts and ends, the substring
it matched, and more.
You can learn about this by interactively experimenting with the :mod:`re`
-module. If you have Tkinter available, you may also want to look at
-:source:`Tools/scripts/redemo.py`, a demonstration program included with the
+module. If you have :mod:`tkinter` available, you may also want to look at
+:source:`Tools/demo/redemo.py`, a demonstration program included with the
Python distribution. It allows you to enter REs and strings, and displays
whether the RE matches or fails. :file:`redemo.py` can be quite useful when
trying to debug a complicated RE. Phil Schwartz's `Kodos
@@ -375,7 +370,6 @@ testing RE patterns.
This HOWTO uses the standard Python interpreter for its examples. First, run the
Python interpreter, import the :mod:`re` module, and compile a RE::
- Python 2.2.2 (#1, Feb 10 2003, 12:57:01)
>>> import re
>>> p = re.compile('[a-z]+')
>>> p #doctest: +ELLIPSIS
@@ -388,7 +382,7 @@ interpreter to print no output. You can explicitly print the result of
:meth:`match` to make this clear. ::
>>> p.match("")
- >>> print p.match("")
+ >>> print(p.match(""))
None
Now, let's try it on a string that it should match, such as ``tempo``. In this
@@ -433,9 +427,9 @@ will always be zero. However, the :meth:`search` method of patterns
scans through the string, so the match may not start at zero in that
case. ::
- >>> print p.match('::: message')
+ >>> print(p.match('::: message'))
None
- >>> m = p.search('::: message'); print m #doctest: +ELLIPSIS
+ >>> m = p.search('::: message'); print(m) #doctest: +ELLIPSIS
<_sre.SRE_Match object at 0x...>
>>> m.group()
'message'
@@ -449,9 +443,9 @@ In actual programs, the most common style is to store the
p = re.compile( ... )
m = p.match( 'string goes here' )
if m:
- print 'Match found: ', m.group()
+ print('Match found: ', m.group())
else:
- print 'No match'
+ print('No match')
Two pattern methods return all of the matches for a pattern.
:meth:`findall` returns a list of matching strings::
@@ -462,13 +456,13 @@ Two pattern methods return all of the matches for a pattern.
:meth:`findall` has to create the entire list before it can be returned as the
result. The :meth:`finditer` method returns a sequence of
-:ref:`match object <match-objects>` instances as an :term:`iterator`. [#]_ ::
+:ref:`match object <match-objects>` instances as an :term:`iterator`::
>>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
>>> iterator #doctest: +ELLIPSIS
- <callable-iterator object at 0x...>
+ <callable_iterator object at 0x...>
>>> for match in iterator:
- ... print match.span()
+ ... print(match.span())
...
(0, 2)
(22, 24)
@@ -485,7 +479,7 @@ take the same arguments as the corresponding pattern method, with
the RE string added as the first argument, and still return either ``None`` or a
:ref:`match object <match-objects>` instance. ::
- >>> print re.match(r'From\s+', 'Fromage amk')
+ >>> print(re.match(r'From\s+', 'Fromage amk'))
None
>>> re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998') #doctest: +ELLIPSIS
<_sre.SRE_Match object at 0x...>
@@ -502,7 +496,7 @@ more convenient. If a program contains a lot of regular expressions, or re-uses
the same ones in several locations, then it might be worthwhile to collect all
the definitions in one place, in a section of code that compiles all the REs
ahead of time. To take an example from the standard library, here's an extract
-from the deprecated :mod:`xmllib` module::
+from the now-defunct Python 2 standard :mod:`xmllib` module::
ref = re.compile( ... )
entityref = re.compile( ... )
@@ -543,9 +537,9 @@ of each one.
| :const:`VERBOSE`, :const:`X` | Enable verbose REs, which can be organized |
| | more cleanly and understandably. |
+---------------------------------+--------------------------------------------+
-| :const:`UNICODE`, :const:`U` | Makes several escapes like ``\w``, ``\b``, |
-| | ``\s`` and ``\d`` dependent on the Unicode |
-| | character database. |
+| :const:`ASCII`, :const:`A` | Makes several escapes like ``\w``, ``\b``, |
+| | ``\s`` and ``\d`` match only on ASCII |
+| | characters with the respective property. |
+---------------------------------+--------------------------------------------+
@@ -601,12 +595,13 @@ of each one.
newline; without this flag, ``'.'`` will match anything *except* a newline.
-.. data:: U
- UNICODE
+.. data:: A
+ ASCII
:noindex:
- Make ``\w``, ``\W``, ``\b``, ``\B``, ``\d``, ``\D``, ``\s`` and ``\S``
- dependent on the Unicode character properties database.
+ Make ``\w``, ``\W``, ``\b``, ``\B``, ``\s`` and ``\S`` perform ASCII-only
+ matching instead of full Unicode matching. This is only meaningful for
+ Unicode patterns, and is ignored for byte patterns.
.. data:: X
@@ -688,9 +683,9 @@ given location, they can obviously be matched an infinite number of times.
For example, if you wish to match the word ``From`` only at the beginning of a
line, the RE to use is ``^From``. ::
- >>> print re.search('^From', 'From Here to Eternity') #doctest: +ELLIPSIS
+ >>> print(re.search('^From', 'From Here to Eternity')) #doctest: +ELLIPSIS
<_sre.SRE_Match object at 0x...>
- >>> print re.search('^From', 'Reciting From Memory')
+ >>> print(re.search('^From', 'Reciting From Memory'))
None
.. To match a literal \character{\^}, use \regexp{\e\^} or enclose it
@@ -700,11 +695,11 @@ given location, they can obviously be matched an infinite number of times.
Matches at the end of a line, which is defined as either the end of the string,
or any location followed by a newline character. ::
- >>> print re.search('}$', '{block}') #doctest: +ELLIPSIS
+ >>> print(re.search('}$', '{block}')) #doctest: +ELLIPSIS
<_sre.SRE_Match object at 0x...>
- >>> print re.search('}$', '{block} ')
+ >>> print(re.search('}$', '{block} '))
None
- >>> print re.search('}$', '{block}\n') #doctest: +ELLIPSIS
+ >>> print(re.search('}$', '{block}\n')) #doctest: +ELLIPSIS
<_sre.SRE_Match object at 0x...>
To match a literal ``'$'``, use ``\$`` or enclose it inside a character class,
@@ -729,11 +724,11 @@ given location, they can obviously be matched an infinite number of times.
match when it's contained inside another word. ::
>>> p = re.compile(r'\bclass\b')
- >>> print p.search('no class at all') #doctest: +ELLIPSIS
+ >>> print(p.search('no class at all')) #doctest: +ELLIPSIS
<_sre.SRE_Match object at 0x...>
- >>> print p.search('the declassified algorithm')
+ >>> print(p.search('the declassified algorithm'))
None
- >>> print p.search('one subclass is')
+ >>> print(p.search('one subclass is'))
None
There are two subtleties you should remember when using this special sequence.
@@ -745,9 +740,9 @@ given location, they can obviously be matched an infinite number of times.
in front of the RE string. ::
>>> p = re.compile('\bclass\b')
- >>> print p.search('no class at all')
+ >>> print(p.search('no class at all'))
None
- >>> print p.search('\b' + 'class' + '\b') #doctest: +ELLIPSIS
+ >>> print(p.search('\b' + 'class' + '\b')) #doctest: +ELLIPSIS
<_sre.SRE_Match object at 0x...>
Second, inside a character class, where there's no use for this assertion,
@@ -785,7 +780,7 @@ of a group with a repeating qualifier, such as ``*``, ``+``, ``?``, or
``ab``. ::
>>> p = re.compile('(ab)*')
- >>> print p.match('ababababab').span()
+ >>> print(p.match('ababababab').span())
(0, 10)
Groups indicated with ``'('``, ``')'`` also capture the starting and ending
@@ -1251,17 +1246,17 @@ It's important to keep this distinction in mind. Remember, :func:`match` will
only report a successful match which will start at 0; if the match wouldn't
start at zero, :func:`match` will *not* report it. ::
- >>> print re.match('super', 'superstition').span()
+ >>> print(re.match('super', 'superstition').span())
(0, 5)
- >>> print re.match('super', 'insuperable')
+ >>> print(re.match('super', 'insuperable'))
None
On the other hand, :func:`search` will scan forward through the string,
reporting the first match it finds. ::
- >>> print re.search('super', 'superstition').span()
+ >>> print(re.search('super', 'superstition').span())
(0, 5)
- >>> print re.search('super', 'insuperable').span()
+ >>> print(re.search('super', 'insuperable').span())
(2, 7)
Sometimes you'll be tempted to keep using :func:`re.match`, and just add ``.*``
@@ -1290,9 +1285,9 @@ doesn't work because of the greedy nature of ``.*``. ::
>>> s = '<html><head><title>Title</title>'
>>> len(s)
32
- >>> print re.match('<.*>', s).span()
+ >>> print(re.match('<.*>', s).span())
(0, 32)
- >>> print re.match('<.*>', s).group()
+ >>> print(re.match('<.*>', s).group())
<html><head><title>Title</title>
The RE matches the ``'<'`` in ``<html>``, and the ``.*`` consumes the rest of
@@ -1308,7 +1303,7 @@ example, the ``'>'`` is tried immediately after the first ``'<'`` matches, and
when it fails, the engine advances a character at a time, retrying the ``'>'``
at every step. This produces just the right result::
- >>> print re.match('<.*?>', s).group()
+ >>> print(re.match('<.*?>', s).group())
<html>
(Note that parsing HTML or XML with regular expressions is painful.
@@ -1319,7 +1314,7 @@ be *very* complicated. Use an HTML or XML parser module for such tasks.)
Using re.VERBOSE
---------------------
+----------------
By now you've probably noticed that regular expressions are a very compact
notation, but they're not terribly readable. REs of moderate complexity can
@@ -1368,8 +1363,3 @@ reference for programming in Python. (The first edition covered Python's
now-removed :mod:`regex` module, which won't help you much.) Consider checking
it out from your library.
-
-.. rubric:: Footnotes
-
-.. [#] Introduced in Python 2.2.2.
-
diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst
index c4b3f71..279bb3e 100644
--- a/Doc/howto/sockets.rst
+++ b/Doc/howto/sockets.rst
@@ -62,12 +62,10 @@ Creating a Socket
Roughly speaking, when you clicked on the link that brought you to this page,
your browser did something like the following::
- #create an INET, STREAMing socket
- s = socket.socket(
- socket.AF_INET, socket.SOCK_STREAM)
- #now connect to the web server on port 80
- # - the normal http port
- s.connect(("www.mcmillan-inc.com", 80))
+ # create an INET, STREAMing socket
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ # now connect to the web server on port 80 - the normal http port
+ s.connect(("www.python.org", 80))
When the ``connect`` completes, the socket ``s`` can be used to send
in a request for the text of the page. The same socket will read the
@@ -78,13 +76,11 @@ exchanges).
What happens in the web server is a bit more complex. First, the web server
creates a "server socket"::
- #create an INET, STREAMing socket
- serversocket = socket.socket(
- socket.AF_INET, socket.SOCK_STREAM)
- #bind the socket to a public host,
- # and a well-known port
+ # create an INET, STREAMing socket
+ serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ # bind the socket to a public host, and a well-known port
serversocket.bind((socket.gethostname(), 80))
- #become a server socket
+ # become a server socket
serversocket.listen(5)
A couple things to notice: we used ``socket.gethostname()`` so that the socket
@@ -103,11 +99,11 @@ connections. If the rest of the code is written properly, that should be plenty.
Now that we have a "server" socket, listening on port 80, we can enter the
mainloop of the web server::
- while 1:
- #accept connections from outside
+ while True:
+ # accept connections from outside
(clientsocket, address) = serversocket.accept()
- #now do something with the clientsocket
- #in this case, we'll pretend this is a threaded server
+ # now do something with the clientsocket
+ # in this case, we'll pretend this is a threaded server
ct = client_thread(clientsocket)
ct.run()
@@ -129,12 +125,13 @@ IPC
---
If you need fast IPC between two processes on one machine, you should look into
-whatever form of shared memory the platform offers. A simple protocol based
-around shared memory and locks or semaphores is by far the fastest technique.
+pipes or shared memory. If you do decide to use AF_INET sockets, bind the
+"server" socket to ``'localhost'``. On most platforms, this will take a
+shortcut around a couple of layers of network code and be quite a bit faster.
-If you do decide to use sockets, bind the "server" socket to ``'localhost'``. On
-most platforms, this will take a shortcut around a couple of layers of network
-code and be quite a bit faster.
+.. seealso::
+ The :mod:`multiprocessing` integrates cross-platform IPC into a higher-level
+ API.
Using a Socket
@@ -188,16 +185,16 @@ Assuming you don't want to end the connection, the simplest solution is a fixed
length message::
class mysocket:
- '''demonstration class only
+ """demonstration class only
- coded for clarity, not efficiency
- '''
+ """
def __init__(self, sock=None):
if sock is None:
self.sock = socket.socket(
- socket.AF_INET, socket.SOCK_STREAM)
- else:
- self.sock = sock
+ socket.AF_INET, socket.SOCK_STREAM)
+ else:
+ self.sock = sock
def connect(self, host, port):
self.sock.connect((host, port))
@@ -303,7 +300,7 @@ When Sockets Die
Probably the worst thing about using blocking sockets is what happens when the
other side comes down hard (without doing a ``close``). Your socket is likely to
-hang. SOCKSTREAM is a reliable protocol, and it will wait a long, long time
+hang. TCP is a reliable protocol, and it will wait a long, long time
before giving up on a connection. If you're using threads, the entire thread is
essentially dead. There's not much you can do about it. As long as you aren't
doing something dumb, like holding a lock while doing a blocking read, the
@@ -398,19 +395,13 @@ Performance
There's no question that the fastest sockets code uses non-blocking sockets and
select to multiplex them. You can put together something that will saturate a
-LAN connection without putting any strain on the CPU. The trouble is that an app
-written this way can't do much of anything else - it needs to be ready to
-shuffle bytes around at all times.
-
-Assuming that your app is actually supposed to do something more than that,
-threading is the optimal solution, (and using non-blocking sockets will be
-faster than using blocking sockets). Unfortunately, threading support in Unixes
-varies both in API and quality. So the normal Unix solution is to fork a
-subprocess to deal with each connection. The overhead for this is significant
-(and don't do this on Windows - the overhead of process creation is enormous
-there). It also means that unless each subprocess is completely independent,
-you'll need to use another form of IPC, say a pipe, or shared memory and
-semaphores, to communicate between the parent and child processes.
+LAN connection without putting any strain on the CPU.
+
+The trouble is that an app written this way can't do much of anything else -
+it needs to be ready to shuffle bytes around at all times. Assuming that your
+app is actually supposed to do something more than that, threading is the
+optimal solution, (and using non-blocking sockets will be faster than using
+blocking sockets).
Finally, remember that even though blocking sockets are somewhat slower than
non-blocking, in many cases they are the "right" solution. After all, if your
diff --git a/Doc/howto/sorting.rst b/Doc/howto/sorting.rst
index 56b65b0..00bc6f7 100644
--- a/Doc/howto/sorting.rst
+++ b/Doc/howto/sorting.rst
@@ -23,7 +23,7 @@ returns a new sorted list::
>>> sorted([5, 2, 3, 1, 4])
[1, 2, 3, 4, 5]
-You can also use the :meth:`list.sort` method of a list. It modifies the list
+You can also use the :meth:`list.sort` method. It modifies the list
in-place (and returns *None* to avoid confusion). Usually it's less convenient
than :func:`sorted` - but if you don't need the original list, it's slightly
more efficient.
@@ -42,9 +42,8 @@ lists. In contrast, the :func:`sorted` function accepts any iterable.
Key Functions
=============
-Starting with Python 2.4, both :meth:`list.sort` and :func:`sorted` added a
-*key* parameter to specify a function to be called on each list element prior to
-making comparisons.
+Both :meth:`list.sort` and :func:`sorted` have a *key* parameter to specify a
+function to be called on each list element prior to making comparisons.
For example, here's a case-insensitive string comparison:
@@ -88,9 +87,9 @@ Operator Module Functions
=========================
The key-function patterns shown above are very common, so Python provides
-convenience functions to make accessor functions easier and faster. The operator
-module has :func:`operator.itemgetter`, :func:`operator.attrgetter`, and
-starting in Python 2.5 a :func:`operator.methodcaller` function.
+convenience functions to make accessor functions easier and faster. The
+:mod:`operator` module has :func:`~operator.itemgetter`,
+:func:`~operator.attrgetter`, and a :func:`~operator.methodcaller` function.
Using those functions, the above examples become simpler and faster:
@@ -111,15 +110,6 @@ sort by *grade* then by *age*:
>>> sorted(student_objects, key=attrgetter('grade', 'age'))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
-The :func:`operator.methodcaller` function makes method calls with fixed
-parameters for each object being sorted. For example, the :meth:`str.count`
-method could be used to compute message priority by counting the
-number of exclamation marks in a message:
-
- >>> messages = ['critical!!!', 'hurry!', 'standby', 'immediate!!']
- >>> sorted(messages, key=methodcaller('count', '!'))
- ['standby', 'hurry!', 'immediate!!', 'critical!!!']
-
Ascending and Descending
========================
@@ -136,7 +126,7 @@ student data in reverse *age* order:
Sort Stability and Complex Sorts
================================
-Starting with Python 2.2, sorts are guaranteed to be `stable
+Sorts are guaranteed to be `stable
<http://en.wikipedia.org/wiki/Sorting_algorithm#Stability>`_\. That means that
when multiple records have the same key, their original order is preserved.
@@ -197,10 +187,8 @@ Another name for this idiom is
`Schwartzian transform <http://en.wikipedia.org/wiki/Schwartzian_transform>`_\,
after Randal L. Schwartz, who popularized it among Perl programmers.
-For large lists and lists where the comparison information is expensive to
-calculate, and Python versions before 2.4, DSU is likely to be the fastest way
-to sort the list. For 2.4 and later, key functions provide the same
-functionality.
+Now that Python sorting provides key-functions, this technique is not often needed.
+
The Old Way Using the *cmp* Parameter
=====================================
@@ -210,11 +198,11 @@ there was no :func:`sorted` builtin and :meth:`list.sort` took no keyword
arguments. Instead, all of the Py2.x versions supported a *cmp* parameter to
handle user specified comparison functions.
-In Python 3, the *cmp* parameter was removed entirely (as part of a larger effort to
+In Py3.0, the *cmp* parameter was removed entirely (as part of a larger effort to
simplify and unify the language, eliminating the conflict between rich
comparisons and the :meth:`__cmp__` magic method).
-In Python 2, :meth:`~list.sort` allowed an optional function which can be called for doing the
+In Py2.x, sort allowed an optional function which can be called for doing the
comparisons. That function should take two arguments to be compared and then
return a negative value for less-than, return zero if they are equal, or return
a positive value for greater-than. For example, we can do:
@@ -259,8 +247,8 @@ To convert to a key function, just wrap the old comparison function:
>>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric))
[5, 4, 3, 2, 1]
-In Python 2.7, the :func:`functools.cmp_to_key` function was added to the
-functools module.
+In Python 3.2, the :func:`functools.cmp_to_key` function was added to the
+:mod:`functools` module in the standard library.
Odd and Ends
============
@@ -269,35 +257,27 @@ Odd and Ends
:func:`locale.strcoll` for a comparison function.
* The *reverse* parameter still maintains sort stability (so that records with
- equal keys retain their original order). Interestingly, that effect can be
+ equal keys retain the original order). Interestingly, that effect can be
simulated without the parameter by using the builtin :func:`reversed` function
twice:
>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> assert sorted(data, reverse=True) == list(reversed(sorted(reversed(data))))
-* To create a standard sort order for a class, just add the appropriate rich
- comparison methods:
+* The sort routines are guaranteed to use :meth:`__lt__` when making comparisons
+ between two objects. So, it is easy to add a standard sort order to a class by
+ defining an :meth:`__lt__` method::
- >>> Student.__eq__ = lambda self, other: self.age == other.age
- >>> Student.__ne__ = lambda self, other: self.age != other.age
>>> Student.__lt__ = lambda self, other: self.age < other.age
- >>> Student.__le__ = lambda self, other: self.age <= other.age
- >>> Student.__gt__ = lambda self, other: self.age > other.age
- >>> Student.__ge__ = lambda self, other: self.age >= other.age
>>> sorted(student_objects)
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
- For general purpose comparisons, the recommended approach is to define all six
- rich comparison operators. The :func:`functools.total_ordering` class
- decorator makes this easy to implement.
-
* Key functions need not depend directly on the objects being sorted. A key
function can also access external resources. For instance, if the student grades
are stored in a dictionary, they can be used to sort a separate list of student
names:
>>> students = ['dave', 'john', 'jane']
- >>> grades = {'john': 'F', 'jane':'A', 'dave': 'C'}
- >>> sorted(students, key=grades.__getitem__)
+ >>> newgrades = {'john': 'F', 'jane':'A', 'dave': 'C'}
+ >>> sorted(students, key=newgrades.__getitem__)
['jane', 'dave', 'john']
diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst
index 10dde01..f9eeae4 100644
--- a/Doc/howto/unicode.rst
+++ b/Doc/howto/unicode.rst
@@ -1,13 +1,14 @@
+.. _unicode-howto:
+
*****************
Unicode HOWTO
*****************
-:Release: 1.03
+:Release: 1.12
-This HOWTO discusses Python 2.x's support for Unicode, and explains
+This HOWTO discusses Python support for Unicode, and explains
various problems that people commonly encounter when trying to work
-with Unicode. For the Python 3 version, see
-<http://docs.python.org/py3k/howto/unicode.html>.
+with Unicode.
Introduction to Unicode
=======================
@@ -17,9 +18,8 @@ History of Character Codes
In 1968, the American Standard Code for Information Interchange, better known by
its acronym ASCII, was standardized. ASCII defined numeric codes for various
-characters, with the numeric values running from 0 to
-127. For example, the lowercase letter 'a' is assigned 97 as its code
-value.
+characters, with the numeric values running from 0 to 127. For example, the
+lowercase letter 'a' is assigned 97 as its code value.
ASCII was an American-developed standard, so it only defined unaccented
characters. There was an 'e', but no 'é' or 'Ã'. This meant that languages
@@ -42,14 +42,14 @@ In the 1980s, almost all personal computers were 8-bit, meaning that bytes could
hold values ranging from 0 to 255. ASCII codes only went up to 127, so some
machines assigned values between 128 and 255 to accented characters. Different
machines had different codes, however, which led to problems exchanging files.
-Eventually various commonly used sets of values for the 128-255 range emerged.
+Eventually various commonly used sets of values for the 128--255 range emerged.
Some were true standards, defined by the International Standards Organization,
and some were **de facto** conventions that were invented by one company or
another and managed to catch on.
255 characters aren't very many. For example, you can't fit both the accented
characters used in Western Europe and the Cyrillic alphabet used for Russian
-into the 128-255 range because there are more than 127 such characters.
+into the 128--255 range because there are more than 127 such characters.
You could write files using different codes (all your Russian files in a coding
system called KOI8, all your French files in a different coding system called
@@ -62,8 +62,8 @@ bits means you have 2^16 = 65,536 distinct values available, making it possible
to represent many different characters from many different alphabets; an initial
goal was to have Unicode contain the alphabets for every single human language.
It turns out that even 16 bits isn't enough to meet that goal, and the modern
-Unicode specification uses a wider range of codes, 0-1,114,111 (0x10ffff in
-base-16).
+Unicode specification uses a wider range of codes, 0 through 1,114,111 (0x10ffff
+in base 16).
There's a related ISO standard, ISO 10646. Unicode and ISO 10646 were
originally separate efforts, but the specifications were merged with the 1.1
@@ -88,7 +88,7 @@ meanings.
The Unicode standard describes how characters are represented by **code
points**. A code point is an integer value, usually denoted in base 16. In the
standard, a code point is written using the notation U+12ca to mean the
-character with value 0x12ca (4810 decimal). The Unicode standard contains a lot
+character with value 0x12ca (4,810 decimal). The Unicode standard contains a lot
of tables listing characters and their corresponding code points::
0061 'a'; LATIN SMALL LETTER A
@@ -115,10 +115,10 @@ Encodings
---------
To summarize the previous section: a Unicode string is a sequence of code
-points, which are numbers from 0 to 0x10ffff. This sequence needs to be
-represented as a set of bytes (meaning, values from 0-255) in memory. The rules
-for translating a Unicode string into a sequence of bytes are called an
-**encoding**.
+points, which are numbers from 0 through 0x10ffff (1,114,111 decimal). This
+sequence needs to be represented as a set of bytes (meaning, values
+from 0 through 255) in memory. The rules for translating a Unicode string
+into a sequence of bytes are called an **encoding**.
The first encoding you might think of is an array of 32-bit integers. In this
representation, the string "Python" would look like this::
@@ -151,9 +151,8 @@ encodings that are more efficient and convenient. UTF-8 is probably
the most commonly supported encoding; it will be discussed below.
Encodings don't have to handle every possible Unicode character, and most
-encodings don't. For example, Python's default encoding is the 'ascii'
-encoding. The rules for converting a Unicode string into the ASCII encoding are
-simple; for each code point:
+encodings don't. The rules for converting a Unicode string into the ASCII
+encoding, for example, are simple; for each code point:
1. If the code point is < 128, each byte is the same as the value of the code
point.
@@ -163,7 +162,7 @@ simple; for each code point:
case.)
Latin-1, also known as ISO-8859-1, is a similar encoding. Unicode code points
-0-255 are identical to the Latin-1 values, so converting to this encoding simply
+0--255 are identical to the Latin-1 values, so converting to this encoding simply
requires converting code points to byte values; if a code point larger than 255
is encountered, the string can't be encoded into Latin-1.
@@ -225,137 +224,94 @@ Wikipedia entries are often helpful; see the entries for "character encoding"
<http://en.wikipedia.org/wiki/UTF-8>, for example.
-Python 2.x's Unicode Support
-============================
+Python's Unicode Support
+========================
Now that you've learned the rudiments of Unicode, we can look at Python's
Unicode features.
+The String Type
+---------------
-The Unicode Type
-----------------
-
-Unicode strings are expressed as instances of the :class:`unicode` type, one of
-Python's repertoire of built-in types. It derives from an abstract type called
-:class:`basestring`, which is also an ancestor of the :class:`str` type; you can
-therefore check if a value is a string type with ``isinstance(value,
-basestring)``. Under the hood, Python represents Unicode strings as either 16-
-or 32-bit integers, depending on how the Python interpreter was compiled.
-
-The :func:`unicode` constructor has the signature ``unicode(string[, encoding,
-errors])``. All of its arguments should be 8-bit strings. The first argument
-is converted to Unicode using the specified encoding; if you leave off the
-``encoding`` argument, the ASCII encoding is used for the conversion, so
-characters greater than 127 will be treated as errors::
-
- >>> unicode('abcdef')
- u'abcdef'
- >>> s = unicode('abcdef')
- >>> type(s)
- <type 'unicode'>
- >>> unicode('abcdef' + chr(255)) #doctest: +NORMALIZE_WHITESPACE
- Traceback (most recent call last):
- ...
- UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 6:
- ordinal not in range(128)
+Since Python 3.0, the language features a ``str`` type that contain Unicode
+characters, meaning any string created using ``"unicode rocks!"``, ``'unicode
+rocks!'``, or the triple-quoted string syntax is stored as Unicode.
+
+To insert a Unicode character that is not part ASCII, e.g., any letters with
+accents, one can use escape sequences in their string literals as such::
+
+ >>> "\N{GREEK CAPITAL LETTER DELTA}" # Using the character name
+ '\u0394'
+ >>> "\u0394" # Using a 16-bit hex value
+ '\u0394'
+ >>> "\U00000394" # Using a 32-bit hex value
+ '\u0394'
-The ``errors`` argument specifies the response when the input string can't be
+In addition, one can create a string using the :func:`decode` method of
+:class:`bytes`. This method takes an encoding, such as UTF-8, and, optionally,
+an *errors* argument.
+
+The *errors* argument specifies the response when the input string can't be
converted according to the encoding's rules. Legal values for this argument are
-'strict' (raise a ``UnicodeDecodeError`` exception), 'replace' (add U+FFFD,
+'strict' (raise a :exc:`UnicodeDecodeError` exception), 'replace' (use U+FFFD,
'REPLACEMENT CHARACTER'), or 'ignore' (just leave the character out of the
Unicode result). The following examples show the differences::
- >>> unicode('\x80abc', errors='strict') #doctest: +NORMALIZE_WHITESPACE
+ >>> b'\x80abc'.decode("utf-8", "strict") #doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
- UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0:
- ordinal not in range(128)
- >>> unicode('\x80abc', errors='replace')
- u'\ufffdabc'
- >>> unicode('\x80abc', errors='ignore')
- u'abc'
-
-Encodings are specified as strings containing the encoding's name. Python 2.7
+ UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0:
+ invalid start byte
+ >>> b'\x80abc'.decode("utf-8", "replace")
+ '\ufffdabc'
+ >>> b'\x80abc'.decode("utf-8", "ignore")
+ 'abc'
+
+(In this code example, the Unicode replacement character has been replaced by
+a question mark because it may not be displayed on some systems.)
+
+Encodings are specified as strings containing the encoding's name. Python 3.2
comes with roughly 100 different encodings; see the Python Library Reference at
-:ref:`standard-encodings` for a list. Some encodings
-have multiple names; for example, 'latin-1', 'iso_8859_1' and '8859' are all
-synonyms for the same encoding.
+:ref:`standard-encodings` for a list. Some encodings have multiple names; for
+example, 'latin-1', 'iso_8859_1' and '8859' are all synonyms for the same
+encoding.
-One-character Unicode strings can also be created with the :func:`unichr`
+One-character Unicode strings can also be created with the :func:`chr`
built-in function, which takes integers and returns a Unicode string of length 1
that contains the corresponding code point. The reverse operation is the
built-in :func:`ord` function that takes a one-character Unicode string and
returns the code point value::
- >>> unichr(40960)
- u'\ua000'
- >>> ord(u'\ua000')
- 40960
-
-Instances of the :class:`unicode` type have many of the same methods as the
-8-bit string type for operations such as searching and formatting::
-
- >>> s = u'Was ever feather so lightly blown to and fro as this multitude?'
- >>> s.count('e')
- 5
- >>> s.find('feather')
- 9
- >>> s.find('bird')
- -1
- >>> s.replace('feather', 'sand')
- u'Was ever sand so lightly blown to and fro as this multitude?'
- >>> s.upper()
- u'WAS EVER FEATHER SO LIGHTLY BLOWN TO AND FRO AS THIS MULTITUDE?'
-
-Note that the arguments to these methods can be Unicode strings or 8-bit
-strings. 8-bit strings will be converted to Unicode before carrying out the
-operation; Python's default ASCII encoding will be used, so characters greater
-than 127 will cause an exception::
-
- >>> s.find('Was\x9f') #doctest: +NORMALIZE_WHITESPACE
- Traceback (most recent call last):
- ...
- UnicodeDecodeError: 'ascii' codec can't decode byte 0x9f in position 3:
- ordinal not in range(128)
- >>> s.find(u'Was\x9f')
- -1
-
-Much Python code that operates on strings will therefore work with Unicode
-strings without requiring any changes to the code. (Input and output code needs
-more updating for Unicode; more on this later.)
-
-Another important method is ``.encode([encoding], [errors='strict'])``, which
-returns an 8-bit string version of the Unicode string, encoded in the requested
-encoding. The ``errors`` parameter is the same as the parameter of the
-``unicode()`` constructor, with one additional possibility; as well as 'strict',
-'ignore', and 'replace', you can also pass 'xmlcharrefreplace' which uses XML's
-character references. The following example shows the different results::
-
- >>> u = unichr(40960) + u'abcd' + unichr(1972)
+ >>> chr(57344)
+ '\ue000'
+ >>> ord('\ue000')
+ 57344
+
+Converting to Bytes
+-------------------
+
+Another important str method is ``.encode([encoding], [errors='strict'])``,
+which returns a ``bytes`` representation of the Unicode string, encoded in the
+requested encoding. The ``errors`` parameter is the same as the parameter of
+the :meth:`decode` method, with one additional possibility; as well as 'strict',
+'ignore', and 'replace' (which in this case inserts a question mark instead of
+the unencodable character), you can also pass 'xmlcharrefreplace' which uses
+XML's character references. The following example shows the different results::
+
+ >>> u = chr(40960) + 'abcd' + chr(1972)
>>> u.encode('utf-8')
- '\xea\x80\x80abcd\xde\xb4'
- >>> u.encode('ascii') #doctest: +NORMALIZE_WHITESPACE
+ b'\xea\x80\x80abcd\xde\xb4'
+ >>> u.encode('ascii') #doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
- UnicodeEncodeError: 'ascii' codec can't encode character u'\ua000' in
- position 0: ordinal not in range(128)
+ UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in
+ position 0: ordinal not in range(128)
>>> u.encode('ascii', 'ignore')
- 'abcd'
+ b'abcd'
>>> u.encode('ascii', 'replace')
- '?abcd?'
+ b'?abcd?'
>>> u.encode('ascii', 'xmlcharrefreplace')
- '&#40960;abcd&#1972;'
-
-Python's 8-bit strings have a ``.decode([encoding], [errors])`` method that
-interprets the string using the given encoding::
-
- >>> u = unichr(40960) + u'abcd' + unichr(1972) # Assemble a string
- >>> utf8_version = u.encode('utf-8') # Encode as UTF-8
- >>> type(utf8_version), utf8_version
- (<type 'str'>, '\xea\x80\x80abcd\xde\xb4')
- >>> u2 = utf8_version.decode('utf-8') # Decode using UTF-8
- >>> u == u2 # The two strings match
- True
+ b'&#40960;abcd&#1972;'
The low-level routines for registering and accessing the available encodings are
found in the :mod:`codecs` module. However, the encoding and decoding functions
@@ -365,38 +321,26 @@ completely new encoding, you'll need to learn about the :mod:`codecs` module
interfaces, but implementing encodings is a specialized task that also won't be
covered here. Consult the Python documentation to learn more about this module.
-The most commonly used part of the :mod:`codecs` module is the
-:func:`codecs.open` function which will be discussed in the section on input and
-output.
-
Unicode Literals in Python Source Code
--------------------------------------
-In Python source code, Unicode literals are written as strings prefixed with the
-'u' or 'U' character: ``u'abcdefghijk'``. Specific code points can be written
-using the ``\u`` escape sequence, which is followed by four hex digits giving
-the code point. The ``\U`` escape sequence is similar, but expects 8 hex
-digits, not 4.
+In Python source code, specific Unicode code points can be written using the
+``\u`` escape sequence, which is followed by four hex digits giving the code
+point. The ``\U`` escape sequence is similar, but expects eight hex digits,
+not four::
-Unicode literals can also use the same escape sequences as 8-bit strings,
-including ``\x``, but ``\x`` only takes two hex digits so it can't express an
-arbitrary code point. Octal escapes can go up to U+01ff, which is octal 777.
-
-::
-
- >>> s = u"a\xac\u1234\u20ac\U00008000"
- ... # ^^^^ two-digit hex escape
- ... # ^^^^^^ four-digit Unicode escape
- ... # ^^^^^^^^^^ eight-digit Unicode escape
- >>> for c in s: print ord(c),
- ...
- 97 172 4660 8364 32768
+ >>> s = "a\xac\u1234\u20ac\U00008000"
+ ... # ^^^^ two-digit hex escape
+ ... # ^^^^^^ four-digit Unicode escape
+ ... # ^^^^^^^^^^ eight-digit Unicode escape
+ >>> [ord(c) for c in s]
+ [97, 172, 4660, 8364, 32768]
Using escape sequences for code points greater than 127 is fine in small doses,
but becomes an annoyance if you're using many accented characters, as you would
in a program with messages in French or some other accent-using language. You
-can also assemble strings using the :func:`unichr` built-in function, but this is
+can also assemble strings using the :func:`chr` built-in function, but this is
even more tedious.
Ideally, you'd want to be able to write literals in your language's natural
@@ -404,15 +348,15 @@ encoding. You could then edit Python source code with your favorite editor
which would display the accented characters naturally, and have the right
characters used at runtime.
-Python supports writing Unicode literals in any encoding, but you have to
-declare the encoding being used. This is done by including a special comment as
-either the first or second line of the source file::
+Python supports writing source code in UTF-8 by default, but you can use almost
+any encoding if you declare the encoding being used. This is done by including
+a special comment as either the first or second line of the source file::
#!/usr/bin/env python
# -*- coding: latin-1 -*-
- u = u'abcdé'
- print ord(u[-1])
+ u = 'abcdé'
+ print(ord(u[-1]))
The syntax is inspired by Emacs's notation for specifying variables local to a
file. Emacs supports many different variables, but Python only supports
@@ -420,30 +364,8 @@ file. Emacs supports many different variables, but Python only supports
they have no significance to Python but are a convention. Python looks for
``coding: name`` or ``coding=name`` in the comment.
-If you don't include such a comment, the default encoding used will be ASCII.
-Versions of Python before 2.4 were Euro-centric and assumed Latin-1 as a default
-encoding for string literals; in Python 2.4, characters greater than 127 still
-work but result in a warning. For example, the following program has no
-encoding declaration::
-
- #!/usr/bin/env python
- u = u'abcdé'
- print ord(u[-1])
-
-When you run it with Python 2.4, it will output the following warning::
-
- amk:~$ python2.4 p263.py
- sys:1: DeprecationWarning: Non-ASCII character '\xe9'
- in file p263.py on line 2, but no encoding declared;
- see http://www.python.org/peps/pep-0263.html for details
-
-Python 2.5 and higher are stricter and will produce a syntax error::
-
- amk:~$ python2.5 p263.py
- File "/tmp/p263.py", line 2
- SyntaxError: Non-ASCII character '\xc3' in file /tmp/p263.py
- on line 2, but no encoding declared; see
- http://www.python.org/peps/pep-0263.html for details
+If you don't include such a comment, the default encoding used will be UTF-8 as
+already mentioned.
Unicode Properties
@@ -461,14 +383,14 @@ prints the numeric value of one particular character::
import unicodedata
- u = unichr(233) + unichr(0x0bf2) + unichr(3972) + unichr(6000) + unichr(13231)
+ u = chr(233) + chr(0x0bf2) + chr(3972) + chr(6000) + chr(13231)
for i, c in enumerate(u):
- print i, '%04x' % ord(c), unicodedata.category(c),
- print unicodedata.name(c)
+ print(i, '%04x' % ord(c), unicodedata.category(c), end=" ")
+ print(unicodedata.name(c))
# Get numeric value of second character
- print unicodedata.numeric(u[1])
+ print(unicodedata.numeric(u[1]))
When run, this prints::
@@ -491,8 +413,8 @@ list of category codes.
References
----------
-The Unicode and 8-bit string types are described in the Python library reference
-at :ref:`typesseq`.
+The ``str`` type is described in the Python library reference at
+:ref:`typesseq`.
The documentation for the :mod:`unicodedata` module.
@@ -501,7 +423,9 @@ The documentation for the :mod:`codecs` module.
Marc-André Lemburg gave a presentation at EuroPython 2002 titled "Python and
Unicode". A PDF version of his slides is available at
<http://downloads.egenix.com/python/Unicode-EPC2002-Talk.pdf>, and is an
-excellent overview of the design of Python's Unicode features.
+excellent overview of the design of Python's Unicode features (based on Python
+2, where the Unicode string type is called ``unicode`` and literals start with
+``u``).
Reading and Writing Unicode Data
@@ -519,8 +443,8 @@ columns and can return Unicode values from an SQL query.
Unicode data is usually converted to a particular encoding before it gets
written to disk or sent over a socket. It's possible to do all the work
-yourself: open a file, read an 8-bit string from it, and convert the string with
-``unicode(str, encoding)``. However, the manual approach is not recommended.
+yourself: open a file, read an 8-bit byte string from it, and convert the string
+with ``str(bytes, encoding)``. However, the manual approach is not recommended.
One problem is the multi-byte nature of encodings; one Unicode character can be
represented by several bytes. If you want to read the file in arbitrary-sized
@@ -534,39 +458,27 @@ string and its Unicode version in memory.)
The solution would be to use the low-level decoding interface to catch the case
of partial coding sequences. The work of implementing this has already been
-done for you: the :mod:`codecs` module includes a version of the :func:`open`
-function that returns a file-like object that assumes the file's contents are in
-a specified encoding and accepts Unicode parameters for methods such as
-``.read()`` and ``.write()``.
-
-The function's parameters are ``open(filename, mode='rb', encoding=None,
-errors='strict', buffering=1)``. ``mode`` can be ``'r'``, ``'w'``, or ``'a'``,
-just like the corresponding parameter to the regular built-in ``open()``
-function; add a ``'+'`` to update the file. ``buffering`` is similarly parallel
-to the standard function's parameter. ``encoding`` is a string giving the
-encoding to use; if it's left as ``None``, a regular Python file object that
-accepts 8-bit strings is returned. Otherwise, a wrapper object is returned, and
-data written to or read from the wrapper object will be converted as needed.
-``errors`` specifies the action for encoding errors and can be one of the usual
-values of 'strict', 'ignore', and 'replace'.
+done for you: the built-in :func:`open` function can return a file-like object
+that assumes the file's contents are in a specified encoding and accepts Unicode
+parameters for methods such as ``.read()`` and ``.write()``. This works through
+:func:`open`\'s *encoding* and *errors* parameters which are interpreted just
+like those in string objects' :meth:`encode` and :meth:`decode` methods.
Reading Unicode from a file is therefore simple::
- import codecs
- f = codecs.open('unicode.rst', encoding='utf-8')
- for line in f:
- print repr(line)
+ with open('unicode.rst', encoding='utf-8') as f:
+ for line in f:
+ print(repr(line))
It's also possible to open files in update mode, allowing both reading and
writing::
- f = codecs.open('test', encoding='utf-8', mode='w+')
- f.write(u'\u4500 blah blah blah\n')
- f.seek(0)
- print repr(f.readline()[:1])
- f.close()
+ with open('test', encoding='utf-8', mode='w+') as f:
+ f.write('\u4500 blah blah blah\n')
+ f.seek(0)
+ print(repr(f.readline()[:1]))
-Unicode character U+FEFF is used as a byte-order mark (BOM), and is often
+The Unicode character U+FEFF is used as a byte-order mark (BOM), and is often
written as the first character of a file in order to assist with autodetection
of the file's byte ordering. Some encodings, such as UTF-16, expect a BOM to be
present at the start of a file; when such an encoding is used, the BOM will be
@@ -575,6 +487,12 @@ the file is read. There are variants of these encodings, such as 'utf-16-le'
and 'utf-16-be' for little-endian and big-endian encodings, that specify one
particular byte ordering and don't skip the BOM.
+In some areas, it is also convention to use a "BOM" at the start of UTF-8
+encoded files; the name is misleading since UTF-8 is not byte-order dependent.
+The mark simply announces that the file is encoded in UTF-8. Use the
+'utf-8-sig' codec to automatically skip the mark if present for reading such
+files.
+
Unicode filenames
-----------------
@@ -594,40 +512,43 @@ not much reason to bother. When opening a file for reading or writing, you can
usually just provide the Unicode string as the filename, and it will be
automatically converted to the right encoding for you::
- filename = u'filename\u4500abc'
- f = open(filename, 'w')
- f.write('blah\n')
- f.close()
+ filename = 'filename\u4500abc'
+ with open(filename, 'w') as f:
+ f.write('blah\n')
Functions in the :mod:`os` module such as :func:`os.stat` will also accept Unicode
filenames.
-:func:`os.listdir`, which returns filenames, raises an issue: should it return
-the Unicode version of filenames, or should it return 8-bit strings containing
+Function :func:`os.listdir`, which returns filenames, raises an issue: should it return
+the Unicode version of filenames, or should it return byte strings containing
the encoded versions? :func:`os.listdir` will do both, depending on whether you
-provided the directory path as an 8-bit string or a Unicode string. If you pass
-a Unicode string as the path, filenames will be decoded using the filesystem's
-encoding and a list of Unicode strings will be returned, while passing an 8-bit
-path will return the 8-bit versions of the filenames. For example, assuming the
-default filesystem encoding is UTF-8, running the following program::
-
- fn = u'filename\u4500abc'
+provided the directory path as a byte string or a Unicode string. If you pass a
+Unicode string as the path, filenames will be decoded using the filesystem's
+encoding and a list of Unicode strings will be returned, while passing a byte
+path will return the byte string versions of the filenames. For example,
+assuming the default filesystem encoding is UTF-8, running the following
+program::
+
+ fn = 'filename\u4500abc'
f = open(fn, 'w')
f.close()
import os
- print os.listdir('.')
- print os.listdir(u'.')
+ print(os.listdir(b'.'))
+ print(os.listdir('.'))
will produce the following output::
amk:~$ python t.py
- ['.svn', 'filename\xe4\x94\x80abc', ...]
- [u'.svn', u'filename\u4500abc', ...]
+ [b'.svn', b'filename\xe4\x94\x80abc', ...]
+ ['.svn', 'filename\u4500abc', ...]
The first list contains UTF-8-encoded filenames, and the second list contains
the Unicode versions.
+Note that in most occasions, the Unicode APIs should be used. The bytes APIs
+should only be used on systems where undecodable file names can be present,
+i.e. Unix systems.
Tips for Writing Unicode-aware Programs
@@ -641,46 +562,20 @@ The most important tip is:
Software should only work with Unicode strings internally, converting to a
particular encoding on output.
-If you attempt to write processing functions that accept both Unicode and 8-bit
+If you attempt to write processing functions that accept both Unicode and byte
strings, you will find your program vulnerable to bugs wherever you combine the
-two different kinds of strings. Python's default encoding is ASCII, so whenever
-a character with an ASCII value > 127 is in the input data, you'll get a
-:exc:`UnicodeDecodeError` because that character can't be handled by the ASCII
-encoding.
-
-It's easy to miss such problems if you only test your software with data that
-doesn't contain any accents; everything will seem to work, but there's actually
-a bug in your program waiting for the first user who attempts to use characters
-> 127. A second tip, therefore, is:
-
- Include characters > 127 and, even better, characters > 255 in your test
- data.
+two different kinds of strings. There is no automatic encoding or decoding if
+you do e.g. ``str + bytes``, a :exc:`TypeError` is raised for this expression.
When using data coming from a web browser or some other untrusted source, a
common technique is to check for illegal characters in a string before using the
string in a generated command line or storing it in a database. If you're doing
-this, be careful to check the string once it's in the form that will be used or
-stored; it's possible for encodings to be used to disguise characters. This is
-especially true if the input data also specifies the encoding; many encodings
-leave the commonly checked-for characters alone, but Python includes some
-encodings such as ``'base64'`` that modify every single character.
-
-For example, let's say you have a content management system that takes a Unicode
-filename, and you want to disallow paths with a '/' character. You might write
-this code::
-
- def read_file (filename, encoding):
- if '/' in filename:
- raise ValueError("'/' not allowed in filenames")
- unicode_name = filename.decode(encoding)
- f = open(unicode_name, 'r')
- # ... return contents of file ...
-
-However, if an attacker could specify the ``'base64'`` encoding, they could pass
-``'L2V0Yy9wYXNzd2Q='``, which is the base-64 encoded form of the string
-``'/etc/passwd'``, to read a system file. The above code looks for ``'/'``
-characters in the encoded form and misses the dangerous character in the
-resulting decoded form.
+this, be careful to check the decoded string, not the encoded bytes data;
+some encodings may have interesting properties, such as not being bijective
+or not being fully ASCII-compatible. This is especially true if the input
+data also specifies the encoding, since the attacker can then choose a
+clever way to hide malicious text in the encoded bytestream.
+
References
----------
@@ -689,30 +584,33 @@ The PDF slides for Marc-André Lemburg's presentation "Writing Unicode-aware
Applications in Python" are available at
<http://downloads.egenix.com/python/LSM2005-Developing-Unicode-aware-applications-in-Python.pdf>
and discuss questions of character encodings as well as how to internationalize
-and localize an application.
+and localize an application. These slides cover Python 2.x only.
-Revision History and Acknowledgements
-=====================================
+Acknowledgements
+================
Thanks to the following people who have noted errors or offered suggestions on
this article: Nicholas Bastin, Marius Gedminas, Kent Johnson, Ken Krugler,
Marc-André Lemburg, Martin von Löwis, Chad Whitacre.
-Version 1.0: posted August 5 2005.
+.. comment
+ Revision History
+
+ Version 1.0: posted August 5 2005.
-Version 1.01: posted August 7 2005. Corrects factual and markup errors; adds
-several links.
+ Version 1.01: posted August 7 2005. Corrects factual and markup errors; adds
+ several links.
-Version 1.02: posted August 16 2005. Corrects factual errors.
+ Version 1.02: posted August 16 2005. Corrects factual errors.
-Version 1.03: posted June 20 2010. Notes that Python 3.x is not covered,
-and that the HOWTO only covers 2.x.
+ Version 1.1: Feb-Nov 2008. Updates the document with respect to Python 3 changes.
+ Version 1.11: posted June 20 2010. Notes that Python 3.x is not covered,
+ and that the HOWTO only covers 2.x.
.. comment Describe Python 3.x support (new section? new document?)
.. comment Additional topic: building Python w/ UCS2 or UCS4 support
-.. comment Describe obscure -U switch somewhere?
.. comment Describe use of codecs.StreamRecoder and StreamReaderWriter
.. comment
diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst
index a855308..87f42ba 100644
--- a/Doc/howto/urllib2.rst
+++ b/Doc/howto/urllib2.rst
@@ -1,12 +1,14 @@
-************************************************
- HOWTO Fetch Internet Resources Using urllib2
-************************************************
+.. _urllib-howto:
+
+***********************************************************
+ HOWTO Fetch Internet Resources Using The urllib Package
+***********************************************************
:Author: `Michael Foord <http://www.voidspace.org.uk/python/index.shtml>`_
.. note::
- There is an French translation of an earlier revision of this
+ There is a French translation of an earlier revision of this
HOWTO, available at `urllib2 - Le Manuel manquant
<http://www.voidspace.org.uk/python/articles/urllib2_francais.shtml>`_.
@@ -18,20 +20,20 @@ Introduction
.. sidebar:: Related Articles
You may also find useful the following article on fetching web resources
- with Python :
+ with Python:
* `Basic Authentication <http://www.voidspace.org.uk/python/articles/authentication.shtml>`_
A tutorial on *Basic Authentication*, with examples in Python.
-**urllib2** is a `Python <http://www.python.org>`_ module for fetching URLs
+**urllib.request** is a `Python <http://www.python.org>`_ module for fetching URLs
(Uniform Resource Locators). It offers a very simple interface, in the form of
the *urlopen* function. This is capable of fetching URLs using a variety of
different protocols. It also offers a slightly more complex interface for
handling common situations - like basic authentication, cookies, proxies and so
on. These are provided by objects called handlers and openers.
-urllib2 supports fetching URLs for many "URL schemes" (identified by the string
+urllib.request supports fetching URLs for many "URL schemes" (identified by the string
before the ":" in URL - for example "ftp" is the URL scheme of
"ftp://python.org/") using their associated network protocols (e.g. FTP, HTTP).
This tutorial focuses on the most common case, HTTP.
@@ -40,43 +42,43 @@ For straightforward situations *urlopen* is very easy to use. But as soon as you
encounter errors or non-trivial cases when opening HTTP URLs, you will need some
understanding of the HyperText Transfer Protocol. The most comprehensive and
authoritative reference to HTTP is :rfc:`2616`. This is a technical document and
-not intended to be easy to read. This HOWTO aims to illustrate using *urllib2*,
+not intended to be easy to read. This HOWTO aims to illustrate using *urllib*,
with enough detail about HTTP to help you through. It is not intended to replace
-the :mod:`urllib2` docs, but is supplementary to them.
+the :mod:`urllib.request` docs, but is supplementary to them.
Fetching URLs
=============
-The simplest way to use urllib2 is as follows::
+The simplest way to use urllib.request is as follows::
- import urllib2
- response = urllib2.urlopen('http://python.org/')
+ import urllib.request
+ response = urllib.request.urlopen('http://python.org/')
html = response.read()
-Many uses of urllib2 will be that simple (note that instead of an 'http:' URL we
+Many uses of urllib will be that simple (note that instead of an 'http:' URL we
could have used an URL starting with 'ftp:', 'file:', etc.). However, it's the
purpose of this tutorial to explain the more complicated cases, concentrating on
HTTP.
HTTP is based on requests and responses - the client makes requests and servers
-send responses. urllib2 mirrors this with a ``Request`` object which represents
+send responses. urllib.request mirrors this with a ``Request`` object which represents
the HTTP request you are making. In its simplest form you create a Request
object that specifies the URL you want to fetch. Calling ``urlopen`` with this
Request object returns a response object for the URL requested. This response is
a file-like object, which means you can for example call ``.read()`` on the
response::
- import urllib2
+ import urllib.request
- req = urllib2.Request('http://www.voidspace.org.uk')
- response = urllib2.urlopen(req)
+ req = urllib.request.Request('http://www.voidspace.org.uk')
+ response = urllib.request.urlopen(req)
the_page = response.read()
-Note that urllib2 makes use of the same Request interface to handle all URL
+Note that urllib.request makes use of the same Request interface to handle all URL
schemes. For example, you can make an FTP request like so::
- req = urllib2.Request('ftp://example.com/')
+ req = urllib.request.Request('ftp://example.com/')
In the case of HTTP, there are two extra things that Request objects allow you
to do: First, you can pass data to be sent to the server. Second, you can pass
@@ -94,20 +96,21 @@ your browser does when you submit a HTML form that you filled in on the web. Not
all POSTs have to come from forms: you can use a POST to transmit arbitrary data
to your own application. In the common case of HTML forms, the data needs to be
encoded in a standard way, and then passed to the Request object as the ``data``
-argument. The encoding is done using a function from the ``urllib`` library
-*not* from ``urllib2``. ::
+argument. The encoding is done using a function from the :mod:`urllib.parse`
+library. ::
- import urllib
- import urllib2
+ import urllib.parse
+ import urllib.request
url = 'http://www.someserver.com/cgi-bin/register.cgi'
values = {'name' : 'Michael Foord',
'location' : 'Northampton',
'language' : 'Python' }
- data = urllib.urlencode(values)
- req = urllib2.Request(url, data)
- response = urllib2.urlopen(req)
+ data = urllib.parse.urlencode(values)
+ data = data.encode('utf-8') # data should be bytes
+ req = urllib.request.Request(url, data)
+ response = urllib.request.urlopen(req)
the_page = response.read()
Note that other encodings are sometimes required (e.g. for file upload from HTML
@@ -115,7 +118,7 @@ forms - see `HTML Specification, Form Submission
<http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13>`_ for more
details).
-If you do not pass the ``data`` argument, urllib2 uses a **GET** request. One
+If you do not pass the ``data`` argument, urllib uses a **GET** request. One
way in which GET and POST requests differ is that POST requests often have
"side-effects": they change the state of the system in some way (for example by
placing an order with the website for a hundredweight of tinned spam to be
@@ -127,18 +130,18 @@ GET request by encoding it in the URL itself.
This is done as follows::
- >>> import urllib2
- >>> import urllib
+ >>> import urllib.request
+ >>> import urllib.parse
>>> data = {}
>>> data['name'] = 'Somebody Here'
>>> data['location'] = 'Northampton'
>>> data['language'] = 'Python'
- >>> url_values = urllib.urlencode(data)
- >>> print url_values # The order may differ. #doctest: +SKIP
+ >>> url_values = urllib.parse.urlencode(data)
+ >>> print(url_values) # The order may differ from below. #doctest: +SKIP
name=Somebody+Here&language=Python&location=Northampton
>>> url = 'http://www.example.com/example.cgi'
>>> full_url = url + '?' + url_values
- >>> data = urllib2.urlopen(full_url)
+ >>> data = urllib.request.urlopen(full_url)
Notice that the full URL is created by adding a ``?`` to the URL, followed by
the encoded values.
@@ -150,7 +153,7 @@ We'll discuss here one particular HTTP header, to illustrate how to add headers
to your HTTP request.
Some websites [#]_ dislike being browsed by programs, or send different versions
-to different browsers [#]_ . By default urllib2 identifies itself as
+to different browsers [#]_ . By default urllib identifies itself as
``Python-urllib/x.y`` (where ``x`` and ``y`` are the major and minor version
numbers of the Python release,
e.g. ``Python-urllib/2.5``), which may confuse the site, or just plain
@@ -160,8 +163,8 @@ pass a dictionary of headers in. The following example makes the same
request as above, but identifies itself as a version of Internet
Explorer [#]_. ::
- import urllib
- import urllib2
+ import urllib.parse
+ import urllib.request
url = 'http://www.someserver.com/cgi-bin/register.cgi'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
@@ -170,9 +173,10 @@ Explorer [#]_. ::
'language' : 'Python' }
headers = { 'User-Agent' : user_agent }
- data = urllib.urlencode(values)
- req = urllib2.Request(url, data, headers)
- response = urllib2.urlopen(req)
+ data = urllib.parse.urlencode(values)
+ data = data.encode('utf-8')
+ req = urllib.request.Request(url, data, headers)
+ response = urllib.request.urlopen(req)
the_page = response.read()
The response also has two useful methods. See the section on `info and geturl`_
@@ -189,6 +193,8 @@ usual with Python APIs, built-in exceptions such as :exc:`ValueError`,
:exc:`HTTPError` is the subclass of :exc:`URLError` raised in the specific case of
HTTP URLs.
+The exception classes are exported from the :mod:`urllib.error` module.
+
URLError
--------
@@ -199,10 +205,10 @@ error code and a text error message.
e.g. ::
- >>> req = urllib2.Request('http://www.pretend_server.org')
- >>> try: urllib2.urlopen(req)
- ... except URLError as e:
- ... print e.reason #doctest: +SKIP
+ >>> req = urllib.request.Request('http://www.pretend_server.org')
+ >>> try: urllib.request.urlopen(req)
+ ... except urllib.error.URLError as e:
+ ... print(e.reason) #doctest: +SKIP
...
(4, 'getaddrinfo failed')
@@ -214,7 +220,7 @@ Every HTTP response from the server contains a numeric "status code". Sometimes
the status code indicates that the server is unable to fulfil the request. The
default handlers will handle some of these responses for you (for example, if
the response is a "redirection" that requests the client fetch the document from
-a different URL, urllib2 will handle that for you). For those it can't handle,
+a different URL, urllib will handle that for you). For those it can't handle,
urlopen will raise an :exc:`HTTPError`. Typical errors include '404' (page not
found), '403' (request forbidden), and '401' (authentication required).
@@ -230,7 +236,7 @@ Because the default handlers handle redirects (codes in the 300 range), and
codes in the 100-299 range indicate success, you will usually only see error
codes in the 400-599 range.
-``BaseHTTPServer.BaseHTTPRequestHandler.responses`` is a useful dictionary of
+:attr:`http.server.BaseHTTPRequestHandler.responses` is a useful dictionary of
response codes in that shows all the response codes used by RFC 2616. The
dictionary is reproduced here for convenience ::
@@ -305,22 +311,21 @@ dictionary is reproduced here for convenience ::
When an error is raised the server responds by returning an HTTP error code
*and* an error page. You can use the :exc:`HTTPError` instance as a response on the
page returned. This means that as well as the code attribute, it also has read,
-geturl, and info, methods. ::
+geturl, and info, methods as returned by the ``urllib.response`` module::
- >>> req = urllib2.Request('http://www.python.org/fish.html')
+ >>> req = urllib.request.Request('http://www.python.org/fish.html')
>>> try:
- ... urllib2.urlopen(req)
- ... except urllib2.HTTPError as e:
- ... print e.code
- ... print e.read() #doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
+ ... urllib.request.urlopen(req)
+ ... except urllib.error.HTTPError as e:
+ ... print(e.code)
+ ... print(e.read()) #doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
...
404
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- ...
- <title>Page Not Found</title>
- ...
-
+ b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n\n<html
+ ...
+ <title>Page Not Found</title>\n
+ ...
Wrapping it Up
--------------
@@ -334,16 +339,17 @@ Number 1
::
- from urllib2 import Request, urlopen, URLError, HTTPError
+ from urllib.request import Request, urlopen
+ from urllib.error import URLError, HTTPError
req = Request(someurl)
try:
response = urlopen(req)
except HTTPError as e:
- print 'The server couldn\'t fulfill the request.'
- print 'Error code: ', e.code
+ print('The server couldn\'t fulfill the request.')
+ print('Error code: ', e.code)
except URLError as e:
- print 'We failed to reach a server.'
- print 'Reason: ', e.reason
+ print('We failed to reach a server.')
+ print('Reason: ', e.reason)
else:
# everything is fine
@@ -358,17 +364,18 @@ Number 2
::
- from urllib2 import Request, urlopen, URLError
+ from urllib.request import Request, urlopen
+ from urllib.error import URLError
req = Request(someurl)
try:
response = urlopen(req)
except URLError as e:
if hasattr(e, 'reason'):
- print 'We failed to reach a server.'
- print 'Reason: ', e.reason
+ print('We failed to reach a server.')
+ print('Reason: ', e.reason)
elif hasattr(e, 'code'):
- print 'The server couldn\'t fulfill the request.'
- print 'Error code: ', e.code
+ print('The server couldn\'t fulfill the request.')
+ print('Error code: ', e.code)
else:
# everything is fine
@@ -376,8 +383,9 @@ Number 2
info and geturl
===============
-The response returned by urlopen (or the :exc:`HTTPError` instance) has two useful
-methods :meth:`info` and :meth:`geturl`.
+The response returned by urlopen (or the :exc:`HTTPError` instance) has two
+useful methods :meth:`info` and :meth:`geturl` and is defined in the module
+:mod:`urllib.response`..
**geturl** - this returns the real URL of the page fetched. This is useful
because ``urlopen`` (or the opener object used) may have followed a
@@ -385,7 +393,7 @@ redirect. The URL of the page fetched may not be the same as the URL requested.
**info** - this returns a dictionary-like object that describes the page
fetched, particularly the headers sent by the server. It is currently an
-``httplib.HTTPMessage`` instance.
+:class:`http.client.HTTPMessage` instance.
Typical headers include 'Content-length', 'Content-type', and so on. See the
`Quick Reference to HTTP Headers <http://www.cs.tut.fi/~jkorpela/http.html>`_
@@ -397,7 +405,7 @@ Openers and Handlers
====================
When you fetch a URL you use an opener (an instance of the perhaps
-confusingly-named :class:`urllib2.OpenerDirector`). Normally we have been using
+confusingly-named :class:`urllib.request.OpenerDirector`). Normally we have been using
the default opener - via ``urlopen`` - but you can create custom
openers. Openers use handlers. All the "heavy lifting" is done by the
handlers. Each handler knows how to open URLs for a particular URL scheme (http,
@@ -466,24 +474,24 @@ The top-level URL is the first URL that requires authentication. URLs "deeper"
than the URL you pass to .add_password() will also match. ::
# create a password manager
- password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
+ password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
# Add the username and password.
# If we knew the realm, we could use it instead of None.
top_level_url = "http://example.com/foo/"
password_mgr.add_password(None, top_level_url, username, password)
- handler = urllib2.HTTPBasicAuthHandler(password_mgr)
+ handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
# create "opener" (OpenerDirector instance)
- opener = urllib2.build_opener(handler)
+ opener = urllib.request.build_opener(handler)
# use the opener to fetch a URL
opener.open(a_url)
# Install the opener.
- # Now all calls to urllib2.urlopen use our opener.
- urllib2.install_opener(opener)
+ # Now all calls to urllib.request.urlopen use our opener.
+ urllib.request.install_opener(opener)
.. note::
@@ -505,46 +513,46 @@ not correct.
Proxies
=======
-**urllib2** will auto-detect your proxy settings and use those. This is through
+**urllib** will auto-detect your proxy settings and use those. This is through
the ``ProxyHandler`` which is part of the normal handler chain. Normally that's
a good thing, but there are occasions when it may not be helpful [#]_. One way
to do this is to setup our own ``ProxyHandler``, with no proxies defined. This
is done using similar steps to setting up a `Basic Authentication`_ handler : ::
- >>> proxy_support = urllib2.ProxyHandler({})
- >>> opener = urllib2.build_opener(proxy_support)
- >>> urllib2.install_opener(opener)
+ >>> proxy_support = urllib.request.ProxyHandler({})
+ >>> opener = urllib.request.build_opener(proxy_support)
+ >>> urllib.request.install_opener(opener)
.. note::
- Currently ``urllib2`` *does not* support fetching of ``https`` locations
- through a proxy. However, this can be enabled by extending urllib2 as
+ Currently ``urllib.request`` *does not* support fetching of ``https`` locations
+ through a proxy. However, this can be enabled by extending urllib.request as
shown in the recipe [#]_.
Sockets and Layers
==================
-The Python support for fetching resources from the web is layered. urllib2 uses
-the httplib library, which in turn uses the socket library.
+The Python support for fetching resources from the web is layered. urllib uses
+the :mod:`http.client` library, which in turn uses the socket library.
As of Python 2.3 you can specify how long a socket should wait for a response
before timing out. This can be useful in applications which have to fetch web
pages. By default the socket module has *no timeout* and can hang. Currently,
-the socket timeout is not exposed at the httplib or urllib2 levels. However,
-you can set the default timeout globally for all sockets using ::
+the socket timeout is not exposed at the http.client or urllib.request levels.
+However, you can set the default timeout globally for all sockets using ::
import socket
- import urllib2
+ import urllib.request
# timeout in seconds
timeout = 10
socket.setdefaulttimeout(timeout)
- # this call to urllib2.urlopen now uses the default timeout
+ # this call to urllib.request.urlopen now uses the default timeout
# we have set in the socket module
- req = urllib2.Request('http://www.voidspace.org.uk')
- response = urllib2.urlopen(req)
+ req = urllib.request.Request('http://www.voidspace.org.uk')
+ response = urllib.request.urlopen(req)
-------
@@ -570,9 +578,9 @@ This document was reviewed and revised by John Lee.
`Quick Reference to HTTP Headers`_.
.. [#] In my case I have to use a proxy to access the internet at work. If you
attempt to fetch *localhost* URLs through this proxy it blocks them. IE
- is set to use the proxy, which urllib2 picks up on. In order to test
- scripts with a localhost server, I have to prevent urllib2 from using
+ is set to use the proxy, which urllib picks up on. In order to test
+ scripts with a localhost server, I have to prevent urllib from using
the proxy.
-.. [#] urllib2 opener for SSL proxy (CONNECT method): `ASPN Cookbook Recipe
+.. [#] urllib opener for SSL proxy (CONNECT method): `ASPN Cookbook Recipe
<http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/456195>`_.
diff --git a/Doc/howto/webservers.rst b/Doc/howto/webservers.rst
index fbc9fd9..72ccd1f 100644
--- a/Doc/howto/webservers.rst
+++ b/Doc/howto/webservers.rst
@@ -103,10 +103,10 @@ simple CGI program::
import cgitb
cgitb.enable()
- print "Content-Type: text/plain;charset=utf-8"
- print
+ print("Content-Type: text/plain;charset=utf-8")
+ print()
- print "Hello World!"
+ print("Hello World!")
Depending on your web server configuration, you may need to save this code with
a ``.py`` or ``.cgi`` extension. Additionally, this file may also need to be
@@ -292,8 +292,8 @@ following WSGI-application::
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
- from cgi import escape
import sys, os
+ from html import escape
from flup.server.fcgi import WSGIServer
def app(environ, start_response):
@@ -302,7 +302,8 @@ following WSGI-application::
yield '<h1>FastCGI Environment</h1>'
yield '<table>'
for k, v in sorted(environ.items()):
- yield '<tr><th>%s</th><td>%s</td></tr>' % (escape(k), escape(v))
+ yield '<tr><th>{0}</th><td>{1}</td></tr>'.format(
+ escape(k), escape(v))
yield '</table>'
WSGIServer(app).run()
@@ -497,16 +498,11 @@ templates exist. Templates are, in the simplest case, just HTML files with
placeholders. The HTML is sent to the user's browser after filling in the
placeholders.
-Python already includes two ways to build simple templates::
+Python already includes a way to build simple templates::
- >>> template = "<html><body><h1>Hello %s!</h1></body></html>"
- >>> print template % "Reader"
- <html><body><h1>Hello Reader!</h1></body></html>
-
- >>> from string import Template
- >>> template = Template("<html><body><h1>Hello ${name}</h1></body></html>")
- >>> print template.substitute(dict(name='Dinsdale'))
- <html><body><h1>Hello Dinsdale!</h1></body></html>
+ # a simple template
+ template = "<html><body><h1>Hello {who}!</h1></body></html>"
+ print(template.format(who="Reader"))
To generate complex HTML based on non-trivial model data, conditional
and looping constructs like Python's *for* and *if* are generally needed.
diff --git a/Doc/includes/dbpickle.py b/Doc/includes/dbpickle.py
new file mode 100644
index 0000000..b88ee87
--- /dev/null
+++ b/Doc/includes/dbpickle.py
@@ -0,0 +1,87 @@
+# Simple example presenting how persistent ID can be used to pickle
+# external objects by reference.
+
+import pickle
+import sqlite3
+from collections import namedtuple
+
+# Simple class representing a record in our database.
+MemoRecord = namedtuple("MemoRecord", "key, task")
+
+class DBPickler(pickle.Pickler):
+
+ def persistent_id(self, obj):
+ # Instead of pickling MemoRecord as a regular class instance, we emit a
+ # persistent ID.
+ if isinstance(obj, MemoRecord):
+ # Here, our persistent ID is simply a tuple, containing a tag and a
+ # key, which refers to a specific record in the database.
+ return ("MemoRecord", obj.key)
+ else:
+ # If obj does not have a persistent ID, return None. This means obj
+ # needs to be pickled as usual.
+ return None
+
+
+class DBUnpickler(pickle.Unpickler):
+
+ def __init__(self, file, connection):
+ super().__init__(file)
+ self.connection = connection
+
+ def persistent_load(self, pid):
+ # This method is invoked whenever a persistent ID is encountered.
+ # Here, pid is the tuple returned by DBPickler.
+ cursor = self.connection.cursor()
+ type_tag, key_id = pid
+ if type_tag == "MemoRecord":
+ # Fetch the referenced record from the database and return it.
+ cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
+ key, task = cursor.fetchone()
+ return MemoRecord(key, task)
+ else:
+ # Always raises an error if you cannot return the correct object.
+ # Otherwise, the unpickler will think None is the object referenced
+ # by the persistent ID.
+ raise pickle.UnpicklingError("unsupported persistent object")
+
+
+def main():
+ import io
+ import pprint
+
+ # Initialize and populate our database.
+ conn = sqlite3.connect(":memory:")
+ cursor = conn.cursor()
+ cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
+ tasks = (
+ 'give food to fish',
+ 'prepare group meeting',
+ 'fight with a zebra',
+ )
+ for task in tasks:
+ cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))
+
+ # Fetch the records to be pickled.
+ cursor.execute("SELECT * FROM memos")
+ memos = [MemoRecord(key, task) for key, task in cursor]
+ # Save the records using our custom DBPickler.
+ file = io.BytesIO()
+ DBPickler(file).dump(memos)
+
+ print("Pickled records:")
+ pprint.pprint(memos)
+
+ # Update a record, just for good measure.
+ cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")
+
+ # Load the records from the pickle data stream.
+ file.seek(0)
+ memos = DBUnpickler(file, conn).load()
+
+ print("Unpickled records:")
+ pprint.pprint(memos)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/Doc/includes/email-alternative.py b/Doc/includes/email-alternative.py
index 82d605e..33c430a 100644
--- a/Doc/includes/email-alternative.py
+++ b/Doc/includes/email-alternative.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
import smtplib
diff --git a/Doc/includes/email-dir.py b/Doc/includes/email-dir.py
index 035442b..cc5529e 100644
--- a/Doc/includes/email-dir.py
+++ b/Doc/includes/email-dir.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
"""Send the contents of a directory as a MIME message."""
diff --git a/Doc/includes/email-headers.py b/Doc/includes/email-headers.py
index 664c3ff..a53317d 100644
--- a/Doc/includes/email-headers.py
+++ b/Doc/includes/email-headers.py
@@ -12,6 +12,6 @@ headers = Parser().parsestr('From: <user@example.com>\n'
'Body would go here\n')
# Now the header items can be accessed as a dictionary:
-print 'To: %s' % headers['to']
-print 'From: %s' % headers['from']
-print 'Subject: %s' % headers['subject']
+print('To: %s' % headers['to'])
+print('From: %s' % headers['from'])
+print('Subject: %s' % headers['subject'])
diff --git a/Doc/includes/email-mime.py b/Doc/includes/email-mime.py
index 7b1c028..a90edc1 100644
--- a/Doc/includes/email-mime.py
+++ b/Doc/includes/email-mime.py
@@ -27,5 +27,5 @@ for file in pngfiles:
# Send the email via our own SMTP server.
s = smtplib.SMTP('localhost')
-s.sendmail(me, family, msg.as_string())
+s.send_message(msg)
s.quit()
diff --git a/Doc/includes/email-simple.py b/Doc/includes/email-simple.py
index 29bd078..077568d 100644
--- a/Doc/includes/email-simple.py
+++ b/Doc/includes/email-simple.py
@@ -17,8 +17,7 @@ msg['Subject'] = 'The contents of %s' % textfile
msg['From'] = me
msg['To'] = you
-# Send the message via our own SMTP server, but don't include the
-# envelope header.
+# Send the message via our own SMTP server.
s = smtplib.SMTP('localhost')
-s.sendmail(me, [you], msg.as_string())
+s.send_message(msg)
s.quit()
diff --git a/Doc/includes/email-unpack.py b/Doc/includes/email-unpack.py
index a8f712d..3653543 100644
--- a/Doc/includes/email-unpack.py
+++ b/Doc/includes/email-unpack.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
"""Unpack a MIME message into a directory of files."""
diff --git a/Doc/includes/minidom-example.py b/Doc/includes/minidom-example.py
index 4bca949..5ee7682 100644
--- a/Doc/includes/minidom-example.py
+++ b/Doc/includes/minidom-example.py
@@ -26,12 +26,12 @@ def getText(nodelist):
return ''.join(rc)
def handleSlideshow(slideshow):
- print "<html>"
+ print("<html>")
handleSlideshowTitle(slideshow.getElementsByTagName("title")[0])
slides = slideshow.getElementsByTagName("slide")
handleToc(slides)
handleSlides(slides)
- print "</html>"
+ print("</html>")
def handleSlides(slides):
for slide in slides:
@@ -42,23 +42,23 @@ def handleSlide(slide):
handlePoints(slide.getElementsByTagName("point"))
def handleSlideshowTitle(title):
- print "<title>%s</title>" % getText(title.childNodes)
+ print("<title>%s</title>" % getText(title.childNodes))
def handleSlideTitle(title):
- print "<h2>%s</h2>" % getText(title.childNodes)
+ print("<h2>%s</h2>" % getText(title.childNodes))
def handlePoints(points):
- print "<ul>"
+ print("<ul>")
for point in points:
handlePoint(point)
- print "</ul>"
+ print("</ul>")
def handlePoint(point):
- print "<li>%s</li>" % getText(point.childNodes)
+ print("<li>%s</li>" % getText(point.childNodes))
def handleToc(slides):
for slide in slides:
title = slide.getElementsByTagName("title")[0]
- print "<p>%s</p>" % getText(title.childNodes)
+ print("<p>%s</p>" % getText(title.childNodes))
handleSlideshow(dom)
diff --git a/Doc/includes/mp_benchmarks.py b/Doc/includes/mp_benchmarks.py
index 16be77e..acdf642 100644
--- a/Doc/includes/mp_benchmarks.py
+++ b/Doc/includes/mp_benchmarks.py
@@ -5,7 +5,12 @@
# All rights reserved.
#
-import time, sys, multiprocessing, threading, Queue, gc
+import time
+import sys
+import multiprocessing
+import threading
+import queue
+import gc
if sys.platform == 'win32':
_timer = time.clock
@@ -23,7 +28,7 @@ def queuespeed_func(q, c, iterations):
c.notify()
c.release()
- for i in xrange(iterations):
+ for i in range(iterations):
q.put(a)
q.put('STOP')
@@ -51,8 +56,8 @@ def test_queuespeed(Process, q, c):
p.join()
- print iterations, 'objects passed through the queue in', elapsed, 'seconds'
- print 'average number/sec:', iterations/elapsed
+ print(iterations, 'objects passed through the queue in', elapsed, 'seconds')
+ print('average number/sec:', iterations/elapsed)
#### TEST_PIPESPEED
@@ -63,7 +68,7 @@ def pipe_func(c, cond, iterations):
cond.notify()
cond.release()
- for i in xrange(iterations):
+ for i in range(iterations):
c.send(a)
c.send('STOP')
@@ -93,8 +98,8 @@ def test_pipespeed():
elapsed = _timer() - t
p.join()
- print iterations, 'objects passed through connection in',elapsed,'seconds'
- print 'average number/sec:', iterations/elapsed
+ print(iterations, 'objects passed through connection in',elapsed,'seconds')
+ print('average number/sec:', iterations/elapsed)
#### TEST_SEQSPEED
@@ -108,13 +113,13 @@ def test_seqspeed(seq):
t = _timer()
- for i in xrange(iterations):
+ for i in range(iterations):
a = seq[5]
- elapsed = _timer()-t
+ elapsed = _timer() - t
- print iterations, 'iterations in', elapsed, 'seconds'
- print 'average number/sec:', iterations/elapsed
+ print(iterations, 'iterations in', elapsed, 'seconds')
+ print('average number/sec:', iterations/elapsed)
#### TEST_LOCK
@@ -128,14 +133,14 @@ def test_lockspeed(l):
t = _timer()
- for i in xrange(iterations):
+ for i in range(iterations):
l.acquire()
l.release()
- elapsed = _timer()-t
+ elapsed = _timer() - t
- print iterations, 'iterations in', elapsed, 'seconds'
- print 'average number/sec:', iterations/elapsed
+ print(iterations, 'iterations in', elapsed, 'seconds')
+ print('average number/sec:', iterations/elapsed)
#### TEST_CONDITION
@@ -144,7 +149,7 @@ def conditionspeed_func(c, N):
c.acquire()
c.notify()
- for i in xrange(N):
+ for i in range(N):
c.wait()
c.notify()
@@ -165,17 +170,17 @@ def test_conditionspeed(Process, c):
t = _timer()
- for i in xrange(iterations):
+ for i in range(iterations):
c.notify()
c.wait()
- elapsed = _timer()-t
+ elapsed = _timer() - t
c.release()
p.join()
- print iterations * 2, 'waits in', elapsed, 'seconds'
- print 'average number/sec:', iterations * 2 / elapsed
+ print(iterations * 2, 'waits in', elapsed, 'seconds')
+ print('average number/sec:', iterations * 2 / elapsed)
####
@@ -184,51 +189,51 @@ def test():
gc.disable()
- print '\n\t######## testing Queue.Queue\n'
- test_queuespeed(threading.Thread, Queue.Queue(),
+ print('\n\t######## testing Queue.Queue\n')
+ test_queuespeed(threading.Thread, queue.Queue(),
threading.Condition())
- print '\n\t######## testing multiprocessing.Queue\n'
+ print('\n\t######## testing multiprocessing.Queue\n')
test_queuespeed(multiprocessing.Process, multiprocessing.Queue(),
multiprocessing.Condition())
- print '\n\t######## testing Queue managed by server process\n'
+ print('\n\t######## testing Queue managed by server process\n')
test_queuespeed(multiprocessing.Process, manager.Queue(),
manager.Condition())
- print '\n\t######## testing multiprocessing.Pipe\n'
+ print('\n\t######## testing multiprocessing.Pipe\n')
test_pipespeed()
- print
+ print()
- print '\n\t######## testing list\n'
- test_seqspeed(range(10))
- print '\n\t######## testing list managed by server process\n'
- test_seqspeed(manager.list(range(10)))
- print '\n\t######## testing Array("i", ..., lock=False)\n'
- test_seqspeed(multiprocessing.Array('i', range(10), lock=False))
- print '\n\t######## testing Array("i", ..., lock=True)\n'
- test_seqspeed(multiprocessing.Array('i', range(10), lock=True))
+ print('\n\t######## testing list\n')
+ test_seqspeed(list(range(10)))
+ print('\n\t######## testing list managed by server process\n')
+ test_seqspeed(manager.list(list(range(10))))
+ print('\n\t######## testing Array("i", ..., lock=False)\n')
+ test_seqspeed(multiprocessing.Array('i', list(range(10)), lock=False))
+ print('\n\t######## testing Array("i", ..., lock=True)\n')
+ test_seqspeed(multiprocessing.Array('i', list(range(10)), lock=True))
- print
+ print()
- print '\n\t######## testing threading.Lock\n'
+ print('\n\t######## testing threading.Lock\n')
test_lockspeed(threading.Lock())
- print '\n\t######## testing threading.RLock\n'
+ print('\n\t######## testing threading.RLock\n')
test_lockspeed(threading.RLock())
- print '\n\t######## testing multiprocessing.Lock\n'
+ print('\n\t######## testing multiprocessing.Lock\n')
test_lockspeed(multiprocessing.Lock())
- print '\n\t######## testing multiprocessing.RLock\n'
+ print('\n\t######## testing multiprocessing.RLock\n')
test_lockspeed(multiprocessing.RLock())
- print '\n\t######## testing lock managed by server process\n'
+ print('\n\t######## testing lock managed by server process\n')
test_lockspeed(manager.Lock())
- print '\n\t######## testing rlock managed by server process\n'
+ print('\n\t######## testing rlock managed by server process\n')
test_lockspeed(manager.RLock())
- print
+ print()
- print '\n\t######## testing threading.Condition\n'
+ print('\n\t######## testing threading.Condition\n')
test_conditionspeed(threading.Thread, threading.Condition())
- print '\n\t######## testing multiprocessing.Condition\n'
+ print('\n\t######## testing multiprocessing.Condition\n')
test_conditionspeed(multiprocessing.Process, multiprocessing.Condition())
- print '\n\t######## testing condition managed by a server process\n'
+ print('\n\t######## testing condition managed by a server process\n')
test_conditionspeed(multiprocessing.Process, manager.Condition())
gc.enable()
diff --git a/Doc/includes/mp_newtype.py b/Doc/includes/mp_newtype.py
index 1858696..7291743 100644
--- a/Doc/includes/mp_newtype.py
+++ b/Doc/includes/mp_newtype.py
@@ -12,17 +12,17 @@ import operator
##
-class Foo(object):
+class Foo:
def f(self):
- print 'you called Foo.f()'
+ print('you called Foo.f()')
def g(self):
- print 'you called Foo.g()'
+ print('you called Foo.g()')
def _h(self):
- print 'you called Foo._h()'
+ print('you called Foo._h()')
# A simple generator function
def baz():
- for i in xrange(10):
+ for i in range(10):
yield i*i
# Proxy type for generator objects
@@ -30,7 +30,7 @@ class GeneratorProxy(BaseProxy):
_exposed_ = ('next', '__next__')
def __iter__(self):
return self
- def next(self):
+ def __next__(self):
return self._callmethod('next')
def __next__(self):
return self._callmethod('__next__')
@@ -62,7 +62,7 @@ def test():
manager = MyManager()
manager.start()
- print '-' * 20
+ print('-' * 20)
f1 = manager.Foo1()
f1.f()
@@ -70,7 +70,7 @@ def test():
assert not hasattr(f1, '_h')
assert sorted(f1._exposed_) == sorted(['f', 'g'])
- print '-' * 20
+ print('-' * 20)
f2 = manager.Foo2()
f2.g()
@@ -78,21 +78,21 @@ def test():
assert not hasattr(f2, 'f')
assert sorted(f2._exposed_) == sorted(['g', '_h'])
- print '-' * 20
+ print('-' * 20)
it = manager.baz()
for i in it:
- print '<%d>' % i,
- print
+ print('<%d>' % i, end=' ')
+ print()
- print '-' * 20
+ print('-' * 20)
op = manager.operator()
- print 'op.add(23, 45) =', op.add(23, 45)
- print 'op.pow(2, 94) =', op.pow(2, 94)
- print 'op.getslice(range(10), 2, 6) =', op.getslice(range(10), 2, 6)
- print 'op.repeat(range(5), 3) =', op.repeat(range(5), 3)
- print 'op._exposed_ =', op._exposed_
+ print('op.add(23, 45) =', op.add(23, 45))
+ print('op.pow(2, 94) =', op.pow(2, 94))
+ print('op.getslice(range(10), 2, 6) =', op.getslice(list(range(10)), 2, 6))
+ print('op.repeat(range(5), 3) =', op.repeat(list(range(5)), 3))
+ print('op._exposed_ =', op._exposed_)
##
diff --git a/Doc/includes/mp_pool.py b/Doc/includes/mp_pool.py
index 0a3d92a..1578498 100644
--- a/Doc/includes/mp_pool.py
+++ b/Doc/includes/mp_pool.py
@@ -25,18 +25,18 @@ def calculatestar(args):
return calculate(*args)
def mul(a, b):
- time.sleep(0.5*random.random())
+ time.sleep(0.5 * random.random())
return a * b
def plus(a, b):
- time.sleep(0.5*random.random())
+ time.sleep(0.5 * random.random())
return a + b
def f(x):
- return 1.0 / (x-5.0)
+ return 1.0 / (x - 5.0)
def pow3(x):
- return x**3
+ return x ** 3
def noop(x):
pass
@@ -46,17 +46,17 @@ def noop(x):
#
def test():
- print 'cpu_count() = %d\n' % multiprocessing.cpu_count()
+ print('cpu_count() = %d\n' % multiprocessing.cpu_count())
#
# Create pool
#
PROCESSES = 4
- print 'Creating pool with %d processes\n' % PROCESSES
+ print('Creating pool with %d processes\n' % PROCESSES)
pool = multiprocessing.Pool(PROCESSES)
- print 'pool = %s' % pool
- print
+ print('pool = %s' % pool)
+ print()
#
# Tests
@@ -69,72 +69,72 @@ def test():
imap_it = pool.imap(calculatestar, TASKS)
imap_unordered_it = pool.imap_unordered(calculatestar, TASKS)
- print 'Ordered results using pool.apply_async():'
+ print('Ordered results using pool.apply_async():')
for r in results:
- print '\t', r.get()
- print
+ print('\t', r.get())
+ print()
- print 'Ordered results using pool.imap():'
+ print('Ordered results using pool.imap():')
for x in imap_it:
- print '\t', x
- print
+ print('\t', x)
+ print()
- print 'Unordered results using pool.imap_unordered():'
+ print('Unordered results using pool.imap_unordered():')
for x in imap_unordered_it:
- print '\t', x
- print
+ print('\t', x)
+ print()
- print 'Ordered results using pool.map() --- will block till complete:'
+ print('Ordered results using pool.map() --- will block till complete:')
for x in pool.map(calculatestar, TASKS):
- print '\t', x
- print
+ print('\t', x)
+ print()
#
# Simple benchmarks
#
N = 100000
- print 'def pow3(x): return x**3'
+ print('def pow3(x): return x**3')
t = time.time()
- A = map(pow3, xrange(N))
- print '\tmap(pow3, xrange(%d)):\n\t\t%s seconds' % \
- (N, time.time() - t)
+ A = list(map(pow3, range(N)))
+ print('\tmap(pow3, range(%d)):\n\t\t%s seconds' % \
+ (N, time.time() - t))
t = time.time()
- B = pool.map(pow3, xrange(N))
- print '\tpool.map(pow3, xrange(%d)):\n\t\t%s seconds' % \
- (N, time.time() - t)
+ B = pool.map(pow3, range(N))
+ print('\tpool.map(pow3, range(%d)):\n\t\t%s seconds' % \
+ (N, time.time() - t))
t = time.time()
- C = list(pool.imap(pow3, xrange(N), chunksize=N//8))
- print '\tlist(pool.imap(pow3, xrange(%d), chunksize=%d)):\n\t\t%s' \
- ' seconds' % (N, N//8, time.time() - t)
+ C = list(pool.imap(pow3, range(N), chunksize=N//8))
+ print('\tlist(pool.imap(pow3, range(%d), chunksize=%d)):\n\t\t%s' \
+ ' seconds' % (N, N//8, time.time() - t))
assert A == B == C, (len(A), len(B), len(C))
- print
+ print()
L = [None] * 1000000
- print 'def noop(x): pass'
- print 'L = [None] * 1000000'
+ print('def noop(x): pass')
+ print('L = [None] * 1000000')
t = time.time()
- A = map(noop, L)
- print '\tmap(noop, L):\n\t\t%s seconds' % \
- (time.time() - t)
+ A = list(map(noop, L))
+ print('\tmap(noop, L):\n\t\t%s seconds' % \
+ (time.time() - t))
t = time.time()
B = pool.map(noop, L)
- print '\tpool.map(noop, L):\n\t\t%s seconds' % \
- (time.time() - t)
+ print('\tpool.map(noop, L):\n\t\t%s seconds' % \
+ (time.time() - t))
t = time.time()
C = list(pool.imap(noop, L, chunksize=len(L)//8))
- print '\tlist(pool.imap(noop, L, chunksize=%d)):\n\t\t%s seconds' % \
- (len(L)//8, time.time() - t)
+ print('\tlist(pool.imap(noop, L, chunksize=%d)):\n\t\t%s seconds' % \
+ (len(L)//8, time.time() - t))
assert A == B == C, (len(A), len(B), len(C))
- print
+ print()
del A, B, C, L
@@ -142,33 +142,33 @@ def test():
# Test error handling
#
- print 'Testing error handling:'
+ print('Testing error handling:')
try:
- print pool.apply(f, (5,))
+ print(pool.apply(f, (5,)))
except ZeroDivisionError:
- print '\tGot ZeroDivisionError as expected from pool.apply()'
+ print('\tGot ZeroDivisionError as expected from pool.apply()')
else:
raise AssertionError('expected ZeroDivisionError')
try:
- print pool.map(f, range(10))
+ print(pool.map(f, list(range(10))))
except ZeroDivisionError:
- print '\tGot ZeroDivisionError as expected from pool.map()'
+ print('\tGot ZeroDivisionError as expected from pool.map()')
else:
raise AssertionError('expected ZeroDivisionError')
try:
- print list(pool.imap(f, range(10)))
+ print(list(pool.imap(f, list(range(10)))))
except ZeroDivisionError:
- print '\tGot ZeroDivisionError as expected from list(pool.imap())'
+ print('\tGot ZeroDivisionError as expected from list(pool.imap())')
else:
raise AssertionError('expected ZeroDivisionError')
- it = pool.imap(f, range(10))
+ it = pool.imap(f, list(range(10)))
for i in range(10):
try:
- x = it.next()
+ x = next(it)
except ZeroDivisionError:
if i == 5:
pass
@@ -179,14 +179,14 @@ def test():
raise AssertionError('expected ZeroDivisionError')
assert i == 9
- print '\tGot ZeroDivisionError as expected from IMapIterator.next()'
- print
+ print('\tGot ZeroDivisionError as expected from IMapIterator.next()')
+ print()
#
# Testing timeouts
#
- print 'Testing ApplyResult.get() with timeout:',
+ print('Testing ApplyResult.get() with timeout:', end=' ')
res = pool.apply_async(calculate, TASKS[0])
while 1:
sys.stdout.flush()
@@ -195,10 +195,10 @@ def test():
break
except multiprocessing.TimeoutError:
sys.stdout.write('.')
- print
- print
+ print()
+ print()
- print 'Testing IMapIterator.next() with timeout:',
+ print('Testing IMapIterator.next() with timeout:', end=' ')
it = pool.imap(calculatestar, TASKS)
while 1:
sys.stdout.flush()
@@ -208,14 +208,14 @@ def test():
break
except multiprocessing.TimeoutError:
sys.stdout.write('.')
- print
- print
+ print()
+ print()
#
# Testing callback
#
- print 'Testing callback:'
+ print('Testing callback:')
A = []
B = [56, 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
@@ -223,13 +223,13 @@ def test():
r = pool.apply_async(mul, (7, 8), callback=A.append)
r.wait()
- r = pool.map_async(pow3, range(10), callback=A.extend)
+ r = pool.map_async(pow3, list(range(10)), callback=A.extend)
r.wait()
if A == B:
- print '\tcallbacks succeeded\n'
+ print('\tcallbacks succeeded\n')
else:
- print '\t*** callbacks failed\n\t\t%s != %s\n' % (A, B)
+ print('\t*** callbacks failed\n\t\t%s != %s\n' % (A, B))
#
# Check there are no outstanding tasks
@@ -241,7 +241,7 @@ def test():
# Check close() methods
#
- print 'Testing close():'
+ print('Testing close():')
for worker in pool._pool:
assert worker.is_alive()
@@ -255,13 +255,13 @@ def test():
for worker in pool._pool:
assert not worker.is_alive()
- print '\tclose() succeeded\n'
+ print('\tclose() succeeded\n')
#
# Check terminate() method
#
- print 'Testing terminate():'
+ print('Testing terminate():')
pool = multiprocessing.Pool(2)
DELTA = 0.1
@@ -273,13 +273,13 @@ def test():
for worker in pool._pool:
assert not worker.is_alive()
- print '\tterminate() succeeded\n'
+ print('\tterminate() succeeded\n')
#
# Check garbage collection
#
- print 'Testing garbage collection:'
+ print('Testing garbage collection:')
pool = multiprocessing.Pool(2)
DELTA = 0.1
@@ -294,7 +294,7 @@ def test():
for worker in processes:
assert not worker.is_alive()
- print '\tgarbage collection succeeded\n'
+ print('\tgarbage collection succeeded\n')
if __name__ == '__main__':
@@ -303,12 +303,12 @@ if __name__ == '__main__':
assert len(sys.argv) in (1, 2)
if len(sys.argv) == 1 or sys.argv[1] == 'processes':
- print ' Using processes '.center(79, '-')
+ print(' Using processes '.center(79, '-'))
elif sys.argv[1] == 'threads':
- print ' Using threads '.center(79, '-')
+ print(' Using threads '.center(79, '-'))
import multiprocessing.dummy as multiprocessing
else:
- print 'Usage:\n\t%s [processes | threads]' % sys.argv[0]
+ print('Usage:\n\t%s [processes | threads]' % sys.argv[0])
raise SystemExit(2)
test()
diff --git a/Doc/includes/mp_synchronize.py b/Doc/includes/mp_synchronize.py
index fd2ae77..81dbc38 100644
--- a/Doc/includes/mp_synchronize.py
+++ b/Doc/includes/mp_synchronize.py
@@ -5,8 +5,10 @@
# All rights reserved.
#
-import time, sys, random
-from Queue import Empty
+import time
+import sys
+import random
+from queue import Empty
import multiprocessing # may get overwritten
@@ -18,7 +20,7 @@ def value_func(running, mutex):
time.sleep(random.random()*4)
mutex.acquire()
- print '\n\t\t\t' + str(multiprocessing.current_process()) + ' has finished'
+ print('\n\t\t\t' + str(multiprocessing.current_process()) + ' has finished')
running.value -= 1
mutex.release()
@@ -34,12 +36,12 @@ def test_value():
while running.value > 0:
time.sleep(0.08)
mutex.acquire()
- print running.value,
+ print(running.value, end=' ')
sys.stdout.flush()
mutex.release()
- print
- print 'No more running processes'
+ print()
+ print('No more running processes')
#### TEST_QUEUE
@@ -60,22 +62,22 @@ def test_queue():
while o != 'STOP':
try:
o = q.get(timeout=0.3)
- print o,
+ print(o, end=' ')
sys.stdout.flush()
except Empty:
- print 'TIMEOUT'
+ print('TIMEOUT')
- print
+ print()
#### TEST_CONDITION
def condition_func(cond):
cond.acquire()
- print '\t' + str(cond)
+ print('\t' + str(cond))
time.sleep(2)
- print '\tchild is notifying'
- print '\t' + str(cond)
+ print('\tchild is notifying')
+ print('\t' + str(cond))
cond.notify()
cond.release()
@@ -83,26 +85,26 @@ def test_condition():
cond = multiprocessing.Condition()
p = multiprocessing.Process(target=condition_func, args=(cond,))
- print cond
+ print(cond)
cond.acquire()
- print cond
+ print(cond)
cond.acquire()
- print cond
+ print(cond)
p.start()
- print 'main is waiting'
+ print('main is waiting')
cond.wait()
- print 'main has woken up'
+ print('main has woken up')
- print cond
+ print(cond)
cond.release()
- print cond
+ print(cond)
cond.release()
p.join()
- print cond
+ print(cond)
#### TEST_SEMAPHORE
@@ -112,7 +114,7 @@ def semaphore_func(sema, mutex, running):
mutex.acquire()
running.value += 1
- print running.value, 'tasks are running'
+ print(running.value, 'tasks are running')
mutex.release()
random.seed()
@@ -120,7 +122,7 @@ def semaphore_func(sema, mutex, running):
mutex.acquire()
running.value -= 1
- print '%s has finished' % multiprocessing.current_process()
+ print('%s has finished' % multiprocessing.current_process())
mutex.release()
sema.release()
@@ -146,30 +148,30 @@ def test_semaphore():
#### TEST_JOIN_TIMEOUT
def join_timeout_func():
- print '\tchild sleeping'
+ print('\tchild sleeping')
time.sleep(5.5)
- print '\n\tchild terminating'
+ print('\n\tchild terminating')
def test_join_timeout():
p = multiprocessing.Process(target=join_timeout_func)
p.start()
- print 'waiting for process to finish'
+ print('waiting for process to finish')
while 1:
p.join(timeout=1)
if not p.is_alive():
break
- print '.',
+ print('.', end=' ')
sys.stdout.flush()
#### TEST_EVENT
def event_func(event):
- print '\t%r is waiting' % multiprocessing.current_process()
+ print('\t%r is waiting' % multiprocessing.current_process())
event.wait()
- print '\t%r has woken up' % multiprocessing.current_process()
+ print('\t%r has woken up' % multiprocessing.current_process())
def test_event():
event = multiprocessing.Event()
@@ -180,10 +182,10 @@ def test_event():
for p in processes:
p.start()
- print 'main is sleeping'
+ print('main is sleeping')
time.sleep(2)
- print 'main is setting event'
+ print('main is setting event')
event.set()
for p in processes:
@@ -203,7 +205,7 @@ def sharedvalues_func(values, arrays, shared_values, shared_arrays):
sa = list(shared_arrays[i][:])
assert a == sa
- print 'Tests passed'
+ print('Tests passed')
def test_sharedvalues():
values = [
@@ -212,9 +214,9 @@ def test_sharedvalues():
('d', 1.25)
]
arrays = [
- ('i', range(100)),
+ ('i', list(range(100))),
('d', [0.25 * i for i in range(100)]),
- ('H', range(1000))
+ ('H', list(range(1000)))
]
shared_values = [multiprocessing.Value(id, v) for id, v in values]
@@ -237,18 +239,18 @@ def test(namespace=multiprocessing):
multiprocessing = namespace
- for func in [ test_value, test_queue, test_condition,
- test_semaphore, test_join_timeout, test_event,
- test_sharedvalues ]:
+ for func in [test_value, test_queue, test_condition,
+ test_semaphore, test_join_timeout, test_event,
+ test_sharedvalues]:
- print '\n\t######## %s\n' % func.__name__
+ print('\n\t######## %s\n' % func.__name__)
func()
ignore = multiprocessing.active_children() # cleanup any old processes
if hasattr(multiprocessing, '_debug_info'):
info = multiprocessing._debug_info()
if info:
- print info
+ print(info)
raise ValueError('there should be no positive refcounts left')
@@ -258,19 +260,19 @@ if __name__ == '__main__':
assert len(sys.argv) in (1, 2)
if len(sys.argv) == 1 or sys.argv[1] == 'processes':
- print ' Using processes '.center(79, '-')
+ print(' Using processes '.center(79, '-'))
namespace = multiprocessing
elif sys.argv[1] == 'manager':
- print ' Using processes and a manager '.center(79, '-')
+ print(' Using processes and a manager '.center(79, '-'))
namespace = multiprocessing.Manager()
namespace.Process = multiprocessing.Process
namespace.current_process = multiprocessing.current_process
namespace.active_children = multiprocessing.active_children
elif sys.argv[1] == 'threads':
- print ' Using threads '.center(79, '-')
+ print(' Using threads '.center(79, '-'))
import multiprocessing.dummy as namespace
else:
- print 'Usage:\n\t%s [processes | manager | threads]' % sys.argv[0]
+ print('Usage:\n\t%s [processes | manager | threads]' % sys.argv[0])
raise SystemExit(2)
test(namespace)
diff --git a/Doc/includes/mp_webserver.py b/Doc/includes/mp_webserver.py
index 96d14c5..651024d 100644
--- a/Doc/includes/mp_webserver.py
+++ b/Doc/includes/mp_webserver.py
@@ -16,15 +16,15 @@ import os
import sys
from multiprocessing import Process, current_process, freeze_support
-from BaseHTTPServer import HTTPServer
-from SimpleHTTPServer import SimpleHTTPRequestHandler
+from http.server import HTTPServer
+from http.server import SimpleHTTPRequestHandler
if sys.platform == 'win32':
import multiprocessing.reduction # make sockets pickable/inheritable
def note(format, *args):
- sys.stderr.write('[%s]\t%s\n' % (current_process().name, format%args))
+ sys.stderr.write('[%s]\t%s\n' % (current_process().name, format % args))
class RequestHandler(SimpleHTTPRequestHandler):
@@ -45,7 +45,7 @@ def runpool(address, number_of_processes):
server = HTTPServer(address, RequestHandler)
# create child processes to act as workers
- for i in range(number_of_processes-1):
+ for i in range(number_of_processes - 1):
Process(target=serve_forever, args=(server,)).start()
# main process also acts as a worker
@@ -57,9 +57,9 @@ def test():
ADDRESS = ('localhost', 8000)
NUMBER_OF_PROCESSES = 4
- print 'Serving at http://%s:%d using %d worker processes' % \
- (ADDRESS[0], ADDRESS[1], NUMBER_OF_PROCESSES)
- print 'To exit press Ctrl-' + ['C', 'Break'][sys.platform=='win32']
+ print('Serving at http://%s:%d using %d worker processes' % \
+ (ADDRESS[0], ADDRESS[1], NUMBER_OF_PROCESSES))
+ print('To exit press Ctrl-' + ['C', 'Break'][sys.platform=='win32'])
os.chdir(DIR)
runpool(ADDRESS, NUMBER_OF_PROCESSES)
diff --git a/Doc/includes/mp_workers.py b/Doc/includes/mp_workers.py
index e64a156..e66d97b 100644
--- a/Doc/includes/mp_workers.py
+++ b/Doc/includes/mp_workers.py
@@ -68,9 +68,9 @@ def test():
Process(target=worker, args=(task_queue, done_queue)).start()
# Get and print results
- print 'Unordered results:'
+ print('Unordered results:')
for i in range(len(TASKS1)):
- print '\t', done_queue.get()
+ print('\t', done_queue.get())
# Add more tasks using `put()`
for task in TASKS2:
@@ -78,7 +78,7 @@ def test():
# Get and print some more results
for i in range(len(TASKS2)):
- print '\t', done_queue.get()
+ print('\t', done_queue.get())
# Tell child processes to stop
for i in range(NUMBER_OF_PROCESSES):
diff --git a/Doc/includes/noddy.c b/Doc/includes/noddy.c
index ec2d669..8f79fcf 100644
--- a/Doc/includes/noddy.c
+++ b/Doc/includes/noddy.c
@@ -6,49 +6,51 @@ typedef struct {
} noddy_NoddyObject;
static PyTypeObject noddy_NoddyType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "noddy.Noddy", /*tp_name*/
- sizeof(noddy_NoddyObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- 0, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "noddy.Noddy", /* tp_name */
+ sizeof(noddy_NoddyObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
"Noddy objects", /* tp_doc */
};
-static PyMethodDef noddy_methods[] = {
- {NULL} /* Sentinel */
+static PyModuleDef noddymodule = {
+ PyModuleDef_HEAD_INIT,
+ "noddy",
+ "Example module that creates an extension type.",
+ -1,
+ NULL, NULL, NULL, NULL, NULL
};
-#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
PyMODINIT_FUNC
-initnoddy(void)
+PyInit_noddy(void)
{
PyObject* m;
noddy_NoddyType.tp_new = PyType_GenericNew;
if (PyType_Ready(&noddy_NoddyType) < 0)
- return;
+ return NULL;
- m = Py_InitModule3("noddy", noddy_methods,
- "Example module that creates an extension type.");
+ m = PyModule_Create(&noddymodule);
+ if (m == NULL)
+ return NULL;
Py_INCREF(&noddy_NoddyType);
PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType);
+ return m;
}
diff --git a/Doc/includes/noddy2.c b/Doc/includes/noddy2.c
index 2caf985..9b8eafb 100644
--- a/Doc/includes/noddy2.c
+++ b/Doc/includes/noddy2.c
@@ -13,7 +13,7 @@ Noddy_dealloc(Noddy* self)
{
Py_XDECREF(self->first);
Py_XDECREF(self->last);
- self->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
}
static PyObject *
@@ -23,14 +23,14 @@ Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self = (Noddy *)type->tp_alloc(type, 0);
if (self != NULL) {
- self->first = PyString_FromString("");
+ self->first = PyUnicode_FromString("");
if (self->first == NULL)
{
Py_DECREF(self);
return NULL;
}
- self->last = PyString_FromString("");
+ self->last = PyUnicode_FromString("");
if (self->last == NULL)
{
Py_DECREF(self);
@@ -90,7 +90,7 @@ Noddy_name(Noddy* self)
PyObject *args, *result;
if (format == NULL) {
- format = PyString_FromString("%s %s");
+ format = PyUnicode_FromString("%s %s");
if (format == NULL)
return NULL;
}
@@ -109,7 +109,7 @@ Noddy_name(Noddy* self)
if (args == NULL)
return NULL;
- result = PyString_Format(format, args);
+ result = PyUnicode_Format(format, args);
Py_DECREF(args);
return result;
@@ -123,27 +123,27 @@ static PyMethodDef Noddy_methods[] = {
};
static PyTypeObject NoddyType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "noddy.Noddy", /*tp_name*/
- sizeof(Noddy), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)Noddy_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "noddy.Noddy", /* tp_name */
+ sizeof(Noddy), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Noddy_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
"Noddy objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@@ -164,27 +164,27 @@ static PyTypeObject NoddyType = {
Noddy_new, /* tp_new */
};
-static PyMethodDef module_methods[] = {
- {NULL} /* Sentinel */
+static PyModuleDef noddy2module = {
+ PyModuleDef_HEAD_INIT,
+ "noddy2",
+ "Example module that creates an extension type.",
+ -1,
+ NULL, NULL, NULL, NULL, NULL
};
-#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
PyMODINIT_FUNC
-initnoddy2(void)
+PyInit_noddy2(void)
{
PyObject* m;
if (PyType_Ready(&NoddyType) < 0)
- return;
-
- m = Py_InitModule3("noddy2", module_methods,
- "Example module that creates an extension type.");
+ return NULL;
+ m = PyModule_Create(&noddy2module);
if (m == NULL)
- return;
+ return NULL;
Py_INCREF(&NoddyType);
PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
+ return m;
}
diff --git a/Doc/includes/noddy3.c b/Doc/includes/noddy3.c
index 60260ad..89f3a77 100644
--- a/Doc/includes/noddy3.c
+++ b/Doc/includes/noddy3.c
@@ -13,7 +13,7 @@ Noddy_dealloc(Noddy* self)
{
Py_XDECREF(self->first);
Py_XDECREF(self->last);
- self->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
}
static PyObject *
@@ -23,14 +23,14 @@ Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self = (Noddy *)type->tp_alloc(type, 0);
if (self != NULL) {
- self->first = PyString_FromString("");
+ self->first = PyUnicode_FromString("");
if (self->first == NULL)
{
Py_DECREF(self);
return NULL;
}
- self->last = PyString_FromString("");
+ self->last = PyUnicode_FromString("");
if (self->last == NULL)
{
Py_DECREF(self);
@@ -93,7 +93,7 @@ Noddy_setfirst(Noddy *self, PyObject *value, void *closure)
return -1;
}
- if (! PyString_Check(value)) {
+ if (! PyUnicode_Check(value)) {
PyErr_SetString(PyExc_TypeError,
"The first attribute value must be a string");
return -1;
@@ -121,7 +121,7 @@ Noddy_setlast(Noddy *self, PyObject *value, void *closure)
return -1;
}
- if (! PyString_Check(value)) {
+ if (! PyUnicode_Check(value)) {
PyErr_SetString(PyExc_TypeError,
"The last attribute value must be a string");
return -1;
@@ -153,7 +153,7 @@ Noddy_name(Noddy* self)
PyObject *args, *result;
if (format == NULL) {
- format = PyString_FromString("%s %s");
+ format = PyUnicode_FromString("%s %s");
if (format == NULL)
return NULL;
}
@@ -162,7 +162,7 @@ Noddy_name(Noddy* self)
if (args == NULL)
return NULL;
- result = PyString_Format(format, args);
+ result = PyUnicode_Format(format, args);
Py_DECREF(args);
return result;
@@ -176,27 +176,27 @@ static PyMethodDef Noddy_methods[] = {
};
static PyTypeObject NoddyType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "noddy.Noddy", /*tp_name*/
- sizeof(Noddy), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)Noddy_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "noddy.Noddy", /* tp_name */
+ sizeof(Noddy), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Noddy_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
"Noddy objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@@ -217,27 +217,27 @@ static PyTypeObject NoddyType = {
Noddy_new, /* tp_new */
};
-static PyMethodDef module_methods[] = {
- {NULL} /* Sentinel */
+static PyModuleDef noddy3module = {
+ PyModuleDef_HEAD_INIT,
+ "noddy3",
+ "Example module that creates an extension type.",
+ -1,
+ NULL, NULL, NULL, NULL, NULL
};
-#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
PyMODINIT_FUNC
-initnoddy3(void)
+PyInit_noddy3(void)
{
PyObject* m;
if (PyType_Ready(&NoddyType) < 0)
- return;
-
- m = Py_InitModule3("noddy3", module_methods,
- "Example module that creates an extension type.");
+ return NULL;
+ m = PyModule_Create(&noddy3module);
if (m == NULL)
- return;
+ return NULL;
Py_INCREF(&NoddyType);
PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
+ return m;
}
diff --git a/Doc/includes/noddy4.c b/Doc/includes/noddy4.c
index 878e086..6a96fac 100644
--- a/Doc/includes/noddy4.c
+++ b/Doc/includes/noddy4.c
@@ -47,7 +47,7 @@ static void
Noddy_dealloc(Noddy* self)
{
Noddy_clear(self);
- self->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
}
static PyObject *
@@ -57,14 +57,14 @@ Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self = (Noddy *)type->tp_alloc(type, 0);
if (self != NULL) {
- self->first = PyString_FromString("");
+ self->first = PyUnicode_FromString("");
if (self->first == NULL)
{
Py_DECREF(self);
return NULL;
}
- self->last = PyString_FromString("");
+ self->last = PyUnicode_FromString("");
if (self->last == NULL)
{
Py_DECREF(self);
@@ -124,7 +124,7 @@ Noddy_name(Noddy* self)
PyObject *args, *result;
if (format == NULL) {
- format = PyString_FromString("%s %s");
+ format = PyUnicode_FromString("%s %s");
if (format == NULL)
return NULL;
}
@@ -143,7 +143,7 @@ Noddy_name(Noddy* self)
if (args == NULL)
return NULL;
- result = PyString_Format(format, args);
+ result = PyUnicode_Format(format, args);
Py_DECREF(args);
return result;
@@ -157,27 +157,28 @@ static PyMethodDef Noddy_methods[] = {
};
static PyTypeObject NoddyType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "noddy.Noddy", /*tp_name*/
- sizeof(Noddy), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)Noddy_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "noddy.Noddy", /* tp_name */
+ sizeof(Noddy), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Noddy_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT |
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC, /* tp_flags */
"Noddy objects", /* tp_doc */
(traverseproc)Noddy_traverse, /* tp_traverse */
(inquiry)Noddy_clear, /* tp_clear */
@@ -198,27 +199,27 @@ static PyTypeObject NoddyType = {
Noddy_new, /* tp_new */
};
-static PyMethodDef module_methods[] = {
- {NULL} /* Sentinel */
+static PyModuleDef noddy4module = {
+ PyModuleDef_HEAD_INIT,
+ "noddy4",
+ "Example module that creates an extension type.",
+ -1,
+ NULL, NULL, NULL, NULL, NULL
};
-#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
PyMODINIT_FUNC
-initnoddy4(void)
+PyInit_noddy4(void)
{
PyObject* m;
if (PyType_Ready(&NoddyType) < 0)
- return;
-
- m = Py_InitModule3("noddy4", module_methods,
- "Example module that creates an extension type.");
+ return NULL;
+ m = PyModule_Create(&noddy4module);
if (m == NULL)
- return;
+ return NULL;
Py_INCREF(&NoddyType);
PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
+ return m;
}
diff --git a/Doc/includes/run-func.c b/Doc/includes/run-func.c
index 5a7df0d..1c9860d 100644
--- a/Doc/includes/run-func.c
+++ b/Doc/includes/run-func.c
@@ -13,7 +13,7 @@ main(int argc, char *argv[])
}
Py_Initialize();
- pName = PyString_FromString(argv[1]);
+ pName = PyUnicode_FromString(argv[1]);
/* Error checking of pName left out */
pModule = PyImport_Import(pName);
@@ -26,7 +26,7 @@ main(int argc, char *argv[])
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(argc - 3);
for (i = 0; i < argc - 3; ++i) {
- pValue = PyInt_FromLong(atoi(argv[i + 3]));
+ pValue = PyLong_FromLong(atoi(argv[i + 3]));
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
@@ -39,7 +39,7 @@ main(int argc, char *argv[])
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL) {
- printf("Result of call: %ld\n", PyInt_AsLong(pValue));
+ printf("Result of call: %ld\n", PyLong_AsLong(pValue));
Py_DECREF(pValue);
}
else {
diff --git a/Doc/includes/shoddy.c b/Doc/includes/shoddy.c
index 07a4177..07a2721 100644
--- a/Doc/includes/shoddy.c
+++ b/Doc/includes/shoddy.c
@@ -10,7 +10,7 @@ static PyObject *
Shoddy_increment(Shoddy *self, PyObject *unused)
{
self->state++;
- return PyInt_FromLong(self->state);
+ return PyLong_FromLong(self->state);
}
@@ -32,7 +32,6 @@ Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds)
static PyTypeObject ShoddyType = {
PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
"shoddy.Shoddy", /* tp_name */
sizeof(Shoddy), /* tp_basicsize */
0, /* tp_itemsize */
@@ -40,7 +39,7 @@ static PyTypeObject ShoddyType = {
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
- 0, /* tp_compare */
+ 0, /* tp_reserved */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
@@ -52,7 +51,7 @@ static PyTypeObject ShoddyType = {
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT |
- Py_TPFLAGS_BASETYPE, /* tp_flags */
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@@ -73,19 +72,28 @@ static PyTypeObject ShoddyType = {
0, /* tp_new */
};
+static PyModuleDef shoddymodule = {
+ PyModuleDef_HEAD_INIT,
+ "shoddy",
+ "Shoddy module",
+ -1,
+ NULL, NULL, NULL, NULL, NULL
+};
+
PyMODINIT_FUNC
-initshoddy(void)
+PyInit_shoddy(void)
{
PyObject *m;
ShoddyType.tp_base = &PyList_Type;
if (PyType_Ready(&ShoddyType) < 0)
- return;
+ return NULL;
- m = Py_InitModule3("shoddy", NULL, "Shoddy module");
+ m = PyModule_Create(&shoddymodule);
if (m == NULL)
- return;
+ return NULL;
Py_INCREF(&ShoddyType);
PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType);
+ return m;
}
diff --git a/Doc/includes/sqlite3/adapter_datetime.py b/Doc/includes/sqlite3/adapter_datetime.py
index 3460498..be33395 100644
--- a/Doc/includes/sqlite3/adapter_datetime.py
+++ b/Doc/includes/sqlite3/adapter_datetime.py
@@ -1,5 +1,6 @@
import sqlite3
-import datetime, time
+import datetime
+import time
def adapt_datetime(ts):
return time.mktime(ts.timetuple())
@@ -11,4 +12,4 @@ cur = con.cursor()
now = datetime.datetime.now()
cur.execute("select ?", (now,))
-print cur.fetchone()[0]
+print(cur.fetchone()[0])
diff --git a/Doc/includes/sqlite3/adapter_point_1.py b/Doc/includes/sqlite3/adapter_point_1.py
index a741f6c..6b1af84 100644
--- a/Doc/includes/sqlite3/adapter_point_1.py
+++ b/Doc/includes/sqlite3/adapter_point_1.py
@@ -1,6 +1,6 @@
import sqlite3
-class Point(object):
+class Point:
def __init__(self, x, y):
self.x, self.y = x, y
@@ -13,4 +13,4 @@ cur = con.cursor()
p = Point(4.0, -3.2)
cur.execute("select ?", (p,))
-print cur.fetchone()[0]
+print(cur.fetchone()[0])
diff --git a/Doc/includes/sqlite3/adapter_point_2.py b/Doc/includes/sqlite3/adapter_point_2.py
index 200a064..d670700 100644
--- a/Doc/includes/sqlite3/adapter_point_2.py
+++ b/Doc/includes/sqlite3/adapter_point_2.py
@@ -1,6 +1,6 @@
import sqlite3
-class Point(object):
+class Point:
def __init__(self, x, y):
self.x, self.y = x, y
@@ -14,4 +14,4 @@ cur = con.cursor()
p = Point(4.0, -3.2)
cur.execute("select ?", (p,))
-print cur.fetchone()[0]
+print(cur.fetchone()[0])
diff --git a/Doc/includes/sqlite3/collation_reverse.py b/Doc/includes/sqlite3/collation_reverse.py
index e956402..3504a35 100644
--- a/Doc/includes/sqlite3/collation_reverse.py
+++ b/Doc/includes/sqlite3/collation_reverse.py
@@ -1,7 +1,12 @@
import sqlite3
def collate_reverse(string1, string2):
- return -cmp(string1, string2)
+ if string1 == string2:
+ return 0
+ elif string1 < string2:
+ return 1
+ else:
+ return -1
con = sqlite3.connect(":memory:")
con.create_collation("reverse", collate_reverse)
@@ -11,5 +16,5 @@ cur.execute("create table test(x)")
cur.executemany("insert into test(x) values (?)", [("a",), ("b",)])
cur.execute("select x from test order by x collate reverse")
for row in cur:
- print row
+ print(row)
con.close()
diff --git a/Doc/includes/sqlite3/complete_statement.py b/Doc/includes/sqlite3/complete_statement.py
index 76ea7f6..cd38d73 100644
--- a/Doc/includes/sqlite3/complete_statement.py
+++ b/Doc/includes/sqlite3/complete_statement.py
@@ -8,11 +8,11 @@ cur = con.cursor()
buffer = ""
-print "Enter your SQL commands to execute in sqlite3."
-print "Enter a blank line to exit."
+print("Enter your SQL commands to execute in sqlite3.")
+print("Enter a blank line to exit.")
while True:
- line = raw_input()
+ line = input()
if line == "":
break
buffer += line
@@ -22,9 +22,9 @@ while True:
cur.execute(buffer)
if buffer.lstrip().upper().startswith("SELECT"):
- print cur.fetchall()
+ print(cur.fetchall())
except sqlite3.Error as e:
- print "An error occurred:", e.args[0]
+ print("An error occurred:", e.args[0])
buffer = ""
con.close()
diff --git a/Doc/includes/sqlite3/converter_point.py b/Doc/includes/sqlite3/converter_point.py
index e220e9b..5df828e 100644
--- a/Doc/includes/sqlite3/converter_point.py
+++ b/Doc/includes/sqlite3/converter_point.py
@@ -1,6 +1,6 @@
import sqlite3
-class Point(object):
+class Point:
def __init__(self, x, y):
self.x, self.y = x, y
@@ -8,10 +8,10 @@ class Point(object):
return "(%f;%f)" % (self.x, self.y)
def adapt_point(point):
- return "%f;%f" % (point.x, point.y)
+ return ("%f;%f" % (point.x, point.y)).encode('ascii')
def convert_point(s):
- x, y = map(float, s.split(";"))
+ x, y = list(map(float, s.split(b";")))
return Point(x, y)
# Register the adapter
@@ -30,7 +30,7 @@ cur.execute("create table test(p point)")
cur.execute("insert into test(p) values (?)", (p,))
cur.execute("select p from test")
-print "with declared types:", cur.fetchone()[0]
+print("with declared types:", cur.fetchone()[0])
cur.close()
con.close()
@@ -42,6 +42,6 @@ cur.execute("create table test(p)")
cur.execute("insert into test(p) values (?)", (p,))
cur.execute('select p as "p [point]" from test')
-print "with column names:", cur.fetchone()[0]
+print("with column names:", cur.fetchone()[0])
cur.close()
con.close()
diff --git a/Doc/includes/sqlite3/countcursors.py b/Doc/includes/sqlite3/countcursors.py
index df04cad..ef3e70a 100644
--- a/Doc/includes/sqlite3/countcursors.py
+++ b/Doc/includes/sqlite3/countcursors.py
@@ -12,4 +12,4 @@ class CountCursorsConnection(sqlite3.Connection):
con = sqlite3.connect(":memory:", factory=CountCursorsConnection)
cur1 = con.cursor()
cur2 = con.cursor()
-print con.numcursors
+print(con.numcursors)
diff --git a/Doc/includes/sqlite3/ctx_manager.py b/Doc/includes/sqlite3/ctx_manager.py
index d6f27e6..7af4ad1 100644
--- a/Doc/includes/sqlite3/ctx_manager.py
+++ b/Doc/includes/sqlite3/ctx_manager.py
@@ -13,4 +13,4 @@ try:
with con:
con.execute("insert into person(firstname) values (?)", ("Joe",))
except sqlite3.IntegrityError:
- print "couldn't add Joe twice"
+ print("couldn't add Joe twice")
diff --git a/Doc/includes/sqlite3/execsql_fetchonerow.py b/Doc/includes/sqlite3/execsql_fetchonerow.py
index 8044ecf..078873b 100644
--- a/Doc/includes/sqlite3/execsql_fetchonerow.py
+++ b/Doc/includes/sqlite3/execsql_fetchonerow.py
@@ -9,9 +9,9 @@ SELECT = "select name_last, age from people order by age, name_last"
# resulting sequences to yield their elements (name_last, age):
cur.execute(SELECT)
for (name_last, age) in cur:
- print '%s is %d years old.' % (name_last, age)
+ print('%s is %d years old.' % (name_last, age))
# 2. Equivalently:
cur.execute(SELECT)
for row in cur:
- print '%s is %d years old.' % (row[0], row[1])
+ print('%s is %d years old.' % (row[0], row[1]))
diff --git a/Doc/includes/sqlite3/execsql_printall_1.py b/Doc/includes/sqlite3/execsql_printall_1.py
index d27d735..a4ce5c5 100644
--- a/Doc/includes/sqlite3/execsql_printall_1.py
+++ b/Doc/includes/sqlite3/execsql_printall_1.py
@@ -10,4 +10,4 @@ cur = con.cursor()
cur.execute("select * from people order by age")
# Retrieve all rows as a sequence and print that sequence:
-print cur.fetchall()
+print(cur.fetchall())
diff --git a/Doc/includes/sqlite3/execute_1.py b/Doc/includes/sqlite3/execute_1.py
index 763167c..f864a89 100644
--- a/Doc/includes/sqlite3/execute_1.py
+++ b/Doc/includes/sqlite3/execute_1.py
@@ -13,4 +13,4 @@ cur.execute("insert into people values (?, ?)", (who, age))
# And this is the named style:
cur.execute("select * from people where name_last=:who and age=:age", {"who": who, "age": age})
-print cur.fetchone()
+print(cur.fetchone())
diff --git a/Doc/includes/sqlite3/execute_3.py b/Doc/includes/sqlite3/execute_3.py
index b64621f..0353683 100644
--- a/Doc/includes/sqlite3/execute_3.py
+++ b/Doc/includes/sqlite3/execute_3.py
@@ -9,4 +9,4 @@ age = 72
cur.execute("select name_last, age from people where name_last=:who and age=:age",
locals())
-print cur.fetchone()
+print(cur.fetchone())
diff --git a/Doc/includes/sqlite3/executemany_1.py b/Doc/includes/sqlite3/executemany_1.py
index 24357c5..efae106 100644
--- a/Doc/includes/sqlite3/executemany_1.py
+++ b/Doc/includes/sqlite3/executemany_1.py
@@ -7,7 +7,7 @@ class IterChars:
def __iter__(self):
return self
- def next(self):
+ def __next__(self):
if self.count > ord('z'):
raise StopIteration
self.count += 1
@@ -21,4 +21,4 @@ theIter = IterChars()
cur.executemany("insert into characters(c) values (?)", theIter)
cur.execute("select c from characters")
-print cur.fetchall()
+print(cur.fetchall())
diff --git a/Doc/includes/sqlite3/executemany_2.py b/Doc/includes/sqlite3/executemany_2.py
index 0b12688..527358e 100644
--- a/Doc/includes/sqlite3/executemany_2.py
+++ b/Doc/includes/sqlite3/executemany_2.py
@@ -2,7 +2,7 @@ import sqlite3
import string
def char_generator():
- for c in string.lowercase:
+ for c in string.ascii_lowercase:
yield (c,)
con = sqlite3.connect(":memory:")
@@ -12,4 +12,4 @@ cur.execute("create table characters(c)")
cur.executemany("insert into characters(c) values (?)", char_generator())
cur.execute("select c from characters")
-print cur.fetchall()
+print(cur.fetchall())
diff --git a/Doc/includes/sqlite3/load_extension.py b/Doc/includes/sqlite3/load_extension.py
index 7f893c9..015aa0d 100644
--- a/Doc/includes/sqlite3/load_extension.py
+++ b/Doc/includes/sqlite3/load_extension.py
@@ -23,4 +23,4 @@ con.executescript("""
insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter');
""")
for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"):
- print row
+ print(row)
diff --git a/Doc/includes/sqlite3/md5func.py b/Doc/includes/sqlite3/md5func.py
index 5769687..0056b2d 100644
--- a/Doc/includes/sqlite3/md5func.py
+++ b/Doc/includes/sqlite3/md5func.py
@@ -1,11 +1,11 @@
import sqlite3
-import md5
+import hashlib
def md5sum(t):
- return md5.md5(t).hexdigest()
+ return hashlib.md5(t).hexdigest()
con = sqlite3.connect(":memory:")
con.create_function("md5", 1, md5sum)
cur = con.cursor()
-cur.execute("select md5(?)", ("foo",))
-print cur.fetchone()[0]
+cur.execute("select md5(?)", (b"foo",))
+print(cur.fetchone()[0])
diff --git a/Doc/includes/sqlite3/mysumaggr.py b/Doc/includes/sqlite3/mysumaggr.py
index 6d0cd55..d2dfd2c 100644
--- a/Doc/includes/sqlite3/mysumaggr.py
+++ b/Doc/includes/sqlite3/mysumaggr.py
@@ -17,4 +17,4 @@ cur.execute("create table test(i)")
cur.execute("insert into test(i) values (1)")
cur.execute("insert into test(i) values (2)")
cur.execute("select mysum(i) from test")
-print cur.fetchone()[0]
+print(cur.fetchone()[0])
diff --git a/Doc/includes/sqlite3/parse_colnames.py b/Doc/includes/sqlite3/parse_colnames.py
index fcded00..cc68c76 100644
--- a/Doc/includes/sqlite3/parse_colnames.py
+++ b/Doc/includes/sqlite3/parse_colnames.py
@@ -5,4 +5,4 @@ con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
cur = con.cursor()
cur.execute('select ? as "x [timestamp]"', (datetime.datetime.now(),))
dt = cur.fetchone()[0]
-print dt, type(dt)
+print(dt, type(dt))
diff --git a/Doc/includes/sqlite3/pysqlite_datetime.py b/Doc/includes/sqlite3/pysqlite_datetime.py
index efa4b06..68d4935 100644
--- a/Doc/includes/sqlite3/pysqlite_datetime.py
+++ b/Doc/includes/sqlite3/pysqlite_datetime.py
@@ -11,10 +11,10 @@ now = datetime.datetime.now()
cur.execute("insert into test(d, ts) values (?, ?)", (today, now))
cur.execute("select d, ts from test")
row = cur.fetchone()
-print today, "=>", row[0], type(row[0])
-print now, "=>", row[1], type(row[1])
+print(today, "=>", row[0], type(row[0]))
+print(now, "=>", row[1], type(row[1]))
cur.execute('select current_date as "d [date]", current_timestamp as "ts [timestamp]"')
row = cur.fetchone()
-print "current_date", row[0], type(row[0])
-print "current_timestamp", row[1], type(row[1])
+print("current_date", row[0], type(row[0]))
+print("current_timestamp", row[1], type(row[1]))
diff --git a/Doc/includes/sqlite3/row_factory.py b/Doc/includes/sqlite3/row_factory.py
index 64676c8..e436ffc 100644
--- a/Doc/includes/sqlite3/row_factory.py
+++ b/Doc/includes/sqlite3/row_factory.py
@@ -10,4 +10,4 @@ con = sqlite3.connect(":memory:")
con.row_factory = dict_factory
cur = con.cursor()
cur.execute("select 1 as a")
-print cur.fetchone()["a"]
+print(cur.fetchone()["a"])
diff --git a/Doc/includes/sqlite3/shortcut_methods.py b/Doc/includes/sqlite3/shortcut_methods.py
index e128a3b..71600d4 100644
--- a/Doc/includes/sqlite3/shortcut_methods.py
+++ b/Doc/includes/sqlite3/shortcut_methods.py
@@ -15,6 +15,6 @@ con.executemany("insert into person(firstname, lastname) values (?, ?)", persons
# Print the table contents
for row in con.execute("select firstname, lastname from person"):
- print row
+ print(row)
-print "I just deleted", con.execute("delete from person").rowcount, "rows"
+print("I just deleted", con.execute("delete from person").rowcount, "rows")
diff --git a/Doc/includes/sqlite3/simple_tableprinter.py b/Doc/includes/sqlite3/simple_tableprinter.py
index 67ea6a2..231d872 100644
--- a/Doc/includes/sqlite3/simple_tableprinter.py
+++ b/Doc/includes/sqlite3/simple_tableprinter.py
@@ -11,9 +11,9 @@ cur.execute(SELECT)
# Print a header.
for fieldDesc in cur.description:
- print fieldDesc[0].ljust(FIELD_MAX_WIDTH) ,
-print # Finish the header with a newline.
-print '-' * 78
+ print(fieldDesc[0].ljust(FIELD_MAX_WIDTH), end=' ')
+print() # Finish the header with a newline.
+print('-' * 78)
# For each row, print the value of each field left-justified within
# the maximum possible width of that field.
@@ -21,6 +21,6 @@ fieldIndices = range(len(cur.description))
for row in cur:
for fieldIndex in fieldIndices:
fieldValue = str(row[fieldIndex])
- print fieldValue.ljust(FIELD_MAX_WIDTH) ,
+ print(fieldValue.ljust(FIELD_MAX_WIDTH), end=' ')
- print # Finish the row with a newline.
+ print() # Finish the row with a newline.
diff --git a/Doc/includes/sqlite3/text_factory.py b/Doc/includes/sqlite3/text_factory.py
index 577378f..5f96cdb 100644
--- a/Doc/includes/sqlite3/text_factory.py
+++ b/Doc/includes/sqlite3/text_factory.py
@@ -3,7 +3,7 @@ import sqlite3
con = sqlite3.connect(":memory:")
cur = con.cursor()
-AUSTRIA = u"\xd6sterreich"
+AUSTRIA = "\xd6sterreich"
# by default, rows are returned as Unicode
cur.execute("select ?", (AUSTRIA,))
@@ -11,30 +11,17 @@ row = cur.fetchone()
assert row[0] == AUSTRIA
# but we can make sqlite3 always return bytestrings ...
-con.text_factory = str
+con.text_factory = bytes
cur.execute("select ?", (AUSTRIA,))
row = cur.fetchone()
-assert type(row[0]) is str
+assert type(row[0]) is bytes
# the bytestrings will be encoded in UTF-8, unless you stored garbage in the
# database ...
assert row[0] == AUSTRIA.encode("utf-8")
# we can also implement a custom text_factory ...
-# here we implement one that will ignore Unicode characters that cannot be
-# decoded from UTF-8
-con.text_factory = lambda x: unicode(x, "utf-8", "ignore")
-cur.execute("select ?", ("this is latin1 and would normally create errors" +
- u"\xe4\xf6\xfc".encode("latin1"),))
+# here we implement one that appends "foo" to all strings
+con.text_factory = lambda x: x.decode("utf-8") + "foo"
+cur.execute("select ?", ("bar",))
row = cur.fetchone()
-assert type(row[0]) is unicode
-
-# sqlite3 offers a built-in optimized text_factory that will return bytestring
-# objects, if the data is in ASCII only, and otherwise return unicode objects
-con.text_factory = sqlite3.OptimizedUnicode
-cur.execute("select ?", (AUSTRIA,))
-row = cur.fetchone()
-assert type(row[0]) is unicode
-
-cur.execute("select ?", ("Germany",))
-row = cur.fetchone()
-assert type(row[0]) is str
+assert row[0] == "barfoo"
diff --git a/Doc/includes/turtle-star.py b/Doc/includes/turtle-star.py
new file mode 100644
index 0000000..1a5db76
--- /dev/null
+++ b/Doc/includes/turtle-star.py
@@ -0,0 +1,10 @@
+from turtle import *
+color('red', 'yellow')
+begin_fill()
+while True:
+ forward(200)
+ left(170)
+ if abs(pos()) < 1:
+ break
+end_fill()
+done()
diff --git a/Doc/includes/typestruct.h b/Doc/includes/typestruct.h
index 0afe375..32647c0 100644
--- a/Doc/includes/typestruct.h
+++ b/Doc/includes/typestruct.h
@@ -9,7 +9,7 @@ typedef struct _typeobject {
printfunc tp_print;
getattrfunc tp_getattr;
setattrfunc tp_setattr;
- cmpfunc tp_compare;
+ void *tp_reserved;
reprfunc tp_repr;
/* Method suites for standard classes */
@@ -34,21 +34,18 @@ typedef struct _typeobject {
char *tp_doc; /* Documentation string */
- /* Assigned meaning in release 2.0 */
/* call function for all accessible objects */
traverseproc tp_traverse;
/* delete references to contained objects */
inquiry tp_clear;
- /* Assigned meaning in release 2.1 */
/* rich comparisons */
richcmpfunc tp_richcompare;
/* weak reference enabler */
long tp_weaklistoffset;
- /* Added in release 2.2 */
/* Iterators */
getiterfunc tp_iter;
iternextfunc tp_iternext;
diff --git a/Doc/includes/tzinfo-examples.py b/Doc/includes/tzinfo-examples.py
index 5132429..3a8cf47 100644
--- a/Doc/includes/tzinfo-examples.py
+++ b/Doc/includes/tzinfo-examples.py
@@ -27,7 +27,7 @@ class FixedOffset(tzinfo):
"""Fixed offset in minutes east from UTC."""
def __init__(self, offset, name):
- self.__offset = timedelta(minutes = offset)
+ self.__offset = timedelta(minutes=offset)
self.__name = name
def utcoffset(self, dt):
diff --git a/Doc/install/index.rst b/Doc/install/index.rst
index b1881b5..52c75dc 100644
--- a/Doc/install/index.rst
+++ b/Doc/install/index.rst
@@ -278,10 +278,12 @@ statements shown below, and get the output as shown, to find out my
'/usr'
A few other placeholders are used in this document: :file:`{X.Y}` stands for the
-version of Python, for example ``2.7``; :file:`{distname}` will be replaced by
-the name of the module distribution being installed. Dots and capitalization
-are important in the paths; for example, a value that uses ``python2.7`` on UNIX
-will typically use ``Python27`` on Windows.
+version of Python, for example ``3.2``; :file:`{abiflags}` will be replaced by
+the value of :data:`sys.abiflags` or the empty string for platforms which don't
+define ABI flags; :file:`{distname}` will be replaced by the name of the module
+distribution being installed. Dots and capitalization are important in the
+paths; for example, a value that uses ``python3.2`` on UNIX will typically use
+``Python32`` on Windows.
If you don't want to install modules to the standard location, or if you don't
have permission to write there, then you need to read about alternate
@@ -339,7 +341,7 @@ Type of file Installation directory
modules :file:`{userbase}/lib/python{X.Y}/site-packages`
scripts :file:`{userbase}/bin`
data :file:`{userbase}`
-C headers :file:`{userbase}/include/python{X.Y}/{distname}`
+C headers :file:`{userbase}/include/python{X.Y}{abiflags}/{distname}`
=============== ===========================================================
And here are the values used on Windows:
@@ -406,9 +408,6 @@ C headers :file:`{home}/include/python/{distname}`
(Mentally replace slashes with backslashes if you're on Windows.)
-.. versionchanged:: 2.4
- The :option:`--home` option used to be supported only on Unix.
-
.. _inst-alt-install-prefix-unix:
@@ -454,7 +453,7 @@ Python modules :file:`{prefix}/lib/python{X.Y}/site-packages`
extension modules :file:`{exec-prefix}/lib/python{X.Y}/site-packages`
scripts :file:`{prefix}/bin`
data :file:`{prefix}`
-C headers :file:`{prefix}/include/python{X.Y}/{distname}`
+C headers :file:`{prefix}/include/python{X.Y}{abiflags}/{distname}`
================= ==========================================================
There is no requirement that :option:`--prefix` or :option:`--exec-prefix`
diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst
index a8b5b5c..d07aaa1 100644
--- a/Doc/library/2to3.rst
+++ b/Doc/library/2to3.rst
@@ -99,7 +99,7 @@ alternate directory for processed output files to be written to. The
:option:`-n` flag is required when using this as backup files do not make sense
when not overwriting the input files.
-.. versionadded:: 2.7.3
+.. versionadded:: 3.2.3
The :option:`-o` option was added.
The :option:`-W` or :option:`--write-unchanged-files` flag tells 2to3 to always
@@ -108,7 +108,7 @@ useful with :option:`-o` so that an entire Python source tree is copied with
translation from one directory to another.
This option implies the :option:`-w` flag as it would not make sense otherwise.
-.. versionadded:: 2.7.3
+.. versionadded:: 3.2.3
The :option:`-W` flag was added.
The :option:`--add-suffix` option specifies a string to append to all output
@@ -119,7 +119,7 @@ are not necessary when writing to different filenames. Example::
Will cause a converted file named ``example.py3`` to be written.
-.. versionadded:: 2.7.3
+.. versionadded:: 3.2.3
The :option:`--add-suffix` option was added.
To translate an entire project from one directory tree to another use::
@@ -175,7 +175,7 @@ and off individually. They are described here in more detail.
.. 2to3fixer:: exec
- Converts the :keyword:`exec` statement to the :func:`exec` function.
+ Converts the ``exec`` statement to the :func:`exec` function.
.. 2to3fixer:: execfile
@@ -264,7 +264,7 @@ and off individually. They are described here in more detail.
.. 2to3fixer:: long
- Strips the ``L`` suffix on long literals and renames :class:`long` to
+ Strips the ``L`` prefix on long literals and renames :class:`long` to
:class:`int`.
.. 2to3fixer:: map
@@ -301,6 +301,25 @@ and off individually. They are described here in more detail.
Converts octal literals into the new syntax.
+.. 2to3fixer:: operator
+
+ Converts calls to various functions in the :mod:`operator` module to other,
+ but equivalent, function calls. When needed, the appropriate ``import``
+ statements are added, e.g. ``import collections``. The following mapping
+ are made:
+
+ ================================== ==========================================
+ From To
+ ================================== ==========================================
+ ``operator.isCallable(obj)`` ``hasattr(obj, '__call__')``
+ ``operator.sequenceIncludes(obj)`` ``operator.contains(obj)``
+ ``operator.isSequenceType(obj)`` ``isinstance(obj, collections.Sequence)``
+ ``operator.isMappingType(obj)`` ``isinstance(obj, collections.Mapping)``
+ ``operator.isNumberType(obj)`` ``isinstance(obj, numbers.Number)``
+ ``operator.repeat(obj, n)`` ``operator.mul(obj, n)``
+ ``operator.irepeat(obj, n)`` ``operator.imul(obj, n)``
+ ================================== ==========================================
+
.. 2to3fixer:: paren
Add extra parenthesis where they are required in list comprehensions. For
@@ -308,13 +327,13 @@ and off individually. They are described here in more detail.
.. 2to3fixer:: print
- Converts the :keyword:`print` statement to the :func:`print` function.
+ Converts the ``print`` statement to the :func:`print` function.
.. 2to3fixer:: raise
Converts ``raise E, V`` to ``raise E(V)``, and ``raise E, V, T`` to ``raise
E(V).with_traceback(T)``. If ``E`` is a tuple, the translation will be
- incorrect because substituting tuples for exceptions has been removed in Python 3.
+ incorrect because substituting tuples for exceptions has been removed in 3.0.
.. 2to3fixer:: raw_input
diff --git a/Doc/library/__builtin__.rst b/Doc/library/__builtin__.rst
deleted file mode 100644
index 673d74f..0000000
--- a/Doc/library/__builtin__.rst
+++ /dev/null
@@ -1,44 +0,0 @@
-
-:mod:`__builtin__` --- Built-in objects
-=======================================
-
-.. module:: __builtin__
- :synopsis: The module that provides the built-in namespace.
-
-
-This module provides direct access to all 'built-in' identifiers of Python; for
-example, ``__builtin__.open`` is the full name for the built-in function
-:func:`open`. See :ref:`built-in-funcs` and :ref:`built-in-consts` for
-documentation.
-
-
-This module is not normally accessed explicitly by most applications, but can be
-useful in modules that provide objects with the same name as a built-in value,
-but in which the built-in of that name is also needed. For example, in a module
-that wants to implement an :func:`open` function that wraps the built-in
-:func:`open`, this module can be used directly::
-
- import __builtin__
-
- def open(path):
- f = __builtin__.open(path, 'r')
- return UpperCaser(f)
-
- class UpperCaser:
- '''Wrapper around a file that converts output to upper-case.'''
-
- def __init__(self, f):
- self._f = f
-
- def read(self, count=-1):
- return self._f.read(count).upper()
-
- # ...
-
-.. impl-detail::
-
- Most modules have the name ``__builtins__`` (note the ``'s'``) made available
- as part of their globals. The value of ``__builtins__`` is normally either
- this module or the value of this modules's :attr:`__dict__` attribute. Since
- this is an implementation detail, it may not be used by alternate
- implementations of Python.
diff --git a/Doc/library/__future__.rst b/Doc/library/__future__.rst
index 329e411..72f2963 100644
--- a/Doc/library/__future__.rst
+++ b/Doc/library/__future__.rst
@@ -29,7 +29,7 @@ Each statement in :file:`__future__.py` is of the form::
where, normally, *OptionalRelease* is less than *MandatoryRelease*, and both are
-5-tuples of the same form as ``sys.version_info``::
+5-tuples of the same form as :data:`sys.version_info`::
(PY_MAJOR_VERSION, # the 2 in 2.1.0a3; an int
PY_MINOR_VERSION, # the 1; an int
@@ -88,6 +88,7 @@ language using this mechanism:
| | | | *Bytes literals in Python 3000* |
+------------------+-------------+--------------+---------------------------------------------+
+
.. seealso::
:ref:`future`
diff --git a/Doc/library/_dummy_thread.rst b/Doc/library/_dummy_thread.rst
new file mode 100644
index 0000000..83aec12
--- /dev/null
+++ b/Doc/library/_dummy_thread.rst
@@ -0,0 +1,25 @@
+:mod:`_dummy_thread` --- Drop-in replacement for the :mod:`_thread` module
+==========================================================================
+
+.. module:: _dummy_thread
+ :synopsis: Drop-in replacement for the _thread module.
+
+**Source code:** :source:`Lib/_dummy_thread.py`
+
+--------------
+
+This module provides a duplicate interface to the :mod:`_thread` module. It is
+meant to be imported when the :mod:`_thread` module is not provided on a
+platform.
+
+Suggested usage is::
+
+ try:
+ import _thread
+ except ImportError:
+ import dummy_thread as _thread
+
+Be careful to not use this module where deadlock might occur from a thread being
+created that blocks waiting for another thread to be created. This often occurs
+with blocking I/O.
+
diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst
new file mode 100644
index 0000000..369e9cd
--- /dev/null
+++ b/Doc/library/_thread.rst
@@ -0,0 +1,191 @@
+:mod:`_thread` --- Low-level threading API
+==========================================
+
+.. module:: _thread
+ :synopsis: Low-level threading API.
+
+
+.. index::
+ single: light-weight processes
+ single: processes, light-weight
+ single: binary semaphores
+ single: semaphores, binary
+
+This module provides low-level primitives for working with multiple threads
+(also called :dfn:`light-weight processes` or :dfn:`tasks`) --- multiple threads of
+control sharing their global data space. For synchronization, simple locks
+(also called :dfn:`mutexes` or :dfn:`binary semaphores`) are provided.
+The :mod:`threading` module provides an easier to use and higher-level
+threading API built on top of this module.
+
+.. index::
+ single: pthreads
+ pair: threads; POSIX
+
+The module is optional. It is supported on Windows, Linux, SGI IRIX, Solaris
+2.x, as well as on systems that have a POSIX thread (a.k.a. "pthread")
+implementation. For systems lacking the :mod:`_thread` module, the
+:mod:`_dummy_thread` module is available. It duplicates this module's interface
+and can be used as a drop-in replacement.
+
+It defines the following constants and functions:
+
+
+.. exception:: error
+
+ Raised on thread-specific errors.
+
+
+.. data:: LockType
+
+ This is the type of lock objects.
+
+
+.. function:: start_new_thread(function, args[, kwargs])
+
+ Start a new thread and return its identifier. The thread executes the function
+ *function* with the argument list *args* (which must be a tuple). The optional
+ *kwargs* argument specifies a dictionary of keyword arguments. When the function
+ returns, the thread silently exits. When the function terminates with an
+ unhandled exception, a stack trace is printed and then the thread exits (but
+ other threads continue to run).
+
+
+.. function:: interrupt_main()
+
+ Raise a :exc:`KeyboardInterrupt` exception in the main thread. A subthread can
+ use this function to interrupt the main thread.
+
+
+.. function:: exit()
+
+ Raise the :exc:`SystemExit` exception. When not caught, this will cause the
+ thread to exit silently.
+
+..
+ function:: exit_prog(status)
+
+ Exit all threads and report the value of the integer argument
+ *status* as the exit status of the entire program.
+ **Caveat:** code in pending :keyword:`finally` clauses, in this thread
+ or in other threads, is not executed.
+
+
+.. function:: allocate_lock()
+
+ Return a new lock object. Methods of locks are described below. The lock is
+ initially unlocked.
+
+
+.. function:: get_ident()
+
+ Return the 'thread identifier' of the current thread. This is a nonzero
+ integer. Its value has no direct meaning; it is intended as a magic cookie to
+ be used e.g. to index a dictionary of thread-specific data. Thread identifiers
+ may be recycled when a thread exits and another thread is created.
+
+
+.. function:: stack_size([size])
+
+ Return the thread stack size used when creating new threads. The optional
+ *size* argument specifies the stack size to be used for subsequently created
+ threads, and must be 0 (use platform or configured default) or a positive
+ integer value of at least 32,768 (32kB). If changing the thread stack size is
+ unsupported, a :exc:`ThreadError` is raised. If the specified stack size is
+ invalid, a :exc:`ValueError` is raised and the stack size is unmodified. 32kB
+ is currently the minimum supported stack size value to guarantee sufficient
+ stack space for the interpreter itself. Note that some platforms may have
+ particular restrictions on values for the stack size, such as requiring a
+ minimum stack size > 32kB or requiring allocation in multiples of the system
+ memory page size - platform documentation should be referred to for more
+ information (4kB pages are common; using multiples of 4096 for the stack size is
+ the suggested approach in the absence of more specific information).
+ Availability: Windows, systems with POSIX threads.
+
+
+.. data:: TIMEOUT_MAX
+
+ The maximum value allowed for the *timeout* parameter of
+ :meth:`Lock.acquire`. Specifying a timeout greater than this value will
+ raise an :exc:`OverflowError`.
+
+ .. versionadded:: 3.2
+
+
+Lock objects have the following methods:
+
+
+.. method:: lock.acquire(waitflag=1, timeout=-1)
+
+ Without any optional argument, this method acquires the lock unconditionally, if
+ necessary waiting until it is released by another thread (only one thread at a
+ time can acquire a lock --- that's their reason for existence).
+
+ If the integer *waitflag* argument is present, the action depends on its
+ value: if it is zero, the lock is only acquired if it can be acquired
+ immediately without waiting, while if it is nonzero, the lock is acquired
+ unconditionally as above.
+
+ If the floating-point *timeout* argument is present and positive, it
+ specifies the maximum wait time in seconds before returning. A negative
+ *timeout* argument specifies an unbounded wait. You cannot specify
+ a *timeout* if *waitflag* is zero.
+
+ The return value is ``True`` if the lock is acquired successfully,
+ ``False`` if not.
+
+ .. versionchanged:: 3.2
+ The *timeout* parameter is new.
+
+ .. versionchanged:: 3.2
+ Lock acquires can now be interrupted by signals on POSIX.
+
+
+.. method:: lock.release()
+
+ Releases the lock. The lock must have been acquired earlier, but not
+ necessarily by the same thread.
+
+
+.. method:: lock.locked()
+
+ Return the status of the lock: ``True`` if it has been acquired by some thread,
+ ``False`` if not.
+
+In addition to these methods, lock objects can also be used via the
+:keyword:`with` statement, e.g.::
+
+ import _thread
+
+ a_lock = _thread.allocate_lock()
+
+ with a_lock:
+ print("a_lock is locked while this executes")
+
+**Caveats:**
+
+ .. index:: module: signal
+
+* Threads interact strangely with interrupts: the :exc:`KeyboardInterrupt`
+ exception will be received by an arbitrary thread. (When the :mod:`signal`
+ module is available, interrupts always go to the main thread.)
+
+* Calling :func:`sys.exit` or raising the :exc:`SystemExit` exception is
+ equivalent to calling :func:`_thread.exit`.
+
+* Not all built-in functions that may block waiting for I/O allow other threads
+ to run. (The most popular ones (:func:`time.sleep`, :meth:`file.read`,
+ :func:`select.select`) work as expected.)
+
+* It is not possible to interrupt the :meth:`acquire` method on a lock --- the
+ :exc:`KeyboardInterrupt` exception will happen after the lock has been acquired.
+
+* When the main thread exits, it is system defined whether the other threads
+ survive. On most systems, they are killed without executing
+ :keyword:`try` ... :keyword:`finally` clauses or executing object
+ destructors.
+
+* When the main thread exits, it does not do any of its usual cleanup (except
+ that :keyword:`try` ... :keyword:`finally` clauses are honored), and the
+ standard I/O files are not flushed.
+
diff --git a/Doc/library/_winreg.rst b/Doc/library/_winreg.rst
deleted file mode 100644
index f82d1c5..0000000
--- a/Doc/library/_winreg.rst
+++ /dev/null
@@ -1,716 +0,0 @@
-:mod:`_winreg` -- Windows registry access
-=========================================
-
-.. module:: _winreg
- :platform: Windows
- :synopsis: Routines and objects for manipulating the Windows registry.
-.. sectionauthor:: Mark Hammond <MarkH@ActiveState.com>
-
-.. note::
- The :mod:`_winreg` module has been renamed to :mod:`winreg` in Python 3.
- The :term:`2to3` tool will automatically adapt imports when converting your
- sources to Python 3.
-
-
-.. versionadded:: 2.0
-
-These functions expose the Windows registry API to Python. Instead of using an
-integer as the registry handle, a :ref:`handle object <handle-object>` is used
-to ensure that the handles are closed correctly, even if the programmer neglects
-to explicitly close them.
-
-This module offers the following functions:
-
-
-.. function:: CloseKey(hkey)
-
- Closes a previously opened registry key. The *hkey* argument specifies a
- previously opened key.
-
- .. note::
- If *hkey* is not closed using this method (or via :meth:`hkey.Close() <PyHKEY.Close>`),
- it is closed when the *hkey* object is destroyed by Python.
-
-
-.. function:: ConnectRegistry(computer_name, key)
-
- Establishes a connection to a predefined registry handle on another computer,
- and returns a :ref:`handle object <handle-object>`.
-
- *computer_name* is the name of the remote computer, of the form
- ``r"\\computername"``. If ``None``, the local computer is used.
-
- *key* is the predefined handle to connect to.
-
- The return value is the handle of the opened key. If the function fails, a
- :exc:`WindowsError` exception is raised.
-
-
-.. function:: CreateKey(key, sub_key)
-
- Creates or opens the specified key, returning a
- :ref:`handle object <handle-object>`.
-
- *key* is an already open key, or one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- *sub_key* is a string that names the key this method opens or creates.
-
- If *key* is one of the predefined keys, *sub_key* may be ``None``. In that
- case, the handle returned is the same key handle passed in to the function.
-
- If the key already exists, this function opens the existing key.
-
- The return value is the handle of the opened key. If the function fails, a
- :exc:`WindowsError` exception is raised.
-
-
-.. function:: CreateKeyEx(key, sub_key[, res[, sam]])
-
- Creates or opens the specified key, returning a
- :ref:`handle object <handle-object>`.
-
- *key* is an already open key, or one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- *sub_key* is a string that names the key this method opens or creates.
-
- *res* is a reserved integer, and must be zero. The default is zero.
-
- *sam* is an integer that specifies an access mask that describes the desired
- security access for the key. Default is :const:`KEY_ALL_ACCESS`. See
- :ref:`Access Rights <access-rights>` for other allowed values.
-
-
- If *key* is one of the predefined keys, *sub_key* may be ``None``. In that
- case, the handle returned is the same key handle passed in to the function.
-
- If the key already exists, this function opens the existing key.
-
- The return value is the handle of the opened key. If the function fails, a
- :exc:`WindowsError` exception is raised.
-
-.. versionadded:: 2.7
-
-
-.. function:: DeleteKey(key, sub_key)
-
- Deletes the specified key.
-
- *key* is an already open key, or any one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- *sub_key* is a string that must be a subkey of the key identified by the *key*
- parameter. This value must not be ``None``, and the key may not have subkeys.
-
- *This method can not delete keys with subkeys.*
-
- If the method succeeds, the entire key, including all of its values, is removed.
- If the method fails, a :exc:`WindowsError` exception is raised.
-
-
-.. function:: DeleteKeyEx(key, sub_key[, sam[, res]])
-
- Deletes the specified key.
-
- .. note::
- The :func:`DeleteKeyEx` function is implemented with the RegDeleteKeyEx
- Windows API function, which is specific to 64-bit versions of Windows.
- See the `RegDeleteKeyEx documentation
- <http://msdn.microsoft.com/en-us/library/ms724847%28VS.85%29.aspx>`__.
-
- *key* is an already open key, or any one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- *sub_key* is a string that must be a subkey of the key identified by the
- *key* parameter. This value must not be ``None``, and the key may not have
- subkeys.
-
- *res* is a reserved integer, and must be zero. The default is zero.
-
- *sam* is an integer that specifies an access mask that describes the desired
- security access for the key. Default is :const:`KEY_WOW64_64KEY`. See
- :ref:`Access Rights <access-rights>` for other allowed values.
-
-
- *This method can not delete keys with subkeys.*
-
- If the method succeeds, the entire key, including all of its values, is
- removed. If the method fails, a :exc:`WindowsError` exception is raised.
-
- On unsupported Windows versions, :exc:`NotImplementedError` is raised.
-
-.. versionadded:: 2.7
-
-
-.. function:: DeleteValue(key, value)
-
- Removes a named value from a registry key.
-
- *key* is an already open key, or one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- *value* is a string that identifies the value to remove.
-
-
-.. function:: EnumKey(key, index)
-
- Enumerates subkeys of an open registry key, returning a string.
-
- *key* is an already open key, or any one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- *index* is an integer that identifies the index of the key to retrieve.
-
- The function retrieves the name of one subkey each time it is called. It is
- typically called repeatedly until a :exc:`WindowsError` exception is
- raised, indicating, no more values are available.
-
-
-.. function:: EnumValue(key, index)
-
- Enumerates values of an open registry key, returning a tuple.
-
- *key* is an already open key, or any one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- *index* is an integer that identifies the index of the value to retrieve.
-
- The function retrieves the name of one subkey each time it is called. It is
- typically called repeatedly, until a :exc:`WindowsError` exception is
- raised, indicating no more values.
-
- The result is a tuple of 3 items:
-
- +-------+--------------------------------------------+
- | Index | Meaning |
- +=======+============================================+
- | ``0`` | A string that identifies the value name |
- +-------+--------------------------------------------+
- | ``1`` | An object that holds the value data, and |
- | | whose type depends on the underlying |
- | | registry type |
- +-------+--------------------------------------------+
- | ``2`` | An integer that identifies the type of the |
- | | value data (see table in docs for |
- | | :meth:`SetValueEx`) |
- +-------+--------------------------------------------+
-
-
-.. function:: ExpandEnvironmentStrings(unicode)
-
- Expands environment variable placeholders ``%NAME%`` in unicode strings like
- :const:`REG_EXPAND_SZ`::
-
- >>> ExpandEnvironmentStrings(u"%windir%")
- u"C:\\Windows"
-
- .. versionadded:: 2.6
-
-
-.. function:: FlushKey(key)
-
- Writes all the attributes of a key to the registry.
-
- *key* is an already open key, or one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- It is not necessary to call :func:`FlushKey` to change a key. Registry changes are
- flushed to disk by the registry using its lazy flusher. Registry changes are
- also flushed to disk at system shutdown. Unlike :func:`CloseKey`, the
- :func:`FlushKey` method returns only when all the data has been written to the
- registry. An application should only call :func:`FlushKey` if it requires
- absolute certainty that registry changes are on disk.
-
- .. note::
-
- If you don't know whether a :func:`FlushKey` call is required, it probably
- isn't.
-
-
-.. function:: LoadKey(key, sub_key, file_name)
-
- Creates a subkey under the specified key and stores registration information
- from a specified file into that subkey.
-
- *key* is a handle returned by :func:`ConnectRegistry` or one of the constants
- :const:`HKEY_USERS` or :const:`HKEY_LOCAL_MACHINE`.
-
- *sub_key* is a string that identifies the subkey to load.
-
- *file_name* is the name of the file to load registry data from. This file must
- have been created with the :func:`SaveKey` function. Under the file allocation
- table (FAT) file system, the filename may not have an extension.
-
- A call to :func:`LoadKey` fails if the calling process does not have the
- :const:`SE_RESTORE_PRIVILEGE` privilege. Note that privileges are different
- from permissions -- see the `RegLoadKey documentation
- <http://msdn.microsoft.com/en-us/library/ms724889%28v=VS.85%29.aspx>`__ for
- more details.
-
- If *key* is a handle returned by :func:`ConnectRegistry`, then the path
- specified in *file_name* is relative to the remote computer.
-
-
-.. function:: OpenKey(key, sub_key[, res[, sam]])
-
- Opens the specified key, returning a :ref:`handle object <handle-object>`.
-
- *key* is an already open key, or any one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- *sub_key* is a string that identifies the sub_key to open.
-
- *res* is a reserved integer, and must be zero. The default is zero.
-
- *sam* is an integer that specifies an access mask that describes the desired
- security access for the key. Default is :const:`KEY_READ`. See
- :ref:`Access Rights <access-rights>` for other allowed values.
-
- The result is a new handle to the specified key.
-
- If the function fails, :exc:`WindowsError` is raised.
-
-
-.. function:: OpenKeyEx()
-
- The functionality of :func:`OpenKeyEx` is provided via :func:`OpenKey`,
- by the use of default arguments.
-
-
-.. function:: QueryInfoKey(key)
-
- Returns information about a key, as a tuple.
-
- *key* is an already open key, or one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- The result is a tuple of 3 items:
-
- +-------+---------------------------------------------+
- | Index | Meaning |
- +=======+=============================================+
- | ``0`` | An integer giving the number of sub keys |
- | | this key has. |
- +-------+---------------------------------------------+
- | ``1`` | An integer giving the number of values this |
- | | key has. |
- +-------+---------------------------------------------+
- | ``2`` | A long integer giving when the key was last |
- | | modified (if available) as 100's of |
- | | nanoseconds since Jan 1, 1600. |
- +-------+---------------------------------------------+
-
-
-.. function:: QueryValue(key, sub_key)
-
- Retrieves the unnamed value for a key, as a string.
-
- *key* is an already open key, or one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- *sub_key* is a string that holds the name of the subkey with which the value is
- associated. If this parameter is ``None`` or empty, the function retrieves the
- value set by the :func:`SetValue` method for the key identified by *key*.
-
- Values in the registry have name, type, and data components. This method
- retrieves the data for a key's first value that has a NULL name. But the
- underlying API call doesn't return the type, so always use
- :func:`QueryValueEx` if possible.
-
-
-.. function:: QueryValueEx(key, value_name)
-
- Retrieves the type and data for a specified value name associated with
- an open registry key.
-
- *key* is an already open key, or one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- *value_name* is a string indicating the value to query.
-
- The result is a tuple of 2 items:
-
- +-------+-----------------------------------------+
- | Index | Meaning |
- +=======+=========================================+
- | ``0`` | The value of the registry item. |
- +-------+-----------------------------------------+
- | ``1`` | An integer giving the registry type for |
- | | this value (see table in docs for |
- | | :meth:`SetValueEx`) |
- +-------+-----------------------------------------+
-
-
-.. function:: SaveKey(key, file_name)
-
- Saves the specified key, and all its subkeys to the specified file.
-
- *key* is an already open key, or one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- *file_name* is the name of the file to save registry data to. This file
- cannot already exist. If this filename includes an extension, it cannot be
- used on file allocation table (FAT) file systems by the :meth:`LoadKey`
- method.
-
- If *key* represents a key on a remote computer, the path described by
- *file_name* is relative to the remote computer. The caller of this method must
- possess the :const:`SeBackupPrivilege` security privilege. Note that
- privileges are different than permissions -- see the
- `Conflicts Between User Rights and Permissions documentation
- <http://msdn.microsoft.com/en-us/library/ms724878%28v=VS.85%29.aspx>`__
- for more details.
-
- This function passes NULL for *security_attributes* to the API.
-
-
-.. function:: SetValue(key, sub_key, type, value)
-
- Associates a value with a specified key.
-
- *key* is an already open key, or one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- *sub_key* is a string that names the subkey with which the value is associated.
-
- *type* is an integer that specifies the type of the data. Currently this must be
- :const:`REG_SZ`, meaning only strings are supported. Use the :func:`SetValueEx`
- function for support for other data types.
-
- *value* is a string that specifies the new value.
-
- If the key specified by the *sub_key* parameter does not exist, the SetValue
- function creates it.
-
- Value lengths are limited by available memory. Long values (more than 2048
- bytes) should be stored as files with the filenames stored in the configuration
- registry. This helps the registry perform efficiently.
-
- The key identified by the *key* parameter must have been opened with
- :const:`KEY_SET_VALUE` access.
-
-
-.. function:: SetValueEx(key, value_name, reserved, type, value)
-
- Stores data in the value field of an open registry key.
-
- *key* is an already open key, or one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- *value_name* is a string that names the subkey with which the value is
- associated.
-
- *type* is an integer that specifies the type of the data. See
- :ref:`Value Types <value-types>` for the available types.
-
- *reserved* can be anything -- zero is always passed to the API.
-
- *value* is a string that specifies the new value.
-
- This method can also set additional value and type information for the specified
- key. The key identified by the key parameter must have been opened with
- :const:`KEY_SET_VALUE` access.
-
- To open the key, use the :func:`CreateKey` or :func:`OpenKey` methods.
-
- Value lengths are limited by available memory. Long values (more than 2048
- bytes) should be stored as files with the filenames stored in the configuration
- registry. This helps the registry perform efficiently.
-
-
-.. function:: DisableReflectionKey(key)
-
- Disables registry reflection for 32-bit processes running on a 64-bit
- operating system.
-
- *key* is an already open key, or one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- Will generally raise :exc:`NotImplemented` if executed on a 32-bit
- operating system.
-
- If the key is not on the reflection list, the function succeeds but has no
- effect. Disabling reflection for a key does not affect reflection of any
- subkeys.
-
-
-.. function:: EnableReflectionKey(key)
-
- Restores registry reflection for the specified disabled key.
-
- *key* is an already open key, or one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- Will generally raise :exc:`NotImplemented` if executed on a 32-bit
- operating system.
-
- Restoring reflection for a key does not affect reflection of any subkeys.
-
-
-.. function:: QueryReflectionKey(key)
-
- Determines the reflection state for the specified key.
-
- *key* is an already open key, or one of the predefined
- :ref:`HKEY_* constants <hkey-constants>`.
-
- Returns ``True`` if reflection is disabled.
-
- Will generally raise :exc:`NotImplemented` if executed on a 32-bit
- operating system.
-
-
-.. _constants:
-
-Constants
-------------------
-
-The following constants are defined for use in many :mod:`_winreg` functions.
-
-.. _hkey-constants:
-
-HKEY_* Constants
-++++++++++++++++
-
-.. data:: HKEY_CLASSES_ROOT
-
- Registry entries subordinate to this key define types (or classes) of
- documents and the properties associated with those types. Shell and
- COM applications use the information stored under this key.
-
-
-.. data:: HKEY_CURRENT_USER
-
- Registry entries subordinate to this key define the preferences of
- the current user. These preferences include the settings of
- environment variables, data about program groups, colors, printers,
- network connections, and application preferences.
-
-.. data:: HKEY_LOCAL_MACHINE
-
- Registry entries subordinate to this key define the physical state
- of the computer, including data about the bus type, system memory,
- and installed hardware and software.
-
-.. data:: HKEY_USERS
-
- Registry entries subordinate to this key define the default user
- configuration for new users on the local computer and the user
- configuration for the current user.
-
-.. data:: HKEY_PERFORMANCE_DATA
-
- Registry entries subordinate to this key allow you to access
- performance data. The data is not actually stored in the registry;
- the registry functions cause the system to collect the data from
- its source.
-
-
-.. data:: HKEY_CURRENT_CONFIG
-
- Contains information about the current hardware profile of the
- local computer system.
-
-.. data:: HKEY_DYN_DATA
-
- This key is not used in versions of Windows after 98.
-
-
-.. _access-rights:
-
-Access Rights
-+++++++++++++
-
-For more information, see `Registry Key Security and Access
-<http://msdn.microsoft.com/en-us/library/ms724878%28v=VS.85%29.aspx>`__.
-
-.. data:: KEY_ALL_ACCESS
-
- Combines the STANDARD_RIGHTS_REQUIRED, :const:`KEY_QUERY_VALUE`,
- :const:`KEY_SET_VALUE`, :const:`KEY_CREATE_SUB_KEY`,
- :const:`KEY_ENUMERATE_SUB_KEYS`, :const:`KEY_NOTIFY`,
- and :const:`KEY_CREATE_LINK` access rights.
-
-.. data:: KEY_WRITE
-
- Combines the STANDARD_RIGHTS_WRITE, :const:`KEY_SET_VALUE`, and
- :const:`KEY_CREATE_SUB_KEY` access rights.
-
-.. data:: KEY_READ
-
- Combines the STANDARD_RIGHTS_READ, :const:`KEY_QUERY_VALUE`,
- :const:`KEY_ENUMERATE_SUB_KEYS`, and :const:`KEY_NOTIFY` values.
-
-.. data:: KEY_EXECUTE
-
- Equivalent to :const:`KEY_READ`.
-
-.. data:: KEY_QUERY_VALUE
-
- Required to query the values of a registry key.
-
-.. data:: KEY_SET_VALUE
-
- Required to create, delete, or set a registry value.
-
-.. data:: KEY_CREATE_SUB_KEY
-
- Required to create a subkey of a registry key.
-
-.. data:: KEY_ENUMERATE_SUB_KEYS
-
- Required to enumerate the subkeys of a registry key.
-
-.. data:: KEY_NOTIFY
-
- Required to request change notifications for a registry key or for
- subkeys of a registry key.
-
-.. data:: KEY_CREATE_LINK
-
- Reserved for system use.
-
-
-.. _64-bit-access-rights:
-
-64-bit Specific
-***************
-
-For more information, see `Accesing an Alternate Registry View
-<http://msdn.microsoft.com/en-us/library/aa384129(v=VS.85).aspx>`__.
-
-.. data:: KEY_WOW64_64KEY
-
- Indicates that an application on 64-bit Windows should operate on
- the 64-bit registry view.
-
-.. data:: KEY_WOW64_32KEY
-
- Indicates that an application on 64-bit Windows should operate on
- the 32-bit registry view.
-
-
-.. _value-types:
-
-Value Types
-+++++++++++
-
-For more information, see `Registry Value Types
-<http://msdn.microsoft.com/en-us/library/ms724884%28v=VS.85%29.aspx>`__.
-
-.. data:: REG_BINARY
-
- Binary data in any form.
-
-.. data:: REG_DWORD
-
- 32-bit number.
-
-.. data:: REG_DWORD_LITTLE_ENDIAN
-
- A 32-bit number in little-endian format.
-
-.. data:: REG_DWORD_BIG_ENDIAN
-
- A 32-bit number in big-endian format.
-
-.. data:: REG_EXPAND_SZ
-
- Null-terminated string containing references to environment
- variables (``%PATH%``).
-
-.. data:: REG_LINK
-
- A Unicode symbolic link.
-
-.. data:: REG_MULTI_SZ
-
- A sequence of null-terminated strings, terminated by two null characters.
- (Python handles this termination automatically.)
-
-.. data:: REG_NONE
-
- No defined value type.
-
-.. data:: REG_RESOURCE_LIST
-
- A device-driver resource list.
-
-.. data:: REG_FULL_RESOURCE_DESCRIPTOR
-
- A hardware setting.
-
-.. data:: REG_RESOURCE_REQUIREMENTS_LIST
-
- A hardware resource list.
-
-.. data:: REG_SZ
-
- A null-terminated string.
-
-
-.. _handle-object:
-
-Registry Handle Objects
------------------------
-
-This object wraps a Windows HKEY object, automatically closing it when the
-object is destroyed. To guarantee cleanup, you can call either the
-:meth:`~PyHKEY.Close` method on the object, or the :func:`CloseKey` function.
-
-All registry functions in this module return one of these objects.
-
-All registry functions in this module which accept a handle object also accept
-an integer, however, use of the handle object is encouraged.
-
-Handle objects provide semantics for :meth:`__nonzero__` -- thus::
-
- if handle:
- print "Yes"
-
-will print ``Yes`` if the handle is currently valid (has not been closed or
-detached).
-
-The object also support comparison semantics, so handle objects will compare
-true if they both reference the same underlying Windows handle value.
-
-Handle objects can be converted to an integer (e.g., using the built-in
-:func:`int` function), in which case the underlying Windows handle value is
-returned. You can also use the :meth:`~PyHKEY.Detach` method to return the
-integer handle, and also disconnect the Windows handle from the handle object.
-
-
-.. method:: PyHKEY.Close()
-
- Closes the underlying Windows handle.
-
- If the handle is already closed, no error is raised.
-
-
-.. method:: PyHKEY.Detach()
-
- Detaches the Windows handle from the handle object.
-
- The result is an integer (or long on 64 bit Windows) that holds the value of the
- handle before it is detached. If the handle is already detached or closed, this
- will return zero.
-
- After calling this function, the handle is effectively invalidated, but the
- handle is not closed. You would call this function when you need the
- underlying Win32 handle to exist beyond the lifetime of the handle object.
-
-.. method:: PyHKEY.__enter__()
- PyHKEY.__exit__(\*exc_info)
-
- The HKEY object implements :meth:`~object.__enter__` and
- :meth:`~object.__exit__` and thus supports the context protocol for the
- :keyword:`with` statement::
-
- with OpenKey(HKEY_LOCAL_MACHINE, "foo") as key:
- ... # work with key
-
- will automatically close *key* when control leaves the :keyword:`with` block.
-
- .. versionadded:: 2.6
-
diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst
index ef8b08e..dcec19a 100644
--- a/Doc/library/abc.rst
+++ b/Doc/library/abc.rst
@@ -7,8 +7,6 @@
.. sectionauthor:: Georg Brandl
.. much of the content adapted from docstrings
-.. versionadded:: 2.6
-
**Source code:** :source:`Lib/abc.py`
--------------
@@ -49,8 +47,8 @@ This module provides the following class:
from abc import ABCMeta
- class MyABC:
- __metaclass__ = ABCMeta
+ class MyABC(metaclass=ABCMeta):
+ pass
MyABC.register(tuple)
@@ -81,7 +79,7 @@ This module provides the following class:
For a demonstration of these concepts, look at this example ABC definition::
- class Foo(object):
+ class Foo:
def __getitem__(self, index):
...
def __len__(self):
@@ -89,8 +87,7 @@ This module provides the following class:
def get_iterator(self):
return iter(self)
- class MyIterable:
- __metaclass__ = ABCMeta
+ class MyIterable(metaclass=ABCMeta):
@abstractmethod
def __iter__(self):
@@ -129,7 +126,7 @@ This module provides the following class:
It also provides the following decorators:
-.. function:: abstractmethod(function)
+.. decorator:: abstractmethod
A decorator indicating abstract methods.
@@ -149,8 +146,7 @@ It also provides the following decorators:
Usage::
- class C:
- __metaclass__ = ABCMeta
+ class C(metaclass=ABCMeta):
@abstractmethod
def my_abstract_method(self, ...):
...
@@ -165,7 +161,37 @@ It also provides the following decorators:
multiple-inheritance.
-.. function:: abstractproperty([fget[, fset[, fdel[, doc]]]])
+.. decorator:: abstractclassmethod
+
+ A subclass of the built-in :func:`classmethod`, indicating an abstract
+ classmethod. Otherwise it is similar to :func:`abstractmethod`.
+
+ Usage::
+
+ class C(metaclass=ABCMeta):
+ @abstractclassmethod
+ def my_abstract_classmethod(cls, ...):
+ ...
+
+ .. versionadded:: 3.2
+
+
+.. decorator:: abstractstaticmethod
+
+ A subclass of the built-in :func:`staticmethod`, indicating an abstract
+ staticmethod. Otherwise it is similar to :func:`abstractmethod`.
+
+ Usage::
+
+ class C(metaclass=ABCMeta):
+ @abstractstaticmethod
+ def my_abstract_staticmethod(...):
+ ...
+
+ .. versionadded:: 3.2
+
+
+.. function:: abstractproperty(fget=None, fset=None, fdel=None, doc=None)
A subclass of the built-in :func:`property`, indicating an abstract property.
@@ -178,8 +204,7 @@ It also provides the following decorators:
Usage::
- class C:
- __metaclass__ = ABCMeta
+ class C(metaclass=ABCMeta):
@abstractproperty
def my_abstract_property(self):
...
@@ -187,8 +212,7 @@ It also provides the following decorators:
This defines a read-only property; you can also define a read-write abstract
property using the 'long' form of property declaration::
- class C:
- __metaclass__ = ABCMeta
+ class C(metaclass=ABCMeta):
def getx(self): ...
def setx(self, value): ...
x = abstractproperty(getx, setx)
diff --git a/Doc/library/aepack.rst b/Doc/library/aepack.rst
deleted file mode 100644
index a2adc9c..0000000
--- a/Doc/library/aepack.rst
+++ /dev/null
@@ -1,92 +0,0 @@
-
-:mod:`aepack` --- Conversion between Python variables and AppleEvent data containers
-====================================================================================
-
-.. module:: aepack
- :platform: Mac
- :synopsis: Conversion between Python variables and AppleEvent data containers.
- :deprecated:
-.. sectionauthor:: Vincent Marchetti <vincem@en.com>
-.. moduleauthor:: Jack Jansen
-
-The :mod:`aepack` module defines functions for converting (packing) Python
-variables to AppleEvent descriptors and back (unpacking). Within Python the
-AppleEvent descriptor is handled by Python objects of built-in type
-:class:`AEDesc`, defined in module :mod:`Carbon.AE`.
-
-.. note::
-
- This module has been removed in Python 3.x.
-
-
-The :mod:`aepack` module defines the following functions:
-
-
-.. function:: pack(x[, forcetype])
-
- Returns an :class:`AEDesc` object containing a conversion of Python value x. If
- *forcetype* is provided it specifies the descriptor type of the result.
- Otherwise, a default mapping of Python types to Apple Event descriptor types is
- used, as follows:
-
- +-----------------+-----------------------------------+
- | Python type | descriptor type |
- +=================+===================================+
- | :class:`FSSpec` | typeFSS |
- +-----------------+-----------------------------------+
- | :class:`FSRef` | typeFSRef |
- +-----------------+-----------------------------------+
- | :class:`Alias` | typeAlias |
- +-----------------+-----------------------------------+
- | integer | typeLong (32 bit integer) |
- +-----------------+-----------------------------------+
- | float | typeFloat (64 bit floating point) |
- +-----------------+-----------------------------------+
- | string | typeText |
- +-----------------+-----------------------------------+
- | unicode | typeUnicodeText |
- +-----------------+-----------------------------------+
- | list | typeAEList |
- +-----------------+-----------------------------------+
- | dictionary | typeAERecord |
- +-----------------+-----------------------------------+
- | instance | *see below* |
- +-----------------+-----------------------------------+
-
- If *x* is a Python instance then this function attempts to call an
- :meth:`__aepack__` method. This method should return an :class:`AEDesc` object.
-
- If the conversion *x* is not defined above, this function returns the Python
- string representation of a value (the repr() function) encoded as a text
- descriptor.
-
-
-.. function:: unpack(x[, formodulename])
-
- *x* must be an object of type :class:`AEDesc`. This function returns a Python
- object representation of the data in the Apple Event descriptor *x*. Simple
- AppleEvent data types (integer, text, float) are returned as their obvious
- Python counterparts. Apple Event lists are returned as Python lists, and the
- list elements are recursively unpacked. Object references (ex. ``line 3 of
- document 1``) are returned as instances of :class:`aetypes.ObjectSpecifier`,
- unless ``formodulename`` is specified. AppleEvent descriptors with descriptor
- type typeFSS are returned as :class:`FSSpec` objects. AppleEvent record
- descriptors are returned as Python dictionaries, with 4-character string keys
- and elements recursively unpacked.
-
- The optional ``formodulename`` argument is used by the stub packages generated
- by :mod:`gensuitemodule`, and ensures that the OSA classes for object specifiers
- are looked up in the correct module. This ensures that if, say, the Finder
- returns an object specifier for a window you get an instance of
- ``Finder.Window`` and not a generic ``aetypes.Window``. The former knows about
- all the properties and elements a window has in the Finder, while the latter
- knows no such things.
-
-
-.. seealso::
-
- Module :mod:`Carbon.AE`
- Built-in access to Apple Event Manager routines.
-
- Module :mod:`aetypes`
- Python definitions of codes for Apple Event descriptor types.
diff --git a/Doc/library/aetools.rst b/Doc/library/aetools.rst
deleted file mode 100644
index 0b8ec77..0000000
--- a/Doc/library/aetools.rst
+++ /dev/null
@@ -1,90 +0,0 @@
-
-:mod:`aetools` --- OSA client support
-=====================================
-
-.. module:: aetools
- :platform: Mac
- :synopsis: Basic support for sending Apple Events
- :deprecated:
-.. sectionauthor:: Jack Jansen <Jack.Jansen@cwi.nl>
-.. moduleauthor:: Jack Jansen
-
-The :mod:`aetools` module contains the basic functionality on which Python
-AppleScript client support is built. It also imports and re-exports the core
-functionality of the :mod:`aetypes` and :mod:`aepack` modules. The stub packages
-generated by :mod:`gensuitemodule` import the relevant portions of
-:mod:`aetools`, so usually you do not need to import it yourself. The exception
-to this is when you cannot use a generated suite package and need lower-level
-access to scripting.
-
-The :mod:`aetools` module itself uses the AppleEvent support provided by the
-:mod:`Carbon.AE` module. This has one drawback: you need access to the window
-manager, see section :ref:`osx-gui-scripts` for details. This restriction may be
-lifted in future releases.
-
-.. note::
-
- This module has been removed in Python 3.x.
-
-
-The :mod:`aetools` module defines the following functions:
-
-
-.. function:: packevent(ae, parameters, attributes)
-
- Stores parameters and attributes in a pre-created ``Carbon.AE.AEDesc`` object.
- ``parameters`` and ``attributes`` are dictionaries mapping 4-character OSA
- parameter keys to Python objects. The objects are packed using
- ``aepack.pack()``.
-
-
-.. function:: unpackevent(ae[, formodulename])
-
- Recursively unpacks a ``Carbon.AE.AEDesc`` event to Python objects. The function
- returns the parameter dictionary and the attribute dictionary. The
- ``formodulename`` argument is used by generated stub packages to control where
- AppleScript classes are looked up.
-
-
-.. function:: keysubst(arguments, keydict)
-
- Converts a Python keyword argument dictionary ``arguments`` to the format
- required by ``packevent`` by replacing the keys, which are Python identifiers,
- by the four-character OSA keys according to the mapping specified in
- ``keydict``. Used by the generated suite packages.
-
-
-.. function:: enumsubst(arguments, key, edict)
-
- If the ``arguments`` dictionary contains an entry for ``key`` convert the value
- for that entry according to dictionary ``edict``. This converts human-readable
- Python enumeration names to the OSA 4-character codes. Used by the generated
- suite packages.
-
-The :mod:`aetools` module defines the following class:
-
-
-.. class:: TalkTo([signature=None, start=0, timeout=0])
-
- Base class for the proxy used to talk to an application. ``signature`` overrides
- the class attribute ``_signature`` (which is usually set by subclasses) and is
- the 4-char creator code defining the application to talk to. ``start`` can be
- set to true to enable running the application on class instantiation.
- ``timeout`` can be specified to change the default timeout used while waiting
- for an AppleEvent reply.
-
-
-.. method:: TalkTo._start()
-
- Test whether the application is running, and attempt to start it if not.
-
-
-.. method:: TalkTo.send(code, subcode[, parameters, attributes])
-
- Create the AppleEvent ``Carbon.AE.AEDesc`` for the verb with the OSA designation
- ``code, subcode`` (which are the usual 4-character strings), pack the
- ``parameters`` and ``attributes`` into it, send it to the target application,
- wait for the reply, unpack the reply with ``unpackevent`` and return the reply
- appleevent, the unpacked return values as a dictionary and the return
- attributes.
-
diff --git a/Doc/library/aetypes.rst b/Doc/library/aetypes.rst
deleted file mode 100644
index 1e1067f..0000000
--- a/Doc/library/aetypes.rst
+++ /dev/null
@@ -1,155 +0,0 @@
-
-:mod:`aetypes` --- AppleEvent objects
-=====================================
-
-.. module:: aetypes
- :platform: Mac
- :synopsis: Python representation of the Apple Event Object Model.
- :deprecated:
-.. sectionauthor:: Vincent Marchetti <vincem@en.com>
-.. moduleauthor:: Jack Jansen
-
-The :mod:`aetypes` defines classes used to represent Apple Event data
-descriptors and Apple Event object specifiers.
-
-Apple Event data is contained in descriptors, and these descriptors are typed.
-For many descriptors the Python representation is simply the corresponding
-Python type: ``typeText`` in OSA is a Python string, ``typeFloat`` is a float,
-etc. For OSA types that have no direct Python counterpart this module declares
-classes. Packing and unpacking instances of these classes is handled
-automatically by :mod:`aepack`.
-
-An object specifier is essentially an address of an object implemented in a
-Apple Event server. An Apple Event specifier is used as the direct object for an
-Apple Event or as the argument of an optional parameter. The :mod:`aetypes`
-module contains the base classes for OSA classes and properties, which are used
-by the packages generated by :mod:`gensuitemodule` to populate the classes and
-properties in a given suite.
-
-For reasons of backward compatibility, and for cases where you need to script an
-application for which you have not generated the stub package this module also
-contains object specifiers for a number of common OSA classes such as
-``Document``, ``Window``, ``Character``, etc.
-
-.. note::
-
- This module has been removed in Python 3.x.
-
-
-
-The :mod:`AEObjects` module defines the following classes to represent Apple
-Event descriptor data:
-
-
-.. class:: Unknown(type, data)
-
- The representation of OSA descriptor data for which the :mod:`aepack` and
- :mod:`aetypes` modules have no support, i.e. anything that is not represented by
- the other classes here and that is not equivalent to a simple Python value.
-
-
-.. class:: Enum(enum)
-
- An enumeration value with the given 4-character string value.
-
-
-.. class:: InsertionLoc(of, pos)
-
- Position ``pos`` in object ``of``.
-
-
-.. class:: Boolean(bool)
-
- A boolean.
-
-
-.. class:: StyledText(style, text)
-
- Text with style information (font, face, etc) included.
-
-
-.. class:: AEText(script, style, text)
-
- Text with script system and style information included.
-
-
-.. class:: IntlText(script, language, text)
-
- Text with script system and language information included.
-
-
-.. class:: IntlWritingCode(script, language)
-
- Script system and language information.
-
-
-.. class:: QDPoint(v, h)
-
- A quickdraw point.
-
-
-.. class:: QDRectangle(v0, h0, v1, h1)
-
- A quickdraw rectangle.
-
-
-.. class:: RGBColor(r, g, b)
-
- A color.
-
-
-.. class:: Type(type)
-
- An OSA type value with the given 4-character name.
-
-
-.. class:: Keyword(name)
-
- An OSA keyword with the given 4-character name.
-
-
-.. class:: Range(start, stop)
-
- A range.
-
-
-.. class:: Ordinal(abso)
-
- Non-numeric absolute positions, such as ``"firs"``, first, or ``"midd"``,
- middle.
-
-
-.. class:: Logical(logc, term)
-
- The logical expression of applying operator ``logc`` to ``term``.
-
-
-.. class:: Comparison(obj1, relo, obj2)
-
- The comparison ``relo`` of ``obj1`` to ``obj2``.
-
-The following classes are used as base classes by the generated stub packages to
-represent AppleScript classes and properties in Python:
-
-
-.. class:: ComponentItem(which[, fr])
-
- Abstract baseclass for an OSA class. The subclass should set the class attribute
- ``want`` to the 4-character OSA class code. Instances of subclasses of this
- class are equivalent to AppleScript Object Specifiers. Upon instantiation you
- should pass a selector in ``which``, and optionally a parent object in ``fr``.
-
-
-.. class:: NProperty(fr)
-
- Abstract baseclass for an OSA property. The subclass should set the class
- attributes ``want`` and ``which`` to designate which property we are talking
- about. Instances of subclasses of this class are Object Specifiers.
-
-
-.. class:: ObjectSpecifier(want, form, seld[, fr])
-
- Base class of ``ComponentItem`` and ``NProperty``, a general OSA Object
- Specifier. See the Apple Open Scripting Architecture documentation for the
- parameters. Note that this class is not abstract.
-
diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst
index 1265423..999bad8 100644
--- a/Doc/library/aifc.rst
+++ b/Doc/library/aifc.rst
@@ -41,13 +41,13 @@ frame size of 4 bytes (2\*2), and a second's worth occupies 2\*2\*44100 bytes
Module :mod:`aifc` defines the following function:
-.. function:: open(file[, mode])
+.. function:: open(file, mode=None)
Open an AIFF or AIFF-C file and return an object instance with methods that are
- described below. The argument *file* is either a string naming a file or a file
- object. *mode* must be ``'r'`` or ``'rb'`` when the file must be opened for
- reading, or ``'w'`` or ``'wb'`` when the file must be opened for writing. If
- omitted, ``file.mode`` is used if it exists, otherwise ``'rb'`` is used. When
+ described below. The argument *file* is either a string naming a file or a
+ :term:`file object`. *mode* must be ``'r'`` or ``'rb'`` when the file must be
+ opened for reading, or ``'w'`` or ``'wb'`` when the file must be opened for writing.
+ If omitted, ``file.mode`` is used if it exists, otherwise ``'rb'`` is used. When
used for writing, the file object should be seekable, unless you know ahead of
time how many samples you are going to write in total and use
:meth:`writeframesraw` and :meth:`setnframes`.
@@ -78,14 +78,16 @@ following methods:
.. method:: aifc.getcomptype()
- Return a four-character string describing the type of compression used in the
- audio file. For AIFF files, the returned value is ``'NONE'``.
+ Return a bytes array of length 4 describing the type of compression
+ used in the audio file. For AIFF files, the returned value is
+ ``b'NONE'``.
.. method:: aifc.getcompname()
- Return a human-readable description of the type of compression used in the audio
- file. For AIFF files, the returned value is ``'not compressed'``.
+ Return a bytes array convertible to a human-readable description
+ of the type of compression used in the audio file. For AIFF files,
+ the returned value is ``b'not compressed'``.
.. method:: aifc.getparams()
@@ -184,11 +186,12 @@ number of frames must be filled in.
single: A-LAW
single: G.722
- Specify the compression type. If not specified, the audio data will not be
- compressed. In AIFF files, compression is not possible. The name parameter
- should be a human-readable description of the compression type, the type
- parameter should be a four-character string. Currently the following
- compression types are supported: NONE, ULAW, ALAW, G722.
+ Specify the compression type. If not specified, the audio data will
+ not be compressed. In AIFF files, compression is not possible.
+ The name parameter should be a human-readable description of the
+ compression type as a bytes array, the type parameter should be a
+ bytes array of length 4. Currently the following compression types
+ are supported: ``b'NONE'``, ``b'ULAW'``, ``b'ALAW'``, ``b'G722'``.
.. method:: aifc.setparams(nchannels, sampwidth, framerate, comptype, compname)
diff --git a/Doc/library/al.rst b/Doc/library/al.rst
deleted file mode 100644
index f796c5c..0000000
--- a/Doc/library/al.rst
+++ /dev/null
@@ -1,214 +0,0 @@
-
-:mod:`al` --- Audio functions on the SGI
-========================================
-
-.. module:: al
- :platform: IRIX
- :synopsis: Audio functions on the SGI.
- :deprecated:
-
-.. deprecated:: 2.6
- The :mod:`al` module has been removed in Python 3.
-
-
-This module provides access to the audio facilities of the SGI Indy and Indigo
-workstations. See section 3A of the IRIX man pages for details. You'll need to
-read those man pages to understand what these functions do! Some of the
-functions are not available in IRIX releases before 4.0.5. Again, see the
-manual to check whether a specific function is available on your platform.
-
-All functions and methods defined in this module are equivalent to the C
-functions with ``AL`` prefixed to their name.
-
-.. index:: module: AL
-
-Symbolic constants from the C header file ``<audio.h>`` are defined in the
-standard module :mod:`AL`, see below.
-
-.. warning::
-
- The current version of the audio library may dump core when bad argument values
- are passed rather than returning an error status. Unfortunately, since the
- precise circumstances under which this may happen are undocumented and hard to
- check, the Python interface can provide no protection against this kind of
- problems. (One example is specifying an excessive queue size --- there is no
- documented upper limit.)
-
-The module defines the following functions:
-
-
-.. function:: openport(name, direction[, config])
-
- The name and direction arguments are strings. The optional *config* argument is
- a configuration object as returned by :func:`newconfig`. The return value is an
- :dfn:`audio port object`; methods of audio port objects are described below.
-
-
-.. function:: newconfig()
-
- The return value is a new :dfn:`audio configuration object`; methods of audio
- configuration objects are described below.
-
-
-.. function:: queryparams(device)
-
- The device argument is an integer. The return value is a list of integers
- containing the data returned by :c:func:`ALqueryparams`.
-
-
-.. function:: getparams(device, list)
-
- The *device* argument is an integer. The list argument is a list such as
- returned by :func:`queryparams`; it is modified in place (!).
-
-
-.. function:: setparams(device, list)
-
- The *device* argument is an integer. The *list* argument is a list such as
- returned by :func:`queryparams`.
-
-
-.. _al-config-objects:
-
-Configuration Objects
----------------------
-
-Configuration objects returned by :func:`newconfig` have the following methods:
-
-
-.. method:: audio configuration.getqueuesize()
-
- Return the queue size.
-
-
-.. method:: audio configuration.setqueuesize(size)
-
- Set the queue size.
-
-
-.. method:: audio configuration.getwidth()
-
- Get the sample width.
-
-
-.. method:: audio configuration.setwidth(width)
-
- Set the sample width.
-
-
-.. method:: audio configuration.getchannels()
-
- Get the channel count.
-
-
-.. method:: audio configuration.setchannels(nchannels)
-
- Set the channel count.
-
-
-.. method:: audio configuration.getsampfmt()
-
- Get the sample format.
-
-
-.. method:: audio configuration.setsampfmt(sampfmt)
-
- Set the sample format.
-
-
-.. method:: audio configuration.getfloatmax()
-
- Get the maximum value for floating sample formats.
-
-
-.. method:: audio configuration.setfloatmax(floatmax)
-
- Set the maximum value for floating sample formats.
-
-
-.. _al-port-objects:
-
-Port Objects
-------------
-
-Port objects, as returned by :func:`openport`, have the following methods:
-
-
-.. method:: audio port.closeport()
-
- Close the port.
-
-
-.. method:: audio port.getfd()
-
- Return the file descriptor as an int.
-
-
-.. method:: audio port.getfilled()
-
- Return the number of filled samples.
-
-
-.. method:: audio port.getfillable()
-
- Return the number of fillable samples.
-
-
-.. method:: audio port.readsamps(nsamples)
-
- Read a number of samples from the queue, blocking if necessary. Return the data
- as a string containing the raw data, (e.g., 2 bytes per sample in big-endian
- byte order (high byte, low byte) if you have set the sample width to 2 bytes).
-
-
-.. method:: audio port.writesamps(samples)
-
- Write samples into the queue, blocking if necessary. The samples are encoded as
- described for the :meth:`readsamps` return value.
-
-
-.. method:: audio port.getfillpoint()
-
- Return the 'fill point'.
-
-
-.. method:: audio port.setfillpoint(fillpoint)
-
- Set the 'fill point'.
-
-
-.. method:: audio port.getconfig()
-
- Return a configuration object containing the current configuration of the port.
-
-
-.. method:: audio port.setconfig(config)
-
- Set the configuration from the argument, a configuration object.
-
-
-.. method:: audio port.getstatus(list)
-
- Get status information on last error.
-
-
-:mod:`AL` --- Constants used with the :mod:`al` module
-======================================================
-
-.. module:: AL
- :platform: IRIX
- :synopsis: Constants used with the al module.
- :deprecated:
-
-.. deprecated:: 2.6
- The :mod:`AL` module has been removed in Python 3.
-
-
-This module defines symbolic constants needed to use the built-in module
-:mod:`al` (see above); they are equivalent to those defined in the C header file
-``<audio.h>`` except that the name prefix ``AL_`` is omitted. Read the module
-source for a complete list of the defined names. Suggested use::
-
- import al
- from AL import *
-
diff --git a/Doc/library/allos.rst b/Doc/library/allos.rst
index 745d1d2..bf91717 100644
--- a/Doc/library/allos.rst
+++ b/Doc/library/allos.rst
@@ -1,4 +1,3 @@
-
.. _allos:
*********************************
diff --git a/Doc/library/anydbm.rst b/Doc/library/anydbm.rst
deleted file mode 100644
index 86d8a59..0000000
--- a/Doc/library/anydbm.rst
+++ /dev/null
@@ -1,114 +0,0 @@
-:mod:`anydbm` --- Generic access to DBM-style databases
-=======================================================
-
-.. module:: anydbm
- :synopsis: Generic interface to DBM-style database modules.
-
-
-.. note::
- The :mod:`anydbm` module has been renamed to :mod:`dbm` in Python 3. The
- :term:`2to3` tool will automatically adapt imports when converting your
- sources to Python 3.
-
-.. index::
- module: dbhash
- module: bsddb
- module: gdbm
- module: dbm
- module: dumbdbm
-
-:mod:`anydbm` is a generic interface to variants of the DBM database ---
-:mod:`dbhash` (requires :mod:`bsddb`), :mod:`gdbm`, or :mod:`dbm`. If none of
-these modules is installed, the slow-but-simple implementation in module
-:mod:`dumbdbm` will be used.
-
-
-.. function:: open(filename[, flag[, mode]])
-
- Open the database file *filename* and return a corresponding object.
-
- If the database file already exists, the :mod:`whichdb` module is used to
- determine its type and the appropriate module is used; if it does not exist,
- the first module listed above that can be imported is used.
-
- The optional *flag* argument must be one of these values:
-
- +---------+-------------------------------------------+
- | Value | Meaning |
- +=========+===========================================+
- | ``'r'`` | Open existing database for reading only |
- | | (default) |
- +---------+-------------------------------------------+
- | ``'w'`` | Open existing database for reading and |
- | | writing |
- +---------+-------------------------------------------+
- | ``'c'`` | Open database for reading and writing, |
- | | creating it if it doesn't exist |
- +---------+-------------------------------------------+
- | ``'n'`` | Always create a new, empty database, open |
- | | for reading and writing |
- +---------+-------------------------------------------+
-
- If not specified, the default value is ``'r'``.
-
- The optional *mode* argument is the Unix mode of the file, used only when the
- database has to be created. It defaults to octal ``0666`` (and will be
- modified by the prevailing umask).
-
-
-.. exception:: error
-
- A tuple containing the exceptions that can be raised by each of the supported
- modules, with a unique exception also named :exc:`anydbm.error` as the first
- item --- the latter is used when :exc:`anydbm.error` is raised.
-
-The object returned by :func:`.open` supports most of the same functionality as
-dictionaries; keys and their corresponding values can be stored, retrieved, and
-deleted, and the :meth:`has_key` and :meth:`keys` methods are available. Keys
-and values must always be strings.
-
-The following example records some hostnames and a corresponding title, and
-then prints out the contents of the database::
-
- import anydbm
-
- # Open database, creating it if necessary.
- db = anydbm.open('cache', 'c')
-
- # Record some values
- db['www.python.org'] = 'Python Website'
- db['www.cnn.com'] = 'Cable News Network'
-
- # Loop through contents. Other dictionary methods
- # such as .keys(), .values() also work.
- for k, v in db.iteritems():
- print k, '\t', v
-
- # Storing a non-string key or value will raise an exception (most
- # likely a TypeError).
- db['www.yahoo.com'] = 4
-
- # Close when done.
- db.close()
-
-
-.. seealso::
-
- Module :mod:`dbhash`
- BSD ``db`` database interface.
-
- Module :mod:`dbm`
- Standard Unix database interface.
-
- Module :mod:`dumbdbm`
- Portable implementation of the ``dbm`` interface.
-
- Module :mod:`gdbm`
- GNU database interface, based on the ``dbm`` interface.
-
- Module :mod:`shelve`
- General object persistence built on top of the Python ``dbm`` interface.
-
- Module :mod:`whichdb`
- Utility module used to determine the type of an existing database.
-
diff --git a/Doc/library/archiving.rst b/Doc/library/archiving.rst
index 472c617..75d137c 100644
--- a/Doc/library/archiving.rst
+++ b/Doc/library/archiving.rst
@@ -1,4 +1,3 @@
-
.. _archiving:
******************************
diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst
index 73d454e..3c2b862 100644
--- a/Doc/library/argparse.rst
+++ b/Doc/library/argparse.rst
@@ -6,7 +6,7 @@
.. moduleauthor:: Steven Bethard <steven.bethard@gmail.com>
.. sectionauthor:: Steven Bethard <steven.bethard@gmail.com>
-.. versionadded:: 2.7
+.. versionadded:: 3.2
**Source code:** :source:`Lib/argparse.py`
@@ -41,7 +41,7 @@ produces either the sum or the max::
help='sum the integers (default: find the max)')
args = parser.parse_args()
- print args.accumulate(args.integers)
+ print(args.accumulate(args.integers))
Assuming the Python code above is saved into a file called ``prog.py``, it can
be run at the command line and provides useful help messages::
@@ -683,17 +683,15 @@ how the command-line arguments should be handled. The supported actions are:
>>> parser.parse_args('--foo'.split())
Namespace(foo=42)
-* ``'store_true'`` and ``'store_false'`` - These are special cases of
- ``'store_const'`` using for storing the values ``True`` and ``False``
- respectively. In addition, they create default values of *False* and *True*
- respectively. For example::
+* ``'store_true'`` and ``'store_false'`` - These store the values ``True`` and
+ ``False`` respectively. These are special cases of ``'store_const'``. For
+ example::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
>>> parser.add_argument('--bar', action='store_false')
- >>> parser.add_argument('--baz', action='store_false')
>>> parser.parse_args('--foo --bar'.split())
- Namespace(bar=False, baz=True, foo=True)
+ Namespace(bar=False, foo=True)
* ``'append'`` - This stores a list, and appends each argument value to the
list. This is useful to allow an option to be specified multiple times.
@@ -714,7 +712,7 @@ how the command-line arguments should be handled. The supported actions are:
>>> parser.add_argument('--str', dest='types', action='append_const', const=str)
>>> parser.add_argument('--int', dest='types', action='append_const', const=int)
>>> parser.parse_args('--str --int'.split())
- Namespace(types=[<type 'str'>, <type 'int'>])
+ Namespace(types=[<class 'str'>, <class 'int'>])
* ``'count'`` - This counts the number of times a keyword argument occurs. For
example, this is useful for increasing verbosity levels::
@@ -762,7 +760,7 @@ An example of a custom action::
>>> class FooAction(argparse.Action):
... def __call__(self, parser, namespace, values, option_string=None):
- ... print '%r %r %r' % (namespace, values, option_string)
+ ... print('%r %r %r' % (namespace, values, option_string))
... setattr(namespace, self.dest, values)
...
>>> parser = argparse.ArgumentParser()
@@ -821,11 +819,11 @@ values are:
>>> parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'),
... default=sys.stdout)
>>> parser.parse_args(['input.txt', 'output.txt'])
- Namespace(infile=<open file 'input.txt', mode 'r' at 0x...>,
- outfile=<open file 'output.txt', mode 'w' at 0x...>)
+ Namespace(infile=<_io.TextIOWrapper name='input.txt' encoding='UTF-8'>,
+ outfile=<_io.TextIOWrapper name='output.txt' encoding='UTF-8'>)
>>> parser.parse_args([])
- Namespace(infile=<open file '<stdin>', mode 'r' at 0x...>,
- outfile=<open file '<stdout>', mode 'w' at 0x...>)
+ Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>,
+ outfile=<_io.TextIOWrapper name='<stdout>' encoding='UTF-8'>)
* ``'*'``. All command-line arguments present are gathered into a list. Note that
it generally doesn't make much sense to have more than one positional argument
@@ -859,7 +857,7 @@ values are:
>>> parser.add_argument('--foo')
>>> parser.add_argument('command')
>>> parser.add_argument('args', nargs=argparse.REMAINDER)
- >>> print parser.parse_args('--foo B cmd --arg1 XX ZZ'.split())
+ >>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split()))
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')
If the ``nargs`` keyword argument is not provided, the number of arguments consumed
@@ -951,22 +949,22 @@ types and functions can be used directly as the value of the ``type`` argument::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', type=int)
- >>> parser.add_argument('bar', type=file)
+ >>> parser.add_argument('bar', type=open)
>>> parser.parse_args('2 temp.txt'.split())
- Namespace(bar=<open file 'temp.txt', mode 'r' at 0x...>, foo=2)
+ Namespace(bar=<_io.TextIOWrapper name='temp.txt' encoding='UTF-8'>, foo=2)
See the section on the default_ keyword argument for information on when the
``type`` argument is applied to default arguments.
To ease the use of various types of files, the argparse module provides the
factory FileType which takes the ``mode=`` and ``bufsize=`` arguments of the
-``file`` object. For example, ``FileType('w')`` can be used to create a
+:func:`open` function. For example, ``FileType('w')`` can be used to create a
writable file::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar', type=argparse.FileType('w'))
>>> parser.parse_args(['out.txt'])
- Namespace(bar=<open file 'out.txt', mode 'w' at 0x...>)
+ Namespace(bar=<_io.TextIOWrapper name='out.txt' encoding='UTF-8'>)
``type=`` can take any callable that takes a single string argument and returns
the converted value::
@@ -991,7 +989,7 @@ The choices_ keyword argument may be more convenient for type checkers that
simply check against a range of values::
>>> parser = argparse.ArgumentParser(prog='PROG')
- >>> parser.add_argument('foo', type=int, choices=xrange(5, 10))
+ >>> parser.add_argument('foo', type=int, choices=range(5, 10))
>>> parser.parse_args('7'.split())
Namespace(foo=7)
>>> parser.parse_args('11'.split())
@@ -1101,6 +1099,9 @@ specifiers include the program name, ``%(prog)s`` and most keyword arguments to
optional arguments:
-h, --help show this help message and exit
+As the help string supports %-formatting, if you want a literal ``%`` to appear
+in the help string, you must escape it as ``%%``.
+
:mod:`argparse` supports silencing the help entry for certain options, by
setting the ``help`` value to ``argparse.SUPPRESS``::
@@ -1380,7 +1381,7 @@ interactive prompt::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument(
- ... 'integers', metavar='int', type=int, choices=xrange(10),
+ ... 'integers', metavar='int', type=int, choices=range(10),
... nargs='+', help='an integer in the range 0..9')
>>> parser.add_argument(
... '--sum', dest='accumulate', action='store_const', const=sum,
@@ -1413,7 +1414,7 @@ It may also be useful to have an :class:`ArgumentParser` assign attributes to an
already existing object, rather than a new :class:`Namespace` object. This can
be achieved by specifying the ``namespace=`` keyword argument::
- >>> class C(object):
+ >>> class C:
... pass
...
>>> c = C()
@@ -1529,6 +1530,16 @@ Sub-commands
{foo,bar} additional help
+ Furthermore, ``add_parser`` supports an additional ``aliases`` argument,
+ which allows multiple strings to refer to the same subparser. This example,
+ like ``svn``, aliases ``co`` as a shorthand for ``checkout``::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> subparsers = parser.add_subparsers()
+ >>> checkout = subparsers.add_parser('checkout', aliases=['co'])
+ >>> checkout.add_argument('foo')
+ >>> parser.parse_args(['co', 'bar'])
+ Namespace(foo='bar')
One particularly effective way of handling sub-commands is to combine the use
of the :meth:`add_subparsers` method with calls to :meth:`set_defaults` so
@@ -1537,10 +1548,10 @@ Sub-commands
>>> # sub-command functions
>>> def foo(args):
- ... print args.x * args.y
+ ... print(args.x * args.y)
...
>>> def bar(args):
- ... print '((%s))' % args.z
+ ... print('((%s))' % args.z)
...
>>> # create the top-level parser
>>> parser = argparse.ArgumentParser()
@@ -1597,7 +1608,7 @@ FileType objects
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--output', type=argparse.FileType('wb', 0))
>>> parser.parse_args(['--output', 'out'])
- Namespace(output=<open file 'out', mode 'wb' at 0x...>)
+ Namespace(output=<_io.BufferedWriter name='out'>)
FileType objects understand the pseudo-argument ``'-'`` and automatically
convert this into ``sys.stdin`` for readable :class:`FileType` objects and
@@ -1606,7 +1617,7 @@ FileType objects
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('infile', type=argparse.FileType('r'))
>>> parser.parse_args(['-'])
- Namespace(infile=<open file '<stdin>', mode 'r' at 0x...>)
+ Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>)
Argument groups
@@ -1831,8 +1842,7 @@ Exiting methods
This method prints a usage message including the *message* to the
standard error and terminates the program with a status code of 2.
-
-.. _argparse-from-optparse:
+.. _upgrading-optparse-code:
Upgrading optparse code
-----------------------
diff --git a/Doc/library/array.rst b/Doc/library/array.rst
index d34cf38..d563cce 100644
--- a/Doc/library/array.rst
+++ b/Doc/library/array.rst
@@ -1,4 +1,3 @@
-
:mod:`array` --- Efficient arrays of numeric values
===================================================
@@ -18,8 +17,6 @@ defined:
+-----------+----------------+-------------------+-----------------------+
| Type code | C Type | Python Type | Minimum size in bytes |
+===========+================+===================+=======================+
-| ``'c'`` | char | character | 1 |
-+-----------+----------------+-------------------+-----------------------+
| ``'b'`` | signed char | int | 1 |
+-----------+----------------+-------------------+-----------------------+
| ``'B'`` | unsigned char | int | 1 |
@@ -32,11 +29,11 @@ defined:
+-----------+----------------+-------------------+-----------------------+
| ``'i'`` | signed int | int | 2 |
+-----------+----------------+-------------------+-----------------------+
-| ``'I'`` | unsigned int | long | 2 |
+| ``'I'`` | unsigned int | int | 2 |
+-----------+----------------+-------------------+-----------------------+
| ``'l'`` | signed long | int | 4 |
+-----------+----------------+-------------------+-----------------------+
-| ``'L'`` | unsigned long | long | 4 |
+| ``'L'`` | unsigned long | int | 4 |
+-----------+----------------+-------------------+-----------------------+
| ``'f'`` | float | float | 4 |
+-----------+----------------+-------------------+-----------------------+
@@ -50,10 +47,7 @@ defined:
The actual representation of values is determined by the machine architecture
(strictly speaking, by the C implementation). The actual size can be accessed
-through the :attr:`itemsize` attribute. The values stored for ``'L'`` and
-``'I'`` items will be represented as Python long integers when retrieved,
-because Python's plain integer type cannot represent the full range of C's
-unsigned (long) integers.
+through the :attr:`itemsize` attribute.
The module defines the following type:
@@ -61,21 +55,19 @@ The module defines the following type:
.. class:: array(typecode[, initializer])
A new array whose items are restricted by *typecode*, and initialized
- from the optional *initializer* value, which must be a list, string, or iterable
- over elements of the appropriate type.
-
- .. versionchanged:: 2.4
- Formerly, only lists or strings were accepted.
+ from the optional *initializer* value, which must be a list, object
+ supporting the buffer interface, or iterable over elements of the
+ appropriate type.
If given a list or string, the initializer is passed to the new array's
- :meth:`fromlist`, :meth:`fromstring`, or :meth:`fromunicode` method (see below)
+ :meth:`fromlist`, :meth:`frombytes`, or :meth:`fromunicode` method (see below)
to add initial items to the array. Otherwise, the iterable initializer is
passed to the :meth:`extend` method.
-.. data:: ArrayType
+.. data:: typecodes
- Obsolete alias for :class:`array`.
+ A string with all available type codes.
Array objects support the ordinary sequence operations of indexing, slicing,
concatenation, and multiplication. When using slice assignment, the assigned
@@ -139,17 +131,23 @@ The following data items and methods are also supported:
be raised. If *iterable* is not an array, it must be iterable and its elements
must be the right type to be appended to the array.
- .. versionchanged:: 2.4
- Formerly, the argument could only be another array.
+
+.. method:: array.frombytes(s)
+
+ Appends items from the string, interpreting the string as an array of machine
+ values (as if it had been read from a file using the :meth:`fromfile` method).
+
+ .. versionadded:: 3.2
+ :meth:`fromstring` is renamed to :meth:`frombytes` for clarity.
.. method:: array.fromfile(f, n)
- Read *n* items (as machine values) from the file object *f* and append them to
- the end of the array. If less than *n* items are available, :exc:`EOFError` is
- raised, but the items that were available are still inserted into the array.
- *f* must be a real built-in file object; something else with a :meth:`read`
- method won't do.
+ Read *n* items (as machine values) from the :term:`file object` *f* and append
+ them to the end of the array. If less than *n* items are available,
+ :exc:`EOFError` is raised, but the items that were available are still
+ inserted into the array. *f* must be a real built-in file object; something
+ else with a :meth:`read` method won't do.
.. method:: array.fromlist(list)
@@ -158,17 +156,16 @@ The following data items and methods are also supported:
a.append(x)`` except that if there is a type error, the array is unchanged.
-.. method:: array.fromstring(s)
+.. method:: array.fromstring()
- Appends items from the string, interpreting the string as an array of machine
- values (as if it had been read from a file using the :meth:`fromfile` method).
+ Deprecated alias for :meth:`frombytes`.
.. method:: array.fromunicode(s)
Extends this array with data from the given unicode string. The array must
be a type ``'u'`` array; otherwise a :exc:`ValueError` is raised. Use
- ``array.fromstring(unicodestring.encode(enc))`` to append Unicode data to an
+ ``array.frombytes(unicodestring.encode(enc))`` to append Unicode data to an
array of some other type.
@@ -191,18 +188,6 @@ The following data items and methods are also supported:
returned.
-.. method:: array.read(f, n)
-
- .. deprecated:: 1.5.1
- Use the :meth:`fromfile` method.
-
- Read *n* items (as machine values) from the file object *f* and append them to
- the end of the array. If less than *n* items are available, :exc:`EOFError` is
- raised, but the items that were available are still inserted into the array.
- *f* must be a real built-in file object; something else with a :meth:`read`
- method won't do.
-
-
.. method:: array.remove(x)
Remove the first occurrence of *x* from the array.
@@ -213,9 +198,19 @@ The following data items and methods are also supported:
Reverse the order of the items in the array.
+.. method:: array.tobytes()
+
+ Convert the array to an array of machine values and return the bytes
+ representation (the same sequence of bytes that would be written to a file by
+ the :meth:`tofile` method.)
+
+ .. versionadded:: 3.2
+ :meth:`tostring` is renamed to :meth:`tobytes` for clarity.
+
+
.. method:: array.tofile(f)
- Write all items (as machine values) to the file object *f*.
+ Write all items (as machine values) to the :term:`file object` *f*.
.. method:: array.tolist()
@@ -225,36 +220,26 @@ The following data items and methods are also supported:
.. method:: array.tostring()
- Convert the array to an array of machine values and return the string
- representation (the same sequence of bytes that would be written to a file by
- the :meth:`tofile` method.)
+ Deprecated alias for :meth:`tobytes`.
.. method:: array.tounicode()
Convert the array to a unicode string. The array must be a type ``'u'`` array;
- otherwise a :exc:`ValueError` is raised. Use ``array.tostring().decode(enc)`` to
+ otherwise a :exc:`ValueError` is raised. Use ``array.tobytes().decode(enc)`` to
obtain a unicode string from an array of some other type.
-.. method:: array.write(f)
-
- .. deprecated:: 1.5.1
- Use the :meth:`tofile` method.
-
- Write all items (as machine values) to the file object *f*.
-
When an array object is printed or converted to a string, it is represented as
``array(typecode, initializer)``. The *initializer* is omitted if the array is
-empty, otherwise it is a string if the *typecode* is ``'c'``, otherwise it is a
+empty, otherwise it is a string if the *typecode* is ``'u'``, otherwise it is a
list of numbers. The string is guaranteed to be able to be converted back to an
array with the same type and value using :func:`eval`, so long as the
:func:`array` function has been imported using ``from array import array``.
Examples::
array('l')
- array('c', 'hello world')
- array('u', u'hello \u2641')
+ array('u', 'hello \u2641')
array('l', [1, 2, 3, 4, 5])
array('d', [1.0, 2.0, 3.14])
diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst
index 5130d00..e2c0b6d 100644
--- a/Doc/library/ast.rst
+++ b/Doc/library/ast.rst
@@ -7,12 +7,6 @@
.. sectionauthor:: Martin v. Löwis <martin@v.loewis.de>
.. sectionauthor:: Georg Brandl <georg@python.org>
-.. versionadded:: 2.5
- The low-level ``_ast`` module containing only the node classes.
-
-.. versionadded:: 2.6
- The high-level ``ast`` module containing all helpers.
-
**Source code:** :source:`Lib/ast.py`
--------------
@@ -96,11 +90,6 @@ Node classes
node = ast.UnaryOp(ast.USub(), ast.Num(5, lineno=0, col_offset=0),
lineno=0, col_offset=0)
- .. versionadded:: 2.6
- The constructor as explained above was added. In Python 2.5 nodes had
- to be created by calling the class constructor without arguments and
- setting the attributes afterwards.
-
.. _abstract-grammar:
@@ -118,8 +107,6 @@ The abstract grammar is currently defined as follows:
:mod:`ast` Helpers
------------------
-.. versionadded:: 2.6
-
Apart from the node classes, :mod:`ast` module defines these utility functions
and classes for traversing abstract syntax trees:
@@ -133,12 +120,15 @@ and classes for traversing abstract syntax trees:
Safely evaluate an expression node or a string containing a Python
expression. The string or node provided may only consist of the following
- Python literal structures: strings, numbers, tuples, lists, dicts, booleans,
- and ``None``.
+ Python literal structures: strings, bytes, numbers, tuples, lists, dicts,
+ sets, booleans, and ``None``.
This can be used for safely evaluating strings containing Python expressions
from untrusted sources without the need to parse the values oneself.
+ .. versionchanged:: 3.2
+ Now allows bytes and set literals.
+
.. function:: get_docstring(node, clean=True)
diff --git a/Doc/library/asynchat.rst b/Doc/library/asynchat.rst
index 37d001b..75b3cda 100644
--- a/Doc/library/asynchat.rst
+++ b/Doc/library/asynchat.rst
@@ -145,7 +145,7 @@ connection requests.
asynchat - Auxiliary Classes
------------------------------------------
-.. class:: fifo([list=None])
+.. class:: fifo(list=None)
A :class:`fifo` holding data which has been pushed by the application but
not yet popped for writing to the channel. A :class:`fifo` is a list used
@@ -204,8 +204,8 @@ any extraneous data sent by the web client are ignored. ::
self.addr = addr
self.sessions = sessions
self.ibuffer = []
- self.obuffer = ""
- self.set_terminator("\r\n\r\n")
+ self.obuffer = b""
+ self.set_terminator(b"\r\n\r\n")
self.reading_headers = True
self.handling = False
self.cgi_data = None
@@ -220,7 +220,7 @@ any extraneous data sent by the web client are ignored. ::
self.reading_headers = False
self.parse_headers("".join(self.ibuffer))
self.ibuffer = []
- if self.op.upper() == "POST":
+ if self.op.upper() == b"POST":
clen = self.headers.getheader("content-length")
self.set_terminator(int(clen))
else:
@@ -229,7 +229,7 @@ any extraneous data sent by the web client are ignored. ::
self.handle_request()
elif not self.handling:
self.set_terminator(None) # browsers sometimes over-send
- self.cgi_data = parse(self.headers, "".join(self.ibuffer))
+ self.cgi_data = parse(self.headers, b"".join(self.ibuffer))
self.handling = True
self.ibuffer = []
self.handle_request()
diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst
index c108450..619b7bb 100644
--- a/Doc/library/asyncore.rst
+++ b/Doc/library/asyncore.rst
@@ -89,7 +89,7 @@ any that have been added to the map during asynchronous service) is closed.
| ``handle_close()`` | Implied by a read event with no data |
| | available |
+----------------------+----------------------------------------+
- | ``handle_accept()`` | Implied by a read event on a listening |
+ | ``handle_accepted()``| Implied by a read event on a listening |
| | socket |
+----------------------+----------------------------------------+
@@ -147,7 +147,21 @@ any that have been added to the map during asynchronous service) is closed.
Called on listening channels (passive openers) when a connection can be
established with a new remote endpoint that has issued a :meth:`connect`
- call for the local endpoint.
+ call for the local endpoint. Deprecated in version 3.2; use
+ :meth:`handle_accepted` instead.
+
+ .. deprecated:: 3.2
+
+
+ .. method:: handle_accepted(sock, addr)
+
+ Called on listening channels (passive openers) when a connection has been
+ established with a new remote endpoint that has issued a :meth:`connect`
+ call for the local endpoint. *sock* is a *new* socket object usable to
+ send and receive data on the connection, and *addr* is the address
+ bound to the socket on the other end of the connection.
+
+ .. versionadded:: 3.2
.. method:: readable()
@@ -229,6 +243,7 @@ any that have been added to the map during asynchronous service) is closed.
flushed). Sockets are automatically closed when they are
garbage-collected.
+
.. class:: dispatcher_with_send()
A :class:`dispatcher` subclass which adds simple buffered output capability,
@@ -237,9 +252,9 @@ any that have been added to the map during asynchronous service) is closed.
.. class:: file_dispatcher()
- A file_dispatcher takes a file descriptor or file object along with an
- optional map argument and wraps it for use with the :c:func:`poll` or
- :c:func:`loop` functions. If provided a file object or anything with a
+ A file_dispatcher takes a file descriptor or :term:`file object` along
+ with an optional map argument and wraps it for use with the :c:func:`poll`
+ or :c:func:`loop` functions. If provided a file object or anything with a
:c:func:`fileno` method, that method will be called and passed to the
:class:`file_wrapper` constructor. Availability: UNIX.
@@ -267,7 +282,8 @@ implement its socket handling::
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect( (host, 80) )
- self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % path
+ self.buffer = bytes('GET %s HTTP/1.0\r\nHost: %s\r\n\r\n' %
+ (path, host), 'ascii')
def handle_connect(self):
pass
@@ -276,7 +292,7 @@ implement its socket handling::
self.close()
def handle_read(self):
- print self.recv(8192)
+ print(self.recv(8192))
def writable(self):
return (len(self.buffer) > 0)
@@ -286,8 +302,8 @@ implement its socket handling::
self.buffer = self.buffer[sent:]
- client = HTTPClient('www.python.org', '/')
- asyncore.loop()
+ client = HTTPClient('www.python.org', '/')
+ asyncore.loop()
.. _asyncore-example-2:
@@ -316,14 +332,9 @@ connections and dispatches the incoming connections to a handler::
self.bind((host, port))
self.listen(5)
- def handle_accept(self):
- pair = self.accept()
- if pair is None:
- pass
- else:
- sock, addr = pair
- print 'Incoming connection from %s' % repr(addr)
- handler = EchoHandler(sock)
+ def handle_accepted(self, sock, addr):
+ print('Incoming connection from %s' % repr(addr))
+ handler = EchoHandler(sock)
server = EchoServer('localhost', 8080)
asyncore.loop()
diff --git a/Doc/library/atexit.rst b/Doc/library/atexit.rst
index 6ac36b2..7c76bab 100644
--- a/Doc/library/atexit.rst
+++ b/Doc/library/atexit.rst
@@ -7,13 +7,7 @@
.. sectionauthor:: Skip Montanaro <skip@pobox.com>
-.. versionadded:: 2.0
-
-**Source code:** :source:`Lib/atexit.py`
-
---------------
-
-The :mod:`atexit` module defines a single function to register cleanup
+The :mod:`atexit` module defines functions to register and unregister cleanup
functions. Functions thus registered are automatically executed upon normal
interpreter termination. The order in which the functions are called is not
defined; if you have cleanup operations that depend on each other, you should
@@ -23,20 +17,8 @@ Note: the functions registered via this module are not called when the program
is killed by a signal not handled by Python, when a Python fatal internal error
is detected, or when :func:`os._exit` is called.
-.. index:: single: exitfunc (in sys)
-
-This is an alternate interface to the functionality provided by the
-:func:`sys.exitfunc` variable.
-
-Note: This module is unlikely to work correctly when used with other code that
-sets ``sys.exitfunc``. In particular, other core Python modules are free to use
-:mod:`atexit` without the programmer's knowledge. Authors who use
-``sys.exitfunc`` should convert their code to use :mod:`atexit` instead. The
-simplest way to convert code that sets ``sys.exitfunc`` is to import
-:mod:`atexit` and register the function that had been bound to ``sys.exitfunc``.
-
-.. function:: register(func[, *args[, **kargs]])
+.. function:: register(func, *args, **kargs)
Register *func* as a function to be executed at termination. Any optional
arguments that are to be passed to *func* must be passed as arguments to
@@ -54,15 +36,24 @@ simplest way to convert code that sets ``sys.exitfunc`` is to import
saved. After all exit handlers have had a chance to run the last exception to
be raised is re-raised.
- .. versionchanged:: 2.6
- This function now returns *func*, which makes it possible to use it as a
- decorator.
+ This function returns *func*, which makes it possible to use it as a
+ decorator.
+
+
+.. function:: unregister(func)
+
+ Remove *func* from the list of functions to be run at interpreter
+ shutdown. After calling :func:`unregister`, *func* is guaranteed not to be
+ called when the interpreter shuts down, even if it was registered more than
+ once. :func:`unregister` silently does nothing if *func* was not previously
+ registered.
.. seealso::
Module :mod:`readline`
- Useful example of :mod:`atexit` to read and write :mod:`readline` history files.
+ Useful example of :mod:`atexit` to read and write :mod:`readline` history
+ files.
.. _atexit-example:
@@ -94,7 +85,7 @@ Positional and keyword arguments may also be passed to :func:`register` to be
passed along to the registered function when it is called::
def goodbye(name, adjective):
- print 'Goodbye, %s, it was %s to meet you.' % (name, adjective)
+ print('Goodbye, %s, it was %s to meet you.' % (name, adjective))
import atexit
atexit.register(goodbye, 'Donny', 'nice')
@@ -108,6 +99,6 @@ Usage as a :term:`decorator`::
@atexit.register
def goodbye():
- print "You are now leaving the Python sector."
+ print("You are now leaving the Python sector.")
This only works with functions that can be called without arguments.
diff --git a/Doc/library/audioop.rst b/Doc/library/audioop.rst
index 0a8ac56..c947608 100644
--- a/Doc/library/audioop.rst
+++ b/Doc/library/audioop.rst
@@ -1,4 +1,3 @@
-
:mod:`audioop` --- Manipulate raw audio data
============================================
@@ -8,8 +7,7 @@
The :mod:`audioop` module contains some useful operations on sound fragments.
It operates on sound fragments consisting of signed integer samples 8, 16 or 32
-bits wide, stored in Python strings. This is the same format as used by the
-:mod:`al` and :mod:`sunaudiodev` modules. All scalar items are integers, unless
+bits wide, stored in bytes objects. All scalar items are integers, unless
specified otherwise.
.. index::
@@ -54,8 +52,6 @@ The module defines the following variables and functions:
a-LAW encoding always uses 8 bits samples, so *width* refers only to the sample
width of the output fragment here.
- .. versionadded:: 2.5
-
.. function:: avg(fragment, width)
@@ -130,12 +126,10 @@ The module defines the following variables and functions:
.. function:: lin2alaw(fragment, width)
Convert samples in the audio fragment to a-LAW encoding and return this as a
- Python string. a-LAW is an audio encoding format whereby you get a dynamic
+ bytes object. a-LAW is an audio encoding format whereby you get a dynamic
range of about 13 bits using only 8 bit samples. It is used by the Sun audio
hardware, among others.
- .. versionadded:: 2.5
-
.. function:: lin2lin(fragment, width, newwidth)
@@ -157,7 +151,7 @@ The module defines the following variables and functions:
.. function:: lin2ulaw(fragment, width)
Convert samples in the audio fragment to u-LAW encoding and return this as a
- Python string. u-LAW is an audio encoding format whereby you get a dynamic
+ bytes object. u-LAW is an audio encoding format whereby you get a dynamic
range of about 14 bits using only 8 bit samples. It is used by the Sun audio
hardware, among others.
diff --git a/Doc/library/autogil.rst b/Doc/library/autogil.rst
deleted file mode 100644
index 1c25cb1..0000000
--- a/Doc/library/autogil.rst
+++ /dev/null
@@ -1,35 +0,0 @@
-
-:mod:`autoGIL` --- Global Interpreter Lock handling in event loops
-==================================================================
-
-.. module:: autoGIL
- :platform: Mac
- :synopsis: Global Interpreter Lock handling in event loops.
- :deprecated:
-.. moduleauthor:: Just van Rossum <just@letterror.com>
-
-
-The :mod:`autoGIL` module provides a function :func:`installAutoGIL` that
-automatically locks and unlocks Python's :term:`Global Interpreter Lock` when
-running an event loop.
-
-.. note::
-
- This module has been removed in Python 3.x.
-
-
-.. exception:: AutoGILError
-
- Raised if the observer callback cannot be installed, for example because the
- current thread does not have a run loop.
-
-
-.. function:: installAutoGIL()
-
- Install an observer callback in the event loop (CFRunLoop) for the current
- thread, that will lock and unlock the Global Interpreter Lock (GIL) at
- appropriate times, allowing other Python threads to run while the event loop is
- idle.
-
- Availability: OSX 10.1 or later.
-
diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst
index ab85436..c08df15 100644
--- a/Doc/library/base64.rst
+++ b/Doc/library/base64.rst
@@ -10,22 +10,23 @@
single: MIME; base64 encoding
This module provides data encoding and decoding as specified in :rfc:`3548`.
-This standard defines the Base16, Base32, and Base64 algorithms for encoding and
-decoding arbitrary binary strings into text strings that can be safely sent by
-email, used as parts of URLs, or included as part of an HTTP POST request. The
-encoding algorithm is not the same as the :program:`uuencode` program.
+This standard defines the Base16, Base32, and Base64 algorithms for encoding
+and decoding arbitrary binary strings into ASCII-only byte strings that can be
+safely sent by email, used as parts of URLs, or included as part of an HTTP
+POST request. The encoding algorithm is not the same as the
+:program:`uuencode` program.
-There are two interfaces provided by this module. The modern interface supports
-encoding and decoding string objects using all three alphabets. The legacy
-interface provides for encoding and decoding to and from file-like objects as
-well as strings, but only using the Base64 standard alphabet.
+There are two interfaces provided by this module. The modern interface
+supports encoding and decoding ASCII byte string objects using all three
+alphabets. The legacy interface provides for encoding and decoding to and from
+file-like objects as well as byte strings, but only using the Base64 standard
+alphabet.
-The modern interface, which was introduced in Python 2.4, provides:
+The modern interface provides:
+.. function:: b64encode(s, altchars=None)
-.. function:: b64encode(s[, altchars])
-
- Encode a string use Base64.
+ Encode a byte string using Base64.
*s* is the string to encode. Optional *altchars* must be a string of at least
length 2 (additional characters are ignored) which specifies an alternative
@@ -33,58 +34,62 @@ The modern interface, which was introduced in Python 2.4, provides:
generate URL or filesystem safe Base64 strings. The default is ``None``, for
which the standard Base64 alphabet is used.
- The encoded string is returned.
+ The encoded byte string is returned.
-.. function:: b64decode(s[, altchars])
+.. function:: b64decode(s, altchars=None, validate=False)
- Decode a Base64 encoded string.
+ Decode a Base64 encoded byte string.
- *s* is the string to decode. Optional *altchars* must be a string of at least
- length 2 (additional characters are ignored) which specifies the alternative
- alphabet used instead of the ``+`` and ``/`` characters.
+ *s* is the byte string to decode. Optional *altchars* must be a string of
+ at least length 2 (additional characters are ignored) which specifies the
+ alternative alphabet used instead of the ``+`` and ``/`` characters.
- The decoded string is returned. A :exc:`TypeError` is raised if *s* were
- incorrectly padded or if there are non-alphabet characters present in the
- string.
+ The decoded string is returned. A :exc:`binascii.Error` exception is raised
+ if *s* is incorrectly padded.
+
+ If *validate* is ``False`` (the default), non-base64-alphabet characters are
+ discarded prior to the padding check. If *validate* is ``True``,
+ non-base64-alphabet characters in the input result in a
+ :exc:`binascii.Error`.
.. function:: standard_b64encode(s)
- Encode string *s* using the standard Base64 alphabet.
+ Encode byte string *s* using the standard Base64 alphabet.
.. function:: standard_b64decode(s)
- Decode string *s* using the standard Base64 alphabet.
+ Decode byte string *s* using the standard Base64 alphabet.
.. function:: urlsafe_b64encode(s)
- Encode string *s* using a URL-safe alphabet, which substitutes ``-`` instead of
+ Encode byte string *s* using a URL-safe alphabet, which substitutes ``-`` instead of
``+`` and ``_`` instead of ``/`` in the standard Base64 alphabet. The result
can still contain ``=``.
.. function:: urlsafe_b64decode(s)
- Decode string *s* using a URL-safe alphabet, which substitutes ``-`` instead of
+ Decode byte string *s* using a URL-safe alphabet, which substitutes ``-`` instead of
``+`` and ``_`` instead of ``/`` in the standard Base64 alphabet.
.. function:: b32encode(s)
- Encode a string using Base32. *s* is the string to encode. The encoded string
+ Encode a byte string using Base32. *s* is the string to encode. The encoded string
is returned.
-.. function:: b32decode(s[, casefold[, map01]])
+.. function:: b32decode(s, casefold=False, map01=None)
- Decode a Base32 encoded string.
+ Decode a Base32 encoded byte string.
- *s* is the string to decode. Optional *casefold* is a flag specifying whether a
- lowercase alphabet is acceptable as input. For security purposes, the default
- is ``False``.
+ *s* is the byte string to decode. Optional *casefold* is a flag specifying
+ whether a lowercase alphabet is acceptable as input. For security purposes,
+ the default is ``False``.
:rfc:`3548` allows for optional mapping of the digit 0 (zero) to the letter O
(oh), and for optional mapping of the digit 1 (one) to either the letter I (eye)
@@ -93,72 +98,79 @@ The modern interface, which was introduced in Python 2.4, provides:
digit 0 is always mapped to the letter O). For security purposes the default is
``None``, so that 0 and 1 are not allowed in the input.
- The decoded string is returned. A :exc:`TypeError` is raised if *s* were
+ The decoded byte string is returned. A :exc:`TypeError` is raised if *s* were
incorrectly padded or if there are non-alphabet characters present in the
string.
.. function:: b16encode(s)
- Encode a string using Base16.
+ Encode a byte string using Base16.
- *s* is the string to encode. The encoded string is returned.
+ *s* is the string to encode. The encoded byte string is returned.
-.. function:: b16decode(s[, casefold])
+.. function:: b16decode(s, casefold=False)
- Decode a Base16 encoded string.
+ Decode a Base16 encoded byte string.
*s* is the string to decode. Optional *casefold* is a flag specifying whether a
lowercase alphabet is acceptable as input. For security purposes, the default
is ``False``.
- The decoded string is returned. A :exc:`TypeError` is raised if *s* were
+ The decoded byte string is returned. A :exc:`TypeError` is raised if *s* were
incorrectly padded or if there are non-alphabet characters present in the
string.
-The legacy interface:
+The legacy interface:
.. function:: decode(input, output)
- Decode the contents of the *input* file and write the resulting binary data to
- the *output* file. *input* and *output* must either be file objects or objects
- that mimic the file object interface. *input* will be read until
- ``input.read()`` returns an empty string.
+ Decode the contents of the binary *input* file and write the resulting binary
+ data to the *output* file. *input* and *output* must be :term:`file objects
+ <file object>`. *input* will be read until ``input.read()`` returns an empty
+ bytes object.
-.. function:: decodestring(s)
+.. function:: decodebytes(s)
+ decodestring(s)
- Decode the string *s*, which must contain one or more lines of base64 encoded
- data, and return a string containing the resulting binary data.
+ Decode the byte string *s*, which must contain one or more lines of base64
+ encoded data, and return a byte string containing the resulting binary data.
+ ``decodestring`` is a deprecated alias.
+
+ .. versionadded:: 3.1
.. function:: encode(input, output)
- Encode the contents of the *input* file and write the resulting base64 encoded
- data to the *output* file. *input* and *output* must either be file objects or
- objects that mimic the file object interface. *input* will be read until
- ``input.read()`` returns an empty string. :func:`encode` returns the encoded
- data plus a trailing newline character (``'\n'``).
+ Encode the contents of the binary *input* file and write the resulting base64
+ encoded data to the *output* file. *input* and *output* must be :term:`file
+ objects <file object>`. *input* will be read until ``input.read()`` returns
+ an empty bytes object. :func:`encode` returns the encoded data plus a trailing
+ newline character (``b'\n'``).
+
+.. function:: encodebytes(s)
+ encodestring(s)
-.. function:: encodestring(s)
+ Encode the byte string *s*, which can contain arbitrary binary data, and
+ return a byte string containing one or more lines of base64-encoded data.
+ :func:`encodebytes` returns a string containing one or more lines of
+ base64-encoded data always including an extra trailing newline (``b'\n'``).
+ ``encodestring`` is a deprecated alias.
- Encode the string *s*, which can contain arbitrary binary data, and return a
- string containing one or more lines of base64-encoded data.
- :func:`encodestring` returns a string containing one or more lines of
- base64-encoded data always including an extra trailing newline (``'\n'``).
An example usage of the module:
>>> import base64
- >>> encoded = base64.b64encode('data to be encoded')
+ >>> encoded = base64.b64encode(b'data to be encoded')
>>> encoded
- 'ZGF0YSB0byBiZSBlbmNvZGVk'
+ b'ZGF0YSB0byBiZSBlbmNvZGVk'
>>> data = base64.b64decode(encoded)
>>> data
- 'data to be encoded'
+ b'data to be encoded'
.. seealso::
diff --git a/Doc/library/basehttpserver.rst b/Doc/library/basehttpserver.rst
deleted file mode 100644
index 01776af..0000000
--- a/Doc/library/basehttpserver.rst
+++ /dev/null
@@ -1,302 +0,0 @@
-:mod:`BaseHTTPServer` --- Basic HTTP server
-===========================================
-
-.. module:: BaseHTTPServer
- :synopsis: Basic HTTP server (base class for SimpleHTTPServer and CGIHTTPServer).
-
-.. note::
- The :mod:`BaseHTTPServer` module has been merged into :mod:`http.server` in
- Python 3. The :term:`2to3` tool will automatically adapt imports when
- converting your sources to Python 3.
-
-
-.. index::
- pair: WWW; server
- pair: HTTP; protocol
- single: URL
- single: httpd
- module: SimpleHTTPServer
- module: CGIHTTPServer
-
-**Source code:** :source:`Lib/BaseHTTPServer.py`
-
---------------
-
-This module defines two classes for implementing HTTP servers (Web servers).
-Usually, this module isn't used directly, but is used as a basis for building
-functioning Web servers. See the :mod:`SimpleHTTPServer` and
-:mod:`CGIHTTPServer` modules.
-
-The first class, :class:`HTTPServer`, is a :class:`SocketServer.TCPServer`
-subclass, and therefore implements the :class:`SocketServer.BaseServer`
-interface. It creates and listens at the HTTP socket, dispatching the requests
-to a handler. Code to create and run the server looks like this::
-
- def run(server_class=BaseHTTPServer.HTTPServer,
- handler_class=BaseHTTPServer.BaseHTTPRequestHandler):
- server_address = ('', 8000)
- httpd = server_class(server_address, handler_class)
- httpd.serve_forever()
-
-
-.. class:: HTTPServer(server_address, RequestHandlerClass)
-
- This class builds on the :class:`TCPServer` class by storing the server
- address as instance variables named :attr:`server_name` and
- :attr:`server_port`. The server is accessible by the handler, typically
- through the handler's :attr:`server` instance variable.
-
-
-.. class:: BaseHTTPRequestHandler(request, client_address, server)
-
- This class is used to handle the HTTP requests that arrive at the server. By
- itself, it cannot respond to any actual HTTP requests; it must be subclassed
- to handle each request method (e.g. GET or
- POST). :class:`BaseHTTPRequestHandler` provides a number of class and
- instance variables, and methods for use by subclasses.
-
- The handler will parse the request and the headers, then call a method
- specific to the request type. The method name is constructed from the
- request. For example, for the request method ``SPAM``, the :meth:`do_SPAM`
- method will be called with no arguments. All of the relevant information is
- stored in instance variables of the handler. Subclasses should not need to
- override or extend the :meth:`__init__` method.
-
- :class:`BaseHTTPRequestHandler` has the following instance variables:
-
-
- .. attribute:: client_address
-
- Contains a tuple of the form ``(host, port)`` referring to the client's
- address.
-
-
- .. attribute:: server
-
- Contains the server instance.
-
-
- .. attribute:: command
-
- Contains the command (request type). For example, ``'GET'``.
-
-
- .. attribute:: path
-
- Contains the request path.
-
-
- .. attribute:: request_version
-
- Contains the version string from the request. For example, ``'HTTP/1.0'``.
-
-
- .. attribute:: headers
-
- Holds an instance of the class specified by the :attr:`MessageClass` class
- variable. This instance parses and manages the headers in the HTTP
- request.
-
-
- .. attribute:: rfile
-
- Contains an input stream, positioned at the start of the optional input
- data.
-
-
- .. attribute:: wfile
-
- Contains the output stream for writing a response back to the
- client. Proper adherence to the HTTP protocol must be used when writing to
- this stream.
-
-
- :class:`BaseHTTPRequestHandler` has the following class variables:
-
-
- .. attribute:: server_version
-
- Specifies the server software version. You may want to override this. The
- format is multiple whitespace-separated strings, where each string is of
- the form name[/version]. For example, ``'BaseHTTP/0.2'``.
-
-
- .. attribute:: sys_version
-
- Contains the Python system version, in a form usable by the
- :attr:`version_string` method and the :attr:`server_version` class
- variable. For example, ``'Python/1.4'``.
-
-
- .. attribute:: error_message_format
-
- Specifies a format string for building an error response to the client. It
- uses parenthesized, keyed format specifiers, so the format operand must be
- a dictionary. The *code* key should be an integer, specifying the numeric
- HTTP error code value. *message* should be a string containing a
- (detailed) error message of what occurred, and *explain* should be an
- explanation of the error code number. Default *message* and *explain*
- values can found in the *responses* class variable.
-
-
- .. attribute:: error_content_type
-
- Specifies the Content-Type HTTP header of error responses sent to the
- client. The default value is ``'text/html'``.
-
- .. versionadded:: 2.6
- Previously, the content type was always ``'text/html'``.
-
-
- .. attribute:: protocol_version
-
- This specifies the HTTP protocol version used in responses. If set to
- ``'HTTP/1.1'``, the server will permit HTTP persistent connections;
- however, your server *must* then include an accurate ``Content-Length``
- header (using :meth:`send_header`) in all of its responses to clients.
- For backwards compatibility, the setting defaults to ``'HTTP/1.0'``.
-
-
- .. attribute:: MessageClass
-
- .. index:: single: Message (in module mimetools)
-
- Specifies a :class:`rfc822.Message`\ -like class to parse HTTP headers.
- Typically, this is not overridden, and it defaults to
- :class:`mimetools.Message`.
-
-
- .. attribute:: responses
-
- This variable contains a mapping of error code integers to two-element tuples
- containing a short and long message. For example, ``{code: (shortmessage,
- longmessage)}``. The *shortmessage* is usually used as the *message* key in an
- error response, and *longmessage* as the *explain* key (see the
- :attr:`error_message_format` class variable).
-
-
- A :class:`BaseHTTPRequestHandler` instance has the following methods:
-
-
- .. method:: handle()
-
- Calls :meth:`handle_one_request` once (or, if persistent connections are
- enabled, multiple times) to handle incoming HTTP requests. You should
- never need to override it; instead, implement appropriate :meth:`do_\*`
- methods.
-
-
- .. method:: handle_one_request()
-
- This method will parse and dispatch the request to the appropriate
- :meth:`do_\*` method. You should never need to override it.
-
-
- .. method:: send_error(code[, message])
-
- Sends and logs a complete error reply to the client. The numeric *code*
- specifies the HTTP error code, with *message* as optional, more specific text. A
- complete set of headers is sent, followed by text composed using the
- :attr:`error_message_format` class variable.
-
-
- .. method:: send_response(code[, message])
-
- Sends a response header and logs the accepted request. The HTTP response
- line is sent, followed by *Server* and *Date* headers. The values for
- these two headers are picked up from the :meth:`version_string` and
- :meth:`date_time_string` methods, respectively.
-
-
- .. method:: send_header(keyword, value)
-
- Writes a specific HTTP header to the output stream. *keyword* should
- specify the header keyword, with *value* specifying its value.
-
-
- .. method:: end_headers()
-
- Sends a blank line, indicating the end of the HTTP headers in the
- response.
-
-
- .. method:: log_request([code[, size]])
-
- Logs an accepted (successful) request. *code* should specify the numeric
- HTTP code associated with the response. If a size of the response is
- available, then it should be passed as the *size* parameter.
-
-
- .. method:: log_error(...)
-
- Logs an error when a request cannot be fulfilled. By default, it passes
- the message to :meth:`log_message`, so it takes the same arguments
- (*format* and additional values).
-
-
- .. method:: log_message(format, ...)
-
- Logs an arbitrary message to ``sys.stderr``. This is typically overridden
- to create custom error logging mechanisms. The *format* argument is a
- standard printf-style format string, where the additional arguments to
- :meth:`log_message` are applied as inputs to the formatting. The client
- ip address and current date and time are prefixed to every message logged.
-
-
- .. method:: version_string()
-
- Returns the server software's version string. This is a combination of the
- :attr:`server_version` and :attr:`sys_version` class variables.
-
-
- .. method:: date_time_string([timestamp])
-
- Returns the date and time given by *timestamp* (which must be in the
- format returned by :func:`time.time`), formatted for a message header. If
- *timestamp* is omitted, it uses the current date and time.
-
- The result looks like ``'Sun, 06 Nov 1994 08:49:37 GMT'``.
-
- .. versionadded:: 2.5
- The *timestamp* parameter.
-
-
- .. method:: log_date_time_string()
-
- Returns the current date and time, formatted for logging.
-
-
- .. method:: address_string()
-
- Returns the client address, formatted for logging. A name lookup is
- performed on the client's IP address.
-
-
-More examples
--------------
-
-To create a server that doesn't run forever, but until some condition is
-fulfilled::
-
- def run_while_true(server_class=BaseHTTPServer.HTTPServer,
- handler_class=BaseHTTPServer.BaseHTTPRequestHandler):
- """
- This assumes that keep_running() is a function of no arguments which
- is tested initially and after each request. If its return value
- is true, the server continues.
- """
- server_address = ('', 8000)
- httpd = server_class(server_address, handler_class)
- while keep_running():
- httpd.handle_request()
-
-
-.. seealso::
-
- Module :mod:`CGIHTTPServer`
- Extended request handler that supports CGI scripts.
-
- Module :mod:`SimpleHTTPServer`
- Basic request handler that limits response to files actually under the
- document root.
-
diff --git a/Doc/library/bastion.rst b/Doc/library/bastion.rst
deleted file mode 100644
index 2e3efcd..0000000
--- a/Doc/library/bastion.rst
+++ /dev/null
@@ -1,64 +0,0 @@
-
-:mod:`Bastion` --- Restricting access to objects
-================================================
-
-.. module:: Bastion
- :synopsis: Providing restricted access to objects.
- :deprecated:
-
-.. deprecated:: 2.6
- The :mod:`Bastion` module has been removed in Python 3.
-
-.. moduleauthor:: Barry Warsaw <bwarsaw@python.org>
-
-
-.. versionchanged:: 2.3
- Disabled module.
-
-.. note::
-
- The documentation has been left in place to help in reading old code that uses
- the module.
-
-According to the dictionary, a bastion is "a fortified area or position", or
-"something that is considered a stronghold." It's a suitable name for this
-module, which provides a way to forbid access to certain attributes of an
-object. It must always be used with the :mod:`rexec` module, in order to allow
-restricted-mode programs access to certain safe attributes of an object, while
-denying access to other, unsafe attributes.
-
-.. I'm concerned that the word 'bastion' won't be understood by people
-.. for whom English is a second language, making the module name
-.. somewhat mysterious. Thus, the brief definition... --amk
-
-.. I've punted on the issue of documenting keyword arguments for now.
-
-
-.. function:: Bastion(object[, filter[, name[, class]]])
-
- Protect the object *object*, returning a bastion for the object. Any attempt to
- access one of the object's attributes will have to be approved by the *filter*
- function; if the access is denied an :exc:`AttributeError` exception will be
- raised.
-
- If present, *filter* must be a function that accepts a string containing an
- attribute name, and returns true if access to that attribute will be permitted;
- if *filter* returns false, the access is denied. The default filter denies
- access to any function beginning with an underscore (``'_'``). The bastion's
- string representation will be ``<Bastion for name>`` if a value for *name* is
- provided; otherwise, ``repr(object)`` will be used.
-
- *class*, if present, should be a subclass of :class:`BastionClass`; see the
- code in :file:`bastion.py` for the details. Overriding the default
- :class:`BastionClass` will rarely be required.
-
-
-.. class:: BastionClass(getfunc, name)
-
- Class which actually implements bastion objects. This is the default class used
- by :func:`Bastion`. The *getfunc* parameter is a function which returns the
- value of an attribute which should be exposed to the restricted execution
- environment when called with the name of the attribute as the only parameter.
- *name* is used to construct the :func:`repr` of the :class:`BastionClass`
- instance.
-
diff --git a/Doc/library/bdb.rst b/Doc/library/bdb.rst
index 1cbb8f6..0737602 100644
--- a/Doc/library/bdb.rst
+++ b/Doc/library/bdb.rst
@@ -20,7 +20,7 @@ The following exception is defined:
The :mod:`bdb` module also defines two classes:
-.. class:: Breakpoint(self, file, line, temporary=0, cond=None , funcname=None)
+.. class:: Breakpoint(self, file, line, temporary=0, cond=None, funcname=None)
This class implements temporary breakpoints, ignore counts, disabling and
(re-)enabling, and conditionals.
@@ -54,9 +54,10 @@ The :mod:`bdb` module also defines two classes:
Mark the breakpoint as disabled.
- .. method:: pprint([out])
+ .. method:: bpformat()
- Print all the information about the breakpoint:
+ Return a string with all the information about the breakpoint, nicely
+ formatted:
* The breakpoint number.
* If it is temporary or not.
@@ -65,6 +66,13 @@ The :mod:`bdb` module also defines two classes:
* If it must be ignored the next N times.
* The breakpoint hit count.
+ .. versionadded:: 3.2
+
+ .. method:: bpprint(out=None)
+
+ Print the output of :meth:`bpformat` to the file *out*, or if it is
+ ``None``, to standard output.
+
.. class:: Bdb(skip=None)
@@ -80,7 +88,7 @@ The :mod:`bdb` module also defines two classes:
frame is considered to originate in a certain module is determined
by the ``__name__`` in the frame globals.
- .. versionadded:: 2.7
+ .. versionadded:: 3.1
The *skip* argument.
The following methods of :class:`Bdb` normally don't need to be overridden.
@@ -245,7 +253,7 @@ The :mod:`bdb` module also defines two classes:
breakpoints. These methods return a string containing an error message if
something went wrong, or ``None`` if all is well.
- .. method:: set_break(filename, lineno, temporary=0, cond=None, funcname=None)
+ .. method:: set_break(filename, lineno, temporary=0, cond, funcname)
Set a new breakpoint. If the *lineno* line doesn't exist for the
*filename* passed as argument, return an error message. The *filename*
@@ -271,6 +279,15 @@ The :mod:`bdb` module also defines two classes:
Delete all existing breakpoints.
+ .. method:: get_bpbynumber(arg)
+
+ Return a breakpoint specified by the given number. If *arg* is a string,
+ it will be converted to a number. If *arg* is a non-numeric string, if
+ the given breakpoint never existed or has been deleted, a
+ :exc:`ValueError` is raised.
+
+ .. versionadded:: 3.2
+
.. method:: get_break(filename, lineno)
Check if there is a breakpoint for *lineno* of *filename*.
@@ -297,7 +314,7 @@ The :mod:`bdb` module also defines two classes:
Get a list of records for a frame and all higher (calling) and lower
frames, and the size of the higher part.
- .. method:: format_stack_entry(frame_lineno, [lprefix=': '])
+ .. method:: format_stack_entry(frame_lineno, lprefix=': ')
Return a string with information about a stack entry, identified by a
``(frame, lineno)`` tuple:
@@ -312,12 +329,12 @@ The :mod:`bdb` module also defines two classes:
The following two methods can be called by clients to use a debugger to debug
a :term:`statement`, given as a string.
- .. method:: run(cmd, [globals, [locals]])
+ .. method:: run(cmd, globals=None, locals=None)
- Debug a statement executed via the :keyword:`exec` statement. *globals*
+ Debug a statement executed via the :func:`exec` function. *globals*
defaults to :attr:`__main__.__dict__`, *locals* defaults to *globals*.
- .. method:: runeval(expr, [globals, [locals]])
+ .. method:: runeval(expr, globals=None, locals=None)
Debug an expression executed via the :func:`eval` function. *globals* and
*locals* have the same meaning as in :meth:`run`.
diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst
index 0f8a3de..2aa3702 100644
--- a/Doc/library/binascii.rst
+++ b/Doc/library/binascii.rst
@@ -1,4 +1,3 @@
-
:mod:`binascii` --- Convert between binary and ASCII
====================================================
@@ -19,6 +18,11 @@ use these functions directly but use wrapper modules like :mod:`uu`,
low-level functions written in C for greater speed that are used by the
higher-level modules.
+.. note::
+
+ Encoding and decoding functions do not accept Unicode strings. Only bytestring
+ and bytearray objects can be processed.
+
The :mod:`binascii` module defines the following functions:
@@ -49,14 +53,17 @@ The :mod:`binascii` module defines the following functions:
should be at most 57 to adhere to the base64 standard.
-.. function:: a2b_qp(string[, header])
+.. function:: a2b_qp(string, header=False)
Convert a block of quoted-printable data back to binary and return the binary
data. More than one line may be passed at a time. If the optional argument
*header* is present and true, underscores will be decoded as spaces.
+ .. versionchanged:: 3.2
+ Accept only bytestring or bytearray objects as input.
+
-.. function:: b2a_qp(data[, quotetabs, istext, header])
+.. function:: b2a_qp(data, quotetabs=False, istext=True, header=False)
Convert binary data to a line(s) of ASCII characters in quoted-printable
encoding. The return value is the converted line(s). If the optional argument
@@ -84,6 +91,9 @@ The :mod:`binascii` module defines the following functions:
decompressed data, unless data input data ends in an orphaned repeat indicator,
in which case the :exc:`Incomplete` exception is raised.
+ .. versionchanged:: 3.2
+ Accept only bytestring or bytearray objects as input.
+
.. function:: rlecode_hqx(data)
@@ -110,11 +120,11 @@ The :mod:`binascii` module defines the following functions:
use as a checksum algorithm, it is not suitable for use as a general hash
algorithm. Use as follows::
- print binascii.crc32("hello world")
+ print(binascii.crc32(b"hello world"))
# Or, in two pieces:
- crc = binascii.crc32("hello")
- crc = binascii.crc32(" world", crc) & 0xffffffff
- print 'crc32 = 0x%08x' % crc
+ crc = binascii.crc32(b"hello")
+ crc = binascii.crc32(b" world", crc) & 0xffffffff
+ print('crc32 = {:#010x}'.format(crc))
.. note::
To generate the same numeric value across all Python versions and
@@ -123,16 +133,6 @@ The :mod:`binascii` module defines the following functions:
return value is the correct 32bit binary representation
regardless of sign.
-.. versionchanged:: 2.6
- The return value is in the range [-2**31, 2**31-1]
- regardless of platform. In the past the value would be signed on
- some platforms and unsigned on others. Use & 0xffffffff on the
- value if you want it to match Python 3 behavior.
-
-.. versionchanged:: 3.0
- The return value is unsigned and in the range [0, 2**32-1]
- regardless of platform.
-
.. function:: b2a_hex(data)
hexlify(data)
@@ -150,6 +150,9 @@ The :mod:`binascii` module defines the following functions:
of hexadecimal digits (which can be upper or lower case), otherwise a
:exc:`TypeError` is raised.
+ .. versionchanged:: 3.2
+ Accept only bytestring or bytearray objects as input.
+
.. exception:: Error
@@ -175,4 +178,3 @@ The :mod:`binascii` module defines the following functions:
Module :mod:`quopri`
Support for quoted-printable encoding used in MIME email messages.
-
diff --git a/Doc/library/binhex.rst b/Doc/library/binhex.rst
index a112813..43c7823 100644
--- a/Doc/library/binhex.rst
+++ b/Doc/library/binhex.rst
@@ -6,14 +6,7 @@
This module encodes and decodes files in binhex4 format, a format allowing
-representation of Macintosh files in ASCII. On the Macintosh, both forks of a
-file and the finder information are encoded (or decoded), on other platforms
-only the data fork is handled.
-
-.. note::
-
- In Python 3.x, special Macintosh support has been removed.
-
+representation of Macintosh files in ASCII. Only the data fork is handled.
The :mod:`binhex` module defines the following functions:
@@ -25,11 +18,11 @@ The :mod:`binhex` module defines the following functions:
supporting a :meth:`write` and :meth:`close` method).
-.. function:: hexbin(input[, output])
+.. function:: hexbin(input, output)
Decode a binhex file *input*. *input* may be a filename or a file-like object
supporting :meth:`read` and :meth:`close` methods. The resulting file is written
- to a file named *output*, unless the argument is omitted in which case the
+ to a file named *output*, unless the argument is ``None`` in which case the
output filename is read from the binhex file.
The following exception is also defined:
diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst
index 64a362e..13b0147 100644
--- a/Doc/library/bisect.rst
+++ b/Doc/library/bisect.rst
@@ -7,8 +7,6 @@
.. sectionauthor:: Raymond Hettinger <python at rcn.com>
.. example based on the PyModules FAQ entry by Aaron Watters <arw@pythonpros.com>
-.. versionadded:: 2.1
-
**Source code:** :source:`Lib/bisect.py`
--------------
@@ -123,9 +121,9 @@ based on a set of ordered numeric breakpoints: 90 and up is an 'A', 80 to 89 is
a 'B', and so on::
>>> def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
- i = bisect(breakpoints, score)
- return grades[i]
-
+ ... i = bisect(breakpoints, score)
+ ... return grades[i]
+ ...
>>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']
diff --git a/Doc/library/bsddb.rst b/Doc/library/bsddb.rst
deleted file mode 100644
index 0ed109d..0000000
--- a/Doc/library/bsddb.rst
+++ /dev/null
@@ -1,206 +0,0 @@
-
-:mod:`bsddb` --- Interface to Berkeley DB library
-=================================================
-
-.. module:: bsddb
- :synopsis: Interface to Berkeley DB database library
-.. sectionauthor:: Skip Montanaro <skip@pobox.com>
-
-.. deprecated:: 2.6
- The :mod:`bsddb` module has been removed in Python 3.
-
-
-The :mod:`bsddb` module provides an interface to the Berkeley DB library. Users
-can create hash, btree or record based library files using the appropriate open
-call. Bsddb objects behave generally like dictionaries. Keys and values must be
-strings, however, so to use other objects as keys or to store other kinds of
-objects the user must serialize them somehow, typically using
-:func:`marshal.dumps` or :func:`pickle.dumps`.
-
-The :mod:`bsddb` module requires a Berkeley DB library version from 4.0 thru
-4.7.
-
-
-.. seealso::
-
- http://www.jcea.es/programacion/pybsddb.htm
- The website with documentation for the :mod:`bsddb.db` Python Berkeley DB
- interface that closely mirrors the object oriented interface provided in
- Berkeley DB 4.x itself.
-
- http://www.oracle.com/database/berkeley-db/
- The Berkeley DB library.
-
-A more modern DB, DBEnv and DBSequence object interface is available in the
-:mod:`bsddb.db` module which closely matches the Berkeley DB C API documented at
-the above URLs. Additional features provided by the :mod:`bsddb.db` API include
-fine tuning, transactions, logging, and multiprocess concurrent database access.
-
-The following is a description of the legacy :mod:`bsddb` interface compatible
-with the old Python bsddb module. Starting in Python 2.5 this interface should
-be safe for multithreaded access. The :mod:`bsddb.db` API is recommended for
-threading users as it provides better control.
-
-The :mod:`bsddb` module defines the following functions that create objects that
-access the appropriate type of Berkeley DB file. The first two arguments of
-each function are the same. For ease of portability, only the first two
-arguments should be used in most instances.
-
-
-.. function:: hashopen(filename[, flag[, mode[, pgsize[, ffactor[, nelem[, cachesize[, lorder[, hflags]]]]]]]])
-
- Open the hash format file named *filename*. Files never intended to be
- preserved on disk may be created by passing ``None`` as the *filename*. The
- optional *flag* identifies the mode used to open the file. It may be ``'r'``
- (read only), ``'w'`` (read-write) , ``'c'`` (read-write - create if necessary;
- the default) or ``'n'`` (read-write - truncate to zero length). The other
- arguments are rarely used and are just passed to the low-level :c:func:`dbopen`
- function. Consult the Berkeley DB documentation for their use and
- interpretation.
-
-
-.. function:: btopen(filename[, flag[, mode[, btflags[, cachesize[, maxkeypage[, minkeypage[, pgsize[, lorder]]]]]]]])
-
- Open the btree format file named *filename*. Files never intended to be
- preserved on disk may be created by passing ``None`` as the *filename*. The
- optional *flag* identifies the mode used to open the file. It may be ``'r'``
- (read only), ``'w'`` (read-write), ``'c'`` (read-write - create if necessary;
- the default) or ``'n'`` (read-write - truncate to zero length). The other
- arguments are rarely used and are just passed to the low-level dbopen function.
- Consult the Berkeley DB documentation for their use and interpretation.
-
-
-.. function:: rnopen(filename[, flag[, mode[, rnflags[, cachesize[, pgsize[, lorder[, rlen[, delim[, source[, pad]]]]]]]]]])
-
- Open a DB record format file named *filename*. Files never intended to be
- preserved on disk may be created by passing ``None`` as the *filename*. The
- optional *flag* identifies the mode used to open the file. It may be ``'r'``
- (read only), ``'w'`` (read-write), ``'c'`` (read-write - create if necessary;
- the default) or ``'n'`` (read-write - truncate to zero length). The other
- arguments are rarely used and are just passed to the low-level dbopen function.
- Consult the Berkeley DB documentation for their use and interpretation.
-
-.. note::
-
- Beginning in 2.3 some Unix versions of Python may have a :mod:`bsddb185` module.
- This is present *only* to allow backwards compatibility with systems which ship
- with the old Berkeley DB 1.85 database library. The :mod:`bsddb185` module
- should never be used directly in new code. The module has been removed in
- Python 3. If you find you still need it look in PyPI.
-
-
-.. seealso::
-
- Module :mod:`dbhash`
- DBM-style interface to the :mod:`bsddb`
-
-
-.. _bsddb-objects:
-
-Hash, BTree and Record Objects
-------------------------------
-
-Once instantiated, hash, btree and record objects support the same methods as
-dictionaries. In addition, they support the methods listed below.
-
-.. versionchanged:: 2.3.1
- Added dictionary methods.
-
-
-.. method:: bsddbobject.close()
-
- Close the underlying file. The object can no longer be accessed. Since there
- is no open :meth:`open` method for these objects, to open the file again a new
- :mod:`bsddb` module open function must be called.
-
-
-.. method:: bsddbobject.keys()
-
- Return the list of keys contained in the DB file. The order of the list is
- unspecified and should not be relied on. In particular, the order of the list
- returned is different for different file formats.
-
-
-.. method:: bsddbobject.has_key(key)
-
- Return ``1`` if the DB file contains the argument as a key.
-
-
-.. method:: bsddbobject.set_location(key)
-
- Set the cursor to the item indicated by *key* and return a tuple containing the
- key and its value. For binary tree databases (opened using :func:`btopen`), if
- *key* does not actually exist in the database, the cursor will point to the next
- item in sorted order and return that key and value. For other databases,
- :exc:`KeyError` will be raised if *key* is not found in the database.
-
-
-.. method:: bsddbobject.first()
-
- Set the cursor to the first item in the DB file and return it. The order of
- keys in the file is unspecified, except in the case of B-Tree databases. This
- method raises :exc:`bsddb.error` if the database is empty.
-
-
-.. method:: bsddbobject.next()
-
- Set the cursor to the next item in the DB file and return it. The order of
- keys in the file is unspecified, except in the case of B-Tree databases.
-
-
-.. method:: bsddbobject.previous()
-
- Set the cursor to the previous item in the DB file and return it. The order of
- keys in the file is unspecified, except in the case of B-Tree databases. This
- is not supported on hashtable databases (those opened with :func:`hashopen`).
-
-
-.. method:: bsddbobject.last()
-
- Set the cursor to the last item in the DB file and return it. The order of keys
- in the file is unspecified. This is not supported on hashtable databases (those
- opened with :func:`hashopen`). This method raises :exc:`bsddb.error` if the
- database is empty.
-
-
-.. method:: bsddbobject.sync()
-
- Synchronize the database on disk.
-
-Example::
-
- >>> import bsddb
- >>> db = bsddb.btopen('/tmp/spam.db', 'c')
- >>> for i in range(10): db['%d'%i] = '%d'% (i*i)
- ...
- >>> db['3']
- '9'
- >>> db.keys()
- ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
- >>> db.first()
- ('0', '0')
- >>> db.next()
- ('1', '1')
- >>> db.last()
- ('9', '81')
- >>> db.set_location('2')
- ('2', '4')
- >>> db.previous()
- ('1', '1')
- >>> for k, v in db.iteritems():
- ... print k, v
- 0 0
- 1 1
- 2 4
- 3 9
- 4 16
- 5 25
- 6 36
- 7 49
- 8 64
- 9 81
- >>> '8' in db
- True
- >>> db.sync()
- 0
-
diff --git a/Doc/library/builtins.rst b/Doc/library/builtins.rst
new file mode 100644
index 0000000..2cca1d0
--- /dev/null
+++ b/Doc/library/builtins.rst
@@ -0,0 +1,41 @@
+:mod:`builtins` --- Built-in objects
+====================================
+
+.. module:: builtins
+ :synopsis: The module that provides the built-in namespace.
+
+
+This module provides direct access to all 'built-in' identifiers of Python; for
+example, ``builtins.open`` is the full name for the built-in function
+:func:`open`. See :ref:`built-in-funcs` and :ref:`built-in-consts` for
+documentation.
+
+
+This module is not normally accessed explicitly by most applications, but can be
+useful in modules that provide objects with the same name as a built-in value,
+but in which the built-in of that name is also needed. For example, in a module
+that wants to implement an :func:`open` function that wraps the built-in
+:func:`open`, this module can be used directly::
+
+ import builtins
+
+ def open(path):
+ f = builtins.open(path, 'r')
+ return UpperCaser(f)
+
+ class UpperCaser:
+ '''Wrapper around a file that converts output to upper-case.'''
+
+ def __init__(self, f):
+ self._f = f
+
+ def read(self, count=-1):
+ return self._f.read(count).upper()
+
+ # ...
+
+As an implementation detail, most modules have the name ``__builtins__`` made
+available as part of their globals. The value of ``__builtins__`` is normally
+either this module or the value of this module's :attr:`__dict__` attribute.
+Since this is an implementation detail, it may not be used by alternate
+implementations of Python.
diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst
index 6793c44..93144b6 100644
--- a/Doc/library/bz2.rst
+++ b/Doc/library/bz2.rst
@@ -1,15 +1,13 @@
-
:mod:`bz2` --- Compression compatible with :program:`bzip2`
===========================================================
.. module:: bz2
- :synopsis: Interface to compression and decompression routines compatible with bzip2.
+ :synopsis: Interface to compression and decompression routines
+ compatible with bzip2.
.. moduleauthor:: Gustavo Niemeyer <niemeyer@conectiva.com>
.. sectionauthor:: Gustavo Niemeyer <niemeyer@conectiva.com>
-.. versionadded:: 2.3
-
This module provides a comprehensive interface for the bz2 compression library.
It implements a complete file interface, one-shot (de)compression functions, and
types for sequential (de)compression.
@@ -24,8 +22,8 @@ Here is a summary of the features offered by the bz2 module:
* :class:`BZ2File` class implements universal newline support;
-* :class:`BZ2File` class offers an optimized line iteration using the readahead
- algorithm borrowed from file objects;
+* :class:`BZ2File` class offers an optimized line iteration using a readahead
+ algorithm;
* Sequential (de)compression supported by :class:`BZ2Compressor` and
:class:`BZ2Decompressor` classes;
@@ -45,7 +43,7 @@ Handling of compressed files is offered by the :class:`BZ2File` class.
.. index::
single: universal newlines; bz2.BZ2File class
-.. class:: BZ2File(filename[, mode[, buffering[, compresslevel]]])
+.. class:: BZ2File(filename, mode='r', buffering=0, compresslevel=9)
Open a bz2 file. Mode can be either ``'r'`` or ``'w'``, for reading (default)
or writing. When opened for writing, the file will be created if it doesn't
@@ -53,7 +51,7 @@ Handling of compressed files is offered by the :class:`BZ2File` class.
unbuffered, and larger numbers specify the buffer size; the default is
``0``. If *compresslevel* is given, it must be a number between ``1`` and
``9``; the default is ``9``. Add a ``'U'`` to mode to open the file for input
- in :term:`universal newlines` mode. Any line ending in the input file will be
+ in :term:`universal newlines` mode. Any line ending in the input file will be
seen as a ``'\n'`` in Python. Also, a file so opened gains the attribute
:attr:`newlines`; the value for this attribute is one of ``None`` (no newline
read yet), ``'\r'``, ``'\n'``, ``'\r\n'`` or a tuple containing all the
@@ -63,7 +61,7 @@ Handling of compressed files is offered by the :class:`BZ2File` class.
:class:`BZ2File` supports the :keyword:`with` statement.
- .. versionchanged:: 2.7
+ .. versionchanged:: 3.1
Support for the :keyword:`with` statement was added.
@@ -88,15 +86,16 @@ Handling of compressed files is offered by the :class:`BZ2File` class.
.. method:: read([size])
- Read at most *size* uncompressed bytes, returned as a string. If the
+ Read at most *size* uncompressed bytes, returned as a byte string. If the
*size* argument is negative or omitted, read until EOF is reached.
.. method:: readline([size])
- Return the next line from the file, as a string, retaining newline. A
- non-negative *size* argument limits the maximum number of bytes to return
- (an incomplete line may be returned then). Return an empty string at EOF.
+ Return the next line from the file, as a byte string, retaining newline.
+ A non-negative *size* argument limits the maximum number of bytes to
+ return (an incomplete line may be returned then). Return an empty byte
+ string at EOF.
.. method:: readlines([size])
@@ -105,18 +104,6 @@ Handling of compressed files is offered by the :class:`BZ2File` class.
approximate bound on the total number of bytes in the lines returned.
- .. method:: xreadlines()
-
- For backward compatibility. :class:`BZ2File` objects now include the
- performance optimizations previously implemented in the :mod:`xreadlines`
- module.
-
- .. deprecated:: 2.3
- This exists only for compatibility with the method by this name on
- :class:`file` objects, which is deprecated. Use ``for line in file``
- instead.
-
-
.. method:: seek(offset[, whence])
Move to new file position. Argument *offset* is a byte count. Optional
@@ -133,20 +120,21 @@ Handling of compressed files is offered by the :class:`BZ2File` class.
.. method:: tell()
- Return the current file position, an integer (may be a long integer).
+ Return the current file position, an integer.
.. method:: write(data)
- Write string *data* to file. Note that due to buffering, :meth:`close` may
- be needed before the file on disk reflects the data written.
+ Write the byte string *data* to file. Note that due to buffering,
+ :meth:`close` may be needed before the file on disk reflects the data
+ written.
- .. method:: writelines(sequence_of_strings)
+ .. method:: writelines(sequence_of_byte_strings)
- Write the sequence of strings to the file. Note that newlines are not
- added. The sequence can be any iterable object producing strings. This is
- equivalent to calling write() for each string.
+ Write the sequence of byte strings to the file. Note that newlines are not
+ added. The sequence can be any iterable object producing byte strings.
+ This is equivalent to calling write() for each byte string.
Sequential (de)compression
@@ -156,14 +144,13 @@ Sequential compression and decompression is done using the classes
:class:`BZ2Compressor` and :class:`BZ2Decompressor`.
-.. class:: BZ2Compressor([compresslevel])
+.. class:: BZ2Compressor(compresslevel=9)
Create a new compressor object. This object may be used to compress data
sequentially. If you want to compress data in one shot, use the
:func:`compress` function instead. The *compresslevel* parameter, if given,
must be a number between ``1`` and ``9``; the default is ``9``.
-
.. method:: compress(data)
Provide more data to the compressor object. It will return chunks of
@@ -184,7 +171,6 @@ Sequential compression and decompression is done using the classes
sequentially. If you want to decompress data in one shot, use the
:func:`decompress` function instead.
-
.. method:: decompress(data)
Provide more data to the decompressor object. It will return chunks of
@@ -201,7 +187,7 @@ One-shot compression and decompression is provided through the :func:`compress`
and :func:`decompress` functions.
-.. function:: compress(data[, compresslevel])
+.. function:: compress(data, compresslevel=9)
Compress *data* in one shot. If you want to compress data sequentially, use
an instance of :class:`BZ2Compressor` instead. The *compresslevel* parameter,
diff --git a/Doc/library/calendar.rst b/Doc/library/calendar.rst
index f4f4693..f495271 100644
--- a/Doc/library/calendar.rst
+++ b/Doc/library/calendar.rst
@@ -2,8 +2,8 @@
======================================================
.. module:: calendar
- :synopsis: Functions for working with calendars, including some emulation of the Unix cal
- program.
+ :synopsis: Functions for working with calendars, including some emulation
+ of the Unix cal program.
.. sectionauthor:: Drew Csillag <drew_csillag@geocities.com>
**Source code:** :source:`Lib/calendar.py`
@@ -19,13 +19,13 @@ are given as integers. For related
functionality, see also the :mod:`datetime` and :mod:`time` modules.
Most of these functions and classes rely on the :mod:`datetime` module which
-uses an idealized calendar, the current Gregorian calendar indefinitely extended
+uses an idealized calendar, the current Gregorian calendar extended
in both directions. This matches the definition of the "proleptic Gregorian"
calendar in Dershowitz and Reingold's book "Calendrical Calculations", where
it's the base calendar for all computations.
-.. class:: Calendar([firstweekday])
+.. class:: Calendar(firstweekday=0)
Creates a :class:`Calendar` object. *firstweekday* is an integer specifying the
first day of the week. ``0`` is Monday (the default), ``6`` is Sunday.
@@ -34,11 +34,9 @@ it's the base calendar for all computations.
preparing the calendar data for formatting. This class doesn't do any formatting
itself. This is the job of subclasses.
- .. versionadded:: 2.5
:class:`Calendar` instances have the following methods:
-
.. method:: iterweekdays()
Return an iterator for the week day numbers that will be used for one
@@ -86,7 +84,7 @@ it's the base calendar for all computations.
weeks. Weeks are lists of seven day numbers.
- .. method:: yeardatescalendar(year[, width])
+ .. method:: yeardatescalendar(year, width=3)
Return the data for the specified year ready for formatting. The return
value is a list of month rows. Each month row contains up to *width*
@@ -94,30 +92,27 @@ it's the base calendar for all computations.
each week contains 1--7 days. Days are :class:`datetime.date` objects.
- .. method:: yeardays2calendar(year[, width])
+ .. method:: yeardays2calendar(year, width=3)
Return the data for the specified year ready for formatting (similar to
:meth:`yeardatescalendar`). Entries in the week lists are tuples of day
numbers and weekday numbers. Day numbers outside this month are zero.
- .. method:: yeardayscalendar(year[, width])
+ .. method:: yeardayscalendar(year, width=3)
Return the data for the specified year ready for formatting (similar to
:meth:`yeardatescalendar`). Entries in the week lists are day numbers. Day
numbers outside this month are zero.
-.. class:: TextCalendar([firstweekday])
+.. class:: TextCalendar(firstweekday=0)
This class can be used to generate plain text calendars.
- .. versionadded:: 2.5
-
:class:`TextCalendar` instances have the following methods:
-
- .. method:: formatmonth(theyear, themonth[, w[, l]])
+ .. method:: formatmonth(theyear, themonth, w=0, l=0)
Return a month's calendar in a multi-line string. If *w* is provided, it
specifies the width of the date columns, which are centered. If *l* is
@@ -126,12 +121,12 @@ it's the base calendar for all computations.
:meth:`setfirstweekday` method.
- .. method:: prmonth(theyear, themonth[, w[, l]])
+ .. method:: prmonth(theyear, themonth, w=0, l=0)
Print a month's calendar as returned by :meth:`formatmonth`.
- .. method:: formatyear(theyear[, w[, l[, c[, m]]]])
+ .. method:: formatyear(theyear, w=2, l=1, c=6, m=3)
Return a *m*-column calendar for an entire year as a multi-line string.
Optional parameters *w*, *l*, and *c* are for date column width, lines per
@@ -141,34 +136,32 @@ it's the base calendar for all computations.
can be generated is platform-dependent.
- .. method:: pryear(theyear[, w[, l[, c[, m]]]])
+ .. method:: pryear(theyear, w=2, l=1, c=6, m=3)
Print the calendar for an entire year as returned by :meth:`formatyear`.
-.. class:: HTMLCalendar([firstweekday])
+.. class:: HTMLCalendar(firstweekday=0)
This class can be used to generate HTML calendars.
- .. versionadded:: 2.5
:class:`HTMLCalendar` instances have the following methods:
-
- .. method:: formatmonth(theyear, themonth[, withyear])
+ .. method:: formatmonth(theyear, themonth, withyear=True)
Return a month's calendar as an HTML table. If *withyear* is true the year
will be included in the header, otherwise just the month name will be
used.
- .. method:: formatyear(theyear[, width])
+ .. method:: formatyear(theyear, width=3)
Return a year's calendar as an HTML table. *width* (defaulting to 3)
specifies the number of months per row.
- .. method:: formatyearpage(theyear[, width[, css[, encoding]]])
+ .. method:: formatyearpage(theyear, width=3, css='calendar.css', encoding=None)
Return a year's calendar as a complete HTML page. *width* (defaulting to
3) specifies the number of months per row. *css* is the name for the
@@ -177,25 +170,21 @@ it's the base calendar for all computations.
output (defaulting to the system default encoding).
-.. class:: LocaleTextCalendar([firstweekday[, locale]])
+.. class:: LocaleTextCalendar(firstweekday=0, locale=None)
This subclass of :class:`TextCalendar` can be passed a locale name in the
constructor and will return month and weekday names in the specified locale.
If this locale includes an encoding all strings containing month and weekday
names will be returned as unicode.
- .. versionadded:: 2.5
-
-.. class:: LocaleHTMLCalendar([firstweekday[, locale]])
+.. class:: LocaleHTMLCalendar(firstweekday=0, locale=None)
This subclass of :class:`HTMLCalendar` can be passed a locale name in the
constructor and will return month and weekday names in the specified
locale. If this locale includes an encoding all strings containing month and
weekday names will be returned as unicode.
- .. versionadded:: 2.5
-
.. note::
The :meth:`formatweekday` and :meth:`formatmonthname` methods of these two
@@ -205,7 +194,6 @@ it's the base calendar for all computations.
For simple text calendars this module provides the following functions.
-
.. function:: setfirstweekday(weekday)
Sets the weekday (``0`` is Monday, ``6`` is Sunday) to start each week. The
@@ -216,15 +204,11 @@ For simple text calendars this module provides the following functions.
import calendar
calendar.setfirstweekday(calendar.SUNDAY)
- .. versionadded:: 2.0
-
.. function:: firstweekday()
Returns the current setting for the weekday to start each week.
- .. versionadded:: 2.0
-
.. function:: isleap(year)
@@ -236,9 +220,7 @@ For simple text calendars this module provides the following functions.
Returns the number of leap years in the range from *y1* to *y2* (exclusive),
where *y1* and *y2* are years.
- .. versionchanged:: 2.0
- This function didn't work for ranges spanning a century change in Python
- 1.5.2.
+ This function works for ranges spanning a century change.
.. function:: weekday(year, month, day)
@@ -266,30 +248,26 @@ For simple text calendars this module provides the following functions.
unless set by :func:`setfirstweekday`.
-.. function:: prmonth(theyear, themonth[, w[, l]])
+.. function:: prmonth(theyear, themonth, w=0, l=0)
Prints a month's calendar as returned by :func:`month`.
-.. function:: month(theyear, themonth[, w[, l]])
+.. function:: month(theyear, themonth, w=0, l=0)
Returns a month's calendar in a multi-line string using the :meth:`formatmonth`
of the :class:`TextCalendar` class.
- .. versionadded:: 2.0
-
-.. function:: prcal(year[, w[, l[c]]])
+.. function:: prcal(year, w=0, l=0, c=6, m=3)
Prints the calendar for an entire year as returned by :func:`calendar`.
-.. function:: calendar(year[, w[, l[c]]])
+.. function:: calendar(year, w=2, l=1, c=6, m=3)
- Returns a 3-column calendar for an entire year as a multi-line string using the
- :meth:`formatyear` of the :class:`TextCalendar` class.
-
- .. versionadded:: 2.0
+ Returns a 3-column calendar for an entire year as a multi-line string using
+ the :meth:`formatyear` of the :class:`TextCalendar` class.
.. function:: timegm(tuple)
@@ -299,11 +277,9 @@ For simple text calendars this module provides the following functions.
Unix timestamp value, assuming an epoch of 1970, and the POSIX encoding. In
fact, :func:`time.gmtime` and :func:`timegm` are each others' inverse.
- .. versionadded:: 2.0
The :mod:`calendar` module exports the following data attributes:
-
.. data:: day_name
An array that represents the days of the week in the current locale.
@@ -336,4 +312,3 @@ The :mod:`calendar` module exports the following data attributes:
Module :mod:`time`
Low-level time related functions.
-
diff --git a/Doc/library/carbon.rst b/Doc/library/carbon.rst
deleted file mode 100644
index 3eebd85..0000000
--- a/Doc/library/carbon.rst
+++ /dev/null
@@ -1,573 +0,0 @@
-
-.. _toolbox:
-
-**********************
-Mac OS Toolbox Modules
-**********************
-
-There are a set of modules that provide interfaces to various Mac OS toolboxes.
-If applicable the module will define a number of Python objects for the various
-structures declared by the toolbox, and operations will be implemented as
-methods of the object. Other operations will be implemented as functions in the
-module. Not all operations possible in C will also be possible in Python
-(callbacks are often a problem), and parameters will occasionally be different
-in Python (input and output buffers, especially). All methods and functions
-have a :attr:`__doc__` string describing their arguments and return values, and
-for additional description you are referred to `Inside Macintosh
-<http://developer.apple.com/legacy/mac/library/#documentation/macos8/mac8.html>`_ or similar works.
-
-These modules all live in a package called :mod:`Carbon`. Despite that name they
-are not all part of the Carbon framework: CF is really in the CoreFoundation
-framework and Qt is in the QuickTime framework. The normal use pattern is ::
-
- from Carbon import AE
-
-.. note::
-
- The Carbon modules have been removed in Python 3.
-
-
-:mod:`Carbon.AE` --- Apple Events
-=================================
-
-.. module:: Carbon.AE
- :platform: Mac
- :synopsis: Interface to the Apple Events toolbox.
- :deprecated:
-
-
-
-:mod:`Carbon.AH` --- Apple Help
-===============================
-
-.. module:: Carbon.AH
- :platform: Mac
- :synopsis: Interface to the Apple Help manager.
- :deprecated:
-
-
-
-:mod:`Carbon.App` --- Appearance Manager
-========================================
-
-.. module:: Carbon.App
- :platform: Mac
- :synopsis: Interface to the Appearance Manager.
- :deprecated:
-
-:mod:`Carbon.Appearance` --- Appearance Manager constants
-=========================================================
-
-.. module:: Carbon.Appearance
- :platform: Mac
- :synopsis: Constant definitions for the interface to the Appearance Manager.
- :deprecated:
-
-
-
-:mod:`Carbon.CF` --- Core Foundation
-====================================
-
-.. module:: Carbon.CF
- :platform: Mac
- :synopsis: Interface to the Core Foundation.
- :deprecated:
-
-
-The ``CFBase``, ``CFArray``, ``CFData``, ``CFDictionary``, ``CFString`` and
-``CFURL`` objects are supported, some only partially.
-
-
-:mod:`Carbon.CG` --- Core Graphics
-==================================
-
-.. module:: Carbon.CG
- :platform: Mac
- :synopsis: Interface to Core Graphics.
- :deprecated:
-
-
-
-:mod:`Carbon.CarbonEvt` --- Carbon Event Manager
-================================================
-
-.. module:: Carbon.CarbonEvt
- :platform: Mac
- :synopsis: Interface to the Carbon Event Manager.
- :deprecated:
-
-:mod:`Carbon.CarbonEvents` --- Carbon Event Manager constants
-=============================================================
-
-.. module:: Carbon.CarbonEvents
- :platform: Mac
- :synopsis: Constants for the interface to the Carbon Event Manager.
- :deprecated:
-
-
-
-:mod:`Carbon.Cm` --- Component Manager
-======================================
-
-.. module:: Carbon.Cm
- :platform: Mac
- :synopsis: Interface to the Component Manager.
- :deprecated:
-
-:mod:`Carbon.Components` --- Component Manager constants
-========================================================
-
-.. module:: Carbon.Components
- :platform: Mac
- :synopsis: Constants for the interface to the Component Manager.
- :deprecated:
-
-
-:mod:`Carbon.ControlAccessor` --- Control Manager accssors
-===========================================================
-
-.. module:: Carbon.ControlAccessor
- :platform: Mac
- :synopsis: Accessor functions for the interface to the Control Manager.
- :deprecated:
-
-:mod:`Carbon.Controls` --- Control Manager constants
-====================================================
-
-.. module:: Carbon.Controls
- :platform: Mac
- :synopsis: Constants for the interface to the Control Manager.
- :deprecated:
-
-:mod:`Carbon.CoreFounation` --- CoreFounation constants
-=======================================================
-
-.. module:: Carbon.CoreFounation
- :platform: Mac
- :synopsis: Constants for the interface to CoreFoundation.
- :deprecated:
-
-:mod:`Carbon.CoreGraphics` --- CoreGraphics constants
-=======================================================
-
-.. module:: Carbon.CoreGraphics
- :platform: Mac
- :synopsis: Constants for the interface to CoreGraphics.
- :deprecated:
-
-:mod:`Carbon.Ctl` --- Control Manager
-=====================================
-
-.. module:: Carbon.Ctl
- :platform: Mac
- :synopsis: Interface to the Control Manager.
- :deprecated:
-
-:mod:`Carbon.Dialogs` --- Dialog Manager constants
-==================================================
-
-.. module:: Carbon.Dialogs
- :platform: Mac
- :synopsis: Constants for the interface to the Dialog Manager.
- :deprecated:
-
-:mod:`Carbon.Dlg` --- Dialog Manager
-====================================
-
-.. module:: Carbon.Dlg
- :platform: Mac
- :synopsis: Interface to the Dialog Manager.
- :deprecated:
-
-:mod:`Carbon.Drag` --- Drag and Drop Manager
-=============================================
-
-.. module:: Carbon.Drag
- :platform: Mac
- :synopsis: Interface to the Drag and Drop Manager.
- :deprecated:
-
-:mod:`Carbon.Dragconst` --- Drag and Drop Manager constants
-===========================================================
-
-.. module:: Carbon.Dragconst
- :platform: Mac
- :synopsis: Constants for the interface to the Drag and Drop Manager.
- :deprecated:
-
-:mod:`Carbon.Events` --- Event Manager constants
-================================================
-
-.. module:: Carbon.Events
- :platform: Mac
- :synopsis: Constants for the interface to the classic Event Manager.
- :deprecated:
-
-:mod:`Carbon.Evt` --- Event Manager
-===================================
-
-.. module:: Carbon.Evt
- :platform: Mac
- :synopsis: Interface to the classic Event Manager.
- :deprecated:
-
-:mod:`Carbon.File` --- File Manager
-===================================
-
-.. module:: Carbon.File
- :platform: Mac
- :synopsis: Interface to the File Manager.
- :deprecated:
-
-:mod:`Carbon.Files` --- File Manager constants
-==============================================
-
-.. module:: Carbon.Files
- :platform: Mac
- :synopsis: Constants for the interface to the File Manager.
- :deprecated:
-
-
-:mod:`Carbon.Fm` --- Font Manager
-=================================
-
-.. module:: Carbon.Fm
- :platform: Mac
- :synopsis: Interface to the Font Manager.
- :deprecated:
-
-
-
-:mod:`Carbon.Folder` --- Folder Manager
-=======================================
-
-.. module:: Carbon.Folder
- :platform: Mac
- :synopsis: Interface to the Folder Manager.
- :deprecated:
-
-:mod:`Carbon.Folders` --- Folder Manager constants
-==================================================
-
-.. module:: Carbon.Folders
- :platform: Mac
- :synopsis: Constants for the interface to the Folder Manager.
- :deprecated:
-
-
-:mod:`Carbon.Fonts` --- Font Manager constants
-==================================================
-
-.. module:: Carbon.Fonts
- :platform: Mac
- :synopsis: Constants for the interface to the Font Manager.
- :deprecated:
-
-
-
-:mod:`Carbon.Help` --- Help Manager
-===================================
-
-.. module:: Carbon.Help
- :platform: Mac
- :synopsis: Interface to the Carbon Help Manager.
- :deprecated:
-
-:mod:`Carbon.IBCarbon` --- Carbon InterfaceBuilder
-==================================================
-
-.. module:: Carbon.IBCarbon
- :platform: Mac
- :synopsis: Interface to the Carbon InterfaceBuilder support libraries.
- :deprecated:
-
-:mod:`Carbon.IBCarbonRuntime` --- Carbon InterfaceBuilder constants
-===================================================================
-
-.. module:: Carbon.IBCarbonRuntime
- :platform: Mac
- :synopsis: Constants for the interface to the Carbon InterfaceBuilder support libraries.
- :deprecated:
-
-:mod:`Carbon.Icn` --- Carbon Icon Manager
-=========================================
-
-.. module:: Carbon.Icns
- :platform: Mac
- :synopsis: Interface to the Carbon Icon Manager
- :deprecated:
-
-:mod:`Carbon.Icons` --- Carbon Icon Manager constants
-=====================================================
-
-.. module:: Carbon.Icons
- :platform: Mac
- :synopsis: Constants for the interface to the Carbon Icon Manager
- :deprecated:
-
-:mod:`Carbon.Launch` --- Carbon Launch Services
-===============================================
-
-.. module:: Carbon.Launch
- :platform: Mac
- :synopsis: Interface to the Carbon Launch Services.
- :deprecated:
-
-:mod:`Carbon.LaunchServices` --- Carbon Launch Services constants
-=================================================================
-
-.. module:: Carbon.LaunchServices
- :platform: Mac
- :synopsis: Constants for the interface to the Carbon Launch Services.
- :deprecated:
-
-
-:mod:`Carbon.List` --- List Manager
-===================================
-
-.. module:: Carbon.List
- :platform: Mac
- :synopsis: Interface to the List Manager.
- :deprecated:
-
-
-
-:mod:`Carbon.Lists` --- List Manager constants
-==============================================
-
-.. module:: Carbon.Lists
- :platform: Mac
- :synopsis: Constants for the interface to the List Manager.
- :deprecated:
-
-:mod:`Carbon.MacHelp` --- Help Manager constants
-================================================
-
-.. module:: Carbon.MacHelp
- :platform: Mac
- :synopsis: Constants for the interface to the Carbon Help Manager.
- :deprecated:
-
-:mod:`Carbon.MediaDescr` --- Parsers and generators for Quicktime Media descriptors
-===================================================================================
-
-.. module:: Carbon.MediaDescr
- :platform: Mac
- :synopsis: Parsers and generators for Quicktime Media descriptors
- :deprecated:
-
-
-:mod:`Carbon.Menu` --- Menu Manager
-===================================
-
-.. module:: Carbon.Menu
- :platform: Mac
- :synopsis: Interface to the Menu Manager.
- :deprecated:
-
-:mod:`Carbon.Menus` --- Menu Manager constants
-==============================================
-
-.. module:: Carbon.Menus
- :platform: Mac
- :synopsis: Constants for the interface to the Menu Manager.
- :deprecated:
-
-
-:mod:`Carbon.Mlte` --- MultiLingual Text Editor
-===============================================
-
-.. module:: Carbon.Mlte
- :platform: Mac
- :synopsis: Interface to the MultiLingual Text Editor.
- :deprecated:
-
-:mod:`Carbon.OSA` --- Carbon OSA Interface
-==========================================
-
-.. module:: Carbon.OSA
- :platform: Mac
- :synopsis: Interface to the Carbon OSA Library.
- :deprecated:
-
-:mod:`Carbon.OSAconst` --- Carbon OSA Interface constants
-=========================================================
-
-.. module:: Carbon.OSAconst
- :platform: Mac
- :synopsis: Constants for the interface to the Carbon OSA Library.
- :deprecated:
-
-:mod:`Carbon.QDOffscreen` --- QuickDraw Offscreen constants
-===========================================================
-
-.. module:: Carbon.QDOffscreen
- :platform: Mac
- :synopsis: Constants for the interface to the QuickDraw Offscreen APIs.
- :deprecated:
-
-
-:mod:`Carbon.Qd` --- QuickDraw
-==============================
-
-.. module:: Carbon.Qd
- :platform: Mac
- :synopsis: Interface to the QuickDraw toolbox.
- :deprecated:
-
-
-
-:mod:`Carbon.Qdoffs` --- QuickDraw Offscreen
-============================================
-
-.. module:: Carbon.Qdoffs
- :platform: Mac
- :synopsis: Interface to the QuickDraw Offscreen APIs.
- :deprecated:
-
-
-
-:mod:`Carbon.Qt` --- QuickTime
-==============================
-
-.. module:: Carbon.Qt
- :platform: Mac
- :synopsis: Interface to the QuickTime toolbox.
- :deprecated:
-
-:mod:`Carbon.QuickDraw` --- QuickDraw constants
-===============================================
-
-.. module:: Carbon.QuickDraw
- :platform: Mac
- :synopsis: Constants for the interface to the QuickDraw toolbox.
- :deprecated:
-
-:mod:`Carbon.QuickTime` --- QuickTime constants
-===============================================
-
-.. module:: Carbon.QuickTime
- :platform: Mac
- :synopsis: Constants for the interface to the QuickTime toolbox.
- :deprecated:
-
-
-:mod:`Carbon.Res` --- Resource Manager and Handles
-==================================================
-
-.. module:: Carbon.Res
- :platform: Mac
- :synopsis: Interface to the Resource Manager and Handles.
- :deprecated:
-
-:mod:`Carbon.Resources` --- Resource Manager and Handles constants
-==================================================================
-
-.. module:: Carbon.Resources
- :platform: Mac
- :synopsis: Constants for the interface to the Resource Manager and Handles.
- :deprecated:
-
-
-:mod:`Carbon.Scrap` --- Scrap Manager
-=====================================
-
-.. module:: Carbon.Scrap
- :platform: Mac
- :synopsis: The Scrap Manager provides basic services for implementing cut & paste and
- clipboard operations.
- :deprecated:
-
-
-This module is only fully available on Mac OS 9 and earlier under classic PPC
-MacPython. Very limited functionality is available under Carbon MacPython.
-
-.. index:: single: Scrap Manager
-
-The Scrap Manager supports the simplest form of cut & paste operations on the
-Macintosh. It can be use for both inter- and intra-application clipboard
-operations.
-
-The :mod:`Scrap` module provides low-level access to the functions of the Scrap
-Manager. It contains the following functions:
-
-
-.. function:: InfoScrap()
-
- Return current information about the scrap. The information is encoded as a
- tuple containing the fields ``(size, handle, count, state, path)``.
-
- +----------+---------------------------------------------+
- | Field | Meaning |
- +==========+=============================================+
- | *size* | Size of the scrap in bytes. |
- +----------+---------------------------------------------+
- | *handle* | Resource object representing the scrap. |
- +----------+---------------------------------------------+
- | *count* | Serial number of the scrap contents. |
- +----------+---------------------------------------------+
- | *state* | Integer; positive if in memory, ``0`` if on |
- | | disk, negative if uninitialized. |
- +----------+---------------------------------------------+
- | *path* | Filename of the scrap when stored on disk. |
- +----------+---------------------------------------------+
-
-
-.. seealso::
-
- `Scrap Manager <http://developer.apple.com/legacy/mac/library/documentation/mac/MoreToolbox/MoreToolbox-109.html>`_
- Apple's documentation for the Scrap Manager gives a lot of useful information
- about using the Scrap Manager in applications.
-
-
-
-:mod:`Carbon.Snd` --- Sound Manager
-===================================
-
-.. module:: Carbon.Snd
- :platform: Mac
- :synopsis: Interface to the Sound Manager.
- :deprecated:
-
-:mod:`Carbon.Sound` --- Sound Manager constants
-===============================================
-
-.. module:: Carbon.Sound
- :platform: Mac
- :synopsis: Constants for the interface to the Sound Manager.
- :deprecated:
-
-
-:mod:`Carbon.TE` --- TextEdit
-=============================
-
-.. module:: Carbon.TE
- :platform: Mac
- :synopsis: Interface to TextEdit.
- :deprecated:
-
-:mod:`Carbon.TextEdit` --- TextEdit constants
-=============================================
-
-.. module:: Carbon.TextEdit
- :platform: Mac
- :synopsis: Constants for the interface to TextEdit.
- :deprecated:
-
-
-
-:mod:`Carbon.Win` --- Window Manager
-====================================
-
-.. module:: Carbon.Win
- :platform: Mac
- :synopsis: Interface to the Window Manager.
- :deprecated:
-
-:mod:`Carbon.Windows` --- Window Manager constants
-==================================================
-
-.. module:: Carbon.Windows
- :platform: Mac
- :synopsis: Constants for the interface to the Window Manager.
- :deprecated:
diff --git a/Doc/library/cd.rst b/Doc/library/cd.rst
deleted file mode 100644
index 40b8ce6..0000000
--- a/Doc/library/cd.rst
+++ /dev/null
@@ -1,340 +0,0 @@
-
-:mod:`cd` --- CD-ROM access on SGI systems
-==========================================
-
-.. module:: cd
- :platform: IRIX
- :synopsis: Interface to the CD-ROM on Silicon Graphics systems.
- :deprecated:
-
-
-.. deprecated:: 2.6
- The :mod:`cd` module has been removed in Python 3.
-
-
-This module provides an interface to the Silicon Graphics CD library. It is
-available only on Silicon Graphics systems.
-
-The way the library works is as follows. A program opens the CD-ROM device with
-:func:`.open` and creates a parser to parse the data from the CD with
-:func:`createparser`. The object returned by :func:`.open` can be used to read
-data from the CD, but also to get status information for the CD-ROM device, and
-to get information about the CD, such as the table of contents. Data from the
-CD is passed to the parser, which parses the frames, and calls any callback
-functions that have previously been added.
-
-An audio CD is divided into :dfn:`tracks` or :dfn:`programs` (the terms are used
-interchangeably). Tracks can be subdivided into :dfn:`indices`. An audio CD
-contains a :dfn:`table of contents` which gives the starts of the tracks on the
-CD. Index 0 is usually the pause before the start of a track. The start of the
-track as given by the table of contents is normally the start of index 1.
-
-Positions on a CD can be represented in two ways. Either a frame number or a
-tuple of three values, minutes, seconds and frames. Most functions use the
-latter representation. Positions can be both relative to the beginning of the
-CD, and to the beginning of the track.
-
-Module :mod:`cd` defines the following functions and constants:
-
-
-.. function:: createparser()
-
- Create and return an opaque parser object. The methods of the parser object are
- described below.
-
-
-.. function:: msftoframe(minutes, seconds, frames)
-
- Converts a ``(minutes, seconds, frames)`` triple representing time in absolute
- time code into the corresponding CD frame number.
-
-
-.. function:: open([device[, mode]])
-
- Open the CD-ROM device. The return value is an opaque player object; methods of
- the player object are described below. The device is the name of the SCSI
- device file, e.g. ``'/dev/scsi/sc0d4l0'``, or ``None``. If omitted or ``None``,
- the hardware inventory is consulted to locate a CD-ROM drive. The *mode*, if
- not omitted, should be the string ``'r'``.
-
-The module defines the following variables:
-
-
-.. exception:: error
-
- Exception raised on various errors.
-
-
-.. data:: DATASIZE
-
- The size of one frame's worth of audio data. This is the size of the audio data
- as passed to the callback of type ``audio``.
-
-
-.. data:: BLOCKSIZE
-
- The size of one uninterpreted frame of audio data.
-
-The following variables are states as returned by :func:`getstatus`:
-
-
-.. data:: READY
-
- The drive is ready for operation loaded with an audio CD.
-
-
-.. data:: NODISC
-
- The drive does not have a CD loaded.
-
-
-.. data:: CDROM
-
- The drive is loaded with a CD-ROM. Subsequent play or read operations will
- return I/O errors.
-
-
-.. data:: ERROR
-
- An error occurred while trying to read the disc or its table of contents.
-
-
-.. data:: PLAYING
-
- The drive is in CD player mode playing an audio CD through its audio jacks.
-
-
-.. data:: PAUSED
-
- The drive is in CD layer mode with play paused.
-
-
-.. data:: STILL
-
- The equivalent of :const:`PAUSED` on older (non 3301) model Toshiba CD-ROM
- drives. Such drives have never been shipped by SGI.
-
-
-.. data:: audio
- pnum
- index
- ptime
- atime
- catalog
- ident
- control
-
- Integer constants describing the various types of parser callbacks that can be
- set by the :meth:`addcallback` method of CD parser objects (see below).
-
-
-.. _player-objects:
-
-Player Objects
---------------
-
-Player objects (returned by :func:`.open`) have the following methods:
-
-
-.. method:: CD player.allowremoval()
-
- Unlocks the eject button on the CD-ROM drive permitting the user to eject the
- caddy if desired.
-
-
-.. method:: CD player.bestreadsize()
-
- Returns the best value to use for the *num_frames* parameter of the
- :meth:`readda` method. Best is defined as the value that permits a continuous
- flow of data from the CD-ROM drive.
-
-
-.. method:: CD player.close()
-
- Frees the resources associated with the player object. After calling
- :meth:`close`, the methods of the object should no longer be used.
-
-
-.. method:: CD player.eject()
-
- Ejects the caddy from the CD-ROM drive.
-
-
-.. method:: CD player.getstatus()
-
- Returns information pertaining to the current state of the CD-ROM drive. The
- returned information is a tuple with the following values: *state*, *track*,
- *rtime*, *atime*, *ttime*, *first*, *last*, *scsi_audio*, *cur_block*. *rtime*
- is the time relative to the start of the current track; *atime* is the time
- relative to the beginning of the disc; *ttime* is the total time on the disc.
- For more information on the meaning of the values, see the man page
- :manpage:`CDgetstatus(3dm)`. The value of *state* is one of the following:
- :const:`ERROR`, :const:`NODISC`, :const:`READY`, :const:`PLAYING`,
- :const:`PAUSED`, :const:`STILL`, or :const:`CDROM`.
-
-
-.. method:: CD player.gettrackinfo(track)
-
- Returns information about the specified track. The returned information is a
- tuple consisting of two elements, the start time of the track and the duration
- of the track.
-
-
-.. method:: CD player.msftoblock(min, sec, frame)
-
- Converts a minutes, seconds, frames triple representing a time in absolute time
- code into the corresponding logical block number for the given CD-ROM drive.
- You should use :func:`msftoframe` rather than :meth:`msftoblock` for comparing
- times. The logical block number differs from the frame number by an offset
- required by certain CD-ROM drives.
-
-
-.. method:: CD player.play(start, play)
-
- Starts playback of an audio CD in the CD-ROM drive at the specified track. The
- audio output appears on the CD-ROM drive's headphone and audio jacks (if
- fitted). Play stops at the end of the disc. *start* is the number of the track
- at which to start playing the CD; if *play* is 0, the CD will be set to an
- initial paused state. The method :meth:`togglepause` can then be used to
- commence play.
-
-
-.. method:: CD player.playabs(minutes, seconds, frames, play)
-
- Like :meth:`play`, except that the start is given in minutes, seconds, and
- frames instead of a track number.
-
-
-.. method:: CD player.playtrack(start, play)
-
- Like :meth:`play`, except that playing stops at the end of the track.
-
-
-.. method:: CD player.playtrackabs(track, minutes, seconds, frames, play)
-
- Like :meth:`play`, except that playing begins at the specified absolute time and
- ends at the end of the specified track.
-
-
-.. method:: CD player.preventremoval()
-
- Locks the eject button on the CD-ROM drive thus preventing the user from
- arbitrarily ejecting the caddy.
-
-
-.. method:: CD player.readda(num_frames)
-
- Reads the specified number of frames from an audio CD mounted in the CD-ROM
- drive. The return value is a string representing the audio frames. This string
- can be passed unaltered to the :meth:`parseframe` method of the parser object.
-
-
-.. method:: CD player.seek(minutes, seconds, frames)
-
- Sets the pointer that indicates the starting point of the next read of digital
- audio data from a CD-ROM. The pointer is set to an absolute time code location
- specified in *minutes*, *seconds*, and *frames*. The return value is the
- logical block number to which the pointer has been set.
-
-
-.. method:: CD player.seekblock(block)
-
- Sets the pointer that indicates the starting point of the next read of digital
- audio data from a CD-ROM. The pointer is set to the specified logical block
- number. The return value is the logical block number to which the pointer has
- been set.
-
-
-.. method:: CD player.seektrack(track)
-
- Sets the pointer that indicates the starting point of the next read of digital
- audio data from a CD-ROM. The pointer is set to the specified track. The
- return value is the logical block number to which the pointer has been set.
-
-
-.. method:: CD player.stop()
-
- Stops the current playing operation.
-
-
-.. method:: CD player.togglepause()
-
- Pauses the CD if it is playing, and makes it play if it is paused.
-
-
-.. _cd-parser-objects:
-
-Parser Objects
---------------
-
-Parser objects (returned by :func:`createparser`) have the following methods:
-
-
-.. method:: CD parser.addcallback(type, func, arg)
-
- Adds a callback for the parser. The parser has callbacks for eight different
- types of data in the digital audio data stream. Constants for these types are
- defined at the :mod:`cd` module level (see above). The callback is called as
- follows: ``func(arg, type, data)``, where *arg* is the user supplied argument,
- *type* is the particular type of callback, and *data* is the data returned for
- this *type* of callback. The type of the data depends on the *type* of callback
- as follows:
-
- +-------------+---------------------------------------------+
- | Type | Value |
- +=============+=============================================+
- | ``audio`` | String which can be passed unmodified to |
- | | :func:`al.writesamps`. |
- +-------------+---------------------------------------------+
- | ``pnum`` | Integer giving the program (track) number. |
- +-------------+---------------------------------------------+
- | ``index`` | Integer giving the index number. |
- +-------------+---------------------------------------------+
- | ``ptime`` | Tuple consisting of the program time in |
- | | minutes, seconds, and frames. |
- +-------------+---------------------------------------------+
- | ``atime`` | Tuple consisting of the absolute time in |
- | | minutes, seconds, and frames. |
- +-------------+---------------------------------------------+
- | ``catalog`` | String of 13 characters, giving the catalog |
- | | number of the CD. |
- +-------------+---------------------------------------------+
- | ``ident`` | String of 12 characters, giving the ISRC |
- | | identification number of the recording. |
- | | The string consists of two characters |
- | | country code, three characters owner code, |
- | | two characters giving the year, and five |
- | | characters giving a serial number. |
- +-------------+---------------------------------------------+
- | ``control`` | Integer giving the control bits from the CD |
- | | subcode data |
- +-------------+---------------------------------------------+
-
-
-.. method:: CD parser.deleteparser()
-
- Deletes the parser and frees the memory it was using. The object should not be
- used after this call. This call is done automatically when the last reference
- to the object is removed.
-
-
-.. method:: CD parser.parseframe(frame)
-
- Parses one or more frames of digital audio data from a CD such as returned by
- :meth:`readda`. It determines which subcodes are present in the data. If these
- subcodes have changed since the last frame, then :meth:`parseframe` executes a
- callback of the appropriate type passing to it the subcode data found in the
- frame. Unlike the C function, more than one frame of digital audio data can be
- passed to this method.
-
-
-.. method:: CD parser.removecallback(type)
-
- Removes the callback for the given *type*.
-
-
-.. method:: CD parser.resetparser()
-
- Resets the fields of the parser used for tracking subcodes to an initial state.
- :meth:`resetparser` should be called after the disc has been changed.
-
diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst
index 0240998..21509d1 100644
--- a/Doc/library/cgi.rst
+++ b/Doc/library/cgi.rst
@@ -49,16 +49,16 @@ line. The first section contains a number of headers, telling the client what
kind of data is following. Python code to generate a minimal header section
looks like this::
- print "Content-Type: text/html" # HTML is following
- print # blank line, end of headers
+ print("Content-Type: text/html") # HTML is following
+ print() # blank line, end of headers
The second section is usually HTML, which allows the client software to display
nicely formatted text with header, in-line images, etc. Here's Python code that
prints a simple piece of HTML::
- print "<TITLE>CGI script output</TITLE>"
- print "<H1>This is my first CGI script</H1>"
- print "Hello, world!"
+ print("<TITLE>CGI script output</TITLE>")
+ print("<H1>This is my first CGI script</H1>")
+ print("Hello, world!")
.. _using-the-cgi-module:
@@ -66,9 +66,7 @@ prints a simple piece of HTML::
Using the cgi module
--------------------
-Begin by writing ``import cgi``. Do not use ``from cgi import *`` --- the
-module defines all sorts of names for its own use or for backward compatibility
-that you don't want in your namespace.
+Begin by writing ``import cgi``.
When you write a new script, consider adding these lines::
@@ -88,12 +86,14 @@ produced by :mod:`cgitb` provide information that can save you a lot of time in
tracking down bugs. You can always remove the ``cgitb`` line later when you
have tested your script and are confident that it works correctly.
-To get at submitted form data, it's best to use the :class:`FieldStorage` class.
-The other classes defined in this module are provided mostly for backward
-compatibility. Instantiate it exactly once, without arguments. This reads the
-form contents from standard input or the environment (depending on the value of
-various environment variables set according to the CGI standard). Since it may
-consume standard input, it should be instantiated only once.
+To get at submitted form data, use the :class:`FieldStorage` class. If the form
+contains non-ASCII characters, use the *encoding* keyword parameter set to the
+value of the encoding defined for the document. It is usually contained in the
+META tag in the HEAD section of the HTML document or by the
+:mailheader:`Content-Type` header). This reads the form contents from the
+standard input or the environment (depending on the value of various
+environment variables set according to the CGI standard). Since it may consume
+standard input, it should be instantiated only once.
The :class:`FieldStorage` instance can be indexed like a Python dictionary.
It allows membership testing with the :keyword:`in` operator, and also supports
@@ -110,11 +110,11 @@ string::
form = cgi.FieldStorage()
if "name" not in form or "addr" not in form:
- print "<H1>Error</H1>"
- print "Please fill in the name and addr fields."
+ print("<H1>Error</H1>")
+ print("Please fill in the name and addr fields.")
return
- print "<p>name:", form["name"].value
- print "<p>addr:", form["addr"].value
+ print("<p>name:", form["name"].value)
+ print("<p>addr:", form["addr"].value)
...further form processing here...
Here the fields, accessed through ``form[key]``, are themselves instances of
@@ -139,16 +139,16 @@ commas::
If a field represents an uploaded file, accessing the value via the
:attr:`value` attribute or the :func:`getvalue` method reads the entire file in
-memory as a string. This may not be what you want. You can test for an uploaded
+memory as bytes. This may not be what you want. You can test for an uploaded
file by testing either the :attr:`filename` attribute or the :attr:`!file`
attribute. You can then read the data at leisure from the :attr:`!file`
-attribute::
+attribute (the :func:`read` and :func:`readline` methods will return bytes)::
fileitem = form["userfile"]
if fileitem.file:
# It's an uploaded file; count lines
linecount = 0
- while 1:
+ while True:
line = fileitem.file.readline()
if not line: break
linecount = linecount + 1
@@ -177,8 +177,6 @@ A form submitted via POST that also has a query string will contain both
Higher Level Interface
----------------------
-.. versionadded:: 2.2
-
The previous section explains how to read CGI form data using the
:class:`FieldStorage` class. This section describes a higher level interface
which was added to this class to allow one to do it in a more readable and
@@ -229,7 +227,7 @@ A more convenient approach is to use the methods :meth:`getfirst` and
:meth:`getlist` provided by this higher level interface.
-.. method:: FieldStorage.getfirst(name[, default])
+.. method:: FieldStorage.getfirst(name, default=None)
This method always returns only one value associated with form field *name*.
The method returns only the first value in case that more values were posted
@@ -255,26 +253,6 @@ Using these methods you can write nice compact code::
do_something(item)
-Old classes
------------
-
-.. deprecated:: 2.6
-
- These classes, present in earlier versions of the :mod:`cgi` module, are
- still supported for backward compatibility. New applications should use the
- :class:`FieldStorage` class.
-
-:class:`SvFormContentDict` stores single value form content as dictionary; it
-assumes each field name occurs in the form only once.
-
-:class:`FormContentDict` stores multiple value form content as a dictionary (the
-form items are lists of values). Useful if your form contains multiple fields
-with the same name.
-
-Other classes (:class:`FormContent`, :class:`InterpFormContentDict`) are present
-for backwards compatibility with really old applications only.
-
-
.. _functions-in-cgi-module:
Functions
@@ -284,22 +262,22 @@ These are useful if you want more control, or if you want to employ some of the
algorithms implemented in this module in other circumstances.
-.. function:: parse(fp[, environ[, keep_blank_values[, strict_parsing]]])
+.. function:: parse(fp=None, environ=os.environ, keep_blank_values=False, strict_parsing=False)
Parse a query in the environment or from a file (the file defaults to
- ``sys.stdin`` and environment defaults to ``os.environ``). The *keep_blank_values* and *strict_parsing* parameters are
- passed to :func:`urlparse.parse_qs` unchanged.
+ ``sys.stdin``). The *keep_blank_values* and *strict_parsing* parameters are
+ passed to :func:`urllib.parse.parse_qs` unchanged.
-.. function:: parse_qs(qs[, keep_blank_values[, strict_parsing]])
+.. function:: parse_qs(qs, keep_blank_values=False, strict_parsing=False)
- This function is deprecated in this module. Use :func:`urlparse.parse_qs`
- instead. It is maintained here only for backward compatiblity.
+ This function is deprecated in this module. Use :func:`urllib.parse.parse_qs`
+ instead. It is maintained here only for backward compatibility.
-.. function:: parse_qsl(qs[, keep_blank_values[, strict_parsing]])
+.. function:: parse_qsl(qs, keep_blank_values=False, strict_parsing=False)
- This function is deprecated in this module. Use :func:`urlparse.parse_qsl`
- instead. It is maintained here only for backward compatiblity.
+ This function is deprecated in this module. Use :func:`urllib.parse.parse_qs`
+ instead. It is maintained here only for backward compatibility.
.. function:: parse_multipart(fp, pdict)
@@ -307,7 +285,7 @@ algorithms implemented in this module in other circumstances.
Arguments are *fp* for the input file and *pdict* for a dictionary containing
other parameters in the :mailheader:`Content-Type` header.
- Returns a dictionary just like :func:`urlparse.parse_qs` keys are the field names, each
+ Returns a dictionary just like :func:`urllib.parse.parse_qs` keys are the field names, each
value is a list of values for that field. This is easy to use but not much good
if you are expecting megabytes to be uploaded --- in that case, use the
:class:`FieldStorage` class instead which is much more flexible.
@@ -348,7 +326,7 @@ algorithms implemented in this module in other circumstances.
Print a list of useful (used by CGI) environment variables in HTML.
-.. function:: escape(s[, quote])
+.. function:: escape(s, quote=False)
Convert the characters ``'&'``, ``'<'`` and ``'>'`` in string *s* to HTML-safe
sequences. Use this if you need to display text that might contain such
@@ -357,9 +335,9 @@ algorithms implemented in this module in other circumstances.
attribute value delimited by double quotes, as in ``<a href="...">``. Note
that single quotes are never translated.
- If the value to be quoted might include single- or double-quote characters,
- or both, consider using the :func:`~xml.sax.saxutils.quoteattr` function in the
- :mod:`xml.sax.saxutils` module instead.
+ .. deprecated:: 3.2
+ This function is unsafe because *quote* is false by default, and therefore
+ deprecated. Use :func:`html.escape` instead.
.. _cgi-security:
@@ -390,7 +368,7 @@ administrator to find the directory where CGI scripts should be installed;
usually this is in a directory :file:`cgi-bin` in the server tree.
Make sure that your script is readable and executable by "others"; the Unix file
-mode should be ``0755`` octal (use ``chmod 0755 filename``). Make sure that the
+mode should be ``0o755`` octal (use ``chmod 0755 filename``). Make sure that the
first line of the script contains ``#!`` starting in column 1 followed by the
pathname of the Python interpreter, for instance::
@@ -399,8 +377,8 @@ pathname of the Python interpreter, for instance::
Make sure the Python interpreter exists and is executable by "others".
Make sure that any files your script needs to read or write are readable or
-writable, respectively, by "others" --- their mode should be ``0644`` for
-readable and ``0666`` for writable. This is because, for security reasons, the
+writable, respectively, by "others" --- their mode should be ``0o644`` for
+readable and ``0o666`` for writable. This is because, for security reasons, the
HTTP server executes your script as user "nobody", without any special
privileges. It can only read (write, execute) files that everybody can read
(write, execute). The current directory at execution time is also different (it
@@ -493,8 +471,8 @@ you can use an even more robust approach (which only uses built-in modules)::
import sys
sys.stderr = sys.stdout
- print "Content-Type: text/plain"
- print
+ print("Content-Type: text/plain")
+ print()
...your code here...
This relies on the Python interpreter to print the traceback. The content type
@@ -537,8 +515,8 @@ Common problems and solutions
.. rubric:: Footnotes
-.. [#] Note that some recent versions of the HTML specification do state what order the
- field values should be supplied in, but knowing whether a request was
- received from a conforming browser, or even from a browser at all, is tedious
- and error-prone.
+.. [#] Note that some recent versions of the HTML specification do state what
+ order the field values should be supplied in, but knowing whether a request
+ was received from a conforming browser, or even from a browser at all, is
+ tedious and error-prone.
diff --git a/Doc/library/cgihttpserver.rst b/Doc/library/cgihttpserver.rst
deleted file mode 100644
index 013ee82..0000000
--- a/Doc/library/cgihttpserver.rst
+++ /dev/null
@@ -1,76 +0,0 @@
-:mod:`CGIHTTPServer` --- CGI-capable HTTP request handler
-=========================================================
-
-.. module:: CGIHTTPServer
- :synopsis: This module provides a request handler for HTTP servers which can run CGI
- scripts.
-.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
-
-.. note::
- The :mod:`CGIHTTPServer` module has been merged into :mod:`http.server` in
- Python 3. The :term:`2to3` tool will automatically adapt imports when
- converting your sources to Python 3.
-
-
-The :mod:`CGIHTTPServer` module defines a request-handler class, interface
-compatible with :class:`BaseHTTPServer.BaseHTTPRequestHandler` and inherits
-behavior from :class:`SimpleHTTPServer.SimpleHTTPRequestHandler` but can also
-run CGI scripts.
-
-.. note::
-
- This module can run CGI scripts on Unix and Windows systems.
-
-.. note::
-
- CGI scripts run by the :class:`CGIHTTPRequestHandler` class cannot execute
- redirects (HTTP code 302), because code 200 (script output follows) is sent
- prior to execution of the CGI script. This pre-empts the status code.
-
-The :mod:`CGIHTTPServer` module defines the following class:
-
-
-.. class:: CGIHTTPRequestHandler(request, client_address, server)
-
- This class is used to serve either files or output of CGI scripts from the
- current directory and below. Note that mapping HTTP hierarchic structure to
- local directory structure is exactly as in
- :class:`SimpleHTTPServer.SimpleHTTPRequestHandler`.
-
- The class will however, run the CGI script, instead of serving it as a file, if
- it guesses it to be a CGI script. Only directory-based CGI are used --- the
- other common server configuration is to treat special extensions as denoting CGI
- scripts.
-
- The :func:`do_GET` and :func:`do_HEAD` functions are modified to run CGI scripts
- and serve the output, instead of serving files, if the request leads to
- somewhere below the ``cgi_directories`` path.
-
- The :class:`CGIHTTPRequestHandler` defines the following data member:
-
-
- .. attribute:: cgi_directories
-
- This defaults to ``['/cgi-bin', '/htbin']`` and describes directories to
- treat as containing CGI scripts.
-
- The :class:`CGIHTTPRequestHandler` defines the following methods:
-
-
- .. method:: do_POST()
-
- This method serves the ``'POST'`` request type, only allowed for CGI
- scripts. Error 501, "Can only POST to CGI scripts", is output when trying
- to POST to a non-CGI url.
-
-Note that CGI scripts will be run with UID of user nobody, for security reasons.
-Problems with the CGI script will be translated to error 403.
-
-For example usage, see the implementation of the :func:`test` function.
-
-
-.. seealso::
-
- Module :mod:`BaseHTTPServer`
- Base class implementation for Web server and request handler.
-
diff --git a/Doc/library/cgitb.rst b/Doc/library/cgitb.rst
index 052b821..6827c8e 100644
--- a/Doc/library/cgitb.rst
+++ b/Doc/library/cgitb.rst
@@ -1,4 +1,3 @@
-
:mod:`cgitb` --- Traceback manager for CGI scripts
==================================================
@@ -8,8 +7,6 @@
.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
-.. versionadded:: 2.2
-
.. index::
single: CGI; exceptions
single: CGI; tracebacks
@@ -36,7 +33,7 @@ displayed in the browser and whether the report is logged to a file for later
analysis.
-.. function:: enable([display[, logdir[, context[, format]]]])
+.. function:: enable(display=1, logdir=None, context=5, format="html")
.. index:: single: excepthook() (in module sys)
@@ -53,7 +50,7 @@ analysis.
value forces plain text output. The default value is ``"html"``.
-.. function:: handler([info])
+.. function:: handler(info=None)
This function handles an exception using the default settings (that is, show a
report in the browser, but don't log to a file). This can be used when you've
diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst
index 64ce4e2..d3558a4 100644
--- a/Doc/library/chunk.rst
+++ b/Doc/library/chunk.rst
@@ -1,4 +1,3 @@
-
:mod:`chunk` --- Read IFF chunked data
======================================
@@ -51,7 +50,7 @@ new instance can be instantiated. At the end of the file, creating a new
instance will fail with a :exc:`EOFError` exception.
-.. class:: Chunk(file[, align, bigendian, inclheader])
+.. class:: Chunk(file, align=True, bigendian=True, inclheader=False)
Class which represents a chunk. The *file* argument is expected to be a
file-like object. An instance of this class is specifically allowed. The
@@ -94,7 +93,7 @@ instance will fail with a :exc:`EOFError` exception.
Returns ``False``.
- .. method:: seek(pos[, whence])
+ .. method:: seek(pos, whence=0)
Set the chunk's current position. The *whence* argument is optional and
defaults to ``0`` (absolute file positioning); other values are ``1``
@@ -108,7 +107,7 @@ instance will fail with a :exc:`EOFError` exception.
Return the current position into the chunk.
- .. method:: read([size])
+ .. method:: read(size=-1)
Read at most *size* bytes from the chunk (less if the read hits the end of
the chunk before obtaining *size* bytes). If the *size* argument is
diff --git a/Doc/library/cmath.rst b/Doc/library/cmath.rst
index 5cbb426..d7778df 100644
--- a/Doc/library/cmath.rst
+++ b/Doc/library/cmath.rst
@@ -54,11 +54,9 @@ rectangular coordinates to polar coordinates and back.
``x.imag`` is zero::
>>> phase(complex(-1.0, 0.0))
- 3.1415926535897931
+ 3.141592653589793
>>> phase(complex(-1.0, -0.0))
- -3.1415926535897931
-
- .. versionadded:: 2.6
+ -3.141592653589793
.. note::
@@ -75,16 +73,12 @@ rectangular coordinates to polar coordinates and back.
phase of *x*. ``polar(x)`` is equivalent to ``(abs(x),
phase(x))``.
- .. versionadded:: 2.6
-
.. function:: rect(r, phi)
Return the complex number *x* with polar coordinates *r* and *phi*.
Equivalent to ``r * (math.cos(phi) + math.sin(phi)*1j)``.
- .. versionadded:: 2.6
-
Power and logarithmic functions
-------------------------------
@@ -100,9 +94,6 @@ Power and logarithmic functions
specified, returns the natural logarithm of *x*. There is one branch cut, from 0
along the negative real axis to -∞, continuous from above.
- .. versionchanged:: 2.4
- *base* argument added.
-
.. function:: log10(x)
@@ -137,9 +128,6 @@ Trigonometric functions
other extends from ``-1j`` along the imaginary axis to ``-∞j``, continuous
from the left.
- .. versionchanged:: 2.6
- direction of continuity of upper cut reversed
-
.. function:: cos(x)
@@ -172,9 +160,6 @@ Hyperbolic functions
continuous from the right. The other extends from ``-1j`` along
the imaginary axis to ``-∞j``, continuous from the left.
- .. versionchanged:: 2.6
- branch cuts moved to match those recommended by the C99 standard
-
.. function:: atanh(x)
@@ -183,9 +168,6 @@ Hyperbolic functions
other extends from ``-1`` along the real axis to ``-∞``, continuous from
above.
- .. versionchanged:: 2.6
- direction of continuity of right cut reversed
-
.. function:: cosh(x)
@@ -205,19 +187,24 @@ Hyperbolic functions
Classification functions
------------------------
-.. function:: isinf(x)
+.. function:: isfinite(x)
- Return *True* if the real or the imaginary part of x is positive
- or negative infinity.
+ Return ``True`` if both the real and imaginary parts of *x* are finite, and
+ ``False`` otherwise.
- .. versionadded:: 2.6
+ .. versionadded:: 3.2
-.. function:: isnan(x)
+.. function:: isinf(x)
- Return *True* if the real or imaginary part of x is not a number (NaN).
+ Return ``True`` if either the real or the imaginary part of *x* is an
+ infinity, and ``False`` otherwise.
+
+
+.. function:: isnan(x)
- .. versionadded:: 2.6
+ Return ``True`` if either the real or the imaginary part of *x* is a NaN,
+ and ``False`` otherwise.
Constants
diff --git a/Doc/library/cmd.rst b/Doc/library/cmd.rst
index ea24122..943c04a 100644
--- a/Doc/library/cmd.rst
+++ b/Doc/library/cmd.rst
@@ -14,7 +14,7 @@ command interpreters. These are often useful for test harnesses, administrative
tools, and prototypes that will later be wrapped in a more sophisticated
interface.
-.. class:: Cmd([completekey[, stdin[, stdout]]])
+.. class:: Cmd(completekey='tab', stdin=None, stdout=None)
A :class:`Cmd` instance or subclass instance is a line-oriented interpreter
framework. There is no good reason to instantiate :class:`Cmd` itself; rather,
@@ -34,9 +34,6 @@ interface.
:attr:`use_rawinput` attribute to ``False``, otherwise *stdin* will be
ignored.
- .. versionchanged:: 2.3
- The *stdin* and *stdout* parameters were added.
-
.. _cmd-objects:
@@ -46,7 +43,7 @@ Cmd Objects
A :class:`Cmd` instance has the following methods:
-.. method:: Cmd.cmdloop([intro])
+.. method:: Cmd.cmdloop(intro=None)
Repeatedly issue a prompt, accept input, parse an initial prefix off the
received input, and dispatch to action methods, passing them the remainder of
@@ -202,9 +199,170 @@ Instances of :class:`Cmd` subclasses have some public instance variables:
.. attribute:: Cmd.use_rawinput
- A flag, defaulting to true. If true, :meth:`cmdloop` uses :func:`raw_input` to
+ A flag, defaulting to true. If true, :meth:`cmdloop` uses :func:`input` to
display a prompt and read the next command; if false, :meth:`sys.stdout.write`
and :meth:`sys.stdin.readline` are used. (This means that by importing
:mod:`readline`, on systems that support it, the interpreter will automatically
support :program:`Emacs`\ -like line editing and command-history keystrokes.)
+
+.. _cmd-example:
+
+Cmd Example
+-----------
+
+.. sectionauthor:: Raymond Hettinger <python at rcn dot com>
+
+The :mod:`cmd` module is mainly useful for building custom shells that let a
+user work with a program interactively.
+
+This section presents a simple example of how to build a shell around a few of
+the commands in the :mod:`turtle` module.
+
+Basic turtle commands such as :meth:`~turtle.forward` are added to a
+:class:`Cmd` subclass with method named :meth:`do_forward`. The argument is
+converted to a number and dispatched to the turtle module. The docstring is
+used in the help utility provided by the shell.
+
+The example also includes a basic record and playback facility implemented with
+the :meth:`~Cmd.precmd` method which is responsible for converting the input to
+lowercase and writing the commands to a file. The :meth:`do_playback` method
+reads the file and adds the recorded commands to the :attr:`cmdqueue` for
+immediate playback::
+
+ import cmd, sys
+ from turtle import *
+
+ class TurtleShell(cmd.Cmd):
+ intro = 'Welcome to the turtle shell. Type help or ? to list commands.\n'
+ prompt = '(turtle) '
+ file = None
+
+ # ----- basic turtle commands -----
+ def do_forward(self, arg):
+ 'Move the turtle forward by the specified distance: FORWARD 10'
+ forward(*parse(arg))
+ def do_right(self, arg):
+ 'Turn turtle right by given number of degrees: RIGHT 20'
+ right(*parse(arg))
+ def do_left(self, arg):
+ 'Turn turtle left by given number of degrees: LEFT 90'
+ left(*parse(arg))
+ def do_goto(self, arg):
+ 'Move turtle to an absolute position with changing orientation. GOTO 100 200'
+ goto(*parse(arg))
+ def do_home(self, arg):
+ 'Return turtle to the home postion: HOME'
+ home()
+ def do_circle(self, arg):
+ 'Draw circle with given radius an options extent and steps: CIRCLE 50'
+ circle(*parse(arg))
+ def do_position(self, arg):
+ 'Print the current turle position: POSITION'
+ print('Current position is %d %d\n' % position())
+ def do_heading(self, arg):
+ 'Print the current turle heading in degrees: HEADING'
+ print('Current heading is %d\n' % (heading(),))
+ def do_color(self, arg):
+ 'Set the color: COLOR BLUE'
+ color(arg.lower())
+ def do_undo(self, arg):
+ 'Undo (repeatedly) the last turtle action(s): UNDO'
+ def do_reset(self, arg):
+ 'Clear the screen and return turtle to center: RESET'
+ reset()
+ def do_bye(self, arg):
+ 'Stop recording, close the turtle window, and exit: BYE'
+ print('Thank you for using Turtle')
+ self.close()
+ bye()
+ return True
+
+ # ----- record and playback -----
+ def do_record(self, arg):
+ 'Save future commands to filename: RECORD rose.cmd'
+ self.file = open(arg, 'w')
+ def do_playback(self, arg):
+ 'Playback commands from a file: PLAYBACK rose.cmd'
+ self.close()
+ cmds = open(arg).read().splitlines()
+ self.cmdqueue.extend(cmds)
+ def precmd(self, line):
+ line = line.lower()
+ if self.file and 'playback' not in line:
+ print(line, file=self.file)
+ return line
+ def close(self):
+ if self.file:
+ self.file.close()
+ self.file = None
+
+ def parse(arg):
+ 'Convert a series of zero or more numbers to an argument tuple'
+ return tuple(map(int, arg.split()))
+
+ if __name__ == '__main__':
+ TurtleShell().cmdloop()
+
+
+Here is a sample session with the turtle shell showing the help functions, using
+blank lines to repeat commands, and the simple record and playback facility::
+
+ Welcome to the turtle shell. Type help or ? to list commands.
+
+ (turtle) ?
+
+ Documented commands (type help <topic>):
+ ========================================
+ bye color goto home playback record right
+ circle forward heading left position reset undo
+
+ (turtle) help forward
+ Move the turtle forward by the specified distance: FORWARD 10
+ (turtle) record spiral.cmd
+ (turtle) position
+ Current position is 0 0
+
+ (turtle) heading
+ Current heading is 0
+
+ (turtle) reset
+ (turtle) circle 20
+ (turtle) right 30
+ (turtle) circle 40
+ (turtle) right 30
+ (turtle) circle 60
+ (turtle) right 30
+ (turtle) circle 80
+ (turtle) right 30
+ (turtle) circle 100
+ (turtle) right 30
+ (turtle) circle 120
+ (turtle) right 30
+ (turtle) circle 120
+ (turtle) heading
+ Current heading is 180
+
+ (turtle) forward 100
+ (turtle)
+ (turtle) right 90
+ (turtle) forward 100
+ (turtle)
+ (turtle) right 90
+ (turtle) forward 400
+ (turtle) right 90
+ (turtle) forward 500
+ (turtle) right 90
+ (turtle) forward 400
+ (turtle) right 90
+ (turtle) forward 300
+ (turtle) playback spiral.cmd
+ Current position is 0 0
+
+ Current heading is 0
+
+ Current heading is 180
+
+ (turtle) bye
+ Thank you for using Turtle
+
diff --git a/Doc/library/code.rst b/Doc/library/code.rst
index 38e26bc..56214b9 100644
--- a/Doc/library/code.rst
+++ b/Doc/library/code.rst
@@ -1,4 +1,3 @@
-
:mod:`code` --- Interpreter base classes
========================================
@@ -6,13 +5,12 @@
:synopsis: Facilities to implement read-eval-print loops.
-
The ``code`` module provides facilities to implement read-eval-print loops in
Python. Two classes and convenience functions are included which can be used to
build applications which provide an interactive interpreter prompt.
-.. class:: InteractiveInterpreter([locals])
+.. class:: InteractiveInterpreter(locals=None)
This class deals with parsing and interpreter state (the user's namespace); it
does not deal with input buffering or prompting or input file naming (the
@@ -22,14 +20,14 @@ build applications which provide an interactive interpreter prompt.
``'__doc__'`` set to ``None``.
-.. class:: InteractiveConsole([locals[, filename]])
+.. class:: InteractiveConsole(locals=None, filename="<console>")
Closely emulate the behavior of the interactive Python interpreter. This class
builds on :class:`InteractiveInterpreter` and adds prompting using the familiar
``sys.ps1`` and ``sys.ps2``, and input buffering.
-.. function:: interact([banner[, readfunc[, local]]])
+.. function:: interact(banner=None, readfunc=None, local=None)
Convenience function to run a read-eval-print loop. This creates a new instance
of :class:`InteractiveConsole` and sets *readfunc* to be used as the
@@ -40,7 +38,7 @@ build applications which provide an interactive interpreter prompt.
discarded after use.
-.. function:: compile_command(source[, filename[, symbol]])
+.. function:: compile_command(source, filename="<input>", symbol="single")
This function is useful for programs that want to emulate Python's interpreter
main loop (a.k.a. the read-eval-print loop). The tricky part is to determine
@@ -67,7 +65,7 @@ Interactive Interpreter Objects
-------------------------------
-.. method:: InteractiveInterpreter.runsource(source[, filename[, symbol]])
+.. method:: InteractiveInterpreter.runsource(source, filename="<input>", symbol="single")
Compile and run some source in the interpreter. Arguments are the same as for
:func:`compile_command`; the default for *filename* is ``'<input>'``, and for
@@ -100,7 +98,7 @@ Interactive Interpreter Objects
with it.
-.. method:: InteractiveInterpreter.showsyntaxerror([filename])
+.. method:: InteractiveInterpreter.showsyntaxerror(filename=None)
Display the syntax error that just occurred. This does not display a stack
trace because there isn't one for syntax errors. If *filename* is given, it is
@@ -132,7 +130,7 @@ The :class:`InteractiveConsole` class is a subclass of
interpreter objects as well as the following additions.
-.. method:: InteractiveConsole.interact([banner])
+.. method:: InteractiveConsole.interact(banner=None)
Closely emulate the interactive Python console. The optional banner argument
specify the banner to print before the first interaction; by default it prints a
@@ -158,10 +156,10 @@ interpreter objects as well as the following additions.
Remove any unhandled source text from the input buffer.
-.. method:: InteractiveConsole.raw_input([prompt])
+.. method:: InteractiveConsole.raw_input(prompt="")
Write a prompt and read a line. The returned line does not include the trailing
newline. When the user enters the EOF key sequence, :exc:`EOFError` is raised.
- The base implementation uses the built-in function :func:`raw_input`; a subclass
- may replace this with a different implementation.
+ The base implementation reads from ``sys.stdin``; a subclass may replace this
+ with a different implementation.
diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst
index 62bb504..762bb98 100644
--- a/Doc/library/codecs.rst
+++ b/Doc/library/codecs.rst
@@ -1,11 +1,10 @@
-
:mod:`codecs` --- Codec registry and base classes
=================================================
.. module:: codecs
:synopsis: Encode and decode data and streams.
-.. moduleauthor:: Marc-Andre Lemburg <mal@lemburg.com>
-.. sectionauthor:: Marc-Andre Lemburg <mal@lemburg.com>
+.. moduleauthor:: Marc-André Lemburg <mal@lemburg.com>
+.. sectionauthor:: Marc-André Lemburg <mal@lemburg.com>
.. sectionauthor:: Martin v. Löwis <martin@v.loewis.de>
@@ -79,6 +78,7 @@ It defines the following functions:
reference (for encoding only)
* ``'backslashreplace'``: replace with backslashed escape sequences (for
encoding only)
+ * ``'surrogateescape'``: replace with surrogate U+DCxx, see :pep:`383`
as well as any other error handling name defined via :func:`register_error`.
@@ -122,8 +122,6 @@ functions which use :func:`lookup` for the codec lookup:
Raises a :exc:`LookupError` in case the encoding cannot be found or the codec
doesn't support an incremental encoder.
- .. versionadded:: 2.5
-
.. function:: getincrementaldecoder(encoding)
@@ -133,8 +131,6 @@ functions which use :func:`lookup` for the codec lookup:
Raises a :exc:`LookupError` in case the encoding cannot be found or the codec
doesn't support an incremental decoder.
- .. versionadded:: 2.5
-
.. function:: getreader(encoding)
@@ -221,15 +217,14 @@ utility functions:
.. note::
- The wrapped version will only accept the object format defined by the codecs,
- i.e. Unicode objects for most built-in codecs. Output is also codec-dependent
- and will usually be Unicode as well.
+ The wrapped version's methods will accept and return strings only. Bytes
+ arguments will be rejected.
.. note::
Files are always opened in binary mode, even if no binary mode was
specified. This is done to avoid data loss due to encodings using 8-bit
- values. This means that no automatic conversion of ``'\n'`` is done
+ values. This means that no automatic conversion of ``b'\n'`` is done
on reading and writing.
*encoding* specifies the encoding which is to be used for the file.
@@ -241,38 +236,35 @@ utility functions:
defaults to line buffered.
-.. function:: EncodedFile(file, input[, output[, errors]])
+.. function:: EncodedFile(file, data_encoding, file_encoding=None, errors='strict')
Return a wrapped version of file which provides transparent encoding
translation.
- Strings written to the wrapped file are interpreted according to the given
- *input* encoding and then written to the original file as strings using the
- *output* encoding. The intermediate encoding will usually be Unicode but depends
- on the specified codecs.
+ Bytes written to the wrapped file are interpreted according to the given
+ *data_encoding* and then written to the original file as bytes using the
+ *file_encoding*.
- If *output* is not given, it defaults to *input*.
+ If *file_encoding* is not given, it defaults to *data_encoding*.
- *errors* may be given to define the error handling. It defaults to ``'strict'``,
- which causes :exc:`ValueError` to be raised in case an encoding error occurs.
+ *errors* may be given to define the error handling. It defaults to
+ ``'strict'``, which causes :exc:`ValueError` to be raised in case an encoding
+ error occurs.
-.. function:: iterencode(iterable, encoding[, errors])
+.. function:: iterencode(iterator, encoding, errors='strict', **kwargs)
Uses an incremental encoder to iteratively encode the input provided by
- *iterable*. This function is a :term:`generator`. *errors* (as well as any
+ *iterator*. This function is a :term:`generator`. *errors* (as well as any
other keyword argument) is passed through to the incremental encoder.
- .. versionadded:: 2.5
-
-.. function:: iterdecode(iterable, encoding[, errors])
+.. function:: iterdecode(iterator, encoding, errors='strict', **kwargs)
Uses an incremental decoder to iteratively decode the input provided by
- *iterable*. This function is a :term:`generator`. *errors* (as well as any
+ *iterator*. This function is a :term:`generator`. *errors* (as well as any
other keyword argument) is passed through to the incremental decoder.
- .. versionadded:: 2.5
The module also provides the following constants which are useful for reading
and writing to platform dependent files:
@@ -341,6 +333,21 @@ and implemented by all standard Python codecs:
| ``'backslashreplace'`` | Replace with backslashed escape sequences |
| | (only for encoding). |
+-------------------------+-----------------------------------------------+
+| ``'surrogateescape'`` | Replace byte with surrogate U+DCxx, as defined|
+| | in :pep:`383`. |
++-------------------------+-----------------------------------------------+
+
+In addition, the following error handlers are specific to a single codec:
+
++-------------------+---------+-------------------------------------------+
+| Value | Codec | Meaning |
++===================+=========+===========================================+
+|``'surrogatepass'``| utf-8 | Allow encoding and decoding of surrogate |
+| | | codes in UTF-8. |
++-------------------+---------+-------------------------------------------+
+
+.. versionadded:: 3.1
+ The ``'surrogateescape'`` and ``'surrogatepass'`` error handlers.
The set of allowed values can be extended via :meth:`register_error`.
@@ -357,8 +364,7 @@ interfaces of the stateless encoder and decoder:
.. method:: Codec.encode(input[, errors])
Encodes the object *input* and returns a tuple (output object, length consumed).
- While codecs are not restricted to use with Unicode, in a Unicode context,
- encoding converts a Unicode object to a plain string using a particular
+ Encoding converts a string object to a bytes object using a particular
character set encoding (e.g., ``cp1252`` or ``iso-8859-1``).
*errors* defines the error handling to apply. It defaults to ``'strict'``
@@ -374,13 +380,12 @@ interfaces of the stateless encoder and decoder:
.. method:: Codec.decode(input[, errors])
- Decodes the object *input* and returns a tuple (output object, length consumed).
- In a Unicode context, decoding converts a plain string encoded using a
- particular character set encoding to a Unicode object.
+ Decodes the object *input* and returns a tuple (output object, length
+ consumed). Decoding converts a bytes object encoded using a particular
+ character set encoding to a string object.
- *input* must be an object which provides the ``bf_getreadbuf`` buffer slot.
- Python strings, buffer objects and memory mapped files are examples of objects
- providing this slot.
+ *input* must be a bytes object or one which provides the read-only character
+ buffer interface -- for example, buffer objects and memory mapped files.
*errors* defines the error handling to apply. It defaults to ``'strict'``
handling.
@@ -409,8 +414,6 @@ encoded/decoded with the stateless encoder/decoder.
IncrementalEncoder Objects
^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. versionadded:: 2.5
-
The :class:`IncrementalEncoder` class is used for encoding an input in multiple
steps. It defines the following methods which every incremental encoder must
define in order to be compatible with the Python codec registry.
@@ -458,6 +461,21 @@ define in order to be compatible with the Python codec registry.
Reset the encoder to the initial state.
+.. method:: IncrementalEncoder.getstate()
+
+ Return the current state of the encoder which must be an integer. The
+ implementation should make sure that ``0`` is the most common state. (States
+ that are more complicated than integers can be converted into an integer by
+ marshaling/pickling the state and encoding the bytes of the resulting string
+ into an integer).
+
+
+.. method:: IncrementalEncoder.setstate(state)
+
+ Set the state of the encoder to *state*. *state* must be an encoder state
+ returned by :meth:`getstate`.
+
+
.. _incremental-decoder-objects:
IncrementalDecoder Objects
@@ -510,6 +528,27 @@ define in order to be compatible with the Python codec registry.
Reset the decoder to the initial state.
+ .. method:: getstate()
+
+ Return the current state of the decoder. This must be a tuple with two
+ items, the first must be the buffer containing the still undecoded
+ input. The second must be an integer and can be additional state
+ info. (The implementation should make sure that ``0`` is the most common
+ additional state info.) If this additional state info is ``0`` it must be
+ possible to set the decoder to the state which has no input buffered and
+ ``0`` as the additional state info, so that feeding the previously
+ buffered input to the decoder returns it to the previous state without
+ producing any output. (Additional state info that is more complicated than
+ integers can be converted into an integer by marshaling/pickling the info
+ and encoding the bytes of the resulting string into an integer.)
+
+
+ .. method:: setstate(state)
+
+ Set the state of the encoder to *state*. *state* must be a decoder state
+ returned by :meth:`getstate`.
+
+
The :class:`StreamWriter` and :class:`StreamReader` classes provide generic
working interfaces which can be used to implement new encoding submodules very
easily. See :mod:`encodings.utf_8` for an example of how this is done.
@@ -639,12 +678,6 @@ compatible with the Python codec registry.
given size, e.g. if optional encoding endings or state markers are
available on the stream, these should be read too.
- .. versionchanged:: 2.4
- *chars* argument added.
-
- .. versionchanged:: 2.4.2
- *firstline* argument added.
-
.. method:: readline([size[, keepends]])
@@ -656,9 +689,6 @@ compatible with the Python codec registry.
If *keepends* is false line-endings will be stripped from the lines
returned.
- .. versionchanged:: 2.4
- *keepends* argument added.
-
.. method:: readlines([sizehint[, keepends]])
@@ -740,9 +770,7 @@ The design is such that one can use the factory functions returned by the
:class:`StreamReader` and :class:`StreamWriter` interface respectively.
*encode* and *decode* are needed for the frontend translation, *Reader* and
- *Writer* for the backend translation. The intermediate format used is
- determined by the two sets of codecs, e.g. the Unicode codecs will use Unicode
- as the intermediate encoding.
+ *Writer* for the backend translation.
Error handling is done in the same way as defined for the stream readers and
writers.
@@ -758,32 +786,32 @@ methods and attributes from the underlying stream.
Encodings and Unicode
---------------------
-Unicode strings are stored internally as sequences of codepoints (to be precise
+Strings are stored internally as sequences of codepoints (to be precise
as :c:type:`Py_UNICODE` arrays). Depending on the way Python is compiled (either
-via ``--enable-unicode=ucs2`` or ``--enable-unicode=ucs4``, with the
+via ``--without-wide-unicode`` or ``--with-wide-unicode``, with the
former being the default) :c:type:`Py_UNICODE` is either a 16-bit or 32-bit data
-type. Once a Unicode object is used outside of CPU and memory, CPU endianness
+type. Once a string object is used outside of CPU and memory, CPU endianness
and how these arrays are stored as bytes become an issue. Transforming a
-unicode object into a sequence of bytes is called encoding and recreating the
-unicode object from the sequence of bytes is known as decoding. There are many
+string object into a sequence of bytes is called encoding and recreating the
+string object from the sequence of bytes is known as decoding. There are many
different methods for how this transformation can be done (these methods are
also called encodings). The simplest method is to map the codepoints 0-255 to
-the bytes ``0x0``-``0xff``. This means that a unicode object that contains
+the bytes ``0x0``-``0xff``. This means that a string object that contains
codepoints above ``U+00FF`` can't be encoded with this method (which is called
-``'latin-1'`` or ``'iso-8859-1'``). :func:`unicode.encode` will raise a
+``'latin-1'`` or ``'iso-8859-1'``). :func:`str.encode` will raise a
:exc:`UnicodeEncodeError` that looks like this: ``UnicodeEncodeError: 'latin-1'
-codec can't encode character u'\u1234' in position 3: ordinal not in
+codec can't encode character '\u1234' in position 3: ordinal not in
range(256)``.
There's another group of encodings (the so called charmap encodings) that choose
-a different subset of all unicode code points and how these codepoints are
+a different subset of all Unicode code points and how these codepoints are
mapped to the bytes ``0x0``-``0xff``. To see how this is done simply open
e.g. :file:`encodings/cp1252.py` (which is an encoding that is used primarily on
Windows). There's a string constant with 256 characters that shows you which
character is mapped to which byte value.
All of these encodings can only encode 256 of the 1114112 codepoints
-defined in unicode. A simple and straightforward way that can store each Unicode
+defined in Unicode. A simple and straightforward way that can store each Unicode
code point, is to store each codepoint as four consecutive bytes. There are two
possibilities: store the bytes in big endian or in little endian order. These
two encodings are called ``UTF-32-BE`` and ``UTF-32-LE`` respectively. Their
@@ -805,7 +833,7 @@ With Unicode 4.0 using ``U+FEFF`` as a ``ZERO WIDTH NO-BREAK SPACE`` has been
deprecated (with ``U+2060`` (``WORD JOINER``) assuming this role). Nevertheless
Unicode software still must be able to handle ``U+FEFF`` in both roles: as a BOM
it's a device to determine the storage layout of the encoded bytes, and vanishes
-once the byte sequence has been decoded into a Unicode string; as a ``ZERO WIDTH
+once the byte sequence has been decoded into a string; as a ``ZERO WIDTH
NO-BREAK SPACE`` it's a normal character that will be decoded like any other.
There's another encoding that is able to encoding the full range of Unicode
@@ -831,11 +859,11 @@ Unicode character):
The least significant bit of the Unicode character is the rightmost x bit.
As UTF-8 is an 8-bit encoding no BOM is required and any ``U+FEFF`` character in
-the decoded Unicode string (even if it's the first character) is treated as a
-``ZERO WIDTH NO-BREAK SPACE``.
+the decoded string (even if it's the first character) is treated as a ``ZERO
+WIDTH NO-BREAK SPACE``.
Without external information it's impossible to reliably determine which
-encoding was used for encoding a Unicode string. Each charmap encoding can
+encoding was used for encoding a string. Each charmap encoding can
decode any random byte sequence. However that's not possible with UTF-8, as
UTF-8 byte sequences have a structure that doesn't allow arbitrary byte
sequences. To increase the reliability with which a UTF-8 encoding can be
@@ -1059,7 +1087,7 @@ particular, the following variants typically exist:
+-----------------+--------------------------------+--------------------------------+
| mac_latin2 | maclatin2, maccentraleurope | Central and Eastern Europe |
+-----------------+--------------------------------+--------------------------------+
-| mac_roman | macroman | Western Europe |
+| mac_roman | macroman, macintosh | Western Europe |
+-----------------+--------------------------------+--------------------------------+
| mac_turkish | macturkish | Turkish |
+-----------------+--------------------------------+--------------------------------+
@@ -1083,9 +1111,9 @@ particular, the following variants typically exist:
+-----------------+--------------------------------+--------------------------------+
| utf_16 | U16, utf16 | all languages |
+-----------------+--------------------------------+--------------------------------+
-| utf_16_be | UTF-16BE | all languages (BMP only) |
+| utf_16_be | UTF-16BE | all languages |
+-----------------+--------------------------------+--------------------------------+
-| utf_16_le | UTF-16LE | all languages (BMP only) |
+| utf_16_le | UTF-16LE | all languages |
+-----------------+--------------------------------+--------------------------------+
| utf_7 | U7, unicode-1-1-utf-7 | all languages |
+-----------------+--------------------------------+--------------------------------+
@@ -1094,83 +1122,83 @@ particular, the following variants typically exist:
| utf_8_sig | | all languages |
+-----------------+--------------------------------+--------------------------------+
-A number of codecs are specific to Python, so their codec names have no meaning
-outside Python. Some of them don't convert from Unicode strings to byte strings,
-but instead use the property of the Python codecs machinery that any bijective
-function with one argument can be considered as an encoding.
-
-For the codecs listed below, the result in the "encoding" direction is always a
-byte string. The result of the "decoding" direction is listed as operand type in
-the table.
-
-+--------------------+---------------------------+----------------+---------------------------+
-| Codec | Aliases | Operand type | Purpose |
-+====================+===========================+================+===========================+
-| base64_codec | base64, base-64 | byte string | Convert operand to MIME |
-| | | | base64 |
-+--------------------+---------------------------+----------------+---------------------------+
-| bz2_codec | bz2 | byte string | Compress the operand |
-| | | | using bz2 |
-+--------------------+---------------------------+----------------+---------------------------+
-| hex_codec | hex | byte string | Convert operand to |
-| | | | hexadecimal |
-| | | | representation, with two |
-| | | | digits per byte |
-+--------------------+---------------------------+----------------+---------------------------+
-| idna | | Unicode string | Implements :rfc:`3490`, |
-| | | | see also |
-| | | | :mod:`encodings.idna` |
-+--------------------+---------------------------+----------------+---------------------------+
-| mbcs | dbcs | Unicode string | Windows only: Encode |
-| | | | operand according to the |
-| | | | ANSI codepage (CP_ACP) |
-+--------------------+---------------------------+----------------+---------------------------+
-| palmos | | Unicode string | Encoding of PalmOS 3.5 |
-+--------------------+---------------------------+----------------+---------------------------+
-| punycode | | Unicode string | Implements :rfc:`3492` |
-+--------------------+---------------------------+----------------+---------------------------+
-| quopri_codec | quopri, quoted-printable, | byte string | Convert operand to MIME |
-| | quotedprintable | | quoted printable |
-+--------------------+---------------------------+----------------+---------------------------+
-| raw_unicode_escape | | Unicode string | Produce a string that is |
-| | | | suitable as raw Unicode |
-| | | | literal in Python source |
-| | | | code |
-+--------------------+---------------------------+----------------+---------------------------+
-| rot_13 | rot13 | Unicode string | Returns the Caesar-cypher |
-| | | | encryption of the operand |
-+--------------------+---------------------------+----------------+---------------------------+
-| string_escape | | byte string | Produce a string that is |
-| | | | suitable as string |
-| | | | literal in Python source |
-| | | | code |
-+--------------------+---------------------------+----------------+---------------------------+
-| undefined | | any | Raise an exception for |
-| | | | all conversions. Can be |
-| | | | used as the system |
-| | | | encoding if no automatic |
-| | | | :term:`coercion` between |
-| | | | byte and Unicode strings |
-| | | | is desired. |
-+--------------------+---------------------------+----------------+---------------------------+
-| unicode_escape | | Unicode string | Produce a string that is |
-| | | | suitable as Unicode |
-| | | | literal in Python source |
-| | | | code |
-+--------------------+---------------------------+----------------+---------------------------+
-| unicode_internal | | Unicode string | Return the internal |
-| | | | representation of the |
-| | | | operand |
-+--------------------+---------------------------+----------------+---------------------------+
-| uu_codec | uu | byte string | Convert the operand using |
-| | | | uuencode |
-+--------------------+---------------------------+----------------+---------------------------+
-| zlib_codec | zip, zlib | byte string | Compress the operand |
-| | | | using gzip |
-+--------------------+---------------------------+----------------+---------------------------+
-
-.. versionadded:: 2.3
- The ``idna`` and ``punycode`` encodings.
+.. XXX fix here, should be in above table
+
++--------------------+---------+---------------------------+
+| Codec | Aliases | Purpose |
++====================+=========+===========================+
+| idna | | Implements :rfc:`3490`, |
+| | | see also |
+| | | :mod:`encodings.idna` |
++--------------------+---------+---------------------------+
+| mbcs | dbcs | Windows only: Encode |
+| | | operand according to the |
+| | | ANSI codepage (CP_ACP) |
++--------------------+---------+---------------------------+
+| palmos | | Encoding of PalmOS 3.5 |
++--------------------+---------+---------------------------+
+| punycode | | Implements :rfc:`3492` |
++--------------------+---------+---------------------------+
+| raw_unicode_escape | | Produce a string that is |
+| | | suitable as raw Unicode |
+| | | literal in Python source |
+| | | code |
++--------------------+---------+---------------------------+
+| undefined | | Raise an exception for |
+| | | all conversions. Can be |
+| | | used as the system |
+| | | encoding if no automatic |
+| | | coercion between byte and |
+| | | Unicode strings is |
+| | | desired. |
++--------------------+---------+---------------------------+
+| unicode_escape | | Produce a string that is |
+| | | suitable as Unicode |
+| | | literal in Python source |
+| | | code |
++--------------------+---------+---------------------------+
+| unicode_internal | | Return the internal |
+| | | representation of the |
+| | | operand |
++--------------------+---------+---------------------------+
+
+The following codecs provide bytes-to-bytes mappings.
+
++--------------------+---------------------------+---------------------------+
+| Codec | Aliases | Purpose |
++====================+===========================+===========================+
+| base64_codec | base64, base-64 | Convert operand to MIME |
+| | | base64 |
++--------------------+---------------------------+---------------------------+
+| bz2_codec | bz2 | Compress the operand |
+| | | using bz2 |
++--------------------+---------------------------+---------------------------+
+| hex_codec | hex | Convert operand to |
+| | | hexadecimal |
+| | | representation, with two |
+| | | digits per byte |
++--------------------+---------------------------+---------------------------+
+| quopri_codec | quopri, quoted-printable, | Convert operand to MIME |
+| | quotedprintable | quoted printable |
++--------------------+---------------------------+---------------------------+
+| uu_codec | uu | Convert the operand using |
+| | | uuencode |
++--------------------+---------------------------+---------------------------+
+| zlib_codec | zip, zlib | Compress the operand |
+| | | using gzip |
++--------------------+---------------------------+---------------------------+
+
+The following codecs provide string-to-string mappings.
+
++--------------------+---------------------------+---------------------------+
+| Codec | Aliases | Purpose |
++====================+===========================+===========================+
+| rot_13 | rot13 | Returns the Caesar-cypher |
+| | | encryption of the operand |
++--------------------+---------------------------+---------------------------+
+
+.. versionadded:: 3.2
+ bytes-to-bytes and string-to-string codecs.
:mod:`encodings.idna` --- Internationalized Domain Names in Applications
@@ -1180,8 +1208,6 @@ the table.
:synopsis: Internationalized Domain Names implementation
.. moduleauthor:: Martin v. Löwis
-.. versionadded:: 2.3
-
This module implements :rfc:`3490` (Internationalized Domain Names in
Applications) and :rfc:`3492` (Nameprep: A Stringprep Profile for
Internationalized Domain Names (IDN)). It builds upon the ``punycode`` encoding
@@ -1207,8 +1233,8 @@ labels found into unicode. Furthermore, the :mod:`socket` module
transparently converts Unicode host names to ACE, so that applications need not
be concerned about converting host names themselves when they pass them to the
socket module. On top of that, modules that have host names as function
-parameters, such as :mod:`httplib` and :mod:`ftplib`, accept Unicode host names
-(:mod:`httplib` then also transparently sends an IDNA hostname in the
+parameters, such as :mod:`http.client` and :mod:`ftplib`, accept Unicode host
+names (:mod:`http.client` then also transparently sends an IDNA hostname in the
:mailheader:`Host` field if it sends that field at all).
.. _section 3.1: http://tools.ietf.org/html/rfc3490#section-3.1
@@ -1240,6 +1266,23 @@ functions can be used directly if desired.
Convert a label to Unicode, as specified in :rfc:`3490`.
+:mod:`encodings.mbcs` --- Windows ANSI codepage
+-----------------------------------------------
+
+.. module:: encodings.mbcs
+ :synopsis: Windows ANSI codepage
+
+Encode operand according to the ANSI codepage (CP_ACP). This codec only
+supports ``'strict'`` and ``'replace'`` error handlers to encode, and
+``'strict'`` and ``'ignore'`` error handlers to decode.
+
+Availability: Windows only.
+
+.. versionchanged:: 3.2
+ Before 3.2, the *errors* argument was ignored; ``'replace'`` was always used
+ to encode, and ``'ignore'`` to decode.
+
+
:mod:`encodings.utf_8_sig` --- UTF-8 codec with BOM signature
-------------------------------------------------------------
@@ -1247,8 +1290,6 @@ functions can be used directly if desired.
:synopsis: UTF-8 codec with BOM signature
.. moduleauthor:: Walter Dörwald
-.. versionadded:: 2.5
-
This module implements a variant of the UTF-8 codec: On encoding a UTF-8 encoded
BOM will be prepended to the UTF-8 encoded bytes. For the stateful encoder this
is only done once (on the first write to the byte stream). For decoding an
diff --git a/Doc/library/codeop.rst b/Doc/library/codeop.rst
index 674c51f..9ae4176 100644
--- a/Doc/library/codeop.rst
+++ b/Doc/library/codeop.rst
@@ -1,4 +1,3 @@
-
:mod:`codeop` --- Compile Python code
=====================================
@@ -26,7 +25,7 @@ of doing them both.
To do just the former:
-.. function:: compile_command(source[, filename[, symbol]])
+.. function:: compile_command(source, filename="<input>", symbol="single")
Tries to compile *source*, which should be a string of Python code and return a
code object if *source* is valid Python code. In that case, the filename
@@ -66,28 +65,3 @@ To do just the former:
:func:`compile_command`; the difference is that if the instance compiles program
text containing a ``__future__`` statement, the instance 'remembers' and
compiles all subsequent program texts with the statement in force.
-
-A note on version compatibility: the :class:`Compile` and
-:class:`CommandCompiler` are new in Python 2.2. If you want to enable the
-future-tracking features of 2.2 but also retain compatibility with 2.1 and
-earlier versions of Python you can either write ::
-
- try:
- from codeop import CommandCompiler
- compile_command = CommandCompiler()
- del CommandCompiler
- except ImportError:
- from codeop import compile_command
-
-which is a low-impact change, but introduces possibly unwanted global state into
-your program, or you can write::
-
- try:
- from codeop import CommandCompiler
- except ImportError:
- def CommandCompiler():
- from codeop import compile_command
- return compile_command
-
-and then call ``CommandCompiler`` every time you need a fresh compiler object.
-
diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst
index be551dc..7a2802d 100644
--- a/Doc/library/collections.rst
+++ b/Doc/library/collections.rst
@@ -1,13 +1,11 @@
-:mod:`collections` --- High-performance container datatypes
-===========================================================
+:mod:`collections` --- Container datatypes
+==========================================
.. module:: collections
- :synopsis: High-performance datatypes
+ :synopsis: Container datatypes
.. moduleauthor:: Raymond Hettinger <python@rcn.com>
.. sectionauthor:: Raymond Hettinger <python@rcn.com>
-.. versionadded:: 2.4
-
.. testsetup:: *
from collections import *
@@ -22,13 +20,16 @@ This module implements specialized container datatypes providing alternatives to
Python's general purpose built-in containers, :class:`dict`, :class:`list`,
:class:`set`, and :class:`tuple`.
-===================== ==================================================================== ===========================
-:func:`namedtuple` factory function for creating tuple subclasses with named fields .. versionadded:: 2.6
-:class:`deque` list-like container with fast appends and pops on either end .. versionadded:: 2.4
-:class:`Counter` dict subclass for counting hashable objects .. versionadded:: 2.7
-:class:`OrderedDict` dict subclass that remembers the order entries were added .. versionadded:: 2.7
-:class:`defaultdict` dict subclass that calls a factory function to supply missing values .. versionadded:: 2.5
-===================== ==================================================================== ===========================
+===================== ====================================================================
+:func:`namedtuple` factory function for creating tuple subclasses with named fields
+:class:`deque` list-like container with fast appends and pops on either end
+:class:`Counter` dict subclass for counting hashable objects
+:class:`OrderedDict` dict subclass that remembers the order entries were added
+:class:`defaultdict` dict subclass that calls a factory function to supply missing values
+:class:`UserDict` wrapper around dictionary objects for easier dict subclassing
+:class:`UserList` wrapper around list objects for easier list subclassing
+:class:`UserString` wrapper around string objects for easier string subclassing
+===================== ====================================================================
In addition to the concrete container classes, the collections module provides
:ref:`abstract base classes <collections-abstract-base-classes>` that can be
@@ -85,7 +86,7 @@ For example::
>>> c['sausage'] = 0 # counter entry with a zero count
>>> del c['sausage'] # del actually removes the entry
- .. versionadded:: 2.7
+ .. versionadded:: 3.1
Counter objects support three methods beyond those available for all
@@ -123,6 +124,8 @@ For example::
>>> c
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
+ .. versionadded:: 3.2
+
The usual dictionary methods are available for :class:`Counter` objects
except for two which work differently for counters.
@@ -221,7 +224,7 @@ counts, but the output will exclude results with counts of zero or less.
:class:`deque` objects
----------------------
-.. class:: deque([iterable[, maxlen]])
+.. class:: deque([iterable, [maxlen]])
Returns a new deque object initialized left-to-right (using :meth:`append`) with
data from *iterable*. If *iterable* is not specified, the new deque is empty.
@@ -236,7 +239,6 @@ counts, but the output will exclude results with counts of zero or less.
``pop(0)`` and ``insert(0, v)`` operations which change both the size and
position of the underlying data representation.
- .. versionadded:: 2.4
If *maxlen* is not specified or is *None*, deques may grow to an
arbitrary length. Otherwise, the deque is bounded to the specified maximum
@@ -246,12 +248,9 @@ counts, but the output will exclude results with counts of zero or less.
Unix. They are also useful for tracking transactions and other pools of data
where only the most recent activity is of interest.
- .. versionchanged:: 2.6
- Added *maxlen* parameter.
Deque objects support the following methods:
-
.. method:: append(x)
Add *x* to the right side of the deque.
@@ -271,7 +270,8 @@ counts, but the output will exclude results with counts of zero or less.
Count the number of deque elements equal to *x*.
- .. versionadded:: 2.7
+ .. versionadded:: 3.2
+
.. method:: extend(iterable)
@@ -303,13 +303,13 @@ counts, but the output will exclude results with counts of zero or less.
Removed the first occurrence of *value*. If not found, raises a
:exc:`ValueError`.
- .. versionadded:: 2.5
.. method:: reverse()
Reverse the elements of the deque in-place and then return ``None``.
- .. versionadded:: 2.7
+ .. versionadded:: 3.2
+
.. method:: rotate(n)
@@ -324,7 +324,7 @@ counts, but the output will exclude results with counts of zero or less.
Maximum size of a deque or *None* if unbounded.
- .. versionadded:: 2.7
+ .. versionadded:: 3.1
In addition to the above, deques support iteration, pickling, ``len(d)``,
@@ -340,7 +340,7 @@ Example:
>>> from collections import deque
>>> d = deque('ghi') # make a new deque with three items
>>> for elem in d: # iterate over the deque's elements
- ... print elem.upper()
+ ... print(elem.upper())
G
H
I
@@ -414,7 +414,7 @@ added elements by appending to the right and popping to the left::
for elem in it:
s += elem - d.popleft()
d.append(elem)
- yield s / float(n)
+ yield s / n
The :meth:`rotate` method provides a way to implement :class:`deque` slicing and
deletion. For example, a pure Python implementation of ``del d[n]`` relies on
@@ -449,7 +449,6 @@ stack manipulations such as ``dup``, ``drop``, ``swap``, ``over``, ``pick``,
as if they were passed to the :class:`dict` constructor, including keyword
arguments.
- .. versionadded:: 2.5
:class:`defaultdict` objects support the following method in addition to the
standard :class:`dict` operations:
@@ -497,7 +496,7 @@ sequence of key-value pairs into a dictionary of lists:
>>> for k, v in s:
... d[k].append(v)
...
- >>> d.items()
+ >>> list(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
When each key is encountered for the first time, it is not already in the
@@ -512,7 +511,7 @@ simpler and faster than an equivalent technique using :meth:`dict.setdefault`:
>>> for k, v in s:
... d.setdefault(k, []).append(v)
...
- >>> d.items()
+ >>> list(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
Setting the :attr:`default_factory` to :class:`int` makes the
@@ -524,7 +523,7 @@ languages):
>>> for k in s:
... d[k] += 1
...
- >>> d.items()
+ >>> list(d.items())
[('i', 4), ('p', 2), ('s', 4), ('m', 1)]
When a letter is first encountered, it is missing from the mapping, so the
@@ -533,11 +532,11 @@ zero. The increment operation then builds up the count for each letter.
The function :func:`int` which always returns zero is just a special case of
constant functions. A faster and more flexible way to create constant functions
-is to use :func:`itertools.repeat` which can supply any constant value (not just
+is to use a lambda function which can supply any constant value (not just
zero):
>>> def constant_factory(value):
- ... return itertools.repeat(value).next
+ ... return lambda: value
>>> d = defaultdict(constant_factory('<missing>'))
>>> d.update(name='John', action='ran')
>>> '%(name)s %(action)s to %(object)s' % d
@@ -551,7 +550,7 @@ Setting the :attr:`default_factory` to :class:`set` makes the
>>> for k, v in s:
... d[k].add(v)
...
- >>> d.items()
+ >>> list(d.items())
[('blue', set([2, 4])), ('red', set([1, 3]))]
@@ -562,7 +561,7 @@ Named tuples assign meaning to each position in a tuple and allow for more reada
self-documenting code. They can be used wherever regular tuples are used, and
they add the ability to access fields by name instead of position index.
-.. function:: namedtuple(typename, field_names, [verbose=False], [rename=False])
+.. function:: namedtuple(typename, field_names, verbose=False, rename=False)
Returns a new tuple subclass named *typename*. The new subclass is used to
create tuple-like objects that have fields accessible by attribute lookup as
@@ -570,14 +569,14 @@ they add the ability to access fields by name instead of position index.
helpful docstring (with typename and field_names) and a helpful :meth:`__repr__`
method which lists the tuple contents in a ``name=value`` format.
- The *field_names* are a sequence of strings such as ``['x', 'y']``.
- Alternatively, *field_names* can be a single string with each fieldname
- separated by whitespace and/or commas, for example ``'x y'`` or ``'x, y'``.
+ The *field_names* are a single string with each fieldname separated by whitespace
+ and/or commas, for example ``'x y'`` or ``'x, y'``. Alternatively, *field_names*
+ can be a sequence of strings such as ``['x', 'y']``.
Any valid Python identifier may be used for a fieldname except for names
starting with an underscore. Valid identifiers consist of letters, digits,
and underscores but do not start with a digit or underscore and cannot be
- a :mod:`keyword` such as *class*, *for*, *return*, *global*, *pass*, *print*,
+ a :mod:`keyword` such as *class*, *for*, *return*, *global*, *pass*,
or *raise*.
If *rename* is true, invalid fieldnames are automatically replaced
@@ -590,61 +589,61 @@ they add the ability to access fields by name instead of position index.
Named tuple instances do not have per-instance dictionaries, so they are
lightweight and require no more memory than regular tuples.
- .. versionadded:: 2.6
-
- .. versionchanged:: 2.7
- added support for *rename*.
+ .. versionchanged:: 3.1
+ Added support for *rename*.
-Example:
.. doctest::
:options: +NORMALIZE_WHITESPACE
- >>> Point = namedtuple('Point', ['x', 'y'], verbose=True)
+ >>> # Basic example
+ >>> Point = namedtuple('Point', ['x', 'y'])
+ >>> p = Point(x=10, y=11)
+
+ >>> # Example using the verbose option to print the class definition
+ >>> Point = namedtuple('Point', 'x y', verbose=True)
class Point(tuple):
- 'Point(x, y)'
- <BLANKLINE>
- __slots__ = ()
+ 'Point(x, y)'
<BLANKLINE>
- _fields = ('x', 'y')
+ __slots__ = ()
<BLANKLINE>
- def __new__(_cls, x, y):
- 'Create a new instance of Point(x, y)'
- return _tuple.__new__(_cls, (x, y))
+ _fields = ('x', 'y')
<BLANKLINE>
- @classmethod
- def _make(cls, iterable, new=tuple.__new__, len=len):
- 'Make a new Point object from a sequence or iterable'
- result = new(cls, iterable)
- if len(result) != 2:
- raise TypeError('Expected 2 arguments, got %d' % len(result))
- return result
+ def __new__(_cls, x, y):
+ 'Create a new instance of Point(x, y)'
+ return _tuple.__new__(_cls, (x, y))
<BLANKLINE>
- def __repr__(self):
- 'Return a nicely formatted representation string'
- return 'Point(x=%r, y=%r)' % self
+ @classmethod
+ def _make(cls, iterable, new=tuple.__new__, len=len):
+ 'Make a new Point object from a sequence or iterable'
+ result = new(cls, iterable)
+ if len(result) != 2:
+ raise TypeError('Expected 2 arguments, got %d' % len(result))
+ return result
<BLANKLINE>
- def _asdict(self):
- 'Return a new OrderedDict which maps field names to their values'
- return OrderedDict(zip(self._fields, self))
+ def __repr__(self):
+ 'Return a nicely formatted representation string'
+ return self.__class__.__name__ + '(x=%r, y=%r)' % self
<BLANKLINE>
- __dict__ = property(_asdict)
+ def _asdict(self):
+ 'Return a new OrderedDict which maps field names to their values'
+ return OrderedDict(zip(self._fields, self))
<BLANKLINE>
- def _replace(_self, **kwds):
- 'Return a new Point object replacing specified fields with new values'
- result = _self._make(map(kwds.pop, ('x', 'y'), _self))
- if kwds:
- raise ValueError('Got unexpected field names: %r' % kwds.keys())
- return result
+ __dict__ = property(_asdict)
<BLANKLINE>
- def __getnewargs__(self):
- 'Return self as a plain tuple. Used by copy and pickle.'
- return tuple(self)
+ def _replace(_self, **kwds):
+ 'Return a new Point object replacing specified fields with new values'
+ result = _self._make(map(kwds.pop, ('x', 'y'), _self))
+ if kwds:
+ raise ValueError('Got unexpected field names: %r' % list(kwds.keys()))
+ return result
<BLANKLINE>
- x = _property(_itemgetter(0), doc='Alias for field number 0')
- <BLANKLINE>
- y = _property(_itemgetter(1), doc='Alias for field number 1')
+ def __getnewargs__(self):
+ 'Return self as a plain tuple. Used by copy and pickle.'
+ return tuple(self)
<BLANKLINE>
+ x = _property(_itemgetter(0), doc='Alias for field number 0')
+ y = _property(_itemgetter(1), doc='Alias for field number 1')
>>> p = Point(11, y=22) # instantiate with positional or keyword arguments
>>> p[0] + p[1] # indexable like the plain tuple (11, 22)
@@ -664,14 +663,14 @@ by the :mod:`csv` or :mod:`sqlite3` modules::
import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):
- print emp.name, emp.title
+ print(emp.name, emp.title)
import sqlite3
conn = sqlite3.connect('/companydata')
cursor = conn.cursor()
cursor.execute('SELECT name, age, title, department, paygrade FROM employees')
for emp in map(EmployeeRecord._make, cursor.fetchall()):
- print emp.name, emp.title
+ print(emp.name, emp.title)
In addition to the methods inherited from tuples, named tuples support
three additional methods and one attribute. To prevent conflicts with
@@ -681,7 +680,7 @@ field names, the method and attribute names start with an underscore.
Class method that makes a new instance from an existing sequence or iterable.
- .. doctest::
+.. doctest::
>>> t = [11, 22]
>>> Point._make(t)
@@ -695,27 +694,29 @@ field names, the method and attribute names start with an underscore.
>>> p._asdict()
OrderedDict([('x', 11), ('y', 22)])
- .. versionchanged:: 2.7
+ .. versionchanged:: 3.1
Returns an :class:`OrderedDict` instead of a regular :class:`dict`.
.. method:: somenamedtuple._replace(kwargs)
Return a new instance of the named tuple replacing specified fields with new
- values::
+ values:
+
+::
>>> p = Point(x=11, y=22)
>>> p._replace(x=33)
Point(x=33, y=22)
>>> for partnum, record in inventory.items():
- inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())
+ ... inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())
.. attribute:: somenamedtuple._fields
Tuple of strings listing the field names. Useful for introspection
and for creating new named tuple types from existing named tuples.
- .. doctest::
+.. doctest::
>>> p._fields # view the field names
('x', 'y')
@@ -750,14 +751,15 @@ a fixed-width print format:
def __str__(self):
return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
- >>> for p in Point(3, 4), Point(14, 5/7.):
- print p
+ >>> for p in Point(3, 4), Point(14, 5/7):
+ print(p)
Point: x= 3.000 y= 4.000 hypot= 5.000
Point: x=14.000 y= 0.714 hypot=14.018
The subclass shown above sets ``__slots__`` to an empty tuple. This helps
keep memory requirements low by preventing the creation of instance dictionaries.
+
Subclassing is not useful for adding new, stored fields. Instead, simply
create a new named tuple type from the :attr:`_fields` attribute:
@@ -781,8 +783,15 @@ and more efficient to use a simple class declaration:
.. seealso::
- `Named tuple recipe <http://code.activestate.com/recipes/500261/>`_
- adapted for Python 2.4.
+ * `Named tuple recipe <http://code.activestate.com/recipes/500261/>`_
+ adapted for Python 2.4.
+
+ * `Recipe for named tuple abstract base class with a metaclass mix-in
+ <http://code.activestate.com/recipes/577629-namedtupleabc-abstract-base-class-mix-in-for-named/>`_
+ by Jan Kaliszewski. Besides providing an :term:`abstract base class` for
+ named tuples, it also supports an alternate :term:`metaclass`-based
+ constructor that is convenient for use cases where named tuples are being
+ subclassed.
:class:`OrderedDict` objects
@@ -800,13 +809,30 @@ the items are returned in the order their keys were first added.
original insertion position is left unchanged. Deleting an entry and
reinserting it will move it to the end.
- .. versionadded:: 2.7
+ .. versionadded:: 3.1
+
+ .. method:: popitem(last=True)
+
+ The :meth:`popitem` method for ordered dictionaries returns and removes a
+ (key, value) pair. The pairs are returned in LIFO order if *last* is true
+ or FIFO order if false.
-.. method:: OrderedDict.popitem(last=True)
+ .. method:: move_to_end(key, last=True)
- The :meth:`popitem` method for ordered dictionaries returns and removes
- a (key, value) pair. The pairs are returned in LIFO order if *last* is
- true or FIFO order if false.
+ Move an existing *key* to either end of an ordered dictionary. The item
+ is moved to the right end if *last* is true (the default) or to the
+ beginning if *last* is false. Raises :exc:`KeyError` if the *key* does
+ not exist::
+
+ >>> d = OrderedDict.fromkeys('abcde')
+ >>> d.move_to_end('b')
+ >>> ''.join(d.keys())
+ 'acdeb'
+ >>> d.move_to_end('b', last=False)
+ >>> ''.join(d.keys())
+ 'bacde'
+
+ .. versionadded:: 3.2
In addition to the usual mapping methods, ordered dictionaries also support
reverse iteration using :func:`reversed`.
@@ -878,10 +904,97 @@ so that the counter remembers the order elements are first encountered::
return self.__class__, (OrderedDict(self),)
+:class:`UserDict` objects
+-------------------------
+
+The class, :class:`UserDict` acts as a wrapper around dictionary objects.
+The need for this class has been partially supplanted by the ability to
+subclass directly from :class:`dict`; however, this class can be easier
+to work with because the underlying dictionary is accessible as an
+attribute.
+
+.. class:: UserDict([initialdata])
+
+ Class that simulates a dictionary. The instance's contents are kept in a
+ regular dictionary, which is accessible via the :attr:`data` attribute of
+ :class:`UserDict` instances. If *initialdata* is provided, :attr:`data` is
+ initialized with its contents; note that a reference to *initialdata* will not
+ be kept, allowing it be used for other purposes.
+
+ In addition to supporting the methods and operations of mappings,
+ :class:`UserDict` instances provide the following attribute:
+
+ .. attribute:: data
+
+ A real dictionary used to store the contents of the :class:`UserDict`
+ class.
+
+
+
+:class:`UserList` objects
+-------------------------
+
+This class acts as a wrapper around list objects. It is a useful base class
+for your own list-like classes which can inherit from them and override
+existing methods or add new ones. In this way, one can add new behaviors to
+lists.
+
+The need for this class has been partially supplanted by the ability to
+subclass directly from :class:`list`; however, this class can be easier
+to work with because the underlying list is accessible as an attribute.
+
+.. class:: UserList([list])
+
+ Class that simulates a list. The instance's contents are kept in a regular
+ list, which is accessible via the :attr:`data` attribute of :class:`UserList`
+ instances. The instance's contents are initially set to a copy of *list*,
+ defaulting to the empty list ``[]``. *list* can be any iterable, for
+ example a real Python list or a :class:`UserList` object.
+
+ In addition to supporting the methods and operations of mutable sequences,
+ :class:`UserList` instances provide the following attribute:
+
+ .. attribute:: data
+
+ A real :class:`list` object used to store the contents of the
+ :class:`UserList` class.
+
+**Subclassing requirements:** Subclasses of :class:`UserList` are expect to
+offer a constructor which can be called with either no arguments or one
+argument. List operations which return a new sequence attempt to create an
+instance of the actual implementation class. To do so, it assumes that the
+constructor can be called with a single parameter, which is a sequence object
+used as a data source.
+
+If a derived class does not wish to comply with this requirement, all of the
+special methods supported by this class will need to be overridden; please
+consult the sources for information about the methods which need to be provided
+in that case.
+
+:class:`UserString` objects
+---------------------------
+
+The class, :class:`UserString` acts as a wrapper around string objects.
+The need for this class has been partially supplanted by the ability to
+subclass directly from :class:`str`; however, this class can be easier
+to work with because the underlying string is accessible as an
+attribute.
+
+.. class:: UserString([sequence])
+
+ Class that simulates a string or a Unicode string object. The instance's
+ content is kept in a regular string object, which is accessible via the
+ :attr:`data` attribute of :class:`UserString` instances. The instance's
+ contents are initially set to a copy of *sequence*. The *sequence* can
+ be an instance of :class:`bytes`, :class:`str`, :class:`UserString` (or a
+ subclass) or an arbitrary sequence which can be converted into a string using
+ the built-in :func:`str` function.
+
+
.. _collections-abstract-base-classes:
-Collections Abstract Base Classes
----------------------------------
+ABCs - abstract base classes
+----------------------------
The collections module offers the following :term:`ABCs <abstract base class>`:
@@ -891,7 +1004,7 @@ ABC Inherits from Abstract Methods Mixin
:class:`Container` ``__contains__``
:class:`Hashable` ``__hash__``
:class:`Iterable` ``__iter__``
-:class:`Iterator` :class:`Iterable` ``next`` ``__iter__``
+:class:`Iterator` :class:`Iterable` ``__next__`` ``__iter__``
:class:`Sized` ``__len__``
:class:`Callable` ``__call__``
@@ -944,7 +1057,7 @@ ABC Inherits from Abstract Methods Mixin
.. class:: Iterator
- ABC for classes that provide the :meth:`__iter__` and :meth:`next` methods.
+ ABC for classes that provide the :meth:`__iter__` and :meth:`__next__` methods.
See also the definition of :term:`iterator`.
.. class:: Sequence
diff --git a/Doc/library/colorpicker.rst b/Doc/library/colorpicker.rst
deleted file mode 100644
index b1a5a73..0000000
--- a/Doc/library/colorpicker.rst
+++ /dev/null
@@ -1,28 +0,0 @@
-
-:mod:`ColorPicker` --- Color selection dialog
-=============================================
-
-.. module:: ColorPicker
- :platform: Mac
- :synopsis: Interface to the standard color selection dialog.
- :deprecated:
-.. moduleauthor:: Just van Rossum <just@letterror.com>
-.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
-
-
-The :mod:`ColorPicker` module provides access to the standard color picker
-dialog.
-
-.. note::
-
- This module has been removed in Python 3.x.
-
-
-.. function:: GetColor(prompt, rgb)
-
- Show a standard color selection dialog and allow the user to select a color.
- The user is given instruction by the *prompt* string, and the default color is
- set to *rgb*. *rgb* must be a tuple giving the red, green, and blue components
- of the color. :func:`GetColor` returns a tuple giving the user's selected color
- and a flag indicating whether they accepted the selection of cancelled.
-
diff --git a/Doc/library/commands.rst b/Doc/library/commands.rst
deleted file mode 100644
index 0b73e42..0000000
--- a/Doc/library/commands.rst
+++ /dev/null
@@ -1,80 +0,0 @@
-
-:mod:`commands` --- Utilities for running commands
-==================================================
-
-.. module:: commands
- :platform: Unix
- :synopsis: Utility functions for running external commands.
- :deprecated:
-
-.. deprecated:: 2.6
- The :mod:`commands` module has been removed in Python 3. Use the
- :mod:`subprocess` module instead.
-
-.. sectionauthor:: Sue Williams <sbw@provis.com>
-
-
-The :mod:`commands` module contains wrapper functions for :func:`os.popen` which
-take a system command as a string and return any output generated by the command
-and, optionally, the exit status.
-
-The :mod:`subprocess` module provides more powerful facilities for spawning new
-processes and retrieving their results. Using the :mod:`subprocess` module is
-preferable to using the :mod:`commands` module.
-
-.. note::
-
- In Python 3.x, :func:`getstatus` and two undocumented functions
- (:func:`mk2arg` and :func:`mkarg`) have been removed. Also,
- :func:`getstatusoutput` and :func:`getoutput` have been moved to the
- :mod:`subprocess` module.
-
-The :mod:`commands` module defines the following functions:
-
-
-.. function:: getstatusoutput(cmd)
-
- Execute the string *cmd* in a shell with :func:`os.popen` and return a 2-tuple
- ``(status, output)``. *cmd* is actually run as ``{ cmd ; } 2>&1``, so that the
- returned output will contain output or error messages. A trailing newline is
- stripped from the output. The exit status for the command can be interpreted
- according to the rules for the C function :c:func:`wait`.
-
-
-.. function:: getoutput(cmd)
-
- Like :func:`getstatusoutput`, except the exit status is ignored and the return
- value is a string containing the command's output.
-
-
-.. function:: getstatus(file)
-
- Return the output of ``ls -ld file`` as a string. This function uses the
- :func:`getoutput` function, and properly escapes backslashes and dollar signs in
- the argument.
-
- .. deprecated:: 2.6
- This function is nonobvious and useless. The name is also misleading in the
- presence of :func:`getstatusoutput`.
-
-
-Example::
-
- >>> import commands
- >>> commands.getstatusoutput('ls /bin/ls')
- (0, '/bin/ls')
- >>> commands.getstatusoutput('cat /bin/junk')
- (256, 'cat: /bin/junk: No such file or directory')
- >>> commands.getstatusoutput('/bin/junk')
- (256, 'sh: /bin/junk: not found')
- >>> commands.getoutput('ls /bin/ls')
- '/bin/ls'
- >>> commands.getstatus('/bin/ls')
- '-rwxr-xr-x 1 root 13352 Oct 14 1994 /bin/ls'
-
-
-.. seealso::
-
- Module :mod:`subprocess`
- Module for spawning and managing subprocesses.
-
diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst
index cf0d5f8..cb7a09c 100644
--- a/Doc/library/compileall.rst
+++ b/Doc/library/compileall.rst
@@ -58,14 +58,24 @@ compile Python sources.
files and directories to compile. If ``list`` is ``-``, read lines from
``stdin``.
-.. versionchanged:: 2.7
- Added the ``-i`` option.
+.. cmdoption:: -b
+ Write the byte-code files to their legacy locations and names, which may
+ overwrite byte-code files created by another version of Python. The default
+ is to write files to their :pep:`3147` locations and names, which allows
+ byte-code files from multiple versions of Python to coexist.
+
+.. versionchanged:: 3.2
+ Added the ``-i``, ``-b`` and ``-h`` options.
+
+There is no command-line option to control the optimization level used by the
+:func:`compile` function, because the Python interpreter itself already
+provides the option: :program:`python -O -m compileall`.
Public functions
----------------
-.. function:: compile_dir(dir[, maxlevels[, ddir[, force[, rx[, quiet]]]]])
+.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=False, legacy=False, optimize=-1)
Recursively descend the directory tree named by *dir*, compiling all :file:`.py`
files along the way.
@@ -89,8 +99,20 @@ Public functions
If *quiet* is true, nothing is printed to the standard output unless errors
occur.
+ If *legacy* is true, byte-code files are written to their legacy locations
+ and names, which may overwrite byte-code files created by another version of
+ Python. The default is to write files to their :pep:`3147` locations and
+ names, which allows byte-code files from multiple versions of Python to
+ coexist.
+
+ *optimize* specifies the optimization level for the compiler. It is passed to
+ the built-in :func:`compile` function.
+
+ .. versionchanged:: 3.2
+ Added the *legacy* and *optimize* parameter.
+
-.. function:: compile_file(fullname[, ddir[, force[, rx[, quiet]]]])
+.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=False, legacy=False, optimize=-1)
Compile the file with path *fullname*.
@@ -107,10 +129,19 @@ Public functions
If *quiet* is true, nothing is printed to the standard output unless errors
occur.
- .. versionadded:: 2.7
+ If *legacy* is true, byte-code files are written to their legacy locations
+ and names, which may overwrite byte-code files created by another version of
+ Python. The default is to write files to their :pep:`3147` locations and
+ names, which allows byte-code files from multiple versions of Python to
+ coexist.
+ *optimize* specifies the optimization level for the compiler. It is passed to
+ the built-in :func:`compile` function.
-.. function:: compile_path([skip_curdir[, maxlevels[, force]]])
+ .. versionadded:: 3.2
+
+
+.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False, legacy=False, optimize=-1)
Byte-compile all the :file:`.py` files found along ``sys.path``. If
*skip_curdir* is true (the default), the current directory is not included
@@ -118,6 +149,10 @@ Public functions
function. Note that unlike the other compile functions, ``maxlevels``
defaults to ``0``.
+ .. versionchanged:: 3.2
+ Added the *legacy* and *optimize* parameter.
+
+
To force a recompile of all the :file:`.py` files in the :file:`Lib/`
subdirectory and all its subdirectories::
diff --git a/Doc/library/compiler.rst b/Doc/library/compiler.rst
deleted file mode 100644
index 229bcb2..0000000
--- a/Doc/library/compiler.rst
+++ /dev/null
@@ -1,644 +0,0 @@
-
-.. _compiler:
-
-***********************
-Python compiler package
-***********************
-
-.. deprecated:: 2.6
- The :mod:`compiler` package has been removed in Python 3.
-
-.. sectionauthor:: Jeremy Hylton <jeremy@zope.com>
-
-
-The Python compiler package is a tool for analyzing Python source code and
-generating Python bytecode. The compiler contains libraries to generate an
-abstract syntax tree from Python source code and to generate Python
-:term:`bytecode` from the tree.
-
-The :mod:`compiler` package is a Python source to bytecode translator written in
-Python. It uses the built-in parser and standard :mod:`parser` module to
-generate a concrete syntax tree. This tree is used to generate an abstract
-syntax tree (AST) and then Python bytecode.
-
-The full functionality of the package duplicates the built-in compiler provided
-with the Python interpreter. It is intended to match its behavior almost
-exactly. Why implement another compiler that does the same thing? The package
-is useful for a variety of purposes. It can be modified more easily than the
-built-in compiler. The AST it generates is useful for analyzing Python source
-code.
-
-This chapter explains how the various components of the :mod:`compiler` package
-work. It blends reference material with a tutorial.
-
-
-The basic interface
-===================
-
-.. module:: compiler
- :synopsis: Python code compiler written in Python.
- :deprecated:
-
-
-The top-level of the package defines four functions. If you import
-:mod:`compiler`, you will get these functions and a collection of modules
-contained in the package.
-
-
-.. function:: parse(buf)
-
- Returns an abstract syntax tree for the Python source code in *buf*. The
- function raises :exc:`SyntaxError` if there is an error in the source code. The
- return value is a :class:`compiler.ast.Module` instance that contains the tree.
-
-
-.. function:: parseFile(path)
-
- Return an abstract syntax tree for the Python source code in the file specified
- by *path*. It is equivalent to ``parse(open(path).read())``.
-
-
-.. function:: walk(ast, visitor[, verbose])
-
- Do a pre-order walk over the abstract syntax tree *ast*. Call the appropriate
- method on the *visitor* instance for each node encountered.
-
-
-.. function:: compile(source, filename, mode, flags=None, dont_inherit=None)
-
- Compile the string *source*, a Python module, statement or expression, into a
- code object that can be executed by the exec statement or :func:`eval`. This
- function is a replacement for the built-in :func:`compile` function.
-
- The *filename* will be used for run-time error messages.
-
- The *mode* must be 'exec' to compile a module, 'single' to compile a single
- (interactive) statement, or 'eval' to compile an expression.
-
- The *flags* and *dont_inherit* arguments affect future-related statements, but
- are not supported yet.
-
-
-.. function:: compileFile(source)
-
- Compiles the file *source* and generates a .pyc file.
-
-The :mod:`compiler` package contains the following modules: :mod:`ast`,
-:mod:`consts`, :mod:`future`, :mod:`misc`, :mod:`pyassem`, :mod:`pycodegen`,
-:mod:`symbols`, :mod:`transformer`, and :mod:`visitor`.
-
-
-Limitations
-===========
-
-There are some problems with the error checking of the compiler package. The
-interpreter detects syntax errors in two distinct phases. One set of errors is
-detected by the interpreter's parser, the other set by the compiler. The
-compiler package relies on the interpreter's parser, so it get the first phases
-of error checking for free. It implements the second phase itself, and that
-implementation is incomplete. For example, the compiler package does not raise
-an error if a name appears more than once in an argument list: ``def f(x, x):
-...``
-
-A future version of the compiler should fix these problems.
-
-
-Python Abstract Syntax
-======================
-
-The :mod:`compiler.ast` module defines an abstract syntax for Python. In the
-abstract syntax tree, each node represents a syntactic construct. The root of
-the tree is :class:`Module` object.
-
-The abstract syntax offers a higher level interface to parsed Python source
-code. The :mod:`parser` module and the compiler written in C for the Python
-interpreter use a concrete syntax tree. The concrete syntax is tied closely to
-the grammar description used for the Python parser. Instead of a single node
-for a construct, there are often several levels of nested nodes that are
-introduced by Python's precedence rules.
-
-The abstract syntax tree is created by the :mod:`compiler.transformer` module.
-The transformer relies on the built-in Python parser to generate a concrete
-syntax tree. It generates an abstract syntax tree from the concrete tree.
-
-.. index::
- single: Stein, Greg
- single: Tutt, Bill
-
-The :mod:`transformer` module was created by Greg Stein and Bill Tutt for an
-experimental Python-to-C compiler. The current version contains a number of
-modifications and improvements, but the basic form of the abstract syntax and of
-the transformer are due to Stein and Tutt.
-
-
-AST Nodes
----------
-
-.. module:: compiler.ast
-
-
-The :mod:`compiler.ast` module is generated from a text file that describes each
-node type and its elements. Each node type is represented as a class that
-inherits from the abstract base class :class:`compiler.ast.Node` and defines a
-set of named attributes for child nodes.
-
-
-.. class:: Node()
-
- The :class:`Node` instances are created automatically by the parser generator.
- The recommended interface for specific :class:`Node` instances is to use the
- public attributes to access child nodes. A public attribute may be bound to a
- single node or to a sequence of nodes, depending on the :class:`Node` type. For
- example, the :attr:`bases` attribute of the :class:`Class` node, is bound to a
- list of base class nodes, and the :attr:`doc` attribute is bound to a single
- node.
-
- Each :class:`Node` instance has a :attr:`lineno` attribute which may be
- ``None``. XXX Not sure what the rules are for which nodes will have a useful
- lineno.
-
- All :class:`Node` objects offer the following methods:
-
-
- .. method:: getChildren()
-
- Returns a flattened list of the child nodes and objects in the order they
- occur. Specifically, the order of the nodes is the order in which they
- appear in the Python grammar. Not all of the children are :class:`Node`
- instances. The names of functions and classes, for example, are plain
- strings.
-
-
- .. method:: getChildNodes()
-
- Returns a flattened list of the child nodes in the order they occur. This
- method is like :meth:`getChildren`, except that it only returns those
- children that are :class:`Node` instances.
-
-
-Two examples illustrate the general structure of :class:`Node` classes. The
-:keyword:`while` statement is defined by the following grammar production::
-
- while_stmt: "while" expression ":" suite
- ["else" ":" suite]
-
-The :class:`While` node has three attributes: :attr:`test`, :attr:`body`, and
-:attr:`else_`. (If the natural name for an attribute is also a Python reserved
-word, it can't be used as an attribute name. An underscore is appended to the
-word to make it a legal identifier, hence :attr:`else_` instead of
-:keyword:`else`.)
-
-The :keyword:`if` statement is more complicated because it can include several
-tests. ::
-
- if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
-
-The :class:`If` node only defines two attributes: :attr:`tests` and
-:attr:`else_`. The :attr:`tests` attribute is a sequence of test expression,
-consequent body pairs. There is one pair for each :keyword:`if`/:keyword:`elif`
-clause. The first element of the pair is the test expression. The second
-elements is a :class:`Stmt` node that contains the code to execute if the test
-is true.
-
-The :meth:`getChildren` method of :class:`If` returns a flat list of child
-nodes. If there are three :keyword:`if`/:keyword:`elif` clauses and no
-:keyword:`else` clause, then :meth:`getChildren` will return a list of six
-elements: the first test expression, the first :class:`Stmt`, the second text
-expression, etc.
-
-The following table lists each of the :class:`Node` subclasses defined in
-:mod:`compiler.ast` and each of the public attributes available on their
-instances. The values of most of the attributes are themselves :class:`Node`
-instances or sequences of instances. When the value is something other than an
-instance, the type is noted in the comment. The attributes are listed in the
-order in which they are returned by :meth:`getChildren` and
-:meth:`getChildNodes`.
-
-+-----------------------+--------------------+---------------------------------+
-| Node type | Attribute | Value |
-+=======================+====================+=================================+
-| :class:`Add` | :attr:`left` | left operand |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`right` | right operand |
-+-----------------------+--------------------+---------------------------------+
-| :class:`And` | :attr:`nodes` | list of operands |
-+-----------------------+--------------------+---------------------------------+
-| :class:`AssAttr` | | *attribute as target of |
-| | | assignment* |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`expr` | expression on the left-hand |
-| | | side of the dot |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`attrname` | the attribute name, a string |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`flags` | XXX |
-+-----------------------+--------------------+---------------------------------+
-| :class:`AssList` | :attr:`nodes` | list of list elements being |
-| | | assigned to |
-+-----------------------+--------------------+---------------------------------+
-| :class:`AssName` | :attr:`name` | name being assigned to |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`flags` | XXX |
-+-----------------------+--------------------+---------------------------------+
-| :class:`AssTuple` | :attr:`nodes` | list of tuple elements being |
-| | | assigned to |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Assert` | :attr:`test` | the expression to be tested |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`fail` | the value of the |
-| | | :exc:`AssertionError` |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Assign` | :attr:`nodes` | a list of assignment targets, |
-| | | one per equal sign |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`expr` | the value being assigned |
-+-----------------------+--------------------+---------------------------------+
-| :class:`AugAssign` | :attr:`node` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`op` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Backquote` | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Bitand` | :attr:`nodes` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Bitor` | :attr:`nodes` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Bitxor` | :attr:`nodes` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Break` | | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`CallFunc` | :attr:`node` | expression for the callee |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`args` | a list of arguments |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`star_args` | the extended \*-arg value |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`dstar_args` | the extended \*\*-arg value |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Class` | :attr:`name` | the name of the class, a string |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`bases` | a list of base classes |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`doc` | doc string, a string or |
-| | | ``None`` |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`code` | the body of the class statement |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Compare` | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`ops` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Const` | :attr:`value` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Continue` | | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Decorators` | :attr:`nodes` | List of function decorator |
-| | | expressions |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Dict` | :attr:`items` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Discard` | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Div` | :attr:`left` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`right` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Ellipsis` | | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Expression` | :attr:`node` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Exec` | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`locals` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`globals` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`FloorDiv` | :attr:`left` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`right` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`For` | :attr:`assign` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`list` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`body` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`else_` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`From` | :attr:`modname` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`names` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Function` | :attr:`decorators` | :class:`Decorators` or ``None`` |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`name` | name used in def, a string |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`argnames` | list of argument names, as |
-| | | strings |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`defaults` | list of default values |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`flags` | xxx |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`doc` | doc string, a string or |
-| | | ``None`` |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`code` | the body of the function |
-+-----------------------+--------------------+---------------------------------+
-| :class:`GenExpr` | :attr:`code` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`GenExprFor` | :attr:`assign` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`iter` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`ifs` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`GenExprIf` | :attr:`test` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`GenExprInner` | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`quals` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Getattr` | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`attrname` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Global` | :attr:`names` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`If` | :attr:`tests` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`else_` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Import` | :attr:`names` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Invert` | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Keyword` | :attr:`name` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Lambda` | :attr:`argnames` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`defaults` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`flags` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`code` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`LeftShift` | :attr:`left` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`right` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`List` | :attr:`nodes` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`ListComp` | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`quals` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`ListCompFor` | :attr:`assign` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`list` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`ifs` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`ListCompIf` | :attr:`test` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Mod` | :attr:`left` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`right` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Module` | :attr:`doc` | doc string, a string or |
-| | | ``None`` |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`node` | body of the module, a |
-| | | :class:`Stmt` |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Mul` | :attr:`left` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`right` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Name` | :attr:`name` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Not` | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Or` | :attr:`nodes` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Pass` | | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Power` | :attr:`left` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`right` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Print` | :attr:`nodes` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`dest` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Printnl` | :attr:`nodes` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`dest` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Raise` | :attr:`expr1` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`expr2` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`expr3` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Return` | :attr:`value` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`RightShift` | :attr:`left` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`right` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Slice` | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`flags` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`lower` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`upper` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Sliceobj` | :attr:`nodes` | list of statements |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Stmt` | :attr:`nodes` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Sub` | :attr:`left` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`right` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Subscript` | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`flags` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`subs` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`TryExcept` | :attr:`body` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`handlers` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`else_` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`TryFinally` | :attr:`body` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`final` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Tuple` | :attr:`nodes` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`UnaryAdd` | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`UnarySub` | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`While` | :attr:`test` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`body` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`else_` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`With` | :attr:`expr` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`vars` | |
-+-----------------------+--------------------+---------------------------------+
-| | :attr:`body` | |
-+-----------------------+--------------------+---------------------------------+
-| :class:`Yield` | :attr:`value` | |
-+-----------------------+--------------------+---------------------------------+
-
-
-Assignment nodes
-----------------
-
-There is a collection of nodes used to represent assignments. Each assignment
-statement in the source code becomes a single :class:`Assign` node in the AST.
-The :attr:`nodes` attribute is a list that contains a node for each assignment
-target. This is necessary because assignment can be chained, e.g. ``a = b =
-2``. Each :class:`Node` in the list will be one of the following classes:
-:class:`AssAttr`, :class:`AssList`, :class:`AssName`, or :class:`AssTuple`.
-
-Each target assignment node will describe the kind of object being assigned to:
-:class:`AssName` for a simple name, e.g. ``a = 1``. :class:`AssAttr` for an
-attribute assigned, e.g. ``a.x = 1``. :class:`AssList` and :class:`AssTuple` for
-list and tuple expansion respectively, e.g. ``a, b, c = a_tuple``.
-
-The target assignment nodes also have a :attr:`flags` attribute that indicates
-whether the node is being used for assignment or in a delete statement. The
-:class:`AssName` is also used to represent a delete statement, e.g. :class:`del
-x`.
-
-When an expression contains several attribute references, an assignment or
-delete statement will contain only one :class:`AssAttr` node -- for the final
-attribute reference. The other attribute references will be represented as
-:class:`Getattr` nodes in the :attr:`expr` attribute of the :class:`AssAttr`
-instance.
-
-
-Examples
---------
-
-This section shows several simple examples of ASTs for Python source code. The
-examples demonstrate how to use the :func:`parse` function, what the repr of an
-AST looks like, and how to access attributes of an AST node.
-
-The first module defines a single function. Assume it is stored in
-:file:`/tmp/doublelib.py`. ::
-
- """This is an example module.
-
- This is the docstring.
- """
-
- def double(x):
- "Return twice the argument"
- return x * 2
-
-In the interactive interpreter session below, I have reformatted the long AST
-reprs for readability. The AST reprs use unqualified class names. If you want
-to create an instance from a repr, you must import the class names from the
-:mod:`compiler.ast` module. ::
-
- >>> import compiler
- >>> mod = compiler.parseFile("/tmp/doublelib.py")
- >>> mod
- Module('This is an example module.\n\nThis is the docstring.\n',
- Stmt([Function(None, 'double', ['x'], [], 0,
- 'Return twice the argument',
- Stmt([Return(Mul((Name('x'), Const(2))))]))]))
- >>> from compiler.ast import *
- >>> Module('This is an example module.\n\nThis is the docstring.\n',
- ... Stmt([Function(None, 'double', ['x'], [], 0,
- ... 'Return twice the argument',
- ... Stmt([Return(Mul((Name('x'), Const(2))))]))]))
- Module('This is an example module.\n\nThis is the docstring.\n',
- Stmt([Function(None, 'double', ['x'], [], 0,
- 'Return twice the argument',
- Stmt([Return(Mul((Name('x'), Const(2))))]))]))
- >>> mod.doc
- 'This is an example module.\n\nThis is the docstring.\n'
- >>> for node in mod.node.nodes:
- ... print node
- ...
- Function(None, 'double', ['x'], [], 0, 'Return twice the argument',
- Stmt([Return(Mul((Name('x'), Const(2))))]))
- >>> func = mod.node.nodes[0]
- >>> func.code
- Stmt([Return(Mul((Name('x'), Const(2))))])
-
-
-Using Visitors to Walk ASTs
-===========================
-
-.. module:: compiler.visitor
-
-
-The visitor pattern is ... The :mod:`compiler` package uses a variant on the
-visitor pattern that takes advantage of Python's introspection features to
-eliminate the need for much of the visitor's infrastructure.
-
-The classes being visited do not need to be programmed to accept visitors. The
-visitor need only define visit methods for classes it is specifically interested
-in; a default visit method can handle the rest.
-
-XXX The magic :meth:`visit` method for visitors.
-
-
-.. function:: walk(tree, visitor[, verbose])
-
-
-.. class:: ASTVisitor()
-
- The :class:`ASTVisitor` is responsible for walking over the tree in the correct
- order. A walk begins with a call to :meth:`preorder`. For each node, it checks
- the *visitor* argument to :meth:`preorder` for a method named 'visitNodeType,'
- where NodeType is the name of the node's class, e.g. for a :class:`While` node a
- :meth:`visitWhile` would be called. If the method exists, it is called with the
- node as its first argument.
-
- The visitor method for a particular node type can control how child nodes are
- visited during the walk. The :class:`ASTVisitor` modifies the visitor argument
- by adding a visit method to the visitor; this method can be used to visit a
- particular child node. If no visitor is found for a particular node type, the
- :meth:`default` method is called.
-
- :class:`ASTVisitor` objects have the following methods:
-
- XXX describe extra arguments
-
-
- .. method:: default(node[, ...])
-
-
- .. method:: dispatch(node[, ...])
-
-
- .. method:: preorder(tree, visitor)
-
-
-Bytecode Generation
-===================
-
-The code generator is a visitor that emits bytecodes. Each visit method can
-call the :meth:`emit` method to emit a new bytecode. The basic code generator
-is specialized for modules, classes, and functions. An assembler converts that
-emitted instructions to the low-level bytecode format. It handles things like
-generation of constant lists of code objects and calculation of jump offsets.
-
diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst
new file mode 100644
index 0000000..eee2285
--- /dev/null
+++ b/Doc/library/concurrent.futures.rst
@@ -0,0 +1,373 @@
+:mod:`concurrent.futures` --- Launching parallel tasks
+======================================================
+
+.. module:: concurrent.futures
+ :synopsis: Execute computations concurrently using threads or processes.
+
+.. versionadded:: 3.2
+
+**Source code:** :source:`Lib/concurrent/futures/thread.py`
+and :source:`Lib/concurrent/futures/process.py`
+
+--------------
+
+The :mod:`concurrent.futures` module provides a high-level interface for
+asynchronously executing callables.
+
+The asynchronous execution can be performed with threads, using
+:class:`ThreadPoolExecutor`, or separate processes, using
+:class:`ProcessPoolExecutor`. Both implement the same interface, which is
+defined by the abstract :class:`Executor` class.
+
+
+Executor Objects
+----------------
+
+.. class:: Executor
+
+ An abstract class that provides methods to execute calls asynchronously. It
+ should not be used directly, but through its concrete subclasses.
+
+ .. method:: submit(fn, *args, **kwargs)
+
+ Schedules the callable, *fn*, to be executed as ``fn(*args **kwargs)``
+ and returns a :class:`Future` object representing the execution of the
+ callable. ::
+
+ with ThreadPoolExecutor(max_workers=1) as executor:
+ future = executor.submit(pow, 323, 1235)
+ print(future.result())
+
+ .. method:: map(func, *iterables, timeout=None)
+
+ Equivalent to ``map(func, *iterables)`` except *func* is executed
+ asynchronously and several calls to *func* may be made concurrently. The
+ returned iterator raises a :exc:`TimeoutError` if
+ :meth:`~iterator.__next__` is called and the result isn't available
+ after *timeout* seconds from the original call to :meth:`Executor.map`.
+ *timeout* can be an int or a float. If *timeout* is not specified or
+ ``None``, there is no limit to the wait time. If a call raises an
+ exception, then that exception will be raised when its value is
+ retrieved from the iterator.
+
+ .. method:: shutdown(wait=True)
+
+ Signal the executor that it should free any resources that it is using
+ when the currently pending futures are done executing. Calls to
+ :meth:`Executor.submit` and :meth:`Executor.map` made after shutdown will
+ raise :exc:`RuntimeError`.
+
+ If *wait* is ``True`` then this method will not return until all the
+ pending futures are done executing and the resources associated with the
+ executor have been freed. If *wait* is ``False`` then this method will
+ return immediately and the resources associated with the executor will be
+ freed when all pending futures are done executing. Regardless of the
+ value of *wait*, the entire Python program will not exit until all
+ pending futures are done executing.
+
+ You can avoid having to call this method explicitly if you use the
+ :keyword:`with` statement, which will shutdown the :class:`Executor`
+ (waiting as if :meth:`Executor.shutdown` were called with *wait* set to
+ ``True``)::
+
+ import shutil
+ with ThreadPoolExecutor(max_workers=4) as e:
+ e.submit(shutil.copy, 'src1.txt', 'dest1.txt')
+ e.submit(shutil.copy, 'src2.txt', 'dest2.txt')
+ e.submit(shutil.copy, 'src3.txt', 'dest3.txt')
+ e.submit(shutil.copy, 'src3.txt', 'dest4.txt')
+
+
+ThreadPoolExecutor
+------------------
+
+:class:`ThreadPoolExecutor` is a :class:`Executor` subclass that uses a pool of
+threads to execute calls asynchronously.
+
+Deadlocks can occur when the callable associated with a :class:`Future` waits on
+the results of another :class:`Future`. For example::
+
+ import time
+ def wait_on_b():
+ time.sleep(5)
+ print(b.result()) # b will never complete because it is waiting on a.
+ return 5
+
+ def wait_on_a():
+ time.sleep(5)
+ print(a.result()) # a will never complete because it is waiting on b.
+ return 6
+
+
+ executor = ThreadPoolExecutor(max_workers=2)
+ a = executor.submit(wait_on_b)
+ b = executor.submit(wait_on_a)
+
+And::
+
+ def wait_on_future():
+ f = executor.submit(pow, 5, 2)
+ # This will never complete because there is only one worker thread and
+ # it is executing this function.
+ print(f.result())
+
+ executor = ThreadPoolExecutor(max_workers=1)
+ executor.submit(wait_on_future)
+
+
+.. class:: ThreadPoolExecutor(max_workers)
+
+ An :class:`Executor` subclass that uses a pool of at most *max_workers*
+ threads to execute calls asynchronously.
+
+
+.. _threadpoolexecutor-example:
+
+ThreadPoolExecutor Example
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+::
+
+ import concurrent.futures
+ import urllib.request
+
+ URLS = ['http://www.foxnews.com/',
+ 'http://www.cnn.com/',
+ 'http://europe.wsj.com/',
+ 'http://www.bbc.co.uk/',
+ 'http://some-made-up-domain.com/']
+
+ def load_url(url, timeout):
+ return urllib.request.urlopen(url, timeout=timeout).read()
+
+ with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
+ future_to_url = dict((executor.submit(load_url, url, 60), url)
+ for url in URLS)
+
+ for future in concurrent.futures.as_completed(future_to_url):
+ url = future_to_url[future]
+ if future.exception() is not None:
+ print('%r generated an exception: %s' % (url,
+ future.exception()))
+ else:
+ print('%r page is %d bytes' % (url, len(future.result())))
+
+
+ProcessPoolExecutor
+-------------------
+
+The :class:`ProcessPoolExecutor` class is an :class:`Executor` subclass that
+uses a pool of processes to execute calls asynchronously.
+:class:`ProcessPoolExecutor` uses the :mod:`multiprocessing` module, which
+allows it to side-step the :term:`Global Interpreter Lock` but also means that
+only picklable objects can be executed and returned.
+
+Calling :class:`Executor` or :class:`Future` methods from a callable submitted
+to a :class:`ProcessPoolExecutor` will result in deadlock.
+
+.. class:: ProcessPoolExecutor(max_workers=None)
+
+ An :class:`Executor` subclass that executes calls asynchronously using a pool
+ of at most *max_workers* processes. If *max_workers* is ``None`` or not
+ given, it will default to the number of processors on the machine.
+
+
+.. _processpoolexecutor-example:
+
+ProcessPoolExecutor Example
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+::
+
+ import concurrent.futures
+ import math
+
+ PRIMES = [
+ 112272535095293,
+ 112582705942171,
+ 112272535095293,
+ 115280095190773,
+ 115797848077099,
+ 1099726899285419]
+
+ def is_prime(n):
+ if n % 2 == 0:
+ return False
+
+ sqrt_n = int(math.floor(math.sqrt(n)))
+ for i in range(3, sqrt_n + 1, 2):
+ if n % i == 0:
+ return False
+ return True
+
+ def main():
+ with concurrent.futures.ProcessPoolExecutor() as executor:
+ for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
+ print('%d is prime: %s' % (number, prime))
+
+ if __name__ == '__main__':
+ main()
+
+
+Future Objects
+--------------
+
+The :class:`Future` class encapsulates the asynchronous execution of a callable.
+:class:`Future` instances are created by :meth:`Executor.submit`.
+
+.. class:: Future
+
+ Encapsulates the asynchronous execution of a callable. :class:`Future`
+ instances are created by :meth:`Executor.submit` and should not be created
+ directly except for testing.
+
+ .. method:: cancel()
+
+ Attempt to cancel the call. If the call is currently being executed and
+ cannot be cancelled then the method will return ``False``, otherwise the
+ call will be cancelled and the method will return ``True``.
+
+ .. method:: cancelled()
+
+ Return ``True`` if the call was successfully cancelled.
+
+ .. method:: running()
+
+ Return ``True`` if the call is currently being executed and cannot be
+ cancelled.
+
+ .. method:: done()
+
+ Return ``True`` if the call was successfully cancelled or finished
+ running.
+
+ .. method:: result(timeout=None)
+
+ Return the value returned by the call. If the call hasn't yet completed
+ then this method will wait up to *timeout* seconds. If the call hasn't
+ completed in *timeout* seconds, then a :exc:`TimeoutError` will be
+ raised. *timeout* can be an int or float. If *timeout* is not specified
+ or ``None``, there is no limit to the wait time.
+
+ If the future is cancelled before completing then :exc:`CancelledError`
+ will be raised.
+
+ If the call raised, this method will raise the same exception.
+
+ .. method:: exception(timeout=None)
+
+ Return the exception raised by the call. If the call hasn't yet
+ completed then this method will wait up to *timeout* seconds. If the
+ call hasn't completed in *timeout* seconds, then a :exc:`TimeoutError`
+ will be raised. *timeout* can be an int or float. If *timeout* is not
+ specified or ``None``, there is no limit to the wait time.
+
+ If the future is cancelled before completing then :exc:`CancelledError`
+ will be raised.
+
+ If the call completed without raising, ``None`` is returned.
+
+ .. method:: add_done_callback(fn)
+
+ Attaches the callable *fn* to the future. *fn* will be called, with the
+ future as its only argument, when the future is cancelled or finishes
+ running.
+
+ Added callables are called in the order that they were added and are
+ always called in a thread belonging to the process that added them. If
+ the callable raises a :exc:`Exception` subclass, it will be logged and
+ ignored. If the callable raises a :exc:`BaseException` subclass, the
+ behavior is undefined.
+
+ If the future has already completed or been cancelled, *fn* will be
+ called immediately.
+
+ The following :class:`Future` methods are meant for use in unit tests and
+ :class:`Executor` implementations.
+
+ .. method:: set_running_or_notify_cancel()
+
+ This method should only be called by :class:`Executor` implementations
+ before executing the work associated with the :class:`Future` and by unit
+ tests.
+
+ If the method returns ``False`` then the :class:`Future` was cancelled,
+ i.e. :meth:`Future.cancel` was called and returned `True`. Any threads
+ waiting on the :class:`Future` completing (i.e. through
+ :func:`as_completed` or :func:`wait`) will be woken up.
+
+ If the method returns ``True`` then the :class:`Future` was not cancelled
+ and has been put in the running state, i.e. calls to
+ :meth:`Future.running` will return `True`.
+
+ This method can only be called once and cannot be called after
+ :meth:`Future.set_result` or :meth:`Future.set_exception` have been
+ called.
+
+ .. method:: set_result(result)
+
+ Sets the result of the work associated with the :class:`Future` to
+ *result*.
+
+ This method should only be used by :class:`Executor` implementations and
+ unit tests.
+
+ .. method:: set_exception(exception)
+
+ Sets the result of the work associated with the :class:`Future` to the
+ :class:`Exception` *exception*.
+
+ This method should only be used by :class:`Executor` implementations and
+ unit tests.
+
+
+Module Functions
+----------------
+
+.. function:: wait(fs, timeout=None, return_when=ALL_COMPLETED)
+
+ Wait for the :class:`Future` instances (possibly created by different
+ :class:`Executor` instances) given by *fs* to complete. Returns a named
+ 2-tuple of sets. The first set, named ``done``, contains the futures that
+ completed (finished or were cancelled) before the wait completed. The second
+ set, named ``not_done``, contains uncompleted futures.
+
+ *timeout* can be used to control the maximum number of seconds to wait before
+ returning. *timeout* can be an int or float. If *timeout* is not specified
+ or ``None``, there is no limit to the wait time.
+
+ *return_when* indicates when this function should return. It must be one of
+ the following constants:
+
+ +-----------------------------+----------------------------------------+
+ | Constant | Description |
+ +=============================+========================================+
+ | :const:`FIRST_COMPLETED` | The function will return when any |
+ | | future finishes or is cancelled. |
+ +-----------------------------+----------------------------------------+
+ | :const:`FIRST_EXCEPTION` | The function will return when any |
+ | | future finishes by raising an |
+ | | exception. If no future raises an |
+ | | exception then it is equivalent to |
+ | | :const:`ALL_COMPLETED`. |
+ +-----------------------------+----------------------------------------+
+ | :const:`ALL_COMPLETED` | The function will return when all |
+ | | futures finish or are cancelled. |
+ +-----------------------------+----------------------------------------+
+
+.. function:: as_completed(fs, timeout=None)
+
+ Returns an iterator over the :class:`Future` instances (possibly created by
+ different :class:`Executor` instances) given by *fs* that yields futures as
+ they complete (finished or were cancelled). Any futures that completed
+ before :func:`as_completed` is called will be yielded first. The returned
+ iterator raises a :exc:`TimeoutError` if :meth:`~iterator.__next__` is
+ called and the result isn't available after *timeout* seconds from the
+ original call to :func:`as_completed`. *timeout* can be an int or float.
+ If *timeout* is not specified or ``None``, there is no limit to the wait
+ time.
+
+
+.. seealso::
+
+ :pep:`3148` -- futures - execute computations asynchronously
+ The proposal which described this feature for inclusion in the Python
+ standard library.
diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst
index 515074a..958375b 100644
--- a/Doc/library/configparser.rst
+++ b/Doc/library/configparser.rst
@@ -1,19 +1,15 @@
-:mod:`ConfigParser` --- Configuration file parser
+:mod:`configparser` --- Configuration file parser
=================================================
-.. module:: ConfigParser
+.. module:: configparser
:synopsis: Configuration file parser.
.. moduleauthor:: Ken Manheimer <klm@zope.com>
.. moduleauthor:: Barry Warsaw <bwarsaw@python.org>
.. moduleauthor:: Eric S. Raymond <esr@thyrsus.com>
+.. moduleauthor:: Åukasz Langa <lukasz@langa.pl>
.. sectionauthor:: Christopher G. Petrilli <petrilli@amber.org>
-
-.. note::
-
- The :mod:`ConfigParser` module has been renamed to :mod:`configparser` in
- Python 3. The :term:`2to3` tool will automatically adapt imports when
- converting your sources to Python 3.
+.. sectionauthor:: Åukasz Langa <lukasz@langa.pl>
.. index::
pair: .ini; file
@@ -21,11 +17,10 @@
single: ini file
single: Windows ini file
-This module defines the class :class:`ConfigParser`. The :class:`ConfigParser`
-class implements a basic configuration file parser language which provides a
-structure similar to what you would find on Microsoft Windows INI files. You
-can use this to write Python programs which can be customized by end users
-easily.
+This module provides the :class:`ConfigParser` class which implements a basic
+configuration language which provides a structure similar to what's found in
+Microsoft Windows INI files. You can use this to write Python programs which
+can be customized by end users easily.
.. note::
@@ -42,518 +37,1241 @@ easily.
The json module implements a subset of JavaScript syntax which can also
be used for this purpose.
-The configuration file consists of sections, led by a ``[section]`` header and
-followed by ``name: value`` entries, with continuations in the style of
-:rfc:`822` (see section 3.1.1, "LONG HEADER FIELDS"); ``name=value`` is also
-accepted. Note that leading whitespace is removed from values. The optional
-values can contain format strings which refer to other values in the same
-section, or values in a special ``DEFAULT`` section. Additional defaults can be
-provided on initialization and retrieval. Lines beginning with ``'#'`` or
-``';'`` are ignored and may be used to provide comments.
-Configuration files may include comments, prefixed by specific characters (``#``
-and ``;``). Comments may appear on their own in an otherwise empty line, or may
-be entered in lines holding values or section names. In the latter case, they
-need to be preceded by a whitespace character to be recognized as a comment.
-(For backwards compatibility, only ``;`` starts an inline comment, while ``#``
-does not.)
+Quick Start
+-----------
-On top of the core functionality, :class:`SafeConfigParser` supports
-interpolation. This means values can contain format strings which refer to
-other values in the same section, or values in a special ``DEFAULT`` section.
-Additional defaults can be provided on initialization.
+Let's take a very basic configuration file that looks like this:
-For example::
+.. code-block:: ini
- [My Section]
- foodir: %(dir)s/whatever
- dir=frob
- long: this value continues
- in the next line
+ [DEFAULT]
+ ServerAliveInterval = 45
+ Compression = yes
+ CompressionLevel = 9
+ ForwardX11 = yes
-would resolve the ``%(dir)s`` to the value of ``dir`` (``frob`` in this case).
-All reference expansions are done on demand.
+ [bitbucket.org]
+ User = hg
-Default values can be specified by passing them into the :class:`ConfigParser`
-constructor as a dictionary. Additional defaults may be passed into the
-:meth:`get` method which will override all others.
+ [topsecret.server.com]
+ Port = 50022
+ ForwardX11 = no
-Sections are normally stored in a built-in dictionary. An alternative dictionary
-type can be passed to the :class:`ConfigParser` constructor. For example, if a
-dictionary type is passed that sorts its keys, the sections will be sorted on
-write-back, as will be the keys within each section.
+The structure of INI files is described `in the following section
+<#supported-ini-file-structure>`_. Essentially, the file
+consists of sections, each of which contains keys with values.
+:mod:`configparser` classes can read and write such files. Let's start by
+creating the above configuration file programatically.
+.. doctest::
-.. class:: RawConfigParser([defaults[, dict_type[, allow_no_value]]])
+ >>> import configparser
+ >>> config = configparser.ConfigParser()
+ >>> config['DEFAULT'] = {'ServerAliveInterval': '45',
+ ... 'Compression': 'yes',
+ ... 'CompressionLevel': '9'}
+ >>> config['bitbucket.org'] = {}
+ >>> config['bitbucket.org']['User'] = 'hg'
+ >>> config['topsecret.server.com'] = {}
+ >>> topsecret = config['topsecret.server.com']
+ >>> topsecret['Port'] = '50022' # mutates the parser
+ >>> topsecret['ForwardX11'] = 'no' # same here
+ >>> config['DEFAULT']['ForwardX11'] = 'yes'
+ >>> with open('example.ini', 'w') as configfile:
+ ... config.write(configfile)
+ ...
+
+As you can see, we can treat a config parser much like a dictionary.
+There are differences, `outlined later <#mapping-protocol-access>`_, but
+the behavior is very close to what you would expect from a dictionary.
+
+Now that we have created and saved a configuration file, let's read it
+back and explore the data it holds.
- The basic configuration object. When *defaults* is given, it is initialized
- into the dictionary of intrinsic defaults. When *dict_type* is given, it will
- be used to create the dictionary objects for the list of sections, for the
- options within a section, and for the default values. When *allow_no_value*
- is true (default: ``False``), options without values are accepted; the value
- presented for these is ``None``.
+.. doctest::
- This class does not
- support the magical interpolation behavior.
+ >>> import configparser
+ >>> config = configparser.ConfigParser()
+ >>> config.sections()
+ []
+ >>> config.read('example.ini')
+ ['example.ini']
+ >>> config.sections()
+ ['bitbucket.org', 'topsecret.server.com']
+ >>> 'bitbucket.org' in config
+ True
+ >>> 'bytebong.com' in config
+ False
+ >>> config['bitbucket.org']['User']
+ 'hg'
+ >>> config['DEFAULT']['Compression']
+ 'yes'
+ >>> topsecret = config['topsecret.server.com']
+ >>> topsecret['ForwardX11']
+ 'no'
+ >>> topsecret['Port']
+ '50022'
+ >>> for key in config['bitbucket.org']: print(key)
+ ...
+ user
+ compressionlevel
+ serveraliveinterval
+ compression
+ forwardx11
+ >>> config['bitbucket.org']['ForwardX11']
+ 'yes'
+
+As we can see above, the API is pretty straightforward. The only bit of magic
+involves the ``DEFAULT`` section which provides default values for all other
+sections [1]_. Note also that keys in sections are
+case-insensitive and stored in lowercase [1]_.
+
+
+Supported Datatypes
+-------------------
+
+Config parsers do not guess datatypes of values in configuration files, always
+storing them internally as strings. This means that if you need other
+datatypes, you should convert on your own:
- All option names are passed through the :meth:`optionxform` method. Its
- default implementation converts option names to lower case.
+.. doctest::
- .. versionadded:: 2.3
+ >>> int(topsecret['Port'])
+ 50022
+ >>> float(topsecret['CompressionLevel'])
+ 9.0
- .. versionchanged:: 2.6
- *dict_type* was added.
+Extracting Boolean values is not that simple, though. Passing the value
+to ``bool()`` would do no good since ``bool('False')`` is still
+``True``. This is why config parsers also provide :meth:`getboolean`.
+This method is case-insensitive and recognizes Boolean values from
+``'yes'``/``'no'``, ``'on'``/``'off'`` and ``'1'``/``'0'`` [1]_.
+For example:
- .. versionchanged:: 2.7
- The default *dict_type* is :class:`collections.OrderedDict`.
- *allow_no_value* was added.
+.. doctest::
+ >>> topsecret.getboolean('ForwardX11')
+ False
+ >>> config['bitbucket.org'].getboolean('ForwardX11')
+ True
+ >>> config.getboolean('bitbucket.org', 'Compression')
+ True
-.. class:: ConfigParser([defaults[, dict_type[, allow_no_value]]])
+Apart from :meth:`getboolean`, config parsers also provide equivalent
+:meth:`getint` and :meth:`getfloat` methods, but these are far less
+useful since conversion using :func:`int` and :func:`float` is
+sufficient for these types.
- Derived class of :class:`RawConfigParser` that implements the magical
- interpolation feature and adds optional arguments to the :meth:`get` and
- :meth:`items` methods. The values in *defaults* must be appropriate for the
- ``%()s`` string interpolation. Note that *__name__* is an intrinsic default;
- its value is the section name, and will override any value provided in
- *defaults*.
- All option names used in interpolation will be passed through the
- :meth:`optionxform` method just like any other option name reference. Using
- the default implementation of :meth:`optionxform`, the values ``foo %(bar)s``
- and ``foo %(BAR)s`` are equivalent.
+Fallback Values
+---------------
- .. versionadded:: 2.3
+As with a dictionary, you can use a section's :meth:`get` method to
+provide fallback values:
- .. versionchanged:: 2.6
- *dict_type* was added.
+.. doctest::
- .. versionchanged:: 2.7
- The default *dict_type* is :class:`collections.OrderedDict`.
- *allow_no_value* was added.
+ >>> topsecret.get('Port')
+ '50022'
+ >>> topsecret.get('CompressionLevel')
+ '9'
+ >>> topsecret.get('Cipher')
+ >>> topsecret.get('Cipher', '3des-cbc')
+ '3des-cbc'
+Please note that default values have precedence over fallback values.
+For instance, in our example the ``'CompressionLevel'`` key was
+specified only in the ``'DEFAULT'`` section. If we try to get it from
+the section ``'topsecret.server.com'``, we will always get the default,
+even if we specify a fallback:
-.. class:: SafeConfigParser([defaults[, dict_type[, allow_no_value]]])
+.. doctest::
- Derived class of :class:`ConfigParser` that implements a more-sane variant of
- the magical interpolation feature. This implementation is more predictable as
- well. New applications should prefer this version if they don't need to be
- compatible with older versions of Python.
+ >>> topsecret.get('CompressionLevel', '3')
+ '9'
- .. XXX Need to explain what's safer/more predictable about it.
+One more thing to be aware of is that the parser-level :meth:`get` method
+provides a custom, more complex interface, maintained for backwards
+compatibility. When using this method, a fallback value can be provided via
+the ``fallback`` keyword-only argument:
- .. versionadded:: 2.3
+.. doctest::
- .. versionchanged:: 2.6
- *dict_type* was added.
+ >>> config.get('bitbucket.org', 'monster',
+ ... fallback='No such things as monsters')
+ 'No such things as monsters'
- .. versionchanged:: 2.7
- The default *dict_type* is :class:`collections.OrderedDict`.
- *allow_no_value* was added.
+The same ``fallback`` argument can be used with the :meth:`getint`,
+:meth:`getfloat` and :meth:`getboolean` methods, for example:
+.. doctest::
-.. exception:: Error
+ >>> 'BatchMode' in topsecret
+ False
+ >>> topsecret.getboolean('BatchMode', fallback=True)
+ True
+ >>> config['DEFAULT']['BatchMode'] = 'no'
+ >>> topsecret.getboolean('BatchMode', fallback=True)
+ False
+
+
+Supported INI File Structure
+----------------------------
+
+A configuration file consists of sections, each led by a ``[section]`` header,
+followed by key/value entries separated by a specific string (``=`` or ``:`` by
+default [1]_). By default, section names are case sensitive but keys are not
+[1]_. Leading and trailing whitespace is removed from keys and values.
+Values can be omitted, in which case the key/value delimiter may also be left
+out. Values can also span multiple lines, as long as they are indented deeper
+than the first line of the value. Depending on the parser's mode, blank lines
+may be treated as parts of multiline values or ignored.
+
+Configuration files may include comments, prefixed by specific
+characters (``#`` and ``;`` by default [1]_). Comments may appear on
+their own on an otherwise empty line, possibly indented. [1]_
+
+For example:
+
+.. code-block:: ini
+
+ [Simple Values]
+ key=value
+ spaces in keys=allowed
+ spaces in values=allowed as well
+ spaces around the delimiter = obviously
+ you can also use : to delimit keys from values
+
+ [All Values Are Strings]
+ values like this: 1000000
+ or this: 3.14159265359
+ are they treated as numbers? : no
+ integers, floats and booleans are held as: strings
+ can use the API to get converted values directly: true
+
+ [Multiline Values]
+ chorus: I'm a lumberjack, and I'm okay
+ I sleep all night and I work all day
+
+ [No Values]
+ key_without_value
+ empty string value here =
+
+ [You can use comments]
+ # like this
+ ; or this
+
+ # By default only in an empty line.
+ # Inline comments can be harmful because they prevent users
+ # from using the delimiting characters as parts of values.
+ # That being said, this can be customized.
+
+ [Sections Can Be Indented]
+ can_values_be_as_well = True
+ does_that_mean_anything_special = False
+ purpose = formatting for readability
+ multiline_values = are
+ handled just fine as
+ long as they are indented
+ deeper than the first line
+ of a value
+ # Did I mention we can indent comments, too?
+
+
+Interpolation of values
+-----------------------
- Base class for all other configparser exceptions.
+On top of the core functionality, :class:`ConfigParser` supports
+interpolation. This means values can be preprocessed before returning them
+from ``get()`` calls.
+.. class:: BasicInterpolation()
-.. exception:: NoSectionError
+ The default implementation used by :class:`ConfigParser`. It enables
+ values to contain format strings which refer to other values in the same
+ section, or values in the special default section [1]_. Additional default
+ values can be provided on initialization.
- Exception raised when a specified section is not found.
+ For example:
+ .. code-block:: ini
-.. exception:: DuplicateSectionError
+ [Paths]
+ home_dir: /Users
+ my_dir: %(home_dir)s/lumberjack
+ my_pictures: %(my_dir)s/Pictures
- Exception raised if :meth:`add_section` is called with the name of a section
- that is already present.
+ In the example above, :class:`ConfigParser` with *interpolation* set to
+ ``BasicInterpolation()`` would resolve ``%(home_dir)s`` to the value of
+ ``home_dir`` (``/Users`` in this case). ``%(my_dir)s`` in effect would
+ resolve to ``/Users/lumberjack``. All interpolations are done on demand so
+ keys used in the chain of references do not have to be specified in any
+ specific order in the configuration file.
-.. exception:: NoOptionError
+ With ``interpolation`` set to ``None``, the parser would simply return
+ ``%(my_dir)s/Pictures`` as the value of ``my_pictures`` and
+ ``%(home_dir)s/lumberjack`` as the value of ``my_dir``.
- Exception raised when a specified option is not found in the specified section.
+.. class:: ExtendedInterpolation()
+ An alternative handler for interpolation which implements a more advanced
+ syntax, used for instance in ``zc.buildout``. Extended interpolation is
+ using ``${section:option}`` to denote a value from a foreign section.
+ Interpolation can span multiple levels. For convenience, if the ``section:``
+ part is omitted, interpolation defaults to the current section (and possibly
+ the default values from the special section).
-.. exception:: InterpolationError
+ For example, the configuration specified above with basic interpolation,
+ would look like this with extended interpolation:
- Base class for exceptions raised when problems occur performing string
- interpolation.
+ .. code-block:: ini
+ [Paths]
+ home_dir: /Users
+ my_dir: ${home_dir}/lumberjack
+ my_pictures: ${my_dir}/Pictures
-.. exception:: InterpolationDepthError
+ Values from other sections can be fetched as well:
- Exception raised when string interpolation cannot be completed because the
- number of iterations exceeds :const:`MAX_INTERPOLATION_DEPTH`. Subclass of
- :exc:`InterpolationError`.
+ .. code-block:: ini
+ [Common]
+ home_dir: /Users
+ library_dir: /Library
+ system_dir: /System
+ macports_dir: /opt/local
-.. exception:: InterpolationMissingOptionError
+ [Frameworks]
+ Python: 3.2
+ path: ${Common:system_dir}/Library/Frameworks/
- Exception raised when an option referenced from a value does not exist. Subclass
- of :exc:`InterpolationError`.
+ [Arthur]
+ nickname: Two Sheds
+ last_name: Jackson
+ my_dir: ${Common:home_dir}/twosheds
+ my_pictures: ${my_dir}/Pictures
+ python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python}
- .. versionadded:: 2.3
+Mapping Protocol Access
+-----------------------
+.. versionadded:: 3.2
+
+Mapping protocol access is a generic name for functionality that enables using
+custom objects as if they were dictionaries. In case of :mod:`configparser`,
+the mapping interface implementation is using the
+``parser['section']['option']`` notation.
+
+``parser['section']`` in particular returns a proxy for the section's data in
+the parser. This means that the values are not copied but they are taken from
+the original parser on demand. What's even more important is that when values
+are changed on a section proxy, they are actually mutated in the original
+parser.
+
+:mod:`configparser` objects behave as close to actual dictionaries as possible.
+The mapping interface is complete and adheres to the ``MutableMapping`` ABC.
+However, there are a few differences that should be taken into account:
+
+* By default, all keys in sections are accessible in a case-insensitive manner
+ [1]_. E.g. ``for option in parser["section"]`` yields only ``optionxform``'ed
+ option key names. This means lowercased keys by default. At the same time,
+ for a section that holds the key ``'a'``, both expressions return ``True``::
+
+ "a" in parser["section"]
+ "A" in parser["section"]
+
+* All sections include ``DEFAULTSECT`` values as well which means that
+ ``.clear()`` on a section may not leave the section visibly empty. This is
+ because default values cannot be deleted from the section (because technically
+ they are not there). If they are overriden in the section, deleting causes
+ the default value to be visible again. Trying to delete a default value
+ causes a ``KeyError``.
+
+* Trying to delete the ``DEFAULTSECT`` raises ``ValueError``.
+
+* ``parser.get(section, option, **kwargs)`` - the second argument is **not**
+ a fallback value. Note however that the section-level ``get()`` methods are
+ compatible both with the mapping protocol and the classic configparser API.
+
+* ``parser.items()`` is compatible with the mapping protocol (returns a list of
+ *section_name*, *section_proxy* pairs including the DEFAULTSECT). However,
+ this method can also be invoked with arguments: ``parser.items(section, raw,
+ vars)``. The latter call returns a list of *option*, *value* pairs for
+ a specified ``section``, with all interpolations expanded (unless
+ ``raw=True`` is provided).
+
+The mapping protocol is implemented on top of the existing legacy API so that
+subclasses overriding the original interface still should have mappings working
+as expected.
+
+
+Customizing Parser Behaviour
+----------------------------
+
+There are nearly as many INI format variants as there are applications using it.
+:mod:`configparser` goes a long way to provide support for the largest sensible
+set of INI styles available. The default functionality is mainly dictated by
+historical background and it's very likely that you will want to customize some
+of the features.
+
+The most common way to change the way a specific config parser works is to use
+the :meth:`__init__` options:
+
+* *defaults*, default value: ``None``
+
+ This option accepts a dictionary of key-value pairs which will be initially
+ put in the ``DEFAULT`` section. This makes for an elegant way to support
+ concise configuration files that don't specify values which are the same as
+ the documented default.
+
+ Hint: if you want to specify default values for a specific section, use
+ :meth:`read_dict` before you read the actual file.
+
+* *dict_type*, default value: :class:`collections.OrderedDict`
+
+ This option has a major impact on how the mapping protocol will behave and how
+ the written configuration files look. With the default ordered
+ dictionary, every section is stored in the order they were added to the
+ parser. Same goes for options within sections.
+
+ An alternative dictionary type can be used for example to sort sections and
+ options on write-back. You can also use a regular dictionary for performance
+ reasons.
+
+ Please note: there are ways to add a set of key-value pairs in a single
+ operation. When you use a regular dictionary in those operations, the order
+ of the keys may be random. For example:
+
+ .. doctest::
+
+ >>> parser = configparser.ConfigParser()
+ >>> parser.read_dict({'section1': {'key1': 'value1',
+ ... 'key2': 'value2',
+ ... 'key3': 'value3'},
+ ... 'section2': {'keyA': 'valueA',
+ ... 'keyB': 'valueB',
+ ... 'keyC': 'valueC'},
+ ... 'section3': {'foo': 'x',
+ ... 'bar': 'y',
+ ... 'baz': 'z'}
+ ... })
+ >>> parser.sections()
+ ['section3', 'section2', 'section1']
+ >>> [option for option in parser['section3']]
+ ['baz', 'foo', 'bar']
+
+ In these operations you need to use an ordered dictionary as well:
+
+ .. doctest::
+
+ >>> from collections import OrderedDict
+ >>> parser = configparser.ConfigParser()
+ >>> parser.read_dict(
+ ... OrderedDict((
+ ... ('s1',
+ ... OrderedDict((
+ ... ('1', '2'),
+ ... ('3', '4'),
+ ... ('5', '6'),
+ ... ))
+ ... ),
+ ... ('s2',
+ ... OrderedDict((
+ ... ('a', 'b'),
+ ... ('c', 'd'),
+ ... ('e', 'f'),
+ ... ))
+ ... ),
+ ... ))
+ ... )
+ >>> parser.sections()
+ ['s1', 's2']
+ >>> [option for option in parser['s1']]
+ ['1', '3', '5']
+ >>> [option for option in parser['s2'].values()]
+ ['b', 'd', 'f']
+
+* *allow_no_value*, default value: ``False``
+
+ Some configuration files are known to include settings without values, but
+ which otherwise conform to the syntax supported by :mod:`configparser`. The
+ *allow_no_value* parameter to the constructor can be used to
+ indicate that such values should be accepted:
+
+ .. doctest::
+
+ >>> import configparser
+
+ >>> sample_config = """
+ ... [mysqld]
+ ... user = mysql
+ ... pid-file = /var/run/mysqld/mysqld.pid
+ ... skip-external-locking
+ ... old_passwords = 1
+ ... skip-bdb
+ ... # we don't need ACID today
+ ... skip-innodb
+ ... """
+ >>> config = configparser.ConfigParser(allow_no_value=True)
+ >>> config.read_string(sample_config)
+
+ >>> # Settings with values are treated as before:
+ >>> config["mysqld"]["user"]
+ 'mysql'
+
+ >>> # Settings without values provide None:
+ >>> config["mysqld"]["skip-bdb"]
+
+ >>> # Settings which aren't specified still raise an error:
+ >>> config["mysqld"]["does-not-exist"]
+ Traceback (most recent call last):
+ ...
+ KeyError: 'does-not-exist'
+
+* *delimiters*, default value: ``('=', ':')``
+
+ Delimiters are substrings that delimit keys from values within a section. The
+ first occurence of a delimiting substring on a line is considered a delimiter.
+ This means values (but not keys) can contain the delimiters.
+
+ See also the *space_around_delimiters* argument to
+ :meth:`ConfigParser.write`.
+
+* *comment_prefixes*, default value: ``('#', ';')``
+
+* *inline_comment_prefixes*, default value: ``None``
+
+ Comment prefixes are strings that indicate the start of a valid comment within
+ a config file. *comment_prefixes* are used only on otherwise empty lines
+ (optionally indented) whereas *inline_comment_prefixes* can be used after
+ every valid value (e.g. section names, options and empty lines as well). By
+ default inline comments are disabled and ``'#'`` and ``';'`` are used as
+ prefixes for whole line comments.
+
+ .. versionchanged:: 3.2
+ In previous versions of :mod:`configparser` behaviour matched
+ ``comment_prefixes=('#',';')`` and ``inline_comment_prefixes=(';',)``.
+
+ Please note that config parsers don't support escaping of comment prefixes so
+ using *inline_comment_prefixes* may prevent users from specifying option
+ values with characters used as comment prefixes. When in doubt, avoid setting
+ *inline_comment_prefixes*. In any circumstances, the only way of storing
+ comment prefix characters at the beginning of a line in multiline values is to
+ interpolate the prefix, for example::
+
+ >>> from configparser import ConfigParser, ExtendedInterpolation
+ >>> parser = ConfigParser(interpolation=ExtendedInterpolation())
+ >>> # the default BasicInterpolation could be used as well
+ >>> parser.read_string("""
+ ... [DEFAULT]
+ ... hash = #
+ ...
+ ... [hashes]
+ ... shebang =
+ ... ${hash}!/usr/bin/env python
+ ... ${hash} -*- coding: utf-8 -*-
+ ...
+ ... extensions =
+ ... enabled_extension
+ ... another_extension
+ ... #disabled_by_comment
+ ... yet_another_extension
+ ...
+ ... interpolation not necessary = if # is not at line start
+ ... even in multiline values = line #1
+ ... line #2
+ ... line #3
+ ... """)
+ >>> print(parser['hashes']['shebang'])
+
+ #!/usr/bin/env python
+ # -*- coding: utf-8 -*-
+ >>> print(parser['hashes']['extensions'])
+
+ enabled_extension
+ another_extension
+ yet_another_extension
+ >>> print(parser['hashes']['interpolation not necessary'])
+ if # is not at line start
+ >>> print(parser['hashes']['even in multiline values'])
+ line #1
+ line #2
+ line #3
+
+* *strict*, default value: ``True``
+
+ When set to ``True``, the parser will not allow for any section or option
+ duplicates while reading from a single source (using :meth:`read_file`,
+ :meth:`read_string` or :meth:`read_dict`). It is recommended to use strict
+ parsers in new applications.
+
+ .. versionchanged:: 3.2
+ In previous versions of :mod:`configparser` behaviour matched
+ ``strict=False``.
+
+* *empty_lines_in_values*, default value: ``True``
+
+ In config parsers, values can span multiple lines as long as they are
+ indented more than the key that holds them. By default parsers also let
+ empty lines to be parts of values. At the same time, keys can be arbitrarily
+ indented themselves to improve readability. In consequence, when
+ configuration files get big and complex, it is easy for the user to lose
+ track of the file structure. Take for instance:
+
+ .. code-block:: ini
+
+ [Section]
+ key = multiline
+ value with a gotcha
+
+ this = is still a part of the multiline value of 'key'
+
+ This can be especially problematic for the user to see if she's using a
+ proportional font to edit the file. That is why when your application does
+ not need values with empty lines, you should consider disallowing them. This
+ will make empty lines split keys every time. In the example above, it would
+ produce two keys, ``key`` and ``this``.
+
+* *default_section*, default value: ``configparser.DEFAULTSECT`` (that is:
+ ``"DEFAULT"``)
+
+ The convention of allowing a special section of default values for other
+ sections or interpolation purposes is a powerful concept of this library,
+ letting users create complex declarative configurations. This section is
+ normally called ``"DEFAULT"`` but this can be customized to point to any
+ other valid section name. Some typical values include: ``"general"`` or
+ ``"common"``. The name provided is used for recognizing default sections when
+ reading from any source and is used when writing configuration back to
+ a file. Its current value can be retrieved using the
+ ``parser_instance.default_section`` attribute and may be modified at runtime
+ (i.e. to convert files from one format to another).
+
+* *interpolation*, default value: ``configparser.BasicInterpolation``
+
+ Interpolation behaviour may be customized by providing a custom handler
+ through the *interpolation* argument. ``None`` can be used to turn off
+ interpolation completely, ``ExtendedInterpolation()`` provides a more
+ advanced variant inspired by ``zc.buildout``. More on the subject in the
+ `dedicated documentation section <#interpolation-of-values>`_.
+ :class:`RawConfigParser` has a default value of ``None``.
+
+
+More advanced customization may be achieved by overriding default values of
+these parser attributes. The defaults are defined on the classes, so they
+may be overriden by subclasses or by attribute assignment.
+
+.. attribute:: BOOLEAN_STATES
+
+ By default when using :meth:`getboolean`, config parsers consider the
+ following values ``True``: ``'1'``, ``'yes'``, ``'true'``, ``'on'`` and the
+ following values ``False``: ``'0'``, ``'no'``, ``'false'``, ``'off'``. You
+ can override this by specifying a custom dictionary of strings and their
+ Boolean outcomes. For example:
+
+ .. doctest::
+
+ >>> custom = configparser.ConfigParser()
+ >>> custom['section1'] = {'funky': 'nope'}
+ >>> custom['section1'].getboolean('funky')
+ Traceback (most recent call last):
+ ...
+ ValueError: Not a boolean: nope
+ >>> custom.BOOLEAN_STATES = {'sure': True, 'nope': False}
+ >>> custom['section1'].getboolean('funky')
+ False
-.. exception:: InterpolationSyntaxError
+ Other typical Boolean pairs include ``accept``/``reject`` or
+ ``enabled``/``disabled``.
- Exception raised when the source text into which substitutions are made does not
- conform to the required syntax. Subclass of :exc:`InterpolationError`.
+.. method:: optionxform(option)
- .. versionadded:: 2.3
+ This method transforms option names on every read, get, or set
+ operation. The default converts the name to lowercase. This also
+ means that when a configuration file gets written, all keys will be
+ lowercase. Override this method if that's unsuitable.
+ For example:
+ .. doctest::
-.. exception:: MissingSectionHeaderError
+ >>> config = """
+ ... [Section1]
+ ... Key = Value
+ ...
+ ... [Section2]
+ ... AnotherKey = Value
+ ... """
+ >>> typical = configparser.ConfigParser()
+ >>> typical.read_string(config)
+ >>> list(typical['Section1'].keys())
+ ['key']
+ >>> list(typical['Section2'].keys())
+ ['anotherkey']
+ >>> custom = configparser.RawConfigParser()
+ >>> custom.optionxform = lambda option: option
+ >>> custom.read_string(config)
+ >>> list(custom['Section1'].keys())
+ ['Key']
+ >>> list(custom['Section2'].keys())
+ ['AnotherKey']
+
+.. attribute:: SECTCRE
+
+ A compiled regular expression used to parse section headers. The default
+ matches ``[section]`` to the name ``"section"``. Whitespace is considered part
+ of the section name, thus ``[ larch ]`` will be read as a section of name
+ ``" larch "``. Override this attribute if that's unsuitable. For example:
+
+ .. doctest::
+
+ >>> config = """
+ ... [Section 1]
+ ... option = value
+ ...
+ ... [ Section 2 ]
+ ... another = val
+ ... """
+ >>> typical = ConfigParser()
+ >>> typical.read_string(config)
+ >>> typical.sections()
+ ['Section 1', ' Section 2 ']
+ >>> custom = ConfigParser()
+ >>> custom.SECTCRE = re.compile(r"\[ *(?P<header>[^]]+?) *\]")
+ >>> custom.read_string(config)
+ >>> custom.sections()
+ ['Section 1', 'Section 2']
+
+ .. note::
+
+ While ConfigParser objects also use an ``OPTCRE`` attribute for recognizing
+ option lines, it's not recommended to override it because that would
+ interfere with constructor options *allow_no_value* and *delimiters*.
+
+
+Legacy API Examples
+-------------------
+
+Mainly because of backwards compatibility concerns, :mod:`configparser`
+provides also a legacy API with explicit ``get``/``set`` methods. While there
+are valid use cases for the methods outlined below, mapping protocol access is
+preferred for new projects. The legacy API is at times more advanced,
+low-level and downright counterintuitive.
- Exception raised when attempting to parse a file which has no section headers.
+An example of writing to a configuration file::
+ import configparser
-.. exception:: ParsingError
+ config = configparser.RawConfigParser()
- Exception raised when errors occur attempting to parse a file.
+ # Please note that using RawConfigParser's set functions, you can assign
+ # non-string values to keys internally, but will receive an error when
+ # attempting to write to a file or when you get it in non-raw mode. Setting
+ # values using the mapping protocol or ConfigParser's set() does not allow
+ # such assignments to take place.
+ config.add_section('Section1')
+ config.set('Section1', 'an_int', '15')
+ config.set('Section1', 'a_bool', 'true')
+ config.set('Section1', 'a_float', '3.1415')
+ config.set('Section1', 'baz', 'fun')
+ config.set('Section1', 'bar', 'Python')
+ config.set('Section1', 'foo', '%(bar)s is %(baz)s!')
+ # Writing our configuration file to 'example.cfg'
+ with open('example.cfg', 'w') as configfile:
+ config.write(configfile)
-.. data:: MAX_INTERPOLATION_DEPTH
+An example of reading the configuration file again::
- The maximum depth for recursive interpolation for :meth:`get` when the *raw*
- parameter is false. This is relevant only for the :class:`ConfigParser` class.
+ import configparser
+ config = configparser.RawConfigParser()
+ config.read('example.cfg')
-.. seealso::
+ # getfloat() raises an exception if the value is not a float
+ # getint() and getboolean() also do this for their respective types
+ a_float = config.getfloat('Section1', 'a_float')
+ an_int = config.getint('Section1', 'an_int')
+ print(a_float + an_int)
- Module :mod:`shlex`
- Support for a creating Unix shell-like mini-languages which can be used as an
- alternate format for application configuration files.
+ # Notice that the next output does not interpolate '%(bar)s' or '%(baz)s'.
+ # This is because we are using a RawConfigParser().
+ if config.getboolean('Section1', 'a_bool'):
+ print(config.get('Section1', 'foo'))
+To get interpolation, use :class:`ConfigParser`::
-.. _rawconfigparser-objects:
+ import configparser
-RawConfigParser Objects
------------------------
+ cfg = configparser.ConfigParser()
+ cfg.read('example.cfg')
-:class:`RawConfigParser` instances have the following methods:
+ # Set the optional *raw* argument of get() to True if you wish to disable
+ # interpolation in a single get operation.
+ print(cfg.get('Section1', 'foo', raw=False)) # -> "Python is fun!"
+ print(cfg.get('Section1', 'foo', raw=True)) # -> "%(bar)s is %(baz)s!"
+ # The optional *vars* argument is a dict with members that will take
+ # precedence in interpolation.
+ print(cfg.get('Section1', 'foo', vars={'bar': 'Documentation',
+ 'baz': 'evil'}))
-.. method:: RawConfigParser.defaults()
+ # The optional *fallback* argument can be used to provide a fallback value
+ print(cfg.get('Section1', 'foo'))
+ # -> "Python is fun!"
- Return a dictionary containing the instance-wide defaults.
+ print(cfg.get('Section1', 'foo', fallback='Monty is not.'))
+ # -> "Python is fun!"
+ print(cfg.get('Section1', 'monster', fallback='No such things as monsters.'))
+ # -> "No such things as monsters."
-.. method:: RawConfigParser.sections()
+ # A bare print(cfg.get('Section1', 'monster')) would raise NoOptionError
+ # but we can also use:
- Return a list of the sections available; ``DEFAULT`` is not included in the
- list.
+ print(cfg.get('Section1', 'monster', fallback=None))
+ # -> None
+Default values are available in both types of ConfigParsers. They are used in
+interpolation if an option used is not defined elsewhere. ::
-.. method:: RawConfigParser.add_section(section)
+ import configparser
- Add a section named *section* to the instance. If a section by the given name
- already exists, :exc:`DuplicateSectionError` is raised. If the name
- ``DEFAULT`` (or any of it's case-insensitive variants) is passed,
- :exc:`ValueError` is raised.
+ # New instance with 'bar' and 'baz' defaulting to 'Life' and 'hard' each
+ config = configparser.ConfigParser({'bar': 'Life', 'baz': 'hard'})
+ config.read('example.cfg')
-.. method:: RawConfigParser.has_section(section)
+ print(config.get('Section1', 'foo')) # -> "Python is fun!"
+ config.remove_option('Section1', 'bar')
+ config.remove_option('Section1', 'baz')
+ print(config.get('Section1', 'foo')) # -> "Life is hard!"
- Indicates whether the named section is present in the configuration. The
- ``DEFAULT`` section is not acknowledged.
+.. _configparser-objects:
-.. method:: RawConfigParser.options(section)
+ConfigParser Objects
+--------------------
- Returns a list of options available in the specified *section*.
+.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BasicInterpolation())
+
+ The main configuration parser. When *defaults* is given, it is initialized
+ into the dictionary of intrinsic defaults. When *dict_type* is given, it
+ will be used to create the dictionary objects for the list of sections, for
+ the options within a section, and for the default values.
+
+ When *delimiters* is given, it is used as the set of substrings that
+ divide keys from values. When *comment_prefixes* is given, it will be used
+ as the set of substrings that prefix comments in otherwise empty lines.
+ Comments can be indented. When *inline_comment_prefixes* is given, it will be
+ used as the set of substrings that prefix comments in non-empty lines.
+
+ When *strict* is ``True`` (the default), the parser won't allow for
+ any section or option duplicates while reading from a single source (file,
+ string or dictionary), raising :exc:`DuplicateSectionError` or
+ :exc:`DuplicateOptionError`. When *empty_lines_in_values* is ``False``
+ (default: ``True``), each empty line marks the end of an option. Otherwise,
+ internal empty lines of a multiline option are kept as part of the value.
+ When *allow_no_value* is ``True`` (default: ``False``), options without
+ values are accepted; the value held for these is ``None`` and they are
+ serialized without the trailing delimiter.
+
+ When *default_section* is given, it specifies the name for the special
+ section holding default values for other sections and interpolation purposes
+ (normally named ``"DEFAULT"``). This value can be retrieved and changed on
+ runtime using the ``default_section`` instance attribute.
+
+ Interpolation behaviour may be customized by providing a custom handler
+ through the *interpolation* argument. ``None`` can be used to turn off
+ interpolation completely, ``ExtendedInterpolation()`` provides a more
+ advanced variant inspired by ``zc.buildout``. More on the subject in the
+ `dedicated documentation section <#interpolation-of-values>`_.
+ All option names used in interpolation will be passed through the
+ :meth:`optionxform` method just like any other option name reference. For
+ example, using the default implementation of :meth:`optionxform` (which
+ converts option names to lower case), the values ``foo %(bar)s`` and ``foo
+ %(BAR)s`` are equivalent.
-.. method:: RawConfigParser.has_option(section, option)
+ .. versionchanged:: 3.1
+ The default *dict_type* is :class:`collections.OrderedDict`.
- If the given section exists, and contains the given option, return
- :const:`True`; otherwise return :const:`False`.
+ .. versionchanged:: 3.2
+ *allow_no_value*, *delimiters*, *comment_prefixes*, *strict*,
+ *empty_lines_in_values*, *default_section* and *interpolation* were
+ added.
- .. versionadded:: 1.6
+ .. method:: defaults()
-.. method:: RawConfigParser.read(filenames)
+ Return a dictionary containing the instance-wide defaults.
- Attempt to read and parse a list of filenames, returning a list of filenames
- which were successfully parsed. If *filenames* is a string or Unicode string,
- it is treated as a single filename. If a file named in *filenames* cannot be
- opened, that file will be ignored. This is designed so that you can specify a
- list of potential configuration file locations (for example, the current
- directory, the user's home directory, and some system-wide directory), and all
- existing configuration files in the list will be read. If none of the named
- files exist, the :class:`ConfigParser` instance will contain an empty dataset.
- An application which requires initial values to be loaded from a file should
- load the required file or files using :meth:`readfp` before calling :meth:`read`
- for any optional files::
- import ConfigParser, os
+ .. method:: sections()
- config = ConfigParser.ConfigParser()
- config.readfp(open('defaults.cfg'))
- config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')])
+ Return a list of the sections available; the *default section* is not
+ included in the list.
- .. versionchanged:: 2.4
- Returns list of successfully parsed filenames.
+ .. method:: add_section(section)
-.. method:: RawConfigParser.readfp(fp[, filename])
+ Add a section named *section* to the instance. If a section by the given
+ name already exists, :exc:`DuplicateSectionError` is raised. If the
+ *default section* name is passed, :exc:`ValueError` is raised. The name
+ of the section must be a string; if not, :exc:`TypeError` is raised.
- Read and parse configuration data from the file or file-like object in *fp*
- (only the :meth:`readline` method is used). If *filename* is omitted and *fp*
- has a :attr:`name` attribute, that is used for *filename*; the default is
- ``<???>``.
+ .. versionchanged:: 3.2
+ Non-string section names raise :exc:`TypeError`.
-.. method:: RawConfigParser.get(section, option)
+ .. method:: has_section(section)
- Get an *option* value for the named *section*.
+ Indicates whether the named *section* is present in the configuration.
+ The *default section* is not acknowledged.
-.. method:: RawConfigParser.getint(section, option)
+ .. method:: options(section)
- A convenience method which coerces the *option* in the specified *section* to an
- integer.
+ Return a list of options available in the specified *section*.
-.. method:: RawConfigParser.getfloat(section, option)
+ .. method:: has_option(section, option)
- A convenience method which coerces the *option* in the specified *section* to a
- floating point number.
+ If the given *section* exists, and contains the given *option*, return
+ :const:`True`; otherwise return :const:`False`. If the specified
+ *section* is :const:`None` or an empty string, DEFAULT is assumed.
-.. method:: RawConfigParser.getboolean(section, option)
+ .. method:: read(filenames, encoding=None)
- A convenience method which coerces the *option* in the specified *section* to a
- Boolean value. Note that the accepted values for the option are ``"1"``,
- ``"yes"``, ``"true"``, and ``"on"``, which cause this method to return ``True``,
- and ``"0"``, ``"no"``, ``"false"``, and ``"off"``, which cause it to return
- ``False``. These string values are checked in a case-insensitive manner. Any
- other value will cause it to raise :exc:`ValueError`.
+ Attempt to read and parse a list of filenames, returning a list of
+ filenames which were successfully parsed. If *filenames* is a string, it
+ is treated as a single filename. If a file named in *filenames* cannot
+ be opened, that file will be ignored. This is designed so that you can
+ specify a list of potential configuration file locations (for example,
+ the current directory, the user's home directory, and some system-wide
+ directory), and all existing configuration files in the list will be
+ read. If none of the named files exist, the :class:`ConfigParser`
+ instance will contain an empty dataset. An application which requires
+ initial values to be loaded from a file should load the required file or
+ files using :meth:`read_file` before calling :meth:`read` for any
+ optional files::
+ import configparser, os
-.. method:: RawConfigParser.items(section)
+ config = configparser.ConfigParser()
+ config.read_file(open('defaults.cfg'))
+ config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')],
+ encoding='cp1250')
- Return a list of ``(name, value)`` pairs for each option in the given *section*.
+ .. versionadded:: 3.2
+ The *encoding* parameter. Previously, all files were read using the
+ default encoding for :func:`open`.
-.. method:: RawConfigParser.set(section, option, value)
+ .. method:: read_file(f, source=None)
- If the given section exists, set the given option to the specified value;
- otherwise raise :exc:`NoSectionError`. While it is possible to use
- :class:`RawConfigParser` (or :class:`ConfigParser` with *raw* parameters set to
- true) for *internal* storage of non-string values, full functionality (including
- interpolation and output to files) can only be achieved using string values.
+ Read and parse configuration data from *f* which must be an iterable
+ yielding Unicode strings (for example files opened in text mode).
- .. versionadded:: 1.6
+ Optional argument *source* specifies the name of the file being read. If
+ not given and *f* has a :attr:`name` attribute, that is used for
+ *source*; the default is ``'<???>'``.
+ .. versionadded:: 3.2
+ Replaces :meth:`readfp`.
-.. method:: RawConfigParser.write(fileobject)
+ .. method:: read_string(string, source='<string>')
- Write a representation of the configuration to the specified file object. This
- representation can be parsed by a future :meth:`read` call.
+ Parse configuration data from a string.
- .. versionadded:: 1.6
+ Optional argument *source* specifies a context-specific name of the
+ string passed. If not given, ``'<string>'`` is used. This should
+ commonly be a filesystem path or a URL.
+ .. versionadded:: 3.2
-.. method:: RawConfigParser.remove_option(section, option)
- Remove the specified *option* from the specified *section*. If the section does
- not exist, raise :exc:`NoSectionError`. If the option existed to be removed,
- return :const:`True`; otherwise return :const:`False`.
+ .. method:: read_dict(dictionary, source='<dict>')
- .. versionadded:: 1.6
+ Load configuration from any object that provides a dict-like ``items()``
+ method. Keys are section names, values are dictionaries with keys and
+ values that should be present in the section. If the used dictionary
+ type preserves order, sections and their keys will be added in order.
+ Values are automatically converted to strings.
+ Optional argument *source* specifies a context-specific name of the
+ dictionary passed. If not given, ``<dict>`` is used.
-.. method:: RawConfigParser.remove_section(section)
+ This method can be used to copy state between parsers.
- Remove the specified *section* from the configuration. If the section in fact
- existed, return ``True``. Otherwise return ``False``.
+ .. versionadded:: 3.2
-.. method:: RawConfigParser.optionxform(option)
+ .. method:: get(section, option, *, raw=False, vars=None[, fallback])
- Transforms the option name *option* as found in an input file or as passed in
- by client code to the form that should be used in the internal structures.
- The default implementation returns a lower-case version of *option*;
- subclasses may override this or client code can set an attribute of this name
- on instances to affect this behavior.
+ Get an *option* value for the named *section*. If *vars* is provided, it
+ must be a dictionary. The *option* is looked up in *vars* (if provided),
+ *section*, and in *DEFAULTSECT* in that order. If the key is not found
+ and *fallback* is provided, it is used as a fallback value. ``None`` can
+ be provided as a *fallback* value.
- You don't necessarily need to subclass a ConfigParser to use this method, you
- can also re-set it on an instance, to a function that takes a string
- argument. Setting it to ``str``, for example, would make option names case
- sensitive::
+ All the ``'%'`` interpolations are expanded in the return values, unless
+ the *raw* argument is true. Values for interpolation keys are looked up
+ in the same manner as the option.
- cfgparser = ConfigParser()
- ...
- cfgparser.optionxform = str
+ .. versionchanged:: 3.2
+ Arguments *raw*, *vars* and *fallback* are keyword only to protect
+ users from trying to use the third argument as the *fallback* fallback
+ (especially when using the mapping protocol).
- Note that when reading configuration files, whitespace around the
- option names are stripped before :meth:`optionxform` is called.
+ .. method:: getint(section, option, *, raw=False, vars=None[, fallback])
-.. _configparser-objects:
+ A convenience method which coerces the *option* in the specified *section*
+ to an integer. See :meth:`get` for explanation of *raw*, *vars* and
+ *fallback*.
-ConfigParser Objects
---------------------
-The :class:`ConfigParser` class extends some methods of the
-:class:`RawConfigParser` interface, adding some optional arguments.
+ .. method:: getfloat(section, option, *, raw=False, vars=None[, fallback])
+ A convenience method which coerces the *option* in the specified *section*
+ to a floating point number. See :meth:`get` for explanation of *raw*,
+ *vars* and *fallback*.
-.. method:: ConfigParser.get(section, option[, raw[, vars]])
- Get an *option* value for the named *section*. If *vars* is provided, it
- must be a dictionary. The *option* is looked up in *vars* (if provided),
- *section*, and in *defaults* in that order.
+ .. method:: getboolean(section, option, *, raw=False, vars=None[, fallback])
- All the ``'%'`` interpolations are expanded in the return values, unless the
- *raw* argument is true. Values for interpolation keys are looked up in the
- same manner as the option.
+ A convenience method which coerces the *option* in the specified *section*
+ to a Boolean value. Note that the accepted values for the option are
+ ``'1'``, ``'yes'``, ``'true'``, and ``'on'``, which cause this method to
+ return ``True``, and ``'0'``, ``'no'``, ``'false'``, and ``'off'``, which
+ cause it to return ``False``. These string values are checked in a
+ case-insensitive manner. Any other value will cause it to raise
+ :exc:`ValueError`. See :meth:`get` for explanation of *raw*, *vars* and
+ *fallback*.
-.. method:: ConfigParser.items(section[, raw[, vars]])
- Return a list of ``(name, value)`` pairs for each option in the given *section*.
- Optional arguments have the same meaning as for the :meth:`get` method.
+ .. method:: items(raw=False, vars=None)
+ items(section, raw=False, vars=None)
- .. versionadded:: 2.3
+ When *section* is not given, return a list of *section_name*,
+ *section_proxy* pairs, including DEFAULTSECT.
+ Otherwise, return a list of *name*, *value* pairs for the options in the
+ given *section*. Optional arguments have the same meaning as for the
+ :meth:`get` method.
-.. _safeconfigparser-objects:
+ .. versionchanged:: 3.2
+ Items present in *vars* no longer appear in the result. The previous
+ behaviour mixed actual parser options with variables provided for
+ interpolation.
-SafeConfigParser Objects
-------------------------
+ .. method:: set(section, option, value)
-The :class:`SafeConfigParser` class implements the same extended interface as
-:class:`ConfigParser`, with the following addition:
+ If the given section exists, set the given option to the specified value;
+ otherwise raise :exc:`NoSectionError`. *option* and *value* must be
+ strings; if not, :exc:`TypeError` is raised.
-.. method:: SafeConfigParser.set(section, option, value)
+ .. method:: write(fileobject, space_around_delimiters=True)
- If the given section exists, set the given option to the specified value;
- otherwise raise :exc:`NoSectionError`. *value* must be a string (:class:`str`
- or :class:`unicode`); if not, :exc:`TypeError` is raised.
+ Write a representation of the configuration to the specified :term:`file
+ object`, which must be opened in text mode (accepting strings). This
+ representation can be parsed by a future :meth:`read` call. If
+ *space_around_delimiters* is true, delimiters between
+ keys and values are surrounded by spaces.
- .. versionadded:: 2.4
+ .. method:: remove_option(section, option)
-Examples
---------
+ Remove the specified *option* from the specified *section*. If the
+ section does not exist, raise :exc:`NoSectionError`. If the option
+ existed to be removed, return :const:`True`; otherwise return
+ :const:`False`.
-An example of writing to a configuration file::
- import ConfigParser
+ .. method:: remove_section(section)
- config = ConfigParser.RawConfigParser()
+ Remove the specified *section* from the configuration. If the section in
+ fact existed, return ``True``. Otherwise return ``False``.
- # When adding sections or items, add them in the reverse order of
- # how you want them to be displayed in the actual file.
- # In addition, please note that using RawConfigParser's and the raw
- # mode of ConfigParser's respective set functions, you can assign
- # non-string values to keys internally, but will receive an error
- # when attempting to write to a file or when you get it in non-raw
- # mode. SafeConfigParser does not allow such assignments to take place.
- config.add_section('Section1')
- config.set('Section1', 'an_int', '15')
- config.set('Section1', 'a_bool', 'true')
- config.set('Section1', 'a_float', '3.1415')
- config.set('Section1', 'baz', 'fun')
- config.set('Section1', 'bar', 'Python')
- config.set('Section1', 'foo', '%(bar)s is %(baz)s!')
- # Writing our configuration file to 'example.cfg'
- with open('example.cfg', 'wb') as configfile:
- config.write(configfile)
+ .. method:: optionxform(option)
-An example of reading the configuration file again::
+ Transforms the option name *option* as found in an input file or as passed
+ in by client code to the form that should be used in the internal
+ structures. The default implementation returns a lower-case version of
+ *option*; subclasses may override this or client code can set an attribute
+ of this name on instances to affect this behavior.
- import ConfigParser
+ You don't need to subclass the parser to use this method, you can also
+ set it on an instance, to a function that takes a string argument and
+ returns a string. Setting it to ``str``, for example, would make option
+ names case sensitive::
- config = ConfigParser.RawConfigParser()
- config.read('example.cfg')
+ cfgparser = ConfigParser()
+ cfgparser.optionxform = str
- # getfloat() raises an exception if the value is not a float
- # getint() and getboolean() also do this for their respective types
- a_float = config.getfloat('Section1', 'a_float')
- an_int = config.getint('Section1', 'an_int')
- print a_float + an_int
+ Note that when reading configuration files, whitespace around the option
+ names is stripped before :meth:`optionxform` is called.
- # Notice that the next output does not interpolate '%(bar)s' or '%(baz)s'.
- # This is because we are using a RawConfigParser().
- if config.getboolean('Section1', 'a_bool'):
- print config.get('Section1', 'foo')
-To get interpolation, you will need to use a :class:`ConfigParser` or
-:class:`SafeConfigParser`::
+ .. method:: readfp(fp, filename=None)
- import ConfigParser
+ .. deprecated:: 3.2
+ Use :meth:`read_file` instead.
- config = ConfigParser.ConfigParser()
- config.read('example.cfg')
+ .. versionchanged:: 3.2
+ :meth:`readfp` now iterates on *f* instead of calling ``f.readline()``.
- # Set the third, optional argument of get to 1 if you wish to use raw mode.
- print config.get('Section1', 'foo', 0) # -> "Python is fun!"
- print config.get('Section1', 'foo', 1) # -> "%(bar)s is %(baz)s!"
+ For existing code calling :meth:`readfp` with arguments which don't
+ support iteration, the following generator may be used as a wrapper
+ around the file-like object::
- # The optional fourth argument is a dict with members that will take
- # precedence in interpolation.
- print config.get('Section1', 'foo', 0, {'bar': 'Documentation',
- 'baz': 'evil'})
+ def readline_generator(f):
+ line = f.readline()
+ while line:
+ yield line
+ line = f.readline()
-Defaults are available in all three types of ConfigParsers. They are used in
-interpolation if an option used is not defined elsewhere. ::
+ Instead of ``parser.readfp(f)`` use
+ ``parser.read_file(readline_generator(f))``.
- import ConfigParser
- # New instance with 'bar' and 'baz' defaulting to 'Life' and 'hard' each
- config = ConfigParser.SafeConfigParser({'bar': 'Life', 'baz': 'hard'})
- config.read('example.cfg')
+.. data:: MAX_INTERPOLATION_DEPTH
- print config.get('Section1', 'foo') # -> "Python is fun!"
- config.remove_option('Section1', 'bar')
- config.remove_option('Section1', 'baz')
- print config.get('Section1', 'foo') # -> "Life is hard!"
+ The maximum depth for recursive interpolation for :meth:`get` when the *raw*
+ parameter is false. This is relevant only when the default *interpolation*
+ is used.
-The function ``opt_move`` below can be used to move options between sections::
- def opt_move(config, section1, section2, option):
- try:
- config.set(section2, option, config.get(section1, option, 1))
- except ConfigParser.NoSectionError:
- # Create non-existent section
- config.add_section(section2)
- opt_move(config, section1, section2, option)
- else:
- config.remove_option(section1, option)
+.. _rawconfigparser-objects:
-Some configuration files are known to include settings without values, but which
-otherwise conform to the syntax supported by :mod:`ConfigParser`. The
-*allow_no_value* parameter to the constructor can be used to indicate that such
-values should be accepted:
+RawConfigParser Objects
+-----------------------
-.. doctest::
+.. class:: RawConfigParser(defaults=None, dict_type=collections.OrderedDict, \
+ allow_no_value=False, *, delimiters=('=', ':'), \
+ comment_prefixes=('#', ';'), \
+ inline_comment_prefixes=None, strict=True, \
+ empty_lines_in_values=True, \
+ default_section=configparser.DEFAULTSECT[, \
+ interpolation])
- >>> import ConfigParser
- >>> import io
-
- >>> sample_config = """
- ... [mysqld]
- ... user = mysql
- ... pid-file = /var/run/mysqld/mysqld.pid
- ... skip-external-locking
- ... old_passwords = 1
- ... skip-bdb
- ... skip-innodb
- ... """
- >>> config = ConfigParser.RawConfigParser(allow_no_value=True)
- >>> config.readfp(io.BytesIO(sample_config))
-
- >>> # Settings with values are treated as before:
- >>> config.get("mysqld", "user")
- 'mysql'
-
- >>> # Settings without values provide None:
- >>> config.get("mysqld", "skip-bdb")
-
- >>> # Settings which aren't specified still raise an error:
- >>> config.get("mysqld", "does-not-exist")
- Traceback (most recent call last):
- ...
- ConfigParser.NoOptionError: No option 'does-not-exist' in section: 'mysqld'
+ Legacy variant of the :class:`ConfigParser` with interpolation disabled
+ by default and unsafe ``add_section`` and ``set`` methods.
+
+ .. note::
+ Consider using :class:`ConfigParser` instead which checks types of
+ the values to be stored internally. If you don't want interpolation, you
+ can use ``ConfigParser(interpolation=None)``.
+
+
+ .. method:: add_section(section)
+
+ Add a section named *section* to the instance. If a section by the given
+ name already exists, :exc:`DuplicateSectionError` is raised. If the
+ *default section* name is passed, :exc:`ValueError` is raised.
+
+ Type of *section* is not checked which lets users create non-string named
+ sections. This behaviour is unsupported and may cause internal errors.
+
+
+ .. method:: set(section, option, value)
+
+ If the given section exists, set the given option to the specified value;
+ otherwise raise :exc:`NoSectionError`. While it is possible to use
+ :class:`RawConfigParser` (or :class:`ConfigParser` with *raw* parameters
+ set to true) for *internal* storage of non-string values, full
+ functionality (including interpolation and output to files) can only be
+ achieved using string values.
+
+ This method lets users assign non-string values to keys internally. This
+ behaviour is unsupported and will cause errors when attempting to write
+ to a file or get it in non-raw mode. **Use the mapping protocol API**
+ which does not allow such assignments to take place.
+
+
+Exceptions
+----------
+
+.. exception:: Error
+
+ Base class for all other :mod:`configparser` exceptions.
+
+
+.. exception:: NoSectionError
+
+ Exception raised when a specified section is not found.
+
+
+.. exception:: DuplicateSectionError
+
+ Exception raised if :meth:`add_section` is called with the name of a section
+ that is already present or in strict parsers when a section if found more
+ than once in a single input file, string or dictionary.
+
+ .. versionadded:: 3.2
+ Optional ``source`` and ``lineno`` attributes and arguments to
+ :meth:`__init__` were added.
+
+
+.. exception:: DuplicateOptionError
+
+ Exception raised by strict parsers if a single option appears twice during
+ reading from a single file, string or dictionary. This catches misspellings
+ and case sensitivity-related errors, e.g. a dictionary may have two keys
+ representing the same case-insensitive configuration key.
+
+
+.. exception:: NoOptionError
+
+ Exception raised when a specified option is not found in the specified
+ section.
+
+
+.. exception:: InterpolationError
+
+ Base class for exceptions raised when problems occur performing string
+ interpolation.
+
+
+.. exception:: InterpolationDepthError
+
+ Exception raised when string interpolation cannot be completed because the
+ number of iterations exceeds :const:`MAX_INTERPOLATION_DEPTH`. Subclass of
+ :exc:`InterpolationError`.
+
+
+.. exception:: InterpolationMissingOptionError
+
+ Exception raised when an option referenced from a value does not exist.
+ Subclass of :exc:`InterpolationError`.
+
+
+.. exception:: InterpolationSyntaxError
+
+ Exception raised when the source text into which substitutions are made does
+ not conform to the required syntax. Subclass of :exc:`InterpolationError`.
+
+
+.. exception:: MissingSectionHeaderError
+
+ Exception raised when attempting to parse a file which has no section
+ headers.
+
+
+.. exception:: ParsingError
+
+ Exception raised when errors occur attempting to parse a file.
+
+ .. versionchanged:: 3.2
+ The ``filename`` attribute and :meth:`__init__` argument were renamed to
+ ``source`` for consistency.
+
+
+.. rubric:: Footnotes
+
+.. [1] Config parsers allow for heavy customization. If you are interested in
+ changing the behaviour outlined by the footnote reference, consult the
+ `Customizing Parser Behaviour`_ section.
diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst
index 0db8337..059a21d 100644
--- a/Doc/library/constants.rst
+++ b/Doc/library/constants.rst
@@ -7,26 +7,21 @@ A small number of constants live in the built-in namespace. They are:
.. data:: False
- The false value of the :class:`bool` type.
-
- .. versionadded:: 2.3
+ The false value of the :class:`bool` type. Assignments to ``False``
+ are illegal and raise a :exc:`SyntaxError`.
.. data:: True
- The true value of the :class:`bool` type.
-
- .. versionadded:: 2.3
+ The true value of the :class:`bool` type. Assignments to ``True``
+ are illegal and raise a :exc:`SyntaxError`.
.. data:: None
- The sole value of :attr:`types.NoneType`. ``None`` is frequently used to
+ The sole value of the type ``NoneType``. ``None`` is frequently used to
represent the absence of a value, as when default arguments are not passed to a
- function.
-
- .. versionchanged:: 2.4
- Assignments to ``None`` are illegal and raise a :exc:`SyntaxError`.
+ function. Assignments to ``None`` are illegal and raise a :exc:`SyntaxError`.
.. data:: NotImplemented
@@ -38,7 +33,8 @@ A small number of constants live in the built-in namespace. They are:
.. data:: Ellipsis
- Special value used in conjunction with extended slicing syntax.
+ The same as ``...``. Special value used mostly in conjunction with extended
+ slicing syntax for user-defined container data types.
.. data:: __debug__
@@ -49,12 +45,9 @@ A small number of constants live in the built-in namespace. They are:
.. note::
- The names :data:`None` and :data:`__debug__` cannot be reassigned
- (assignments to them, even as an attribute name, raise :exc:`SyntaxError`),
- so they can be considered "true" constants.
-
- .. versionchanged:: 2.7
- Assignments to ``__debug__`` as an attribute became illegal.
+ The names :data:`None`, :data:`False`, :data:`True` and :data:`__debug__`
+ cannot be reassigned (assignments to them, even as an attribute name, raise
+ :exc:`SyntaxError`), so they can be considered "true" constants.
Constants added by the :mod:`site` module
@@ -65,8 +58,8 @@ if the :option:`-S` command-line option is given) adds several constants to the
built-in namespace. They are useful for the interactive interpreter shell and
should not be used in programs.
-.. data:: quit([code=None])
- exit([code=None])
+.. data:: quit(code=None)
+ exit(code=None)
Objects that when printed, print a message like "Use quit() or Ctrl-D
(i.e. EOF) to exit", and when called, raise :exc:`SystemExit` with the
@@ -79,3 +72,4 @@ should not be used in programs.
Objects that when printed, print a message like "Type license() to see the
full license text", and when called, display the corresponding text in a
pager-like fashion (one screen at a time).
+
diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst
index 610c0b0..e8dc17f 100644
--- a/Doc/library/contextlib.rst
+++ b/Doc/library/contextlib.rst
@@ -4,9 +4,6 @@
.. module:: contextlib
:synopsis: Utilities for with-statement contexts.
-
-.. versionadded:: 2.5
-
**Source code:** :source:`Lib/contextlib.py`
--------------
@@ -18,7 +15,7 @@ statement. For more information see also :ref:`typecontextmanager` and
Functions provided:
-.. function:: contextmanager(func)
+.. decorator:: contextmanager
This function is a :term:`decorator` that can be used to define a factory
function for :keyword:`with` statement context managers, without needing to
@@ -30,12 +27,12 @@ Functions provided:
@contextmanager
def tag(name):
- print "<%s>" % name
+ print("<%s>" % name)
yield
- print "</%s>" % name
+ print("</%s>" % name)
>>> with tag("h1"):
- ... print "foo"
+ ... print("foo")
...
<h1>
foo
@@ -57,54 +54,16 @@ Functions provided:
the exception has been handled, and execution will resume with the statement
immediately following the :keyword:`with` statement.
+ :func:`contextmanager` uses :class:`ContextDecorator` so the context managers
+ it creates can be used as decorators as well as in :keyword:`with` statements.
+ When used as a decorator, a new generator instance is implicitly created on
+ each function call (this allows the otherwise "one-shot" context managers
+ created by :func:`contextmanager` to meet the requirement that context
+ managers support multiple invocations in order to be used as decorators).
-.. function:: nested(mgr1[, mgr2[, ...]])
-
- Combine multiple context managers into a single nested context manager.
-
- This function has been deprecated in favour of the multiple manager form
- of the :keyword:`with` statement.
-
- The one advantage of this function over the multiple manager form of the
- :keyword:`with` statement is that argument unpacking allows it to be
- used with a variable number of context managers as follows::
-
- from contextlib import nested
-
- with nested(*managers):
- do_something()
-
- Note that if the :meth:`__exit__` method of one of the nested context managers
- indicates an exception should be suppressed, no exception information will be
- passed to any remaining outer context managers. Similarly, if the
- :meth:`__exit__` method of one of the nested managers raises an exception, any
- previous exception state will be lost; the new exception will be passed to the
- :meth:`__exit__` methods of any remaining outer context managers. In general,
- :meth:`__exit__` methods should avoid raising exceptions, and in particular they
- should not re-raise a passed-in exception.
-
- This function has two major quirks that have led to it being deprecated. Firstly,
- as the context managers are all constructed before the function is invoked, the
- :meth:`__new__` and :meth:`__init__` methods of the inner context managers are
- not actually covered by the scope of the outer context managers. That means, for
- example, that using :func:`nested` to open two files is a programming error as the
- first file will not be closed promptly if an exception is thrown when opening
- the second file.
+ .. versionchanged:: 3.2
+ Use of :class:`ContextDecorator`.
- Secondly, if the :meth:`__enter__` method of one of the inner context managers
- raises an exception that is caught and suppressed by the :meth:`__exit__` method
- of one of the outer context managers, this construct will raise
- :exc:`RuntimeError` rather than skipping the body of the :keyword:`with`
- statement.
-
- Developers that need to support nesting of a variable number of context managers
- can either use the :mod:`warnings` module to suppress the DeprecationWarning
- raised by this function or else use this function as a model for an application
- specific implementation.
-
- .. deprecated:: 2.7
- The with-statement now supports this functionality directly (without the
- confusing error prone quirks).
.. function:: closing(thing)
@@ -123,16 +82,92 @@ Functions provided:
And lets you write code like this::
from contextlib import closing
- import urllib
+ from urllib.request import urlopen
- with closing(urllib.urlopen('http://www.python.org')) as page:
+ with closing(urlopen('http://www.python.org')) as page:
for line in page:
- print line
+ print(line)
without needing to explicitly close ``page``. Even if an error occurs,
``page.close()`` will be called when the :keyword:`with` block is exited.
+.. class:: ContextDecorator()
+
+ A base class that enables a context manager to also be used as a decorator.
+
+ Context managers inheriting from ``ContextDecorator`` have to implement
+ ``__enter__`` and ``__exit__`` as normal. ``__exit__`` retains its optional
+ exception handling even when used as a decorator.
+
+ ``ContextDecorator`` is used by :func:`contextmanager`, so you get this
+ functionality automatically.
+
+ Example of ``ContextDecorator``::
+
+ from contextlib import ContextDecorator
+
+ class mycontext(ContextDecorator):
+ def __enter__(self):
+ print('Starting')
+ return self
+
+ def __exit__(self, *exc):
+ print('Finishing')
+ return False
+
+ >>> @mycontext()
+ ... def function():
+ ... print('The bit in the middle')
+ ...
+ >>> function()
+ Starting
+ The bit in the middle
+ Finishing
+
+ >>> with mycontext():
+ ... print('The bit in the middle')
+ ...
+ Starting
+ The bit in the middle
+ Finishing
+
+ This change is just syntactic sugar for any construct of the following form::
+
+ def f():
+ with cm():
+ # Do stuff
+
+ ``ContextDecorator`` lets you instead write::
+
+ @cm()
+ def f():
+ # Do stuff
+
+ It makes it clear that the ``cm`` applies to the whole function, rather than
+ just a piece of it (and saving an indentation level is nice, too).
+
+ Existing context managers that already have a base class can be extended by
+ using ``ContextDecorator`` as a mixin class::
+
+ from contextlib import ContextDecorator
+
+ class mycontext(ContextBaseClass, ContextDecorator):
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *exc):
+ return False
+
+ .. note::
+ As the decorated function must be able to be called multiple times, the
+ underlying context manager must support use in multiple :keyword:`with`
+ statements. If this is not the case, then the original construct with the
+ explicit :keyword:`with` statement inside the function should be used.
+
+ .. versionadded:: 3.2
+
+
.. seealso::
:pep:`0343` - The "with" statement
diff --git a/Doc/library/cookie.rst b/Doc/library/cookie.rst
deleted file mode 100644
index 19786f7..0000000
--- a/Doc/library/cookie.rst
+++ /dev/null
@@ -1,311 +0,0 @@
-:mod:`Cookie` --- HTTP state management
-=======================================
-
-.. module:: Cookie
- :synopsis: Support for HTTP state management (cookies).
-.. moduleauthor:: Timothy O'Malley <timo@alum.mit.edu>
-.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
-
-.. note::
- The :mod:`Cookie` module has been renamed to :mod:`http.cookies` in Python
- 3. The :term:`2to3` tool will automatically adapt imports when converting
- your sources to Python 3.
-
-**Source code:** :source:`Lib/Cookie.py`
-
---------------
-
-The :mod:`Cookie` module defines classes for abstracting the concept of
-cookies, an HTTP state management mechanism. It supports both simple string-only
-cookies, and provides an abstraction for having any serializable data-type as
-cookie value.
-
-The module formerly strictly applied the parsing rules described in the
-:rfc:`2109` and :rfc:`2068` specifications. It has since been discovered that
-MSIE 3.0x doesn't follow the character rules outlined in those specs and also
-many current day browsers and servers have relaxed parsing rules when comes to
-Cookie handling. As a result, the parsing rules used are a bit less strict.
-
-The character set, :data:`string.ascii_letters`, :data:`string.digits` and
-``!#$%&'*+-.^_`|~`` denote the set of valid characters allowed by this module
-in Cookie name (as :attr:`~Morsel.key`).
-
-
-.. note::
-
- On encountering an invalid cookie, :exc:`CookieError` is raised, so if your
- cookie data comes from a browser you should always prepare for invalid data
- and catch :exc:`CookieError` on parsing.
-
-
-.. exception:: CookieError
-
- Exception failing because of :rfc:`2109` invalidity: incorrect attributes,
- incorrect :mailheader:`Set-Cookie` header, etc.
-
-
-.. class:: BaseCookie([input])
-
- This class is a dictionary-like object whose keys are strings and whose values
- are :class:`Morsel` instances. Note that upon setting a key to a value, the
- value is first converted to a :class:`Morsel` containing the key and the value.
-
- If *input* is given, it is passed to the :meth:`load` method.
-
-
-.. class:: SimpleCookie([input])
-
- This class derives from :class:`BaseCookie` and overrides :meth:`value_decode`
- and :meth:`value_encode` to be the identity and :func:`str` respectively.
-
-
-.. class:: SerialCookie([input])
-
- This class derives from :class:`BaseCookie` and overrides :meth:`value_decode`
- and :meth:`value_encode` to be the :func:`pickle.loads` and
- :func:`pickle.dumps`.
-
- .. deprecated:: 2.3
- Reading pickled values from untrusted cookie data is a huge security hole, as
- pickle strings can be crafted to cause arbitrary code to execute on your server.
- It is supported for backwards compatibility only, and may eventually go away.
-
-
-.. class:: SmartCookie([input])
-
- This class derives from :class:`BaseCookie`. It overrides :meth:`value_decode`
- to be :func:`pickle.loads` if it is a valid pickle, and otherwise the value
- itself. It overrides :meth:`value_encode` to be :func:`pickle.dumps` unless it
- is a string, in which case it returns the value itself.
-
- .. deprecated:: 2.3
- The same security warning from :class:`SerialCookie` applies here.
-
-A further security note is warranted. For backwards compatibility, the
-:mod:`Cookie` module exports a class named :class:`Cookie` which is just an
-alias for :class:`SmartCookie`. This is probably a mistake and will likely be
-removed in a future version. You should not use the :class:`Cookie` class in
-your applications, for the same reason why you should not use the
-:class:`SerialCookie` class.
-
-
-.. seealso::
-
- Module :mod:`cookielib`
- HTTP cookie handling for web *clients*. The :mod:`cookielib` and :mod:`Cookie`
- modules do not depend on each other.
-
- :rfc:`2109` - HTTP State Management Mechanism
- This is the state management specification implemented by this module.
-
-
-.. _cookie-objects:
-
-Cookie Objects
---------------
-
-
-.. method:: BaseCookie.value_decode(val)
-
- Return a decoded value from a string representation. Return value can be any
- type. This method does nothing in :class:`BaseCookie` --- it exists so it can be
- overridden.
-
-
-.. method:: BaseCookie.value_encode(val)
-
- Return an encoded value. *val* can be any type, but return value must be a
- string. This method does nothing in :class:`BaseCookie` --- it exists so it can
- be overridden
-
- In general, it should be the case that :meth:`value_encode` and
- :meth:`value_decode` are inverses on the range of *value_decode*.
-
-
-.. method:: BaseCookie.output([attrs[, header[, sep]]])
-
- Return a string representation suitable to be sent as HTTP headers. *attrs* and
- *header* are sent to each :class:`Morsel`'s :meth:`output` method. *sep* is used
- to join the headers together, and is by default the combination ``'\r\n'``
- (CRLF).
-
- .. versionchanged:: 2.5
- The default separator has been changed from ``'\n'`` to match the cookie
- specification.
-
-
-.. method:: BaseCookie.js_output([attrs])
-
- Return an embeddable JavaScript snippet, which, if run on a browser which
- supports JavaScript, will act the same as if the HTTP headers was sent.
-
- The meaning for *attrs* is the same as in :meth:`output`.
-
-
-.. method:: BaseCookie.load(rawdata)
-
- If *rawdata* is a string, parse it as an ``HTTP_COOKIE`` and add the values
- found there as :class:`Morsel`\ s. If it is a dictionary, it is equivalent to::
-
- for k, v in rawdata.items():
- cookie[k] = v
-
-
-.. _morsel-objects:
-
-Morsel Objects
---------------
-
-
-.. class:: Morsel
-
- Abstract a key/value pair, which has some :rfc:`2109` attributes.
-
- Morsels are dictionary-like objects, whose set of keys is constant --- the valid
- :rfc:`2109` attributes, which are
-
- * ``expires``
- * ``path``
- * ``comment``
- * ``domain``
- * ``max-age``
- * ``secure``
- * ``version``
- * ``httponly``
-
- The attribute :attr:`httponly` specifies that the cookie is only transfered
- in HTTP requests, and is not accessible through JavaScript. This is intended
- to mitigate some forms of cross-site scripting.
-
- The keys are case-insensitive.
-
- .. versionadded:: 2.6
- The :attr:`httponly` attribute was added.
-
-
-.. attribute:: Morsel.value
-
- The value of the cookie.
-
-
-.. attribute:: Morsel.coded_value
-
- The encoded value of the cookie --- this is what should be sent.
-
-
-.. attribute:: Morsel.key
-
- The name of the cookie.
-
-
-.. method:: Morsel.set(key, value, coded_value)
-
- Set the *key*, *value* and *coded_value* attributes.
-
-
-.. method:: Morsel.isReservedKey(K)
-
- Whether *K* is a member of the set of keys of a :class:`Morsel`.
-
-
-.. method:: Morsel.output([attrs[, header]])
-
- Return a string representation of the Morsel, suitable to be sent as an HTTP
- header. By default, all the attributes are included, unless *attrs* is given, in
- which case it should be a list of attributes to use. *header* is by default
- ``"Set-Cookie:"``.
-
-
-.. method:: Morsel.js_output([attrs])
-
- Return an embeddable JavaScript snippet, which, if run on a browser which
- supports JavaScript, will act the same as if the HTTP header was sent.
-
- The meaning for *attrs* is the same as in :meth:`output`.
-
-
-.. method:: Morsel.OutputString([attrs])
-
- Return a string representing the Morsel, without any surrounding HTTP or
- JavaScript.
-
- The meaning for *attrs* is the same as in :meth:`output`.
-
-
-.. _cookie-example:
-
-Example
--------
-
-The following example demonstrates how to use the :mod:`Cookie` module.
-
-.. doctest::
- :options: +NORMALIZE_WHITESPACE
-
- >>> import Cookie
- >>> C = Cookie.SimpleCookie()
- >>> C["fig"] = "newton"
- >>> C["sugar"] = "wafer"
- >>> print C # generate HTTP headers
- Set-Cookie: fig=newton
- Set-Cookie: sugar=wafer
- >>> print C.output() # same thing
- Set-Cookie: fig=newton
- Set-Cookie: sugar=wafer
- >>> C = Cookie.SimpleCookie()
- >>> C["rocky"] = "road"
- >>> C["rocky"]["path"] = "/cookie"
- >>> print C.output(header="Cookie:")
- Cookie: rocky=road; Path=/cookie
- >>> print C.output(attrs=[], header="Cookie:")
- Cookie: rocky=road
- >>> C = Cookie.SimpleCookie()
- >>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header)
- >>> print C
- Set-Cookie: chips=ahoy
- Set-Cookie: vienna=finger
- >>> C = Cookie.SimpleCookie()
- >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
- >>> print C
- Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
- >>> C = Cookie.SimpleCookie()
- >>> C["oreo"] = "doublestuff"
- >>> C["oreo"]["path"] = "/"
- >>> print C
- Set-Cookie: oreo=doublestuff; Path=/
- >>> C["twix"] = "none for you"
- >>> C["twix"].value
- 'none for you'
- >>> C = Cookie.SimpleCookie()
- >>> C["number"] = 7 # equivalent to C["number"] = str(7)
- >>> C["string"] = "seven"
- >>> C["number"].value
- '7'
- >>> C["string"].value
- 'seven'
- >>> print C
- Set-Cookie: number=7
- Set-Cookie: string=seven
- >>> # SerialCookie and SmartCookie are deprecated
- >>> # using it can cause security loopholes in your code.
- >>> C = Cookie.SerialCookie()
- >>> C["number"] = 7
- >>> C["string"] = "seven"
- >>> C["number"].value
- 7
- >>> C["string"].value
- 'seven'
- >>> print C
- Set-Cookie: number="I7\012."
- Set-Cookie: string="S'seven'\012p1\012."
- >>> C = Cookie.SmartCookie()
- >>> C["number"] = 7
- >>> C["string"] = "seven"
- >>> C["number"].value
- 7
- >>> C["string"].value
- 'seven'
- >>> print C
- Set-Cookie: number="I7\012."
- Set-Cookie: string=seven
-
diff --git a/Doc/library/cookielib.rst b/Doc/library/cookielib.rst
deleted file mode 100644
index 2ace510..0000000
--- a/Doc/library/cookielib.rst
+++ /dev/null
@@ -1,771 +0,0 @@
-:mod:`cookielib` --- Cookie handling for HTTP clients
-=====================================================
-
-.. module:: cookielib
- :synopsis: Classes for automatic handling of HTTP cookies.
-.. moduleauthor:: John J. Lee <jjl@pobox.com>
-.. sectionauthor:: John J. Lee <jjl@pobox.com>
-
-.. note::
- The :mod:`cookielib` module has been renamed to :mod:`http.cookiejar` in
- Python 3. The :term:`2to3` tool will automatically adapt imports when
- converting your sources to Python 3.
-
-.. versionadded:: 2.4
-
-**Source code:** :source:`Lib/cookielib.py`
-
---------------
-
-The :mod:`cookielib` module defines classes for automatic handling of HTTP
-cookies. It is useful for accessing web sites that require small pieces of data
--- :dfn:`cookies` -- to be set on the client machine by an HTTP response from a
-web server, and then returned to the server in later HTTP requests.
-
-Both the regular Netscape cookie protocol and the protocol defined by
-:rfc:`2965` are handled. RFC 2965 handling is switched off by default.
-:rfc:`2109` cookies are parsed as Netscape cookies and subsequently treated
-either as Netscape or RFC 2965 cookies according to the 'policy' in effect.
-Note that the great majority of cookies on the Internet are Netscape cookies.
-:mod:`cookielib` attempts to follow the de-facto Netscape cookie protocol (which
-differs substantially from that set out in the original Netscape specification),
-including taking note of the ``max-age`` and ``port`` cookie-attributes
-introduced with RFC 2965.
-
-.. note::
-
- The various named parameters found in :mailheader:`Set-Cookie` and
- :mailheader:`Set-Cookie2` headers (eg. ``domain`` and ``expires``) are
- conventionally referred to as :dfn:`attributes`. To distinguish them from
- Python attributes, the documentation for this module uses the term
- :dfn:`cookie-attribute` instead.
-
-
-The module defines the following exception:
-
-
-.. exception:: LoadError
-
- Instances of :class:`FileCookieJar` raise this exception on failure to load
- cookies from a file.
-
- .. note::
-
- For backwards-compatibility with Python 2.4 (which raised an :exc:`IOError`),
- :exc:`LoadError` is a subclass of :exc:`IOError`.
-
-
-The following classes are provided:
-
-
-.. class:: CookieJar(policy=None)
-
- *policy* is an object implementing the :class:`CookiePolicy` interface.
-
- The :class:`CookieJar` class stores HTTP cookies. It extracts cookies from HTTP
- requests, and returns them in HTTP responses. :class:`CookieJar` instances
- automatically expire contained cookies when necessary. Subclasses are also
- responsible for storing and retrieving cookies from a file or database.
-
-
-.. class:: FileCookieJar(filename, delayload=None, policy=None)
-
- *policy* is an object implementing the :class:`CookiePolicy` interface. For the
- other arguments, see the documentation for the corresponding attributes.
-
- A :class:`CookieJar` which can load cookies from, and perhaps save cookies to, a
- file on disk. Cookies are **NOT** loaded from the named file until either the
- :meth:`load` or :meth:`revert` method is called. Subclasses of this class are
- documented in section :ref:`file-cookie-jar-classes`.
-
-
-.. class:: CookiePolicy()
-
- This class is responsible for deciding whether each cookie should be accepted
- from / returned to the server.
-
-
-.. class:: DefaultCookiePolicy( blocked_domains=None, allowed_domains=None, netscape=True, rfc2965=False, rfc2109_as_netscape=None, hide_cookie2=False, strict_domain=False, strict_rfc2965_unverifiable=True, strict_ns_unverifiable=False, strict_ns_domain=DefaultCookiePolicy.DomainLiberal, strict_ns_set_initial_dollar=False, strict_ns_set_path=False )
-
- Constructor arguments should be passed as keyword arguments only.
- *blocked_domains* is a sequence of domain names that we never accept cookies
- from, nor return cookies to. *allowed_domains* if not :const:`None`, this is a
- sequence of the only domains for which we accept and return cookies. For all
- other arguments, see the documentation for :class:`CookiePolicy` and
- :class:`DefaultCookiePolicy` objects.
-
- :class:`DefaultCookiePolicy` implements the standard accept / reject rules for
- Netscape and RFC 2965 cookies. By default, RFC 2109 cookies (ie. cookies
- received in a :mailheader:`Set-Cookie` header with a version cookie-attribute of
- 1) are treated according to the RFC 2965 rules. However, if RFC 2965 handling
- is turned off or :attr:`rfc2109_as_netscape` is True, RFC 2109 cookies are
- 'downgraded' by the :class:`CookieJar` instance to Netscape cookies, by
- setting the :attr:`version` attribute of the :class:`Cookie` instance to 0.
- :class:`DefaultCookiePolicy` also provides some parameters to allow some
- fine-tuning of policy.
-
-
-.. class:: Cookie()
-
- This class represents Netscape, RFC 2109 and RFC 2965 cookies. It is not
- expected that users of :mod:`cookielib` construct their own :class:`Cookie`
- instances. Instead, if necessary, call :meth:`make_cookies` on a
- :class:`CookieJar` instance.
-
-
-.. seealso::
-
- Module :mod:`urllib2`
- URL opening with automatic cookie handling.
-
- Module :mod:`Cookie`
- HTTP cookie classes, principally useful for server-side code. The
- :mod:`cookielib` and :mod:`Cookie` modules do not depend on each other.
-
- http://wp.netscape.com/newsref/std/cookie_spec.html
- The specification of the original Netscape cookie protocol. Though this is
- still the dominant protocol, the 'Netscape cookie protocol' implemented by all
- the major browsers (and :mod:`cookielib`) only bears a passing resemblance to
- the one sketched out in ``cookie_spec.html``.
-
- :rfc:`2109` - HTTP State Management Mechanism
- Obsoleted by RFC 2965. Uses :mailheader:`Set-Cookie` with version=1.
-
- :rfc:`2965` - HTTP State Management Mechanism
- The Netscape protocol with the bugs fixed. Uses :mailheader:`Set-Cookie2` in
- place of :mailheader:`Set-Cookie`. Not widely used.
-
- http://kristol.org/cookie/errata.html
- Unfinished errata to RFC 2965.
-
- :rfc:`2964` - Use of HTTP State Management
-
-.. _cookie-jar-objects:
-
-CookieJar and FileCookieJar Objects
------------------------------------
-
-:class:`CookieJar` objects support the :term:`iterator` protocol for iterating over
-contained :class:`Cookie` objects.
-
-:class:`CookieJar` has the following methods:
-
-
-.. method:: CookieJar.add_cookie_header(request)
-
- Add correct :mailheader:`Cookie` header to *request*.
-
- If policy allows (ie. the :attr:`rfc2965` and :attr:`hide_cookie2` attributes of
- the :class:`CookieJar`'s :class:`CookiePolicy` instance are true and false
- respectively), the :mailheader:`Cookie2` header is also added when appropriate.
-
- The *request* object (usually a :class:`urllib2.Request` instance) must support
- the methods :meth:`get_full_url`, :meth:`get_host`, :meth:`get_type`,
- :meth:`unverifiable`, :meth:`get_origin_req_host`, :meth:`has_header`,
- :meth:`get_header`, :meth:`header_items`, and :meth:`add_unredirected_header`,as
- documented by :mod:`urllib2`.
-
-
-.. method:: CookieJar.extract_cookies(response, request)
-
- Extract cookies from HTTP *response* and store them in the :class:`CookieJar`,
- where allowed by policy.
-
- The :class:`CookieJar` will look for allowable :mailheader:`Set-Cookie` and
- :mailheader:`Set-Cookie2` headers in the *response* argument, and store cookies
- as appropriate (subject to the :meth:`CookiePolicy.set_ok` method's approval).
-
- The *response* object (usually the result of a call to :meth:`urllib2.urlopen`,
- or similar) should support an :meth:`info` method, which returns an object with
- a :meth:`getallmatchingheaders` method (usually a :class:`mimetools.Message`
- instance).
-
- The *request* object (usually a :class:`urllib2.Request` instance) must support
- the methods :meth:`get_full_url`, :meth:`get_host`, :meth:`unverifiable`, and
- :meth:`get_origin_req_host`, as documented by :mod:`urllib2`. The request is
- used to set default values for cookie-attributes as well as for checking that
- the cookie is allowed to be set.
-
-
-.. method:: CookieJar.set_policy(policy)
-
- Set the :class:`CookiePolicy` instance to be used.
-
-
-.. method:: CookieJar.make_cookies(response, request)
-
- Return sequence of :class:`Cookie` objects extracted from *response* object.
-
- See the documentation for :meth:`extract_cookies` for the interfaces required of
- the *response* and *request* arguments.
-
-
-.. method:: CookieJar.set_cookie_if_ok(cookie, request)
-
- Set a :class:`Cookie` if policy says it's OK to do so.
-
-
-.. method:: CookieJar.set_cookie(cookie)
-
- Set a :class:`Cookie`, without checking with policy to see whether or not it
- should be set.
-
-
-.. method:: CookieJar.clear([domain[, path[, name]]])
-
- Clear some cookies.
-
- If invoked without arguments, clear all cookies. If given a single argument,
- only cookies belonging to that *domain* will be removed. If given two arguments,
- cookies belonging to the specified *domain* and URL *path* are removed. If
- given three arguments, then the cookie with the specified *domain*, *path* and
- *name* is removed.
-
- Raises :exc:`KeyError` if no matching cookie exists.
-
-
-.. method:: CookieJar.clear_session_cookies()
-
- Discard all session cookies.
-
- Discards all contained cookies that have a true :attr:`discard` attribute
- (usually because they had either no ``max-age`` or ``expires`` cookie-attribute,
- or an explicit ``discard`` cookie-attribute). For interactive browsers, the end
- of a session usually corresponds to closing the browser window.
-
- Note that the :meth:`save` method won't save session cookies anyway, unless you
- ask otherwise by passing a true *ignore_discard* argument.
-
-:class:`FileCookieJar` implements the following additional methods:
-
-
-.. method:: FileCookieJar.save(filename=None, ignore_discard=False, ignore_expires=False)
-
- Save cookies to a file.
-
- This base class raises :exc:`NotImplementedError`. Subclasses may leave this
- method unimplemented.
-
- *filename* is the name of file in which to save cookies. If *filename* is not
- specified, :attr:`self.filename` is used (whose default is the value passed to
- the constructor, if any); if :attr:`self.filename` is :const:`None`,
- :exc:`ValueError` is raised.
-
- *ignore_discard*: save even cookies set to be discarded. *ignore_expires*: save
- even cookies that have expired
-
- The file is overwritten if it already exists, thus wiping all the cookies it
- contains. Saved cookies can be restored later using the :meth:`load` or
- :meth:`revert` methods.
-
-
-.. method:: FileCookieJar.load(filename=None, ignore_discard=False, ignore_expires=False)
-
- Load cookies from a file.
-
- Old cookies are kept unless overwritten by newly loaded ones.
-
- Arguments are as for :meth:`save`.
-
- The named file must be in the format understood by the class, or
- :exc:`LoadError` will be raised. Also, :exc:`IOError` may be raised, for
- example if the file does not exist.
-
- .. note::
-
- For backwards-compatibility with Python 2.4 (which raised an :exc:`IOError`),
- :exc:`LoadError` is a subclass of :exc:`IOError`.
-
-
-.. method:: FileCookieJar.revert(filename=None, ignore_discard=False, ignore_expires=False)
-
- Clear all cookies and reload cookies from a saved file.
-
- :meth:`revert` can raise the same exceptions as :meth:`load`. If there is a
- failure, the object's state will not be altered.
-
-:class:`FileCookieJar` instances have the following public attributes:
-
-
-.. attribute:: FileCookieJar.filename
-
- Filename of default file in which to keep cookies. This attribute may be
- assigned to.
-
-
-.. attribute:: FileCookieJar.delayload
-
- If true, load cookies lazily from disk. This attribute should not be assigned
- to. This is only a hint, since this only affects performance, not behaviour
- (unless the cookies on disk are changing). A :class:`CookieJar` object may
- ignore it. None of the :class:`FileCookieJar` classes included in the standard
- library lazily loads cookies.
-
-
-.. _file-cookie-jar-classes:
-
-FileCookieJar subclasses and co-operation with web browsers
------------------------------------------------------------
-
-The following :class:`CookieJar` subclasses are provided for reading and
-writing .
-
-.. class:: MozillaCookieJar(filename, delayload=None, policy=None)
-
- A :class:`FileCookieJar` that can load from and save cookies to disk in the
- Mozilla ``cookies.txt`` file format (which is also used by the Lynx and Netscape
- browsers).
-
- .. note::
-
- Version 3 of the Firefox web browser no longer writes cookies in the
- ``cookies.txt`` file format.
-
- .. note::
-
- This loses information about RFC 2965 cookies, and also about newer or
- non-standard cookie-attributes such as ``port``.
-
- .. warning::
-
- Back up your cookies before saving if you have cookies whose loss / corruption
- would be inconvenient (there are some subtleties which may lead to slight
- changes in the file over a load / save round-trip).
-
- Also note that cookies saved while Mozilla is running will get clobbered by
- Mozilla.
-
-
-.. class:: LWPCookieJar(filename, delayload=None, policy=None)
-
- A :class:`FileCookieJar` that can load from and save cookies to disk in format
- compatible with the libwww-perl library's ``Set-Cookie3`` file format. This is
- convenient if you want to store cookies in a human-readable file.
-
-
-.. _cookie-policy-objects:
-
-CookiePolicy Objects
---------------------
-
-Objects implementing the :class:`CookiePolicy` interface have the following
-methods:
-
-
-.. method:: CookiePolicy.set_ok(cookie, request)
-
- Return boolean value indicating whether cookie should be accepted from server.
-
- *cookie* is a :class:`cookielib.Cookie` instance. *request* is an object
- implementing the interface defined by the documentation for
- :meth:`CookieJar.extract_cookies`.
-
-
-.. method:: CookiePolicy.return_ok(cookie, request)
-
- Return boolean value indicating whether cookie should be returned to server.
-
- *cookie* is a :class:`cookielib.Cookie` instance. *request* is an object
- implementing the interface defined by the documentation for
- :meth:`CookieJar.add_cookie_header`.
-
-
-.. method:: CookiePolicy.domain_return_ok(domain, request)
-
- Return false if cookies should not be returned, given cookie domain.
-
- This method is an optimization. It removes the need for checking every cookie
- with a particular domain (which might involve reading many files). Returning
- true from :meth:`domain_return_ok` and :meth:`path_return_ok` leaves all the
- work to :meth:`return_ok`.
-
- If :meth:`domain_return_ok` returns true for the cookie domain,
- :meth:`path_return_ok` is called for the cookie path. Otherwise,
- :meth:`path_return_ok` and :meth:`return_ok` are never called for that cookie
- domain. If :meth:`path_return_ok` returns true, :meth:`return_ok` is called
- with the :class:`Cookie` object itself for a full check. Otherwise,
- :meth:`return_ok` is never called for that cookie path.
-
- Note that :meth:`domain_return_ok` is called for every *cookie* domain, not just
- for the *request* domain. For example, the function might be called with both
- ``".example.com"`` and ``"www.example.com"`` if the request domain is
- ``"www.example.com"``. The same goes for :meth:`path_return_ok`.
-
- The *request* argument is as documented for :meth:`return_ok`.
-
-
-.. method:: CookiePolicy.path_return_ok(path, request)
-
- Return false if cookies should not be returned, given cookie path.
-
- See the documentation for :meth:`domain_return_ok`.
-
-In addition to implementing the methods above, implementations of the
-:class:`CookiePolicy` interface must also supply the following attributes,
-indicating which protocols should be used, and how. All of these attributes may
-be assigned to.
-
-
-.. attribute:: CookiePolicy.netscape
-
- Implement Netscape protocol.
-
-
-.. attribute:: CookiePolicy.rfc2965
-
- Implement RFC 2965 protocol.
-
-
-.. attribute:: CookiePolicy.hide_cookie2
-
- Don't add :mailheader:`Cookie2` header to requests (the presence of this header
- indicates to the server that we understand RFC 2965 cookies).
-
-The most useful way to define a :class:`CookiePolicy` class is by subclassing
-from :class:`DefaultCookiePolicy` and overriding some or all of the methods
-above. :class:`CookiePolicy` itself may be used as a 'null policy' to allow
-setting and receiving any and all cookies (this is unlikely to be useful).
-
-
-.. _default-cookie-policy-objects:
-
-DefaultCookiePolicy Objects
----------------------------
-
-Implements the standard rules for accepting and returning cookies.
-
-Both RFC 2965 and Netscape cookies are covered. RFC 2965 handling is switched
-off by default.
-
-The easiest way to provide your own policy is to override this class and call
-its methods in your overridden implementations before adding your own additional
-checks::
-
- import cookielib
- class MyCookiePolicy(cookielib.DefaultCookiePolicy):
- def set_ok(self, cookie, request):
- if not cookielib.DefaultCookiePolicy.set_ok(self, cookie, request):
- return False
- if i_dont_want_to_store_this_cookie(cookie):
- return False
- return True
-
-In addition to the features required to implement the :class:`CookiePolicy`
-interface, this class allows you to block and allow domains from setting and
-receiving cookies. There are also some strictness switches that allow you to
-tighten up the rather loose Netscape protocol rules a little bit (at the cost of
-blocking some benign cookies).
-
-A domain blacklist and whitelist is provided (both off by default). Only domains
-not in the blacklist and present in the whitelist (if the whitelist is active)
-participate in cookie setting and returning. Use the *blocked_domains*
-constructor argument, and :meth:`blocked_domains` and
-:meth:`set_blocked_domains` methods (and the corresponding argument and methods
-for *allowed_domains*). If you set a whitelist, you can turn it off again by
-setting it to :const:`None`.
-
-Domains in block or allow lists that do not start with a dot must equal the
-cookie domain to be matched. For example, ``"example.com"`` matches a blacklist
-entry of ``"example.com"``, but ``"www.example.com"`` does not. Domains that do
-start with a dot are matched by more specific domains too. For example, both
-``"www.example.com"`` and ``"www.coyote.example.com"`` match ``".example.com"``
-(but ``"example.com"`` itself does not). IP addresses are an exception, and
-must match exactly. For example, if blocked_domains contains ``"192.168.1.2"``
-and ``".168.1.2"``, 192.168.1.2 is blocked, but 193.168.1.2 is not.
-
-:class:`DefaultCookiePolicy` implements the following additional methods:
-
-
-.. method:: DefaultCookiePolicy.blocked_domains()
-
- Return the sequence of blocked domains (as a tuple).
-
-
-.. method:: DefaultCookiePolicy.set_blocked_domains(blocked_domains)
-
- Set the sequence of blocked domains.
-
-
-.. method:: DefaultCookiePolicy.is_blocked(domain)
-
- Return whether *domain* is on the blacklist for setting or receiving cookies.
-
-
-.. method:: DefaultCookiePolicy.allowed_domains()
-
- Return :const:`None`, or the sequence of allowed domains (as a tuple).
-
-
-.. method:: DefaultCookiePolicy.set_allowed_domains(allowed_domains)
-
- Set the sequence of allowed domains, or :const:`None`.
-
-
-.. method:: DefaultCookiePolicy.is_not_allowed(domain)
-
- Return whether *domain* is not on the whitelist for setting or receiving
- cookies.
-
-:class:`DefaultCookiePolicy` instances have the following attributes, which are
-all initialised from the constructor arguments of the same name, and which may
-all be assigned to.
-
-
-.. attribute:: DefaultCookiePolicy.rfc2109_as_netscape
-
- If true, request that the :class:`CookieJar` instance downgrade RFC 2109 cookies
- (ie. cookies received in a :mailheader:`Set-Cookie` header with a version
- cookie-attribute of 1) to Netscape cookies by setting the version attribute of
- the :class:`Cookie` instance to 0. The default value is :const:`None`, in which
- case RFC 2109 cookies are downgraded if and only if RFC 2965 handling is turned
- off. Therefore, RFC 2109 cookies are downgraded by default.
-
- .. versionadded:: 2.5
-
-General strictness switches:
-
-
-.. attribute:: DefaultCookiePolicy.strict_domain
-
- Don't allow sites to set two-component domains with country-code top-level
- domains like ``.co.uk``, ``.gov.uk``, ``.co.nz``.etc. This is far from perfect
- and isn't guaranteed to work!
-
-RFC 2965 protocol strictness switches:
-
-
-.. attribute:: DefaultCookiePolicy.strict_rfc2965_unverifiable
-
- Follow RFC 2965 rules on unverifiable transactions (usually, an unverifiable
- transaction is one resulting from a redirect or a request for an image hosted on
- another site). If this is false, cookies are *never* blocked on the basis of
- verifiability
-
-Netscape protocol strictness switches:
-
-
-.. attribute:: DefaultCookiePolicy.strict_ns_unverifiable
-
- apply RFC 2965 rules on unverifiable transactions even to Netscape cookies
-
-
-.. attribute:: DefaultCookiePolicy.strict_ns_domain
-
- Flags indicating how strict to be with domain-matching rules for Netscape
- cookies. See below for acceptable values.
-
-
-.. attribute:: DefaultCookiePolicy.strict_ns_set_initial_dollar
-
- Ignore cookies in Set-Cookie: headers that have names starting with ``'$'``.
-
-
-.. attribute:: DefaultCookiePolicy.strict_ns_set_path
-
- Don't allow setting cookies whose path doesn't path-match request URI.
-
-:attr:`strict_ns_domain` is a collection of flags. Its value is constructed by
-or-ing together (for example, ``DomainStrictNoDots|DomainStrictNonDomain`` means
-both flags are set).
-
-
-.. attribute:: DefaultCookiePolicy.DomainStrictNoDots
-
- When setting cookies, the 'host prefix' must not contain a dot (eg.
- ``www.foo.bar.com`` can't set a cookie for ``.bar.com``, because ``www.foo``
- contains a dot).
-
-
-.. attribute:: DefaultCookiePolicy.DomainStrictNonDomain
-
- Cookies that did not explicitly specify a ``domain`` cookie-attribute can only
- be returned to a domain equal to the domain that set the cookie (eg.
- ``spam.example.com`` won't be returned cookies from ``example.com`` that had no
- ``domain`` cookie-attribute).
-
-
-.. attribute:: DefaultCookiePolicy.DomainRFC2965Match
-
- When setting cookies, require a full RFC 2965 domain-match.
-
-The following attributes are provided for convenience, and are the most useful
-combinations of the above flags:
-
-
-.. attribute:: DefaultCookiePolicy.DomainLiberal
-
- Equivalent to 0 (ie. all of the above Netscape domain strictness flags switched
- off).
-
-
-.. attribute:: DefaultCookiePolicy.DomainStrict
-
- Equivalent to ``DomainStrictNoDots|DomainStrictNonDomain``.
-
-
-.. _cookielib-cookie-objects:
-
-Cookie Objects
---------------
-
-:class:`Cookie` instances have Python attributes roughly corresponding to the
-standard cookie-attributes specified in the various cookie standards. The
-correspondence is not one-to-one, because there are complicated rules for
-assigning default values, because the ``max-age`` and ``expires``
-cookie-attributes contain equivalent information, and because RFC 2109 cookies
-may be 'downgraded' by :mod:`cookielib` from version 1 to version 0 (Netscape)
-cookies.
-
-Assignment to these attributes should not be necessary other than in rare
-circumstances in a :class:`CookiePolicy` method. The class does not enforce
-internal consistency, so you should know what you're doing if you do that.
-
-
-.. attribute:: Cookie.version
-
- Integer or :const:`None`. Netscape cookies have :attr:`version` 0. RFC 2965 and
- RFC 2109 cookies have a ``version`` cookie-attribute of 1. However, note that
- :mod:`cookielib` may 'downgrade' RFC 2109 cookies to Netscape cookies, in which
- case :attr:`version` is 0.
-
-
-.. attribute:: Cookie.name
-
- Cookie name (a string).
-
-
-.. attribute:: Cookie.value
-
- Cookie value (a string), or :const:`None`.
-
-
-.. attribute:: Cookie.port
-
- String representing a port or a set of ports (eg. '80', or '80,8080'), or
- :const:`None`.
-
-
-.. attribute:: Cookie.path
-
- Cookie path (a string, eg. ``'/acme/rocket_launchers'``).
-
-
-.. attribute:: Cookie.secure
-
- True if cookie should only be returned over a secure connection.
-
-
-.. attribute:: Cookie.expires
-
- Integer expiry date in seconds since epoch, or :const:`None`. See also the
- :meth:`is_expired` method.
-
-
-.. attribute:: Cookie.discard
-
- True if this is a session cookie.
-
-
-.. attribute:: Cookie.comment
-
- String comment from the server explaining the function of this cookie, or
- :const:`None`.
-
-
-.. attribute:: Cookie.comment_url
-
- URL linking to a comment from the server explaining the function of this cookie,
- or :const:`None`.
-
-
-.. attribute:: Cookie.rfc2109
-
- True if this cookie was received as an RFC 2109 cookie (ie. the cookie
- arrived in a :mailheader:`Set-Cookie` header, and the value of the Version
- cookie-attribute in that header was 1). This attribute is provided because
- :mod:`cookielib` may 'downgrade' RFC 2109 cookies to Netscape cookies, in
- which case :attr:`version` is 0.
-
- .. versionadded:: 2.5
-
-
-.. attribute:: Cookie.port_specified
-
- True if a port or set of ports was explicitly specified by the server (in the
- :mailheader:`Set-Cookie` / :mailheader:`Set-Cookie2` header).
-
-
-.. attribute:: Cookie.domain_specified
-
- True if a domain was explicitly specified by the server.
-
-
-.. attribute:: Cookie.domain_initial_dot
-
- True if the domain explicitly specified by the server began with a dot
- (``'.'``).
-
-Cookies may have additional non-standard cookie-attributes. These may be
-accessed using the following methods:
-
-
-.. method:: Cookie.has_nonstandard_attr(name)
-
- Return true if cookie has the named cookie-attribute.
-
-
-.. method:: Cookie.get_nonstandard_attr(name, default=None)
-
- If cookie has the named cookie-attribute, return its value. Otherwise, return
- *default*.
-
-
-.. method:: Cookie.set_nonstandard_attr(name, value)
-
- Set the value of the named cookie-attribute.
-
-The :class:`Cookie` class also defines the following method:
-
-
-.. method:: Cookie.is_expired([now=None])
-
- True if cookie has passed the time at which the server requested it should
- expire. If *now* is given (in seconds since the epoch), return whether the
- cookie has expired at the specified time.
-
-
-.. _cookielib-examples:
-
-Examples
---------
-
-The first example shows the most common usage of :mod:`cookielib`::
-
- import cookielib, urllib2
- cj = cookielib.CookieJar()
- opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
- r = opener.open("http://example.com/")
-
-This example illustrates how to open a URL using your Netscape, Mozilla, or Lynx
-cookies (assumes Unix/Netscape convention for location of the cookies file)::
-
- import os, cookielib, urllib2
- cj = cookielib.MozillaCookieJar()
- cj.load(os.path.join(os.path.expanduser("~"), ".netscape", "cookies.txt"))
- opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
- r = opener.open("http://example.com/")
-
-The next example illustrates the use of :class:`DefaultCookiePolicy`. Turn on
-RFC 2965 cookies, be more strict about domains when setting and returning
-Netscape cookies, and block some domains from setting cookies or having them
-returned::
-
- import urllib2
- from cookielib import CookieJar, DefaultCookiePolicy
- policy = DefaultCookiePolicy(
- rfc2965=True, strict_ns_domain=DefaultCookiePolicy.DomainStrict,
- blocked_domains=["ads.net", ".ads.net"])
- cj = CookieJar(policy)
- opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
- r = opener.open("http://example.com/")
-
diff --git a/Doc/library/copy.rst b/Doc/library/copy.rst
index 0f23a95..1db5c2d 100644
--- a/Doc/library/copy.rst
+++ b/Doc/library/copy.rst
@@ -63,15 +63,12 @@ Shallow copies of dictionaries can be made using :meth:`dict.copy`, and
of lists by assigning a slice of the entire list, for example,
``copied_list = original_list[:]``.
-.. versionchanged:: 2.5
- Added copying functions.
-
.. index:: module: pickle
Classes can use the same interfaces to control copying that they use to control
pickling. See the description of module :mod:`pickle` for information on these
-methods. The :mod:`copy` module does not use the :mod:`copy_reg` registration
-module.
+methods. In fact, :mod:`copy` module uses the registered pickle functions from
+:mod:`copyreg` module.
.. index::
single: __copy__() (copy protocol)
diff --git a/Doc/library/copy_reg.rst b/Doc/library/copy_reg.rst
deleted file mode 100644
index 3d8ef77..0000000
--- a/Doc/library/copy_reg.rst
+++ /dev/null
@@ -1,66 +0,0 @@
-:mod:`copy_reg` --- Register :mod:`pickle` support functions
-============================================================
-
-.. module:: copy_reg
- :synopsis: Register pickle support functions.
-
-.. note::
- The :mod:`copy_reg` module has been renamed to :mod:`copyreg` in Python 3.
- The :term:`2to3` tool will automatically adapt imports when converting your
- sources to Python 3.
-
-.. index::
- module: pickle
- module: cPickle
- module: copy
-
-The :mod:`copy_reg` module offers a way to define fuctions used while pickling
-specific objects. The :mod:`pickle`, :mod:`cPickle`, and :mod:`copy` modules
-use those functions when pickling/copying those objects. The module provides
-configuration information about object constructors which are not classes.
-Such constructors may be factory functions or class instances.
-
-
-.. function:: constructor(object)
-
- Declares *object* to be a valid constructor. If *object* is not callable (and
- hence not valid as a constructor), raises :exc:`TypeError`.
-
-
-.. function:: pickle(type, function[, constructor])
-
- Declares that *function* should be used as a "reduction" function for objects of
- type *type*; *type* must not be a "classic" class object. (Classic classes are
- handled differently; see the documentation for the :mod:`pickle` module for
- details.) *function* should return either a string or a tuple containing two or
- three elements.
-
- The optional *constructor* parameter, if provided, is a callable object which
- can be used to reconstruct the object when called with the tuple of arguments
- returned by *function* at pickling time. :exc:`TypeError` will be raised if
- *object* is a class or *constructor* is not callable.
-
- See the :mod:`pickle` module for more details on the interface expected of
- *function* and *constructor*.
-
-Example
--------
-
-The example below would like to show how to register a pickle function and how
-it will be used:
-
- >>> import copy_reg, copy, pickle
- >>> class C(object):
- ... def __init__(self, a):
- ... self.a = a
- ...
- >>> def pickle_c(c):
- ... print("pickling a C instance...")
- ... return C, (c.a,)
- ...
- >>> copy_reg.pickle(C, pickle_c)
- >>> c = C(1)
- >>> d = copy.copy(c)
- pickling a C instance...
- >>> p = pickle.dumps(c)
- pickling a C instance...
diff --git a/Doc/library/copyreg.rst b/Doc/library/copyreg.rst
new file mode 100644
index 0000000..f3721d1
--- /dev/null
+++ b/Doc/library/copyreg.rst
@@ -0,0 +1,60 @@
+:mod:`copyreg` --- Register :mod:`pickle` support functions
+===========================================================
+
+.. module:: copyreg
+ :synopsis: Register pickle support functions.
+
+
+.. index::
+ module: pickle
+ module: copy
+
+The :mod:`copyreg` module offers a way to define fuctions used while pickling
+specific objects. The :mod:`pickle` and :mod:`copy` modules use those functions
+when pickling/copying those objects. The module provides configuration
+information about object constructors which are not classes.
+Such constructors may be factory functions or class instances.
+
+
+.. function:: constructor(object)
+
+ Declares *object* to be a valid constructor. If *object* is not callable (and
+ hence not valid as a constructor), raises :exc:`TypeError`.
+
+
+.. function:: pickle(type, function, constructor=None)
+
+ Declares that *function* should be used as a "reduction" function for objects
+ of type *type*. *function* should return either a string or a tuple
+ containing two or three elements.
+
+ The optional *constructor* parameter, if provided, is a callable object which
+ can be used to reconstruct the object when called with the tuple of arguments
+ returned by *function* at pickling time. :exc:`TypeError` will be raised if
+ *object* is a class or *constructor* is not callable.
+
+ See the :mod:`pickle` module for more details on the interface expected of
+ *function* and *constructor*.
+
+
+Example
+-------
+
+The example below would like to show how to register a pickle function and how
+it will be used:
+
+ >>> import copyreg, copy, pickle
+ >>> class C(object):
+ ... def __init__(self, a):
+ ... self.a = a
+ ...
+ >>> def pickle_c(c):
+ ... print("pickling a C instance...")
+ ... return C, (c.a,)
+ ...
+ >>> copyreg.pickle(C, pickle_c)
+ >>> c = C(1)
+ >>> d = copy.copy(c)
+ pickling a C instance...
+ >>> p = pickle.dumps(c)
+ pickling a C instance...
diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst
index 91464ef..0be571e 100644
--- a/Doc/library/crypt.rst
+++ b/Doc/library/crypt.rst
@@ -1,4 +1,3 @@
-
:mod:`crypt` --- Function to check Unix passwords
=================================================
@@ -48,12 +47,11 @@ A simple example illustrating typical use::
import crypt, getpass, pwd
def login():
- username = raw_input('Python login:')
+ username = input('Python login:')
cryptedpasswd = pwd.getpwnam(username)[1]
if cryptedpasswd:
if cryptedpasswd == 'x' or cryptedpasswd == '*':
- raise NotImplementedError(
- "Sorry, currently no support for shadow passwords")
+ raise "Sorry, currently no support for shadow passwords"
cleartext = getpass.getpass()
return crypt.crypt(cleartext, cryptedpasswd) == cryptedpasswd
else:
diff --git a/Doc/library/crypto.rst b/Doc/library/crypto.rst
index 21cc251..a233561 100644
--- a/Doc/library/crypto.rst
+++ b/Doc/library/crypto.rst
@@ -1,4 +1,3 @@
-
.. _crypto:
**********************
@@ -16,8 +15,7 @@ Here's an overview:
hashlib.rst
hmac.rst
- md5.rst
- sha.rst
+
.. index::
pair: AES; algorithm
single: cryptography
diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst
index 66b2fb4..90261e2 100644
--- a/Doc/library/csv.rst
+++ b/Doc/library/csv.rst
@@ -1,4 +1,3 @@
-
:mod:`csv` --- CSV File Reading and Writing
===========================================
@@ -7,8 +6,6 @@
.. sectionauthor:: Skip Montanaro <skip@pobox.com>
-.. versionadded:: 2.3
-
.. index::
single: csv
pair: data; tabular
@@ -35,14 +32,6 @@ The :mod:`csv` module's :class:`reader` and :class:`writer` objects read and
write sequences. Programmers can also read and write data in dictionary form
using the :class:`DictReader` and :class:`DictWriter` classes.
-.. note::
-
- This version of the :mod:`csv` module doesn't support Unicode input. Also,
- there are currently some issues regarding ASCII NUL characters. Accordingly,
- all input should be UTF-8 or printable ASCII to be safe; see the examples in
- section :ref:`csv-examples`.
-
-
.. seealso::
:pep:`305` - CSV File API
@@ -57,13 +46,16 @@ Module Contents
The :mod:`csv` module defines the following functions:
+.. index::
+ single: universal newlines; csv.reader function
+
.. function:: reader(csvfile, dialect='excel', **fmtparams)
Return a reader object which will iterate over lines in the given *csvfile*.
*csvfile* can be any object which supports the :term:`iterator` protocol and returns a
- string each time its :meth:`!next` method is called --- file objects and list
- objects are both suitable. If *csvfile* is a file object, it must be opened
- with the 'b' flag on platforms where that makes a difference. An optional
+ string each time its :meth:`!__next__` method is called --- :term:`file objects
+ <file object>` and list objects are both suitable. If *csvfile* is a file object,
+ it should be opened with ``newline=''``. [1]_ An optional
*dialect* parameter can be given which is used to define a set of parameters
specific to a particular CSV dialect. It may be an instance of a subclass of
the :class:`Dialect` class or one of the strings returned by the
@@ -73,34 +65,26 @@ The :mod:`csv` module defines the following functions:
section :ref:`csv-fmt-params`.
Each row read from the csv file is returned as a list of strings. No
- automatic data type conversion is performed.
+ automatic data type conversion is performed unless the ``QUOTE_NONNUMERIC`` format
+ option is specified (in which case unquoted fields are transformed into floats).
A short usage example::
>>> import csv
- >>> with open('eggs.csv', 'rb') as csvfile:
+ >>> with open('eggs.csv', newline='') as csvfile:
... spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
... for row in spamreader:
- ... print ', '.join(row)
+ ... print(', '.join(row))
Spam, Spam, Spam, Spam, Spam, Baked Beans
Spam, Lovely Spam, Wonderful Spam
- .. versionchanged:: 2.5
- The parser is now stricter with respect to multi-line quoted fields. Previously,
- if a line ended within a quoted field without a terminating newline character, a
- newline would be inserted into the returned field. This behavior caused problems
- when reading files which contained carriage return characters within fields.
- The behavior was changed to return the field without inserting newlines. As a
- consequence, if newlines embedded within fields are important, the input should
- be split into lines in a manner which preserves the newline characters.
-
.. function:: writer(csvfile, dialect='excel', **fmtparams)
Return a writer object responsible for converting the user's data into delimited
strings on the given file-like object. *csvfile* can be any object with a
- :func:`write` method. If *csvfile* is a file object, it must be opened with the
- 'b' flag on platforms where that makes a difference. An optional *dialect*
+ :func:`write` method. If *csvfile* is a file object, it should be opened with
+ ``newline=''`` [1]_. An optional *dialect*
parameter can be given which is used to define a set of parameters specific to a
particular CSV dialect. It may be an instance of a subclass of the
:class:`Dialect` class or one of the strings returned by the
@@ -117,7 +101,7 @@ The :mod:`csv` module defines the following functions:
A short usage example::
import csv
- with open('eggs.csv', 'wb') as csvfile:
+ with open('eggs.csv', 'w', newline='') as csvfile:
spamwriter = csv.writer(csvfile, delimiter=' ',
quotechar='|', quoting=csv.QUOTE_MINIMAL)
spamwriter.writerow(['Spam'] * 5 + ['Baked Beans'])
@@ -126,7 +110,7 @@ The :mod:`csv` module defines the following functions:
.. function:: register_dialect(name[, dialect], **fmtparams)
- Associate *dialect* with *name*. *name* must be a string or Unicode object. The
+ Associate *dialect* with *name*. *name* must be a string. The
dialect can be specified either by passing a sub-class of :class:`Dialect`, or
by *fmtparams* keyword arguments, or both, with keyword arguments overriding
parameters of the dialect. For full details about the dialect and formatting
@@ -141,13 +125,9 @@ The :mod:`csv` module defines the following functions:
.. function:: get_dialect(name)
- Return the dialect associated with *name*. An :exc:`Error` is raised if *name*
- is not a registered dialect name.
-
- .. versionchanged:: 2.5
- This function now returns an immutable :class:`Dialect`. Previously an
- instance of the requested dialect was returned. Users could modify the
- underlying class, changing the behavior of active readers and writers.
+ Return the dialect associated with *name*. An :exc:`Error` is raised if
+ *name* is not a registered dialect name. This function returns an immutable
+ :class:`Dialect`.
.. function:: list_dialects()
@@ -159,11 +139,9 @@ The :mod:`csv` module defines the following functions:
Returns the current maximum field size allowed by the parser. If *new_limit* is
given, this becomes the new limit.
- .. versionadded:: 2.5
The :mod:`csv` module defines the following classes:
-
.. class:: DictReader(csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)
Create an object which operates like a regular reader but maps the information
@@ -215,6 +193,15 @@ The :mod:`csv` module defines the following classes:
TAB-delimited file. It is registered with the dialect name ``'excel-tab'``.
+.. class:: unix_dialect()
+
+ The :class:`unix_dialect` class defines the usual properties of a CSV file
+ generated on UNIX systems, i.e. using ``'\n'`` as line terminator and quoting
+ all fields. It is registered with the dialect name ``'unix'``.
+
+ .. versionadded:: 3.2
+
+
.. class:: Sniffer()
The :class:`Sniffer` class is used to deduce the format of a CSV file.
@@ -236,7 +223,7 @@ The :mod:`csv` module defines the following classes:
An example for :class:`Sniffer` use::
- with open('example.csv', 'rb') as csvfile:
+ with open('example.csv') as csvfile:
dialect = csv.Sniffer().sniff(csvfile.read(1024))
csvfile.seek(0)
reader = csv.reader(csvfile, dialect)
@@ -280,7 +267,6 @@ The :mod:`csv` module defines the following exception:
Raised by any of the functions when an error is detected.
-
.. _csv-fmt-params:
Dialects and Formatting Parameters
@@ -366,14 +352,13 @@ Reader Objects
Reader objects (:class:`DictReader` instances and objects returned by the
:func:`reader` function) have the following public methods:
-
-.. method:: csvreader.next()
+.. method:: csvreader.__next__()
Return the next row of the reader's iterable object as a list, parsed according
- to the current dialect.
+ to the current dialect. Usually you should call this as ``next(reader)``.
-Reader objects have the following public attributes:
+Reader objects have the following public attributes:
.. attribute:: csvreader.dialect
@@ -385,19 +370,15 @@ Reader objects have the following public attributes:
The number of lines read from the source iterator. This is not the same as the
number of records returned, as records can span multiple lines.
- .. versionadded:: 2.5
-
DictReader objects have the following public attribute:
-
.. attribute:: csvreader.fieldnames
If not passed as a parameter when creating the object, this attribute is
initialized upon first access or when the first record is read from the
file.
- .. versionchanged:: 2.6
Writer Objects
@@ -438,7 +419,7 @@ DictWriter objects have the following public method:
Write a row with the field names (as specified in the constructor).
- .. versionadded:: 2.7
+ .. versionadded:: 3.2
.. _csv-examples:
@@ -449,140 +430,71 @@ Examples
The simplest example of reading a CSV file::
import csv
- with open('some.csv', 'rb') as f:
+ with open('some.csv', newline='') as f:
reader = csv.reader(f)
for row in reader:
- print row
+ print(row)
Reading a file with an alternate format::
import csv
- with open('passwd', 'rb') as f:
+ with open('passwd', newline='') as f:
reader = csv.reader(f, delimiter=':', quoting=csv.QUOTE_NONE)
for row in reader:
- print row
+ print(row)
The corresponding simplest possible writing example is::
import csv
- with open('some.csv', 'wb') as f:
+ with open('some.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerows(someiterable)
+Since :func:`open` is used to open a CSV file for reading, the file
+will by default be decoded into unicode using the system default
+encoding (see :func:`locale.getpreferredencoding`). To decode a file
+using a different encoding, use the ``encoding`` argument of open::
+
+ import csv
+ with open('some.csv', newline='', encoding='utf-8') as f:
+ reader = csv.reader(f)
+ for row in reader:
+ print(row)
+
+The same applies to writing in something other than the system default
+encoding: specify the encoding argument when opening the output file.
+
Registering a new dialect::
import csv
csv.register_dialect('unixpwd', delimiter=':', quoting=csv.QUOTE_NONE)
- with open('passwd', 'rb') as f:
+ with open('passwd', newline='') as f:
reader = csv.reader(f, 'unixpwd')
A slightly more advanced use of the reader --- catching and reporting errors::
import csv, sys
filename = 'some.csv'
- with open(filename, 'rb') as f:
+ with open(filename, newline='') as f:
reader = csv.reader(f)
try:
for row in reader:
- print row
+ print(row)
except csv.Error as e:
- sys.exit('file %s, line %d: %s' % (filename, reader.line_num, e))
+ sys.exit('file {}, line {}: {}'.format(filename, reader.line_num, e))
And while the module doesn't directly support parsing strings, it can easily be
done::
import csv
for row in csv.reader(['one,two,three']):
- print row
+ print(row)
-The :mod:`csv` module doesn't directly support reading and writing Unicode, but
-it is 8-bit-clean save for some problems with ASCII NUL characters. So you can
-write functions or classes that handle the encoding and decoding for you as long
-as you avoid encodings like UTF-16 that use NULs. UTF-8 is recommended.
-
-:func:`unicode_csv_reader` below is a :term:`generator` that wraps :class:`csv.reader`
-to handle Unicode CSV data (a list of Unicode strings). :func:`utf_8_encoder`
-is a :term:`generator` that encodes the Unicode strings as UTF-8, one string (or row) at
-a time. The encoded strings are parsed by the CSV reader, and
-:func:`unicode_csv_reader` decodes the UTF-8-encoded cells back into Unicode::
-
- import csv
- def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
- # csv.py doesn't do Unicode; encode temporarily as UTF-8:
- csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
- dialect=dialect, **kwargs)
- for row in csv_reader:
- # decode UTF-8 back to Unicode, cell by cell:
- yield [unicode(cell, 'utf-8') for cell in row]
-
- def utf_8_encoder(unicode_csv_data):
- for line in unicode_csv_data:
- yield line.encode('utf-8')
-
-For all other encodings the following :class:`UnicodeReader` and
-:class:`UnicodeWriter` classes can be used. They take an additional *encoding*
-parameter in their constructor and make sure that the data passes the real
-reader or writer encoded as UTF-8::
-
- import csv, codecs, cStringIO
-
- class UTF8Recoder:
- """
- Iterator that reads an encoded stream and reencodes the input to UTF-8
- """
- def __init__(self, f, encoding):
- self.reader = codecs.getreader(encoding)(f)
-
- def __iter__(self):
- return self
-
- def next(self):
- return self.reader.next().encode("utf-8")
-
- class UnicodeReader:
- """
- A CSV reader which will iterate over lines in the CSV file "f",
- which is encoded in the given encoding.
- """
-
- def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
- f = UTF8Recoder(f, encoding)
- self.reader = csv.reader(f, dialect=dialect, **kwds)
-
- def next(self):
- row = self.reader.next()
- return [unicode(s, "utf-8") for s in row]
-
- def __iter__(self):
- return self
-
- class UnicodeWriter:
- """
- A CSV writer which will write rows to CSV file "f",
- which is encoded in the given encoding.
- """
-
- def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
- # Redirect output to a queue
- self.queue = cStringIO.StringIO()
- self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
- self.stream = f
- self.encoder = codecs.getincrementalencoder(encoding)()
-
- def writerow(self, row):
- self.writer.writerow([s.encode("utf-8") for s in row])
- # Fetch UTF-8 output from the queue ...
- data = self.queue.getvalue()
- data = data.decode("utf-8")
- # ... and reencode it into the target encoding
- data = self.encoder.encode(data)
- # write to the target stream
- self.stream.write(data)
- # empty queue
- self.queue.truncate(0)
-
- def writerows(self, rows):
- for row in rows:
- self.writerow(row)
+.. rubric:: Footnotes
+.. [1] If ``newline=''`` is not specified, newlines embedded inside quoted fields
+ will not be interpreted correctly, and on platforms that use ``\r\n`` linendings
+ on write an extra ``\r`` will be added. It should always be safe to specify
+ ``newline=''``, since the csv module does its own
+ (:term:`universal <universal newlines>`) newline handling.
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
index 67cbf45..3887ee1 100644
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -6,8 +6,6 @@
.. moduleauthor:: Thomas Heller <theller@python.net>
-.. versionadded:: 2.5
-
:mod:`ctypes` is a foreign function library for Python. It provides C compatible
data types, and allows calling functions in DLLs or shared libraries. It can be
used to wrap these libraries in pure Python.
@@ -49,9 +47,9 @@ library containing most standard C functions, and uses the cdecl calling
convention::
>>> from ctypes import *
- >>> print windll.kernel32 # doctest: +WINDOWS
+ >>> print(windll.kernel32) # doctest: +WINDOWS
<WinDLL 'kernel32', handle ... at ...>
- >>> print cdll.msvcrt # doctest: +WINDOWS
+ >>> print(cdll.msvcrt) # doctest: +WINDOWS
<CDLL 'msvcrt', handle ... at ...>
>>> libc = cdll.msvcrt # doctest: +WINDOWS
>>>
@@ -83,9 +81,9 @@ Functions are accessed as attributes of dll objects::
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
- >>> print windll.kernel32.GetModuleHandleA # doctest: +WINDOWS
+ >>> print(windll.kernel32.GetModuleHandleA) # doctest: +WINDOWS
<_FuncPtr object at 0x...>
- >>> print windll.kernel32.MyOwnFunction # doctest: +WINDOWS
+ >>> print(windll.kernel32.MyOwnFunction) # doctest: +WINDOWS
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "ctypes.py", line 239, in __getattr__
@@ -108,8 +106,7 @@ UNICODE is defined or not::
*windll* does not try to select one of them by magic, you must access the
version you need by specifying ``GetModuleHandleA`` or ``GetModuleHandleW``
-explicitly, and then call it with strings or unicode strings
-respectively.
+explicitly, and then call it with bytes or string objects respectively.
Sometimes, dlls export functions with names which aren't valid Python
identifiers, like ``"??2@YAPAXI@Z"``. In this case you have to use
@@ -146,9 +143,9 @@ handle.
This example calls both functions with a NULL pointer (``None`` should be used
as the NULL pointer)::
- >>> print libc.time(None) # doctest: +SKIP
+ >>> print(libc.time(None)) # doctest: +SKIP
1150640792
- >>> print hex(windll.kernel32.GetModuleHandleA(None)) # doctest: +WINDOWS
+ >>> print(hex(windll.kernel32.GetModuleHandleA(None))) # doctest: +WINDOWS
0x1d000000
>>>
@@ -176,7 +173,7 @@ The same exception is raised when you call an ``stdcall`` function with the
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>>
- >>> windll.msvcrt.printf("spam") # doctest: +WINDOWS
+ >>> windll.msvcrt.printf(b"spam") # doctest: +WINDOWS
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
@@ -198,13 +195,12 @@ argument values::
There are, however, enough ways to crash Python with :mod:`ctypes`, so you
should be careful anyway.
-``None``, integers, longs, byte strings and unicode strings are the only native
+``None``, integers, bytes objects and (unicode) strings are the only native
Python objects that can directly be used as parameters in these function calls.
-``None`` is passed as a C ``NULL`` pointer, byte strings and unicode strings are
-passed as pointer to the memory block that contains their data (:c:type:`char *`
-or :c:type:`wchar_t *`). Python integers and Python longs are passed as the
-platforms default C :c:type:`int` type, their value is masked to fit into the C
-type.
+``None`` is passed as a C ``NULL`` pointer, bytes objects and strings are passed
+as pointer to the memory block that contains their data (:c:type:`char *` or
+:c:type:`wchar_t *`). Python integers are passed as the platforms default C
+:c:type:`int` type, their value is masked to fit into the C type.
Before we move on calling functions with other parameter types, we have to learn
more about :mod:`ctypes` data types.
@@ -222,42 +218,47 @@ Fundamental data types
+======================+==========================================+============================+
| :class:`c_bool` | :c:type:`_Bool` | bool (1) |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_char` | :c:type:`char` | 1-character string |
+| :class:`c_char` | :c:type:`char` | 1-character bytes object |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_wchar` | :c:type:`wchar_t` | 1-character unicode string |
+| :class:`c_wchar` | :c:type:`wchar_t` | 1-character string |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_byte` | :c:type:`char` | int/long |
+| :class:`c_byte` | :c:type:`char` | int |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_ubyte` | :c:type:`unsigned char` | int/long |
+| :class:`c_ubyte` | :c:type:`unsigned char` | int |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_short` | :c:type:`short` | int/long |
+| :class:`c_short` | :c:type:`short` | int |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_ushort` | :c:type:`unsigned short` | int/long |
+| :class:`c_ushort` | :c:type:`unsigned short` | int |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_int` | :c:type:`int` | int/long |
+| :class:`c_int` | :c:type:`int` | int |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_uint` | :c:type:`unsigned int` | int/long |
+| :class:`c_uint` | :c:type:`unsigned int` | int |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_long` | :c:type:`long` | int/long |
+| :class:`c_long` | :c:type:`long` | int |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_ulong` | :c:type:`unsigned long` | int/long |
+| :class:`c_ulong` | :c:type:`unsigned long` | int |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_longlong` | :c:type:`__int64` or :c:type:`long long` | int/long |
+| :class:`c_longlong` | :c:type:`__int64` or :c:type:`long long` | int |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_ulonglong` | :c:type:`unsigned __int64` or | int/long |
+| :class:`c_ulonglong` | :c:type:`unsigned __int64` or | int |
| | :c:type:`unsigned long long` | |
+----------------------+------------------------------------------+----------------------------+
+| :class:`c_size_t` | :c:type:`size_t` | int |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_ssize_t` | :c:type:`ssize_t` or | int |
+| | :c:type:`Py_ssize_t` | |
++----------------------+------------------------------------------+----------------------------+
| :class:`c_float` | :c:type:`float` | float |
+----------------------+------------------------------------------+----------------------------+
| :class:`c_double` | :c:type:`double` | float |
+----------------------+------------------------------------------+----------------------------+
| :class:`c_longdouble`| :c:type:`long double` | float |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_char_p` | :c:type:`char *` (NUL terminated) | string or ``None`` |
+| :class:`c_char_p` | :c:type:`char *` (NUL terminated) | bytes object or ``None`` |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_wchar_p` | :c:type:`wchar_t *` (NUL terminated) | unicode or ``None`` |
+| :class:`c_wchar_p` | :c:type:`wchar_t *` (NUL terminated) | string or ``None`` |
+----------------------+------------------------------------------+----------------------------+
-| :class:`c_void_p` | :c:type:`void *` | int/long or ``None`` |
+| :class:`c_void_p` | :c:type:`void *` | int or ``None`` |
+----------------------+------------------------------------------+----------------------------+
(1)
@@ -268,8 +269,8 @@ the correct type and value::
>>> c_int()
c_long(0)
- >>> c_char_p("Hello, World")
- c_char_p('Hello, World')
+ >>> c_wchar_p("Hello, World")
+ c_wchar_p('Hello, World')
>>> c_ushort(-3)
c_ushort(65533)
>>>
@@ -277,28 +278,28 @@ the correct type and value::
Since these types are mutable, their value can also be changed afterwards::
>>> i = c_int(42)
- >>> print i
+ >>> print(i)
c_long(42)
- >>> print i.value
+ >>> print(i.value)
42
>>> i.value = -99
- >>> print i.value
+ >>> print(i.value)
-99
>>>
Assigning a new value to instances of the pointer types :class:`c_char_p`,
:class:`c_wchar_p`, and :class:`c_void_p` changes the *memory location* they
point to, *not the contents* of the memory block (of course not, because Python
-strings are immutable)::
+bytes objects are immutable)::
>>> s = "Hello, World"
- >>> c_s = c_char_p(s)
- >>> print c_s
- c_char_p('Hello, World')
+ >>> c_s = c_wchar_p(s)
+ >>> print(c_s)
+ c_wchar_p('Hello, World')
>>> c_s.value = "Hi, there"
- >>> print c_s
- c_char_p('Hi, there')
- >>> print s # first string is unchanged
+ >>> print(c_s)
+ c_wchar_p('Hi, there')
+ >>> print(s) # first object is unchanged
Hello, World
>>>
@@ -310,20 +311,20 @@ property; if you want to access it as NUL terminated string, use the ``value``
property::
>>> from ctypes import *
- >>> p = create_string_buffer(3) # create a 3 byte buffer, initialized to NUL bytes
- >>> print sizeof(p), repr(p.raw)
- 3 '\x00\x00\x00'
- >>> p = create_string_buffer("Hello") # create a buffer containing a NUL terminated string
- >>> print sizeof(p), repr(p.raw)
- 6 'Hello\x00'
- >>> print repr(p.value)
- 'Hello'
- >>> p = create_string_buffer("Hello", 10) # create a 10 byte buffer
- >>> print sizeof(p), repr(p.raw)
- 10 'Hello\x00\x00\x00\x00\x00'
- >>> p.value = "Hi"
- >>> print sizeof(p), repr(p.raw)
- 10 'Hi\x00lo\x00\x00\x00\x00\x00'
+ >>> p = create_string_buffer(3) # create a 3 byte buffer, initialized to NUL bytes
+ >>> print(sizeof(p), repr(p.raw))
+ 3 b'\x00\x00\x00'
+ >>> p = create_string_buffer(b"Hello") # create a buffer containing a NUL terminated string
+ >>> print(sizeof(p), repr(p.raw))
+ 6 b'Hello\x00'
+ >>> print(repr(p.value))
+ b'Hello'
+ >>> p = create_string_buffer(b"Hello", 10) # create a 10 byte buffer
+ >>> print(sizeof(p), repr(p.raw))
+ 10 b'Hello\x00\x00\x00\x00\x00'
+ >>> p.value = b"Hi"
+ >>> print(sizeof(p), repr(p.raw))
+ 10 b'Hi\x00lo\x00\x00\x00\x00\x00'
>>>
The :func:`create_string_buffer` function replaces the :func:`c_buffer` function
@@ -343,26 +344,26 @@ Note that printf prints to the real standard output channel, *not* to
from within *IDLE* or *PythonWin*::
>>> printf = libc.printf
- >>> printf("Hello, %s\n", "World!")
+ >>> printf(b"Hello, %s\n", b"World!")
Hello, World!
14
- >>> printf("Hello, %S\n", u"World!")
+ >>> printf(b"Hello, %S\n", "World!")
Hello, World!
14
- >>> printf("%d bottles of beer\n", 42)
+ >>> printf(b"%d bottles of beer\n", 42)
42 bottles of beer
19
- >>> printf("%f bottles of beer\n", 42.5)
+ >>> printf(b"%f bottles of beer\n", 42.5)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ArgumentError: argument 2: exceptions.TypeError: Don't know how to convert parameter 2
>>>
As has been mentioned before, all Python types except integers, strings, and
-unicode strings have to be wrapped in their corresponding :mod:`ctypes` type, so
+bytes objects have to be wrapped in their corresponding :mod:`ctypes` type, so
that they can be converted to the required C data type::
- >>> printf("An int %d, a double %f\n", 1234, c_double(3.14))
+ >>> printf(b"An int %d, a double %f\n", 1234, c_double(3.14))
An int 1234, a double 3.140000
31
>>>
@@ -376,21 +377,21 @@ Calling functions with your own custom data types
You can also customize :mod:`ctypes` argument conversion to allow instances of
your own classes be used as function arguments. :mod:`ctypes` looks for an
:attr:`_as_parameter_` attribute and uses this as the function argument. Of
-course, it must be one of integer, string, or unicode::
+course, it must be one of integer, string, or bytes::
- >>> class Bottles(object):
+ >>> class Bottles:
... def __init__(self, number):
... self._as_parameter_ = number
...
>>> bottles = Bottles(42)
- >>> printf("%d bottles of beer\n", bottles)
+ >>> printf(b"%d bottles of beer\n", bottles)
42 bottles of beer
19
>>>
If you don't want to store the instance's data in the :attr:`_as_parameter_`
-instance variable, you could define a :func:`property` which makes the data
-available.
+instance variable, you could define a :class:`property` which makes the
+attribute available on request.
.. _ctypes-specifying-required-argument-types:
@@ -407,7 +408,7 @@ different types of parameters depending on the format string, on the other hand
this is quite handy to experiment with this feature)::
>>> printf.argtypes = [c_char_p, c_char_p, c_int, c_double]
- >>> printf("String '%s', Int %d, Double %f\n", "Hi", 10, 2.2)
+ >>> printf(b"String '%s', Int %d, Double %f\n", b"Hi", 10, 2.2)
String 'Hi', Int 10, Double 2.200000
37
>>>
@@ -415,11 +416,11 @@ this is quite handy to experiment with this feature)::
Specifying a format protects against incompatible argument types (just as a
prototype for a C function), and tries to convert the arguments to valid types::
- >>> printf("%d %d %d", 1, 2, 3)
+ >>> printf(b"%d %d %d", 1, 2, 3)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ArgumentError: argument 2: exceptions.TypeError: wrong type
- >>> printf("%s %d %f\n", "X", 2, 3)
+ >>> printf(b"%s %d %f\n", b"X", 2, 3)
X 2 3.000000
13
>>>
@@ -431,7 +432,7 @@ the Python object passed to the function call, it should do a typecheck or
whatever is needed to make sure this object is acceptable, and then return the
object itself, its :attr:`_as_parameter_` attribute, or whatever you want to
pass as the C function argument in this case. Again, the result should be an
-integer, string, unicode, a :mod:`ctypes` instance, or an object with an
+integer, string, bytes, a :mod:`ctypes` instance, or an object with an
:attr:`_as_parameter_` attribute.
@@ -448,30 +449,30 @@ Here is a more advanced example, it uses the ``strchr`` function, which expects
a string pointer and a char, and returns a pointer to a string::
>>> strchr = libc.strchr
- >>> strchr("abcdef", ord("d")) # doctest: +SKIP
+ >>> strchr(b"abcdef", ord("d")) # doctest: +SKIP
8059983
- >>> strchr.restype = c_char_p # c_char_p is a pointer to a string
- >>> strchr("abcdef", ord("d"))
- 'def'
- >>> print strchr("abcdef", ord("x"))
+ >>> strchr.restype = c_char_p # c_char_p is a pointer to a string
+ >>> strchr(b"abcdef", ord("d"))
+ b'def'
+ >>> print(strchr(b"abcdef", ord("x")))
None
>>>
If you want to avoid the ``ord("x")`` calls above, you can set the
:attr:`argtypes` attribute, and the second argument will be converted from a
-single character Python string into a C char::
+single character Python bytes object into a C char::
>>> strchr.restype = c_char_p
>>> strchr.argtypes = [c_char_p, c_char]
- >>> strchr("abcdef", "d")
+ >>> strchr(b"abcdef", b"d")
'def'
- >>> strchr("abcdef", "def")
+ >>> strchr(b"abcdef", b"def")
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ArgumentError: argument 2: exceptions.TypeError: one character string expected
- >>> print strchr("abcdef", "x")
+ >>> print(strchr(b"abcdef", b"x"))
None
- >>> strchr("abcdef", "d")
+ >>> strchr(b"abcdef", b"d")
'def'
>>>
@@ -516,22 +517,22 @@ Sometimes a C api function expects a *pointer* to a data type as parameter,
probably to write into the corresponding location, or if the data is too large
to be passed by value. This is also known as *passing parameters by reference*.
-:mod:`ctypes` exports the :func:`byref` function which is used to pass
-parameters by reference. The same effect can be achieved with the
-:func:`pointer` function, although :func:`pointer` does a lot more work since it
-constructs a real pointer object, so it is faster to use :func:`byref` if you
-don't need the pointer object in Python itself::
+:mod:`ctypes` exports the :func:`byref` function which is used to pass parameters
+by reference. The same effect can be achieved with the :func:`pointer` function,
+although :func:`pointer` does a lot more work since it constructs a real pointer
+object, so it is faster to use :func:`byref` if you don't need the pointer
+object in Python itself::
>>> i = c_int()
>>> f = c_float()
- >>> s = create_string_buffer('\000' * 32)
- >>> print i.value, f.value, repr(s.value)
- 0 0.0 ''
- >>> libc.sscanf("1 3.14 Hello", "%d %f %s",
+ >>> s = create_string_buffer(b'\000' * 32)
+ >>> print(i.value, f.value, repr(s.value))
+ 0 0.0 b''
+ >>> libc.sscanf(b"1 3.14 Hello", b"%d %f %s",
... byref(i), byref(f), s)
3
- >>> print i.value, f.value, repr(s.value)
- 1 3.1400001049 'Hello'
+ >>> print(i.value, f.value, repr(s.value))
+ 1 3.1400001049 b'Hello'
>>>
@@ -557,10 +558,10 @@ Here is a simple example of a POINT structure, which contains two integers named
... ("y", c_int)]
...
>>> point = POINT(10, 20)
- >>> print point.x, point.y
+ >>> print(point.x, point.y)
10 20
>>> point = POINT(y=5)
- >>> print point.x, point.y
+ >>> print(point.x, point.y)
0 5
>>> POINT(1, 2, 3)
Traceback (most recent call last):
@@ -579,9 +580,9 @@ Here is a RECT structure which contains two POINTs named *upperleft* and
... ("lowerright", POINT)]
...
>>> rc = RECT(point)
- >>> print rc.upperleft.x, rc.upperleft.y
+ >>> print(rc.upperleft.x, rc.upperleft.y)
0 5
- >>> print rc.lowerright.x, rc.lowerright.y
+ >>> print(rc.lowerright.x, rc.lowerright.y)
0 0
>>>
@@ -593,9 +594,9 @@ Nested structures can also be initialized in the constructor in several ways::
Field :term:`descriptor`\s can be retrieved from the *class*, they are useful
for debugging because they can provide useful information::
- >>> print POINT.x
+ >>> print(POINT.x)
<Field type=c_long, ofs=0, size=4>
- >>> print POINT.y
+ >>> print(POINT.y)
<Field type=c_long, ofs=4, size=4>
>>>
@@ -631,9 +632,9 @@ item in the :attr:`_fields_` tuples::
... _fields_ = [("first_16", c_int, 16),
... ("second_16", c_int, 16)]
...
- >>> print Int.first_16
+ >>> print(Int.first_16)
<Field type=c_long, ofs=0:0, bits=16>
- >>> print Int.second_16
+ >>> print(Int.second_16)
<Field type=c_long, ofs=0:16, bits=16>
>>>
@@ -662,7 +663,7 @@ POINTs among other stuff::
... ("b", c_float),
... ("point_array", POINT * 4)]
>>>
- >>> print len(MyStruct().point_array)
+ >>> print(len(MyStruct().point_array))
4
>>>
@@ -670,7 +671,7 @@ Instances are created in the usual way, by calling the class::
arr = TenPointsArrayType()
for pt in arr:
- print pt.x, pt.y
+ print(pt.x, pt.y)
The above code print a series of ``0 0`` lines, because the array contents is
initialized to zeros.
@@ -680,9 +681,9 @@ Initializers of the correct type can also be specified::
>>> from ctypes import *
>>> TenIntegers = c_int * 10
>>> ii = TenIntegers(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
- >>> print ii
+ >>> print(ii)
<c_long_Array_10 object at 0x...>
- >>> for i in ii: print i,
+ >>> for i in ii: print(i, end=" ")
...
1 2 3 4 5 6 7 8 9 10
>>>
@@ -737,10 +738,10 @@ Pointer instances can also be indexed with integers::
Assigning to an integer index changes the pointed to value::
- >>> print i
+ >>> print(i)
c_long(99)
>>> pi[0] = 22
- >>> print i
+ >>> print(i)
c_long(22)
>>>
@@ -751,9 +752,9 @@ and you *know* that the pointer actually points to an array instead of a single
item.
Behind the scenes, the :func:`pointer` function does more than simply create
-pointer instances, it has to create pointer *types* first. This is done with
-the :func:`POINTER` function, which accepts any :mod:`ctypes` type, and returns
-a new type::
+pointer instances, it has to create pointer *types* first. This is done with the
+:func:`POINTER` function, which accepts any :mod:`ctypes` type, and returns a
+new type::
>>> PI = POINTER(c_int)
>>> PI
@@ -770,7 +771,7 @@ Calling the pointer type without an argument creates a ``NULL`` pointer.
``NULL`` pointers have a ``False`` boolean value::
>>> null_ptr = POINTER(c_int)()
- >>> print bool(null_ptr)
+ >>> print(bool(null_ptr))
False
>>>
@@ -809,7 +810,7 @@ pointer types. So, for ``POINTER(c_int)``, ctypes accepts an array of c_int::
>>> bar.values = (c_int * 3)(1, 2, 3)
>>> bar.count = 3
>>> for i in range(bar.count):
- ... print bar.values[i]
+ ... print(bar.values[i])
...
1
2
@@ -853,7 +854,7 @@ structure::
>>> bar = Bar()
>>> bar.values = cast((c_byte * 4)(), POINTER(c_int))
- >>> print bar.values[0]
+ >>> print(bar.values[0])
0
>>>
@@ -910,7 +911,7 @@ other, and finally follow the pointer chain a few times::
>>> c2.next = pointer(c1)
>>> p = c1
>>> for i in range(8):
- ... print p.name,
+ ... print(p.name, end=" ")
... p = p.next[0]
...
foo bar foo bar foo bar foo bar
@@ -938,9 +939,9 @@ Both of these factory functions are called with the result type as first
argument, and the callback functions expected argument types as the remaining
arguments.
-I will present an example here which uses the standard C library's :func:`qsort`
-function, this is used to sort items with the help of a callback function.
-:func:`qsort` will be used to sort an array of integers::
+I will present an example here which uses the standard C library's
+:c:func:`qsort` function, this is used to sort items with the help of a callback
+function. :c:func:`qsort` will be used to sort an array of integers::
>>> IntArray5 = c_int * 5
>>> ia = IntArray5(5, 1, 7, 33, 99)
@@ -964,7 +965,7 @@ For the first implementation of the callback function, we simply print the
arguments we get, and return 0 (incremental development ;-)::
>>> def py_cmp_func(a, b):
- ... print "py_cmp_func", a, b
+ ... print("py_cmp_func", a, b)
... return 0
...
>>>
@@ -992,7 +993,7 @@ And we're ready to go::
We know how to access the contents of a pointer, so lets redefine our callback::
>>> def py_cmp_func(a, b):
- ... print "py_cmp_func", a[0], b[0]
+ ... print("py_cmp_func", a[0], b[0])
... return 0
...
>>> cmp_func = CMPFUNC(py_cmp_func)
@@ -1028,7 +1029,7 @@ Ah, we're nearly done! The last step is to actually compare the two items and
return a useful result::
>>> def py_cmp_func(a, b):
- ... print "py_cmp_func", a[0], b[0]
+ ... print("py_cmp_func", a[0], b[0])
... return a[0] - b[0]
...
>>>
@@ -1063,7 +1064,7 @@ more comparisons than the linux version!
As we can easily check, our array is sorted now::
- >>> for i in ia: print i,
+ >>> for i in ia: print(i, end=" ")
...
1 5 7 33 99
>>>
@@ -1081,8 +1082,8 @@ Accessing values exported from dlls
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Some shared libraries not only export functions, they also export variables. An
-example in the Python library itself is the ``Py_OptimizeFlag``, an integer set
-to 0, 1, or 2, depending on the :option:`-O` or :option:`-OO` flag given on
+example in the Python library itself is the :c:data:`Py_OptimizeFlag`, an integer
+set to 0, 1, or 2, depending on the :option:`-O` or :option:`-OO` flag given on
startup.
:mod:`ctypes` can access values like this with the :meth:`in_dll` class methods of
@@ -1090,7 +1091,7 @@ the type. *pythonapi* is a predefined symbol giving access to the Python C
api::
>>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag")
- >>> print opt_flag
+ >>> print(opt_flag)
c_long(0)
>>>
@@ -1099,13 +1100,14 @@ have printed ``c_long(1)``, or ``c_long(2)`` if :option:`-OO` would have been
specified.
An extended example which also demonstrates the use of pointers accesses the
-``PyImport_FrozenModules`` pointer exported by Python.
+:c:data:`PyImport_FrozenModules` pointer exported by Python.
+
+Quoting the docs for that value:
-Quoting the Python docs: *This pointer is initialized to point to an array of
-"struct _frozen" records, terminated by one whose members are all NULL or zero.
-When a frozen module is imported, it is searched in this table. Third-party code
-could play tricks with this to provide a dynamically created collection of
-frozen modules.*
+ This pointer is initialized to point to an array of :c:type:`struct _frozen`
+ records, terminated by one whose members are all *NULL* or zero. When a frozen
+ module is imported, it is searched in this table. Third-party code could play
+ tricks with this to provide a dynamically created collection of frozen modules.
So manipulating this pointer could even prove useful. To restrict the example
size, we show only how this table can be read with :mod:`ctypes`::
@@ -1119,8 +1121,8 @@ size, we show only how this table can be read with :mod:`ctypes`::
...
>>>
-We have defined the ``struct _frozen`` data type, so we can get the pointer to
-the table::
+We have defined the :c:type:`struct _frozen` data type, so we can get the pointer
+to the table::
>>> FrozenTable = POINTER(struct_frozen)
>>> table = FrozenTable.in_dll(pythonapi, "PyImport_FrozenModules")
@@ -1133,7 +1135,7 @@ access violation or whatever, so it's better to break out of the loop when we
hit the NULL entry::
>>> for item in table:
- ... print item.name, item.size
+ ... print(item.name, item.size)
... if item.name is None:
... break
...
@@ -1153,8 +1155,8 @@ testing. Try it out with ``import __hello__`` for example.
Surprises
^^^^^^^^^
-There are some edge cases in :mod:`ctypes` where you might expect something
-other than what actually happens.
+There are some edges in :mod:`ctypes` where you might expect something other
+than what actually happens.
Consider the following example::
@@ -1168,11 +1170,11 @@ Consider the following example::
>>> p1 = POINT(1, 2)
>>> p2 = POINT(3, 4)
>>> rc = RECT(p1, p2)
- >>> print rc.a.x, rc.a.y, rc.b.x, rc.b.y
+ >>> print(rc.a.x, rc.a.y, rc.b.x, rc.b.y)
1 2 3 4
>>> # now swap the two points
>>> rc.a, rc.b = rc.b, rc.a
- >>> print rc.a.x, rc.a.y, rc.b.x, rc.b.y
+ >>> print(rc.a.x, rc.a.y, rc.b.x, rc.b.y)
3 4 3 4
>>>
@@ -1225,7 +1227,7 @@ made smaller than the natural memory block specified by the objects type, a
:exc:`ValueError` is raised if this is tried::
>>> short_array = (c_short * 4)()
- >>> print sizeof(short_array)
+ >>> print(sizeof(short_array))
8
>>> resize(short_array, 4)
Traceback (most recent call last):
@@ -1274,8 +1276,8 @@ similar to what the compiler does (on platforms with several versions of a
shared library the most recent should be loaded), while the ctypes library
loaders act like when a program is run, and call the runtime loader directly.
-The :mod:`ctypes.util` module provides a function which can help to determine the
-library to load.
+The :mod:`ctypes.util` module provides a function which can help to determine
+the library to load.
.. data:: find_library(name)
@@ -1402,9 +1404,6 @@ the Windows error code which is managed by the :func:`GetLastError` and
:func:`ctypes.set_last_error` are used to request and change the ctypes private
copy of the windows error code.
-.. versionadded:: 2.6
- The *use_last_error* and *use_errno* optional parameters were added.
-
.. data:: RTLD_GLOBAL
:noindex:
@@ -1459,14 +1458,13 @@ loader instance.
accessing it as attribute of a library loader instance. The result is cached,
so repeated attribute accesses return the same library each time.
-
.. method:: LoadLibrary(name)
Load a shared library into the process and return it. This method always
returns a new instance of the library.
-These prefabricated library loaders are available:
+These prefabricated library loaders are available:
.. data:: cdll
:noindex:
@@ -1491,10 +1489,10 @@ These prefabricated library loaders are available:
Creates :class:`PyDLL` instances.
+
For accessing the C Python api directly, a ready-to-use Python shared library
object is available:
-
.. data:: pythonapi
:noindex:
@@ -1526,7 +1524,6 @@ They are instances of a private class:
This behavior can be customized by assigning to special attributes of the
foreign function object.
-
.. attribute:: restype
Assign a ctypes type to specify the result type of the foreign function.
@@ -1539,7 +1536,6 @@ They are instances of a private class:
post processing or error checking use a ctypes data type as
:attr:`restype` and assign a callable to the :attr:`errcheck` attribute.
-
.. attribute:: argtypes
Assign a tuple of ctypes types to specify the argument types that the
@@ -1552,15 +1548,14 @@ They are instances of a private class:
:meth:`from_param` class method of the items in the :attr:`argtypes`
tuple, this method allows to adapt the actual argument to an object that
the foreign function accepts. For example, a :class:`c_char_p` item in
- the :attr:`argtypes` tuple will convert a unicode string passed as
- argument into an byte string using ctypes conversion rules.
+ the :attr:`argtypes` tuple will convert a string passed as argument into
+ a bytes object using ctypes conversion rules.
New: It is now possible to put items in argtypes which are not ctypes
types, but each item must have a :meth:`from_param` method which returns a
value usable as argument (integer, string, ctypes instance). This allows
to define adapters that can adapt custom objects as function parameters.
-
.. attribute:: errcheck
Assign a Python function or another callable to this attribute. The
@@ -1568,6 +1563,7 @@ They are instances of a private class:
.. function:: callable(result, func, arguments)
:noindex:
+ :module:
*result* is what the foreign function returns, as specified by the
:attr:`restype` attribute.
@@ -1585,7 +1581,7 @@ They are instances of a private class:
and raise an exception if the foreign function call failed.
-.. exception:: ArgumentError()
+.. exception:: ArgumentError
This exception is raised when a foreign function call cannot convert one of the
passed arguments.
@@ -1612,9 +1608,6 @@ type and the argument types of the function.
and after the call; *use_last_error* does the same for the Windows error
code.
- .. versionchanged:: 2.6
- The optional *use_errno* and *use_last_error* parameters were added.
-
.. function:: WINFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False)
@@ -1652,24 +1645,24 @@ different ways, depending on the type and number of the parameters in the call:
:noindex:
:module:
- Returns a foreign function exported by a shared library. *func_spec* must be a
- 2-tuple ``(name_or_ordinal, library)``. The first item is the name of the
- exported function as string, or the ordinal of the exported function as small
- integer. The second item is the shared library instance.
+ Returns a foreign function exported by a shared library. *func_spec* must
+ be a 2-tuple ``(name_or_ordinal, library)``. The first item is the name of
+ the exported function as string, or the ordinal of the exported function
+ as small integer. The second item is the shared library instance.
.. function:: prototype(vtbl_index, name[, paramflags[, iid]])
:noindex:
:module:
- Returns a foreign function that will call a COM method. *vtbl_index* is the
- index into the virtual function table, a small non-negative integer. *name* is
- name of the COM method. *iid* is an optional pointer to the interface identifier
- which is used in extended error reporting.
+ Returns a foreign function that will call a COM method. *vtbl_index* is
+ the index into the virtual function table, a small non-negative
+ integer. *name* is name of the COM method. *iid* is an optional pointer to
+ the interface identifier which is used in extended error reporting.
- COM methods use a special calling convention: They require a pointer to the COM
- interface as first argument, in addition to those parameters that are specified
- in the :attr:`argtypes` tuple.
+ COM methods use a special calling convention: They require a pointer to
+ the COM interface as first argument, in addition to those parameters that
+ are specified in the :attr:`argtypes` tuple.
The optional *paramflags* parameter creates foreign function wrappers with much
more functionality than the features described above.
@@ -1780,7 +1773,6 @@ instead, the normal processing will no longer take place::
Utility functions
^^^^^^^^^^^^^^^^^
-
.. function:: addressof(obj)
Returns the address of the memory buffer as integer. *obj* must be an
@@ -1803,55 +1795,47 @@ Utility functions
(((char *)&obj) + offset)
- The returned object can only be used as a foreign function call
- parameter. It behaves similar to ``pointer(obj)``, but the
- construction is a lot faster.
-
- .. versionadded:: 2.6
- The *offset* optional argument was added.
+ The returned object can only be used as a foreign function call parameter.
+ It behaves similar to ``pointer(obj)``, but the construction is a lot faster.
.. function:: cast(obj, type)
- This function is similar to the cast operator in C. It returns a new
- instance of *type* which points to the same memory block as *obj*. *type*
- must be a pointer type, and *obj* must be an object that can be interpreted
- as a pointer.
+ This function is similar to the cast operator in C. It returns a new instance
+ of *type* which points to the same memory block as *obj*. *type* must be a
+ pointer type, and *obj* must be an object that can be interpreted as a
+ pointer.
-.. function:: create_string_buffer(init_or_size[, size])
+.. function:: create_string_buffer(init_or_size, size=None)
This function creates a mutable character buffer. The returned object is a
ctypes array of :class:`c_char`.
*init_or_size* must be an integer which specifies the size of the array, or a
- string which will be used to initialize the array items.
+ bytes object which will be used to initialize the array items.
- If a string is specified as first argument, the buffer is made one item larger
- than the length of the string so that the last element in the array is a NUL
+ If a bytes object is specified as first argument, the buffer is made one item
+ larger than its length so that the last element in the array is a NUL
termination character. An integer can be passed as second argument which allows
- to specify the size of the array if the length of the string should not be used.
+ to specify the size of the array if the length of the bytes should not be used.
- If the first parameter is a unicode string, it is converted into an 8-bit string
- according to ctypes conversion rules.
-.. function:: create_unicode_buffer(init_or_size[, size])
+.. function:: create_unicode_buffer(init_or_size, size=None)
This function creates a mutable unicode character buffer. The returned object is
a ctypes array of :class:`c_wchar`.
*init_or_size* must be an integer which specifies the size of the array, or a
- unicode string which will be used to initialize the array items.
+ string which will be used to initialize the array items.
- If a unicode string is specified as first argument, the buffer is made one item
+ If a string is specified as first argument, the buffer is made one item
larger than the length of the string so that the last element in the array is a
NUL termination character. An integer can be passed as second argument which
allows to specify the size of the array if the length of the string should not
be used.
- If the first parameter is a 8-bit string, it is converted into an unicode string
- according to ctypes conversion rules.
.. function:: DllCanUnloadNow()
@@ -1878,10 +1862,6 @@ Utility functions
The exact functionality is system dependent.
- .. versionchanged:: 2.6
- Windows only: ``find_library("m")`` or ``find_library("c")`` return the
- result of a call to ``find_msvcrt()``.
-
.. function:: find_msvcrt()
:module: ctypes.util
@@ -1894,8 +1874,6 @@ Utility functions
with a call to the ``free(void *)``, it is important that you use the
function in the same library that allocated the memory.
- .. versionadded:: 2.6
-
.. function:: FormatError([code])
@@ -1915,15 +1893,11 @@ Utility functions
Returns the current value of the ctypes-private copy of the system
:data:`errno` variable in the calling thread.
- .. versionadded:: 2.6
-
.. function:: get_last_error()
Windows only: returns the current value of the ctypes-private copy of the system
:data:`LastError` variable in the calling thread.
- .. versionadded:: 2.6
-
.. function:: memmove(dst, src, count)
Same as the standard C memmove library function: copies *count* bytes from
@@ -1962,25 +1936,11 @@ Utility functions
but it is possible to enlarge the buffer.
-.. function:: set_conversion_mode(encoding, errors)
-
- This function sets the rules that ctypes objects use when converting between
- 8-bit strings and unicode strings. *encoding* must be a string specifying an
- encoding, like ``'utf-8'`` or ``'mbcs'``, *errors* must be a string
- specifying the error handling on encoding/decoding errors. Examples of
- possible values are ``"strict"``, ``"replace"``, or ``"ignore"``.
-
- :func:`set_conversion_mode` returns a 2-tuple containing the previous
- conversion rules. On windows, the initial conversion rules are ``('mbcs',
- 'ignore')``, on other systems ``('ascii', 'strict')``.
-
-
.. function:: set_errno(value)
Set the current value of the ctypes-private copy of the system :data:`errno`
variable in the calling thread to *value* and return the previous value.
- .. versionadded:: 2.6
.. function:: set_last_error(value)
@@ -1989,7 +1949,6 @@ Utility functions
:data:`LastError` variable in the calling thread to *value* and return the
previous value.
- .. versionadded:: 2.6
.. function:: sizeof(obj_or_type)
@@ -1998,27 +1957,27 @@ Utility functions
same as the C ``sizeof()`` function.
-.. function:: string_at(address[, size])
+.. function:: string_at(address, size=-1)
- This function returns the string starting at memory address *address*. If size
- is specified, it is used as size, otherwise the string is assumed to be
- zero-terminated.
+ This function returns the C string starting at memory address *address* as a bytes
+ object. If size is specified, it is used as size, otherwise the string is assumed
+ to be zero-terminated.
.. function:: WinError(code=None, descr=None)
- Windows only: this function is probably the worst-named thing in ctypes. It
+ Windows only: this function is probably the worst-named thing in ctypes. It
creates an instance of WindowsError. If *code* is not specified,
- ``GetLastError`` is called to determine the error code. If ``descr`` is not
+ ``GetLastError`` is called to determine the error code. If *descr* is not
specified, :func:`FormatError` is called to get a textual description of the
error.
-.. function:: wstring_at(address[, size])
+.. function:: wstring_at(address, size=-1)
This function returns the wide character string starting at memory address
- *address* as unicode string. If *size* is specified, it is used as the
- number of characters of the string, otherwise the string is assumed to be
+ *address* as a string. If *size* is specified, it is used as the number of
+ characters of the string, otherwise the string is assumed to be
zero-terminated.
@@ -2033,14 +1992,13 @@ Data types
This non-public class is the common base class of all ctypes data types.
Among other things, all ctypes type instances contain a memory block that
hold C compatible data; the address of the memory block is returned by the
- :func:`addressof` helper function. Another instance variable is exposed as
+ :func:`addressof` helper function. Another instance variable is exposed as
:attr:`_objects`; this contains other Python objects that need to be kept
alive in case the memory block contains pointers.
Common methods of ctypes data types, these are all class methods (to be
exact, they are methods of the :term:`metaclass`):
-
.. method:: _CData.from_buffer(source[, offset])
This method returns a ctypes instance that shares the buffer of the
@@ -2049,8 +2007,6 @@ Data types
source buffer in bytes; the default is zero. If the source buffer is not
large enough a :exc:`ValueError` is raised.
- .. versionadded:: 2.6
-
.. method:: _CData.from_buffer_copy(source[, offset])
@@ -2060,15 +2016,11 @@ Data types
is zero. If the source buffer is not large enough a :exc:`ValueError` is
raised.
- .. versionadded:: 2.6
-
-
.. method:: from_address(address)
This method returns a ctypes type instance using the memory specified by
*address* which must be an integer.
-
.. method:: from_param(obj)
This method adapts *obj* to a ctypes type. It is called with the actual
@@ -2080,14 +2032,12 @@ Data types
that normally returns *obj* if that is an instance of the type. Some
types accept other objects as well.
-
.. method:: in_dll(library, name)
This method returns a ctypes type instance exported by a shared
library. *name* is the name of the symbol that exports the data, *library*
is the loaded shared library.
-
Common instance variables of ctypes data types:
.. attribute:: _b_base_
@@ -2097,13 +2047,11 @@ Data types
:attr:`_b_base_` read-only member is the root ctypes object that owns the
memory block.
-
.. attribute:: _b_needsfree_
This read-only variable is true when the ctypes data instance has
allocated the memory block itself, false otherwise.
-
.. attribute:: _objects
This member is either ``None`` or a dictionary containing Python objects
@@ -2117,17 +2065,13 @@ Data types
Fundamental data types
^^^^^^^^^^^^^^^^^^^^^^
-
.. class:: _SimpleCData
This non-public class is the base class of all fundamental ctypes data
types. It is mentioned here because it contains the common attributes of the
fundamental ctypes data types. :class:`_SimpleCData` is a subclass of
- :class:`_CData`, so it inherits their methods and attributes.
-
- .. versionchanged:: 2.6
- ctypes data types that are not and do not contain pointers can now be
- pickled.
+ :class:`_CData`, so it inherits their methods and attributes. ctypes data
+ types that are not and do not contain pointers can now be pickled.
Instances have a single attribute:
@@ -2135,8 +2079,8 @@ Fundamental data types
This attribute contains the actual value of the instance. For integer and
pointer types, it is an integer, for character types, it is a single
- character string, for character pointer types it is a Python string or
- unicode string.
+ character bytes object or string, for character pointer types it is a
+ Python bytes object or string.
When the ``value`` attribute is retrieved from a ctypes instance, usually
a new object is returned each time. :mod:`ctypes` does *not* implement
@@ -2147,8 +2091,10 @@ Fundamental data types
Fundamental data types, when returned as foreign function call results, or, for
example, by retrieving structure field members or array items, are transparently
converted to native Python types. In other words, if a foreign function has a
-:attr:`restype` of :class:`c_char_p`, you will always receive a Python string,
-*not* a :class:`c_char_p` instance.
+:attr:`restype` of :class:`c_char_p`, you will always receive a Python bytes
+object, *not* a :class:`c_char_p` instance.
+
+.. XXX above is false, it actually returns a Unicode string
Subclasses of fundamental data types do *not* inherit this behavior. So, if a
foreign functions :attr:`restype` is a subclass of :class:`c_void_p`, you will
@@ -2176,7 +2122,7 @@ These are the fundamental ctypes data types:
Represents the C :c:type:`char *` datatype when it points to a zero-terminated
string. For a general character pointer that may also point to binary data,
``POINTER(c_char)`` must be used. The constructor accepts an integer
- address, or a string.
+ address, or a bytes object.
.. class:: c_double
@@ -2191,8 +2137,6 @@ These are the fundamental ctypes data types:
optional float initializer. On platforms where ``sizeof(long double) ==
sizeof(double)`` it is an alias to :class:`c_double`.
- .. versionadded:: 2.6
-
.. class:: c_float
Represents the C :c:type:`float` datatype. The constructor accepts an
@@ -2257,7 +2201,7 @@ These are the fundamental ctypes data types:
Represents the C :c:type:`ssize_t` datatype.
- .. versionadded:: 2.7
+ .. versionadded:: 3.2
.. class:: c_ubyte
@@ -2342,8 +2286,6 @@ These are the fundamental ctypes data types:
C99). Its value can be True or False, and the constructor accepts any object
that has a truth value.
- .. versionadded:: 2.6
-
.. class:: HRESULT
@@ -2419,7 +2361,7 @@ other data types containing pointer type fields.
]
The :attr:`_fields_` class variable must, however, be defined before the
- type is first used (an instance is created, ``sizeof()`` is called on it,
+ type is first used (an instance is created, :func:`sizeof` is called on it,
and so on). Later assignments to the :attr:`_fields_` class variable will
raise an AttributeError.
diff --git a/Doc/library/curses.ascii.rst b/Doc/library/curses.ascii.rst
index 0a45c2a..6bc1fb9 100644
--- a/Doc/library/curses.ascii.rst
+++ b/Doc/library/curses.ascii.rst
@@ -1,4 +1,3 @@
-
:mod:`curses.ascii` --- Utilities for ASCII characters
======================================================
@@ -8,8 +7,6 @@
.. sectionauthor:: Eric S. Raymond <esr@thyrsus.com>
-.. versionadded:: 1.6
-
The :mod:`curses.ascii` module supplies name constants for ASCII characters and
functions to test membership in various ASCII character classes. The constants
supplied are names for control characters as follows:
diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst
index a3c098b..11ab5d0 100644
--- a/Doc/library/curses.rst
+++ b/Doc/library/curses.rst
@@ -2,15 +2,12 @@
===============================================================
.. module:: curses
- :synopsis: An interface to the curses library, providing portable terminal
- handling.
+ :synopsis: An interface to the curses library, providing portable
+ terminal handling.
:platform: Unix
.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
.. sectionauthor:: Eric Raymond <esr@thyrsus.com>
-.. versionchanged:: 1.6
- Added support for the ``ncurses`` library and converted to a package.
-
The :mod:`curses` module provides an interface to the curses library, the
de-facto standard for portable advanced terminal handling.
@@ -48,7 +45,7 @@ Linux and the BSD variants of Unix.
Tutorial material on using curses with Python, by Andrew Kuchling and Eric
Raymond.
- The :file:`Demo/curses/` directory in the Python source distribution contains
+ The :file:`Tools/demo/` directory in the Python source distribution contains
some example programs using the curses bindings provided by this module.
@@ -566,11 +563,11 @@ The module :mod:`curses` defines the following functions:
capability, or is canceled or absent from the terminal description.
-.. function:: tparm(str[,...])
+.. function:: tparm(str[, ...])
Instantiate the string *str* with the supplied parameters, where *str* should
be a parameterized string obtained from the terminfo database. E.g.
- ``tparm(tigetstr("cup"), 5, 3)`` could result in ``'\033[6;4H'``, the exact
+ ``tparm(tigetstr("cup"), 5, 3)`` could result in ``b'\033[6;4H'``, the exact
result depending on terminal type.
@@ -1610,8 +1607,6 @@ The following table lists the predefined colors:
.. sectionauthor:: Eric Raymond <esr@thyrsus.com>
-.. versionadded:: 1.6
-
The :mod:`curses.textpad` module provides a :class:`Textbox` class that handles
elementary text editing in a curses window, supporting a set of keybindings
resembling those of Emacs (thus, also of Netscape Navigator, BBedit 6.x,
@@ -1737,4 +1732,3 @@ You can instantiate a :class:`Textbox` object as follows:
cursor motion that would land the cursor on a trailing blank goes to the
end of that line instead, and trailing blanks are stripped when the window
contents are gathered.
-
diff --git a/Doc/library/custominterp.rst b/Doc/library/custominterp.rst
index 2a9f0a4..5eeced2 100644
--- a/Doc/library/custominterp.rst
+++ b/Doc/library/custominterp.rst
@@ -1,4 +1,3 @@
-
.. _custominterp:
**************************
diff --git a/Doc/library/datatypes.rst b/Doc/library/datatypes.rst
index 4ebaa6c..6b4a71a 100644
--- a/Doc/library/datatypes.rst
+++ b/Doc/library/datatypes.rst
@@ -1,4 +1,3 @@
-
.. _datatypes:
**********
@@ -10,10 +9,9 @@ types such as dates and times, fixed-type arrays, heap queues, synchronized
queues, and sets.
Python also provides some built-in data types, in particular,
-:class:`dict`, :class:`list`, :class:`set` (which along with
-:class:`frozenset`, replaces the deprecated :mod:`sets` module), and
-:class:`tuple`. The :class:`str` class can be used to handle binary data
-and 8-bit text, and the :class:`unicode` class to handle Unicode text.
+:class:`dict`, :class:`list`, :class:`set` and :class:`frozenset`, and
+:class:`tuple`. The :class:`str` class is used to hold
+Unicode strings, and the :class:`bytes` class is used to hold binary data.
The following modules are documented in this chapter:
@@ -26,14 +24,10 @@ The following modules are documented in this chapter:
heapq.rst
bisect.rst
array.rst
- sets.rst
sched.rst
- mutex.rst
queue.rst
weakref.rst
- userdict.rst
types.rst
- new.rst
copy.rst
pprint.rst
- repr.rst
+ reprlib.rst
diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst
index b6a2070..8bdd961 100644
--- a/Doc/library/datetime.rst
+++ b/Doc/library/datetime.rst
@@ -9,8 +9,6 @@
.. XXX what order should the types be discussed in?
-.. versionadded:: 2.3
-
The :mod:`datetime` module supplies classes for manipulating dates and times in
both simple and complex ways. While date and time arithmetic is supported, the
focus of the implementation is on efficient attribute extraction for output
@@ -28,20 +26,22 @@ interpretation [#]_.
A naive object does not contain enough information to unambiguously locate
itself relative to other date/time objects. Whether a naive object represents
Coordinated Universal Time (UTC), local time, or time in some other timezone is
-purely up to the program, just like it's up to the program whether a particular
-number represents metres, miles, or mass. Naive objects are easy to understand
-and to work with, at the cost of ignoring some aspects of reality.
+purely up to the program, just like it is up to the program whether a
+particular number represents metres, miles, or mass. Naive objects are easy to
+understand and to work with, at the cost of ignoring some aspects of reality.
For applications requiring aware objects, :class:`.datetime` and :class:`.time`
objects have an optional time zone information attribute, :attr:`tzinfo`, that
can be set to an instance of a subclass of the abstract :class:`tzinfo` class.
These :class:`tzinfo` objects capture information about the offset from UTC
time, the time zone name, and whether Daylight Saving Time is in effect. Note
-that no concrete :class:`tzinfo` classes are supplied by the :mod:`datetime`
-module. Supporting timezones at whatever level of detail is required is up to
-the application. The rules for time adjustment across the world are more
-political than rational, and there is no standard suitable for every
-application.
+that only one concrete :class:`tzinfo` class, the :class:`timezone` class, is
+supplied by the :mod:`datetime` module. The :class:`timezone` class can
+represent simple timezones with fixed offset from UTC, such as UTC itself or
+North American EST and EDT timezones. Supporting timezones at deeper levels of
+detail is up to the application. The rules for time adjustment across the
+world are more political than rational, change frequently, and there is no
+standard suitable for every application aside from UTC.
The :mod:`datetime` module exports the following constants:
@@ -108,6 +108,14 @@ Available Types
time adjustment (for example, to account for time zone and/or daylight saving
time).
+.. class:: timezone
+
+ A class that implements the :class:`tzinfo` abstract base class as a
+ fixed offset from the UTC.
+
+ .. versionadded:: 3.2
+
+
Objects of these types are immutable.
Objects of the :class:`date` type are always naive.
@@ -128,6 +136,7 @@ Subclass relationships::
object
timedelta
tzinfo
+ timezone
time
date
datetime
@@ -141,9 +150,9 @@ Subclass relationships::
A :class:`timedelta` object represents a duration, the difference between two
dates or times.
-.. class:: timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])
+.. class:: timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
- All arguments are optional and default to ``0``. Arguments may be ints, longs,
+ All arguments are optional and default to ``0``. Arguments may be integers
or floats, and may be positive or negative.
Only *days*, *seconds* and *microseconds* are stored internally. Arguments are
@@ -225,15 +234,35 @@ Supported operations:
| | == *t2* - *t3* and *t2* == *t1* + *t3* are |
| | true. (1) |
+--------------------------------+-----------------------------------------------+
-| ``t1 = t2 * i or t1 = i * t2`` | Delta multiplied by an integer or long. |
+| ``t1 = t2 * i or t1 = i * t2`` | Delta multiplied by an integer. |
| | Afterwards *t1* // i == *t2* is true, |
| | provided ``i != 0``. |
+--------------------------------+-----------------------------------------------+
| | In general, *t1* \* i == *t1* \* (i-1) + *t1* |
| | is true. (1) |
+--------------------------------+-----------------------------------------------+
-| ``t1 = t2 // i`` | The floor is computed and the remainder (if |
-| | any) is thrown away. (3) |
+| ``t1 = t2 * f or t1 = f * t2`` | Delta multiplied by a float. The result is |
+| | rounded to the nearest multiple of |
+| | timedelta.resolution using round-half-to-even.|
++--------------------------------+-----------------------------------------------+
+| ``f = t2 / t3`` | Division (3) of *t2* by *t3*. Returns a |
+| | :class:`float` object. |
++--------------------------------+-----------------------------------------------+
+| ``t1 = t2 / f or t1 = t2 / i`` | Delta divided by a float or an int. The result|
+| | is rounded to the nearest multiple of |
+| | timedelta.resolution using round-half-to-even.|
++--------------------------------+-----------------------------------------------+
+| ``t1 = t2 // i`` or | The floor is computed and the remainder (if |
+| ``t1 = t2 // t3`` | any) is thrown away. In the second case, an |
+| | integer is returned. (3) |
++--------------------------------+-----------------------------------------------+
+| ``t1 = t2 % t3`` | The remainder is computed as a |
+| | :class:`timedelta` object. (3) |
++--------------------------------+-----------------------------------------------+
+| ``q, r = divmod(t1, t2)`` | Computes the quotient and the remainder: |
+| | ``q = t1 // t2`` (3) and ``r = t1 % t2``. |
+| | q is an integer and r is a :class:`timedelta` |
+| | object. |
+--------------------------------+-----------------------------------------------+
| ``+t1`` | Returns a :class:`timedelta` object with the |
| | same value. (2) |
@@ -282,6 +311,13 @@ In addition to the operations listed above :class:`timedelta` objects support
certain additions and subtractions with :class:`date` and :class:`.datetime`
objects (see below).
+.. versionchanged:: 3.2
+ Floor division and true division of a :class:`timedelta` object by another
+ :class:`timedelta` object are now supported, as are remainder operations and
+ the :func:`divmod` function. True division and multiplication of a
+ :class:`timedelta` object by a :class:`float` object are now supported.
+
+
Comparisons of :class:`timedelta` objects are supported with the
:class:`timedelta` object representing the smaller duration considered to be the
smaller timedelta. In order to stop mixed-type comparisons from falling back to
@@ -298,14 +334,13 @@ Instance methods:
.. method:: timedelta.total_seconds()
- Return the total number of seconds contained in the duration.
- Equivalent to ``(td.microseconds + (td.seconds + td.days * 24 *
- 3600) * 10**6) / 10**6`` computed with true division enabled.
+ Return the total number of seconds contained in the duration. Equivalent to
+ ``td / timedelta(seconds=1)``.
Note that for very large time intervals (greater than 270 years on
most platforms) this method will lose microsecond accuracy.
- .. versionadded:: 2.7
+ .. versionadded:: 3.2
Example usage:
@@ -348,7 +383,7 @@ systems.
.. class:: date(year, month, day)
- All arguments are required. Arguments may be ints or longs, in the following
+ All arguments are required. Arguments may be integers, in the following
ranges:
* ``MINYEAR <= year <= MAXYEAR``
@@ -583,7 +618,7 @@ Example of working with :class:`date`:
datetime.date(2002, 3, 11)
>>> t = d.timetuple()
>>> for i in t: # doctest: +SKIP
- ... print i
+ ... print(i)
2002 # year
3 # month
11 # day
@@ -595,7 +630,7 @@ Example of working with :class:`date`:
-1
>>> ic = d.isocalendar()
>>> for i in ic: # doctest: +SKIP
- ... print i
+ ... print(i)
2002 # ISO year
11 # ISO week number
1 # ISO day number ( 1 = Monday )
@@ -620,11 +655,11 @@ both directions; like a time object, :class:`.datetime` assumes there are exactl
Constructor:
-.. class:: datetime(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])
+.. class:: datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
The year, month and day arguments are required. *tzinfo* may be ``None``, or an
- instance of a :class:`tzinfo` subclass. The remaining arguments may be ints or
- longs, in the following ranges:
+ instance of a :class:`tzinfo` subclass. The remaining arguments may be integers,
+ in the following ranges:
* ``MINYEAR <= year <= MAXYEAR``
* ``1 <= month <= 12``
@@ -645,7 +680,7 @@ Other constructors, all class methods:
:meth:`fromtimestamp`.
-.. classmethod:: datetime.now([tz])
+.. classmethod:: datetime.now(tz=None)
Return the current local date and time. If optional argument *tz* is ``None``
or not specified, this is like :meth:`today`, but, if possible, supplies more
@@ -663,10 +698,10 @@ Other constructors, all class methods:
Return the current UTC date and time, with :attr:`tzinfo` ``None``. This is like
:meth:`now`, but returns the current UTC date and time, as a naive
- :class:`.datetime` object. See also :meth:`now`.
-
+ :class:`.datetime` object. An aware current UTC datetime can be obtained by
+ calling ``datetime.now(timezone.utc)``. See also :meth:`now`.
-.. classmethod:: datetime.fromtimestamp(timestamp[, tz])
+.. classmethod:: datetime.fromtimestamp(timestamp, tz=None)
Return the local date and time corresponding to the POSIX timestamp, such as is
returned by :func:`time.time`. If optional argument *tz* is ``None`` or not
@@ -723,7 +758,6 @@ Other constructors, all class methods:
can't be parsed by :func:`time.strptime` or if it returns a value which isn't a
time tuple. See section :ref:`strftime-strptime-behavior`.
- .. versionadded:: 2.5
Class attributes:
@@ -969,10 +1003,10 @@ Instance methods:
``d.dst()`` returns. DST is never in effect for a UTC time.
If *d* is aware, *d* is normalized to UTC time, by subtracting
- ``d.utcoffset()``, and a :class:`time.struct_time` for the normalized time is
- returned. :attr:`tm_isdst` is forced to 0. Note that the result's
- :attr:`tm_year` member may be :const:`MINYEAR`\ -1 or :const:`MAXYEAR`\ +1, if
- *d*.year was ``MINYEAR`` or ``MAXYEAR`` and UTC adjustment spills over a year
+ ``d.utcoffset()``, and a :class:`time.struct_time` for the
+ normalized time is returned. :attr:`tm_isdst` is forced to 0. Note
+ that an :exc:`OverflowError` may be raised if *d*.year was
+ ``MINYEAR`` or ``MAXYEAR`` and UTC adjustment spills over a year
boundary.
@@ -1001,7 +1035,7 @@ Instance methods:
``self.date().isocalendar()``.
-.. method:: datetime.isoformat([sep])
+.. method:: datetime.isoformat(sep='T')
Return a string representing the date and time in ISO 8601 format,
YYYY-MM-DDTHH:MM:SS.mmmmmm or, if :attr:`microsecond` is 0,
@@ -1066,7 +1100,7 @@ Examples of working with datetime objects:
>>> # Using datetime.timetuple() to get tuple of all attributes
>>> tt = dt.timetuple()
>>> for it in tt: # doctest: +SKIP
- ... print it
+ ... print(it)
...
2006 # year
11 # month
@@ -1080,7 +1114,7 @@ Examples of working with datetime objects:
>>> # Date in ISO format
>>> ic = dt.isocalendar()
>>> for it in ic: # doctest: +SKIP
- ... print it
+ ... print(it)
...
2006 # ISO year
47 # ISO week
@@ -1154,10 +1188,10 @@ Using datetime with tzinfo:
A time object represents a (local) time of day, independent of any particular
day, and subject to adjustment via a :class:`tzinfo` object.
-.. class:: time([hour[, minute[, second[, microsecond[, tzinfo]]]]])
+.. class:: time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
All arguments are optional. *tzinfo* may be ``None``, or an instance of a
- :class:`tzinfo` subclass. The remaining arguments may be ints or longs, in the
+ :class:`tzinfo` subclass. The remaining arguments may be integers, in the
following ranges:
* ``0 <= hour < 24``
@@ -1324,8 +1358,10 @@ Example:
:class:`tzinfo` is an abstract base class, meaning that this class should not be
instantiated directly. You need to derive a concrete subclass, and (at least)
supply implementations of the standard :class:`tzinfo` methods needed by the
-:class:`.datetime` methods you use. The :mod:`datetime` module does not supply
-any concrete subclasses of :class:`tzinfo`.
+:class:`.datetime` methods you use. The :mod:`datetime` module supplies
+a simple concrete subclass of :class:`tzinfo` :class:`timezone` which can represent
+timezones with fixed offset from UTC such as UTC itself or North American EST and
+EDT.
An instance of (a concrete subclass of) :class:`tzinfo` can be passed to the
constructors for :class:`.datetime` and :class:`.time` objects. The latter objects
@@ -1343,7 +1379,7 @@ methods. Exactly which methods are needed depends on the uses made of aware
:mod:`datetime` objects. If in doubt, simply implement all of them.
-.. method:: tzinfo.utcoffset(self, dt)
+.. method:: tzinfo.utcoffset(dt)
Return offset of local time from UTC, in minutes east of UTC. If local time is
west of UTC, this should be negative. Note that this is intended to be the
@@ -1365,7 +1401,7 @@ methods. Exactly which methods are needed depends on the uses made of aware
:exc:`NotImplementedError`.
-.. method:: tzinfo.dst(self, dt)
+.. method:: tzinfo.dst(dt)
Return the daylight saving time (DST) adjustment, in minutes east of UTC, or
``None`` if DST information isn't known. Return ``timedelta(0)`` if DST is not
@@ -1413,7 +1449,7 @@ methods. Exactly which methods are needed depends on the uses made of aware
The default implementation of :meth:`dst` raises :exc:`NotImplementedError`.
-.. method:: tzinfo.tzname(self, dt)
+.. method:: tzinfo.tzname(dt)
Return the time zone name corresponding to the :class:`.datetime` object *dt*, as
a string. Nothing about string names is defined by the :mod:`datetime` module,
@@ -1449,7 +1485,7 @@ time, and not need worry about objects in other timezones.
There is one more :class:`tzinfo` method that a subclass may wish to override:
-.. method:: tzinfo.fromutc(self, dt)
+.. method:: tzinfo.fromutc(dt)
This is called from the default :class:`datetime.astimezone()`
implementation. When called from that, ``dt.tzinfo`` is *self*, and *dt*'s
@@ -1490,7 +1526,6 @@ Example :class:`tzinfo` classes:
.. literalinclude:: ../includes/tzinfo-examples.py
-
Note that there are unavoidable subtleties twice per year in a :class:`tzinfo`
subclass accounting for both standard and daylight time, at the DST transition
points. For concreteness, consider US Eastern (UTC -0500), where EDT begins the
@@ -1509,7 +1544,7 @@ When DST starts (the "start" line), the local wall clock leaps from 1:59 to
3:00. A wall time of the form 2:MM doesn't really make sense on that day, so
``astimezone(Eastern)`` won't deliver a result with ``hour == 2`` on the day DST
begins. In order for :meth:`astimezone` to make this guarantee, the
-:meth:`rzinfo.dst` method must consider times in the "missing hour" (2:MM for
+:meth:`tzinfo.dst` method must consider times in the "missing hour" (2:MM for
Eastern) to be in daylight time.
When DST ends (the "end" line), there's a potentially worse problem: there's an
@@ -1526,9 +1561,9 @@ arranged, as in the example, by expressing DST switch times in the time zone's
standard local time.
Applications that can't bear such ambiguities should avoid using hybrid
-:class:`tzinfo` subclasses; there are no ambiguities when using UTC, or any
-other fixed-offset :class:`tzinfo` subclass (such as a class representing only
-EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)).
+:class:`tzinfo` subclasses; there are no ambiguities when using :class:`timezone`,
+or any other fixed-offset :class:`tzinfo` subclass (such as a class representing
+only EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)).
.. seealso::
@@ -1546,6 +1581,63 @@ EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)).
made by political bodies to time zone boundaries, UTC offsets, and
daylight-saving rules.
+
+.. _datetime-timezone:
+
+:class:`timezone` Objects
+--------------------------
+
+A :class:`timezone` object represents a timezone that is defined by a
+fixed offset from UTC. Note that objects of this class cannot be used
+to represent timezone information in the locations where different
+offsets are used in different days of the year or where historical
+changes have been made to civil time.
+
+
+.. class:: timezone(offset[, name])
+
+ The *offset* argument must be specified as a :class:`timedelta`
+ object representing the difference between the local time and UTC. It must
+ be strictly between ``-timedelta(hours=24)`` and
+ ``timedelta(hours=24)`` and represent a whole number of minutes,
+ otherwise :exc:`ValueError` is raised.
+
+ The *name* argument is optional. If specified it must be a string that
+ is used as the value returned by the ``tzname(dt)`` method. Otherwise,
+ ``tzname(dt)`` returns a string 'UTCsHH:MM', where s is the sign of
+ *offset*, HH and MM are two digits of ``offset.hours`` and
+ ``offset.minutes`` respectively.
+
+.. method:: timezone.utcoffset(dt)
+
+ Return the fixed value specified when the :class:`timezone` instance is
+ constructed. The *dt* argument is ignored. The return value is a
+ :class:`timedelta` instance equal to the difference between the
+ local time and UTC.
+
+.. method:: timezone.tzname(dt)
+
+ Return the fixed value specified when the :class:`timezone` instance is
+ constructed or a string 'UTCsHH:MM', where s is the sign of
+ *offset*, HH and MM are two digits of ``offset.hours`` and
+ ``offset.minutes`` respectively.
+
+.. method:: timezone.dst(dt)
+
+ Always returns ``None``.
+
+.. method:: timezone.fromutc(dt)
+
+ Return ``dt + offset``. The *dt* argument must be an aware
+ :class:`.datetime` instance, with ``tzinfo`` set to ``self``.
+
+Class attributes:
+
+.. attribute:: timezone.utc
+
+ The UTC timezone, ``timezone(timedelta(0))``.
+
+
.. _strftime-strptime-behavior:
:meth:`strftime` and :meth:`strptime` Behavior
@@ -1570,11 +1662,6 @@ For :class:`date` objects, the format codes for hours, minutes, seconds, and
microseconds should not be used, as :class:`date` objects have no such
values. If they're used anyway, ``0`` is substituted for them.
-.. versionadded:: 2.6
- :class:`.time` and :class:`.datetime` objects support a ``%f`` format code
- which expands to the number of microseconds in the object, zero-padded on
- the left to six places.
-
For a naive object, the ``%z`` and ``%Z`` format codes are replaced by empty
strings.
@@ -1600,9 +1687,6 @@ version) requires, and these work on all platforms with a standard C
implementation. Note that the 1999 version of the C standard added additional
format codes.
-The exact range of years for which :meth:`strftime` works also varies across
-platforms. Regardless of platform, years before 1900 cannot be used.
-
+-----------+--------------------------------+-------+
| Directive | Meaning | Notes |
+===========+================================+=======+
@@ -1645,7 +1729,7 @@ platforms. Regardless of platform, years before 1900 cannot be used.
| | AM or PM. | |
+-----------+--------------------------------+-------+
| ``%S`` | Second as a decimal number | \(3) |
-| | [00,61]. | |
+| | [00,59]. | |
+-----------+--------------------------------+-------+
| ``%U`` | Week number of the year | \(4) |
| | (Sunday as the first day of | |
@@ -1675,10 +1759,11 @@ platforms. Regardless of platform, years before 1900 cannot be used.
| ``%y`` | Year without century as a | |
| | decimal number [00,99]. | |
+-----------+--------------------------------+-------+
-| ``%Y`` | Year with century as a decimal | |
-| | number. | |
+| ``%Y`` | Year with century as a decimal | \(5) |
+| | number [0001,9999] (strptime), | |
+| | [1000,9999] (strftime). | |
+-----------+--------------------------------+-------+
-| ``%z`` | UTC offset in the form +HHMM | \(5) |
+| ``%z`` | UTC offset in the form +HHMM | \(6) |
| | or -HHMM (empty string if the | |
| | the object is naive). | |
+-----------+--------------------------------+-------+
@@ -1702,21 +1787,33 @@ Notes:
the output hour field if the ``%I`` directive is used to parse the hour.
(3)
- The range really is ``0`` to ``61``; according to the Posix standard this
- accounts for leap seconds and the (very rare) double leap seconds.
- The :mod:`time` module may produce and does accept leap seconds since
- it is based on the Posix standard, but the :mod:`datetime` module
- does not accept leap seconds in :meth:`strptime` input nor will it
- produce them in :func:`strftime` output.
+ Unlike :mod:`time` module, :mod:`datetime` module does not support
+ leap seconds.
(4)
When used with the :meth:`strptime` method, ``%U`` and ``%W`` are only used in
calculations when the day of the week and the year are specified.
(5)
+ For technical reasons, :meth:`strftime` method does not support
+ dates before year 1000: ``t.strftime(format)`` will raise a
+ :exc:`ValueError` when ``t.year < 1000`` even if ``format`` does
+ not contain ``%Y`` directive. The :meth:`strptime` method can
+ parse years in the full [1, 9999] range, but years < 1000 must be
+ zero-filled to 4-digit width.
+
+ .. versionchanged:: 3.2
+ In previous versions, :meth:`strftime` method was restricted to
+ years >= 1900.
+
+(6)
For example, if :meth:`utcoffset` returns ``timedelta(hours=-3, minutes=-30)``,
``%z`` is replaced with the string ``'-0330'``.
+.. versionchanged:: 3.2
+ When the ``%z`` directive is provided to the :meth:`strptime` method, an
+ aware :class:`.datetime` object will be produced. The ``tzinfo`` of the
+ result will be set to a :class:`timezone` instance.
.. rubric:: Footnotes
diff --git a/Doc/library/dbhash.rst b/Doc/library/dbhash.rst
deleted file mode 100644
index ed965e1..0000000
--- a/Doc/library/dbhash.rst
+++ /dev/null
@@ -1,115 +0,0 @@
-:mod:`dbhash` --- DBM-style interface to the BSD database library
-=================================================================
-
-.. module:: dbhash
- :synopsis: DBM-style interface to the BSD database library.
-.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
-
-.. deprecated:: 2.6
- The :mod:`dbhash` module has been removed in Python 3.
-
-.. index:: module: bsddb
-
-The :mod:`dbhash` module provides a function to open databases using the BSD
-``db`` library. This module mirrors the interface of the other Python database
-modules that provide access to DBM-style databases. The :mod:`bsddb` module is
-required to use :mod:`dbhash`.
-
-This module provides an exception and a function:
-
-
-.. exception:: error
-
- Exception raised on database errors other than :exc:`KeyError`. It is a synonym
- for :exc:`bsddb.error`.
-
-
-.. function:: open(path[, flag[, mode]])
-
- Open a ``db`` database and return the database object. The *path* argument is
- the name of the database file.
-
- The *flag* argument can be:
-
- +---------+-------------------------------------------+
- | Value | Meaning |
- +=========+===========================================+
- | ``'r'`` | Open existing database for reading only |
- | | (default) |
- +---------+-------------------------------------------+
- | ``'w'`` | Open existing database for reading and |
- | | writing |
- +---------+-------------------------------------------+
- | ``'c'`` | Open database for reading and writing, |
- | | creating it if it doesn't exist |
- +---------+-------------------------------------------+
- | ``'n'`` | Always create a new, empty database, open |
- | | for reading and writing |
- +---------+-------------------------------------------+
-
- For platforms on which the BSD ``db`` library supports locking, an ``'l'``
- can be appended to indicate that locking should be used.
-
- The optional *mode* parameter is used to indicate the Unix permission bits that
- should be set if a new database must be created; this will be masked by the
- current umask value for the process.
-
-
-.. seealso::
-
- Module :mod:`anydbm`
- Generic interface to ``dbm``\ -style databases.
-
- Module :mod:`bsddb`
- Lower-level interface to the BSD ``db`` library.
-
- Module :mod:`whichdb`
- Utility module used to determine the type of an existing database.
-
-
-.. _dbhash-objects:
-
-Database Objects
-----------------
-
-The database objects returned by :func:`.open` provide the methods common to all
-the DBM-style databases and mapping objects. The following methods are
-available in addition to the standard methods.
-
-
-.. method:: dbhash.first()
-
- It's possible to loop over every key/value pair in the database using this
- method and the :meth:`!next` method. The traversal is ordered by the databases
- internal hash values, and won't be sorted by the key values. This method
- returns the starting key.
-
-
-.. method:: dbhash.last()
-
- Return the last key/value pair in a database traversal. This may be used to
- begin a reverse-order traversal; see :meth:`previous`.
-
-
-.. method:: dbhash.next()
-
- Returns the key next key/value pair in a database traversal. The following code
- prints every key in the database ``db``, without having to create a list in
- memory that contains them all::
-
- print db.first()
- for i in xrange(1, len(db)):
- print db.next()
-
-
-.. method:: dbhash.previous()
-
- Returns the previous key/value pair in a forward-traversal of the database. In
- conjunction with :meth:`last`, this may be used to implement a reverse-order
- traversal.
-
-
-.. method:: dbhash.sync()
-
- This method forces any unwritten data to be written to the disk.
-
diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst
index 6f9781e..e3d50b9 100644
--- a/Doc/library/dbm.rst
+++ b/Doc/library/dbm.rst
@@ -1,33 +1,243 @@
-:mod:`dbm` --- Simple "database" interface
-==========================================
+:mod:`dbm` --- Interfaces to Unix "databases"
+=============================================
.. module:: dbm
+ :synopsis: Interfaces to various Unix "database" formats.
+
+:mod:`dbm` is a generic interface to variants of the DBM database ---
+:mod:`dbm.gnu` or :mod:`dbm.ndbm`. If none of these modules is installed, the
+slow-but-simple implementation in module :mod:`dbm.dumb` will be used. There
+is a `third party interface <http://www.jcea.es/programacion/pybsddb.htm>`_ to
+the Oracle Berkeley DB.
+
+
+.. exception:: error
+
+ A tuple containing the exceptions that can be raised by each of the supported
+ modules, with a unique exception also named :exc:`dbm.error` as the first
+ item --- the latter is used when :exc:`dbm.error` is raised.
+
+
+.. function:: whichdb(filename)
+
+ This function attempts to guess which of the several simple database modules
+ available --- :mod:`dbm.gnu`, :mod:`dbm.ndbm` or :mod:`dbm.dumb` --- should
+ be used to open a given file.
+
+ Returns one of the following values: ``None`` if the file can't be opened
+ because it's unreadable or doesn't exist; the empty string (``''``) if the
+ file's format can't be guessed; or a string containing the required module
+ name, such as ``'dbm.ndbm'`` or ``'dbm.gnu'``.
+
+
+.. function:: open(file, flag='r', mode=0o666)
+
+ Open the database file *file* and return a corresponding object.
+
+ If the database file already exists, the :func:`whichdb` function is used to
+ determine its type and the appropriate module is used; if it does not exist,
+ the first module listed above that can be imported is used.
+
+ The optional *flag* argument can be:
+
+ +---------+-------------------------------------------+
+ | Value | Meaning |
+ +=========+===========================================+
+ | ``'r'`` | Open existing database for reading only |
+ | | (default) |
+ +---------+-------------------------------------------+
+ | ``'w'`` | Open existing database for reading and |
+ | | writing |
+ +---------+-------------------------------------------+
+ | ``'c'`` | Open database for reading and writing, |
+ | | creating it if it doesn't exist |
+ +---------+-------------------------------------------+
+ | ``'n'`` | Always create a new, empty database, open |
+ | | for reading and writing |
+ +---------+-------------------------------------------+
+
+ The optional *mode* argument is the Unix mode of the file, used only when the
+ database has to be created. It defaults to octal ``0o666`` (and will be
+ modified by the prevailing umask).
+
+
+The object returned by :func:`.open` supports the same basic functionality as
+dictionaries; keys and their corresponding values can be stored, retrieved, and
+deleted, and the :keyword:`in` operator and the :meth:`keys` method are
+available, as well as :meth:`get` and :meth:`setdefault`.
+
+.. versionchanged:: 3.2
+ :meth:`get` and :meth:`setdefault` are now available in all database modules.
+
+Key and values are always stored as bytes. This means that when
+strings are used they are implicitly converted to the default encoding before
+being stored.
+
+The following example records some hostnames and a corresponding title, and
+then prints out the contents of the database::
+
+ import dbm
+
+ # Open database, creating it if necessary.
+ db = dbm.open('cache', 'c')
+
+ # Record some values
+ db[b'hello'] = b'there'
+ db['www.python.org'] = 'Python Website'
+ db['www.cnn.com'] = 'Cable News Network'
+
+ # Note that the keys are considered bytes now.
+ assert db[b'www.python.org'] == b'Python Website'
+ # Notice how the value is now in bytes.
+ assert db['www.cnn.com'] == b'Cable News Network'
+
+ # Often-used methods of the dict interface work too.
+ print(db.get('python.org', b'not present'))
+
+ # Storing a non-string key or value will raise an exception (most
+ # likely a TypeError).
+ db['www.yahoo.com'] = 4
+
+ # Close when done.
+ db.close()
+
+
+.. seealso::
+
+ Module :mod:`shelve`
+ Persistence module which stores non-string data.
+
+
+The individual submodules are described in the following sections.
+
+
+:mod:`dbm.gnu` --- GNU's reinterpretation of dbm
+------------------------------------------------
+
+.. module:: dbm.gnu
:platform: Unix
- :synopsis: The standard "database" interface, based on ndbm.
+ :synopsis: GNU's reinterpretation of dbm.
-.. note::
- The :mod:`dbm` module has been renamed to :mod:`dbm.ndbm` in Python 3. The
- :term:`2to3` tool will automatically adapt imports when converting your
- sources to Python 3.
+This module is quite similar to the :mod:`dbm` module, but uses the GNU library
+``gdbm`` instead to provide some additional functionality. Please note that the
+file formats created by :mod:`dbm.gnu` and :mod:`dbm.ndbm` are incompatible.
-The :mod:`dbm` module provides an interface to the Unix "(n)dbm" library. Dbm
-objects behave like mappings (dictionaries), except that keys and values are
-always strings. Printing a dbm object doesn't print the keys and values, and the
-:meth:`items` and :meth:`values` methods are not supported.
+The :mod:`dbm.gnu` module provides an interface to the GNU DBM library.
+``dbm.gnu.gdbm`` objects behave like mappings (dictionaries), except that keys and
+values are always converted to bytes before storing. Printing a ``gdbm``
+object doesn't print the
+keys and values, and the :meth:`items` and :meth:`values` methods are not
+supported.
-This module can be used with the "classic" ndbm interface, the BSD DB
-compatibility interface, or the GNU GDBM compatibility interface. On Unix, the
-:program:`configure` script will attempt to locate the appropriate header file
-to simplify building this module.
+.. exception:: error
-The module defines the following:
+ Raised on :mod:`dbm.gnu`-specific errors, such as I/O errors. :exc:`KeyError` is
+ raised for general mapping errors like specifying an incorrect key.
+
+
+.. function:: open(filename[, flag[, mode]])
+ Open a ``gdbm`` database and return a :class:`gdbm` object. The *filename*
+ argument is the name of the database file.
+
+ The optional *flag* argument can be:
+
+ +---------+-------------------------------------------+
+ | Value | Meaning |
+ +=========+===========================================+
+ | ``'r'`` | Open existing database for reading only |
+ | | (default) |
+ +---------+-------------------------------------------+
+ | ``'w'`` | Open existing database for reading and |
+ | | writing |
+ +---------+-------------------------------------------+
+ | ``'c'`` | Open database for reading and writing, |
+ | | creating it if it doesn't exist |
+ +---------+-------------------------------------------+
+ | ``'n'`` | Always create a new, empty database, open |
+ | | for reading and writing |
+ +---------+-------------------------------------------+
+
+ The following additional characters may be appended to the flag to control
+ how the database is opened:
+
+ +---------+--------------------------------------------+
+ | Value | Meaning |
+ +=========+============================================+
+ | ``'f'`` | Open the database in fast mode. Writes |
+ | | to the database will not be synchronized. |
+ +---------+--------------------------------------------+
+ | ``'s'`` | Synchronized mode. This will cause changes |
+ | | to the database to be immediately written |
+ | | to the file. |
+ +---------+--------------------------------------------+
+ | ``'u'`` | Do not lock database. |
+ +---------+--------------------------------------------+
+
+ Not all flags are valid for all versions of ``gdbm``. The module constant
+ :const:`open_flags` is a string of supported flag characters. The exception
+ :exc:`error` is raised if an invalid flag is specified.
+
+ The optional *mode* argument is the Unix mode of the file, used only when the
+ database has to be created. It defaults to octal ``0o666``.
+
+ In addition to the dictionary-like methods, ``gdbm`` objects have the
+ following methods:
+
+ .. method:: gdbm.firstkey()
+
+ It's possible to loop over every key in the database using this method and the
+ :meth:`nextkey` method. The traversal is ordered by ``gdbm``'s internal
+ hash values, and won't be sorted by the key values. This method returns
+ the starting key.
+
+ .. method:: gdbm.nextkey(key)
+
+ Returns the key that follows *key* in the traversal. The following code prints
+ every key in the database ``db``, without having to create a list in memory that
+ contains them all::
+
+ k = db.firstkey()
+ while k != None:
+ print(k)
+ k = db.nextkey(k)
+
+ .. method:: gdbm.reorganize()
+
+ If you have carried out a lot of deletions and would like to shrink the space
+ used by the ``gdbm`` file, this routine will reorganize the database. ``gdbm``
+ objects will not shorten the length of a database file except by using this
+ reorganization; otherwise, deleted file space will be kept and reused as new
+ (key, value) pairs are added.
+
+ .. method:: gdbm.sync()
+
+ When the database has been opened in fast mode, this method forces any
+ unwritten data to be written to the disk.
+
+
+:mod:`dbm.ndbm` --- Interface based on ndbm
+-------------------------------------------
+
+.. module:: dbm.ndbm
+ :platform: Unix
+ :synopsis: The standard "database" interface, based on ndbm.
+
+
+The :mod:`dbm.ndbm` module provides an interface to the Unix "(n)dbm" library.
+Dbm objects behave like mappings (dictionaries), except that keys and values are
+always stored as bytes. Printing a ``dbm`` object doesn't print the keys and
+values, and the :meth:`items` and :meth:`values` methods are not supported.
+
+This module can be used with the "classic" ndbm interface or the GNU GDBM
+compatibility interface. On Unix, the :program:`configure` script will attempt
+to locate the appropriate header file to simplify building this module.
.. exception:: error
- Raised on dbm-specific errors, such as I/O errors. :exc:`KeyError` is raised for
- general mapping errors like specifying an incorrect key.
+ Raised on :mod:`dbm.ndbm`-specific errors, such as I/O errors. :exc:`KeyError` is raised
+ for general mapping errors like specifying an incorrect key.
.. data:: library
@@ -37,10 +247,8 @@ The module defines the following:
.. function:: open(filename[, flag[, mode]])
- Open a dbm database and return a dbm object. The *filename* argument is the
- name of the database file (without the :file:`.dir` or :file:`.pag` extensions;
- note that the BSD DB implementation of the interface will append the extension
- :file:`.db` and only create one file).
+ Open a dbm database and return a ``dbm`` object. The *filename* argument is the
+ name of the database file (without the :file:`.dir` or :file:`.pag` extensions).
The optional *flag* argument must be one of these values:
@@ -61,18 +269,58 @@ The module defines the following:
+---------+-------------------------------------------+
The optional *mode* argument is the Unix mode of the file, used only when the
- database has to be created. It defaults to octal ``0666`` (and will be
+ database has to be created. It defaults to octal ``0o666`` (and will be
modified by the prevailing umask).
-.. seealso::
- Module :mod:`anydbm`
- Generic interface to ``dbm``\ -style databases.
+:mod:`dbm.dumb` --- Portable DBM implementation
+-----------------------------------------------
+
+.. module:: dbm.dumb
+ :synopsis: Portable implementation of the simple DBM interface.
+
+.. index:: single: databases
+
+.. note::
+
+ The :mod:`dbm.dumb` module is intended as a last resort fallback for the
+ :mod:`dbm` module when a more robust module is not available. The :mod:`dbm.dumb`
+ module is not written for speed and is not nearly as heavily used as the other
+ database modules.
+
+The :mod:`dbm.dumb` module provides a persistent dictionary-like interface which
+is written entirely in Python. Unlike other modules such as :mod:`dbm.gnu` no
+external library is required. As with other persistent mappings, the keys and
+values are always stored as bytes.
+
+The module defines the following:
+
+
+.. exception:: error
+
+ Raised on :mod:`dbm.dumb`-specific errors, such as I/O errors. :exc:`KeyError` is
+ raised for general mapping errors like specifying an incorrect key.
+
+
+.. function:: open(filename[, flag[, mode]])
+
+ Open a ``dumbdbm`` database and return a dumbdbm object. The *filename* argument is
+ the basename of the database file (without any specific extensions). When a
+ dumbdbm database is created, files with :file:`.dat` and :file:`.dir` extensions
+ are created.
+
+ The optional *flag* argument is currently ignored; the database is always opened
+ for update, and will be created if it does not exist.
+
+ The optional *mode* argument is the Unix mode of the file, used only when the
+ database has to be created. It defaults to octal ``0o666`` (and will be modified
+ by the prevailing umask).
- Module :mod:`gdbm`
- Similar interface to the GNU GDBM library.
+ In addition to the methods provided by the :class:`collections.MutableMapping` class,
+ :class:`dumbdbm` objects provide the following method:
- Module :mod:`whichdb`
- Utility module used to determine the type of an existing database.
+ .. method:: dumbdbm.sync()
+ Synchronize the on-disk directory and data files. This method is called
+ by the :meth:`Shelve.sync` method.
diff --git a/Doc/library/debug.rst b/Doc/library/debug.rst
index 7480087..b2ee4fa 100644
--- a/Doc/library/debug.rst
+++ b/Doc/library/debug.rst
@@ -12,6 +12,5 @@ allowing you to identify bottlenecks in your programs.
bdb.rst
pdb.rst
profile.rst
- hotshot.rst
timeit.rst
trace.rst \ No newline at end of file
diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst
index 934b26e..d989e3f 100644
--- a/Doc/library/decimal.rst
+++ b/Doc/library/decimal.rst
@@ -1,22 +1,16 @@
-
:mod:`decimal` --- Decimal fixed point and floating point arithmetic
====================================================================
.. module:: decimal
:synopsis: Implementation of the General Decimal Arithmetic Specification.
-
.. moduleauthor:: Eric Price <eprice at tjhsst.edu>
.. moduleauthor:: Facundo Batista <facundo at taniquetil.com.ar>
.. moduleauthor:: Raymond Hettinger <python at rcn.com>
.. moduleauthor:: Aahz <aahz at pobox.com>
.. moduleauthor:: Tim Peters <tim.one at comcast.net>
-
-
.. sectionauthor:: Raymond D. Hettinger <python at rcn.com>
-.. versionadded:: 2.4
-
.. import modules for testing inline doctests with the Sphinx doctest builder
.. testsetup:: *
@@ -36,7 +30,7 @@ arithmetic. It offers several advantages over the :class:`float` datatype:
* Decimal numbers can be represented exactly. In contrast, numbers like
:const:`1.1` and :const:`2.2` do not have exact representations in binary
- floating point. End users typically would not expect ``1.1 + 2.2`` to display
+ floating point. End users typically would not expect ``1.1 + 2.2`` to display
as :const:`3.3000000000000003` as it does with binary floating point.
* The exactness carries over into arithmetic. In decimal floating point, ``0.1
@@ -109,7 +103,7 @@ reset them before monitoring a calculation.
.. seealso::
* IBM's General Decimal Arithmetic Specification, `The General Decimal Arithmetic
- Specification <http://speleotrove.com/decimal/>`_.
+ Specification <http://speleotrove.com/decimal/decarith.html>`_.
* IEEE standard 854-1987, `Unofficial IEEE 854 Text
<http://754r.ucbtest.org/standards/854.pdf>`_.
@@ -129,7 +123,7 @@ precision, rounding, or enabled traps::
>>> from decimal import *
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
- capitals=1, flags=[], traps=[Overflow, DivisionByZero,
+ capitals=1, clamp=0, flags=[], traps=[Overflow, DivisionByZero,
InvalidOperation])
>>> getcontext().prec = 7 # Set a new precision
@@ -150,7 +144,7 @@ value of that integer or float. Decimal numbers include special values such as
>>> Decimal((0, (3, 1, 4), -2))
Decimal('3.14')
>>> Decimal(str(2.0 ** 0.5))
- Decimal('1.41421356237')
+ Decimal('1.4142135623730951')
>>> Decimal(2) ** Decimal('0.5')
Decimal('1.414213562373095048801688724')
>>> Decimal('NaN')
@@ -181,7 +175,7 @@ floating point flying circus:
.. doctest::
:options: +NORMALIZE_WHITESPACE
- >>> data = map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split())
+ >>> data = list(map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split()))
>>> max(data)
Decimal('9.25')
>>> min(data)
@@ -196,8 +190,8 @@ floating point flying circus:
'1.34'
>>> float(a)
1.34
- >>> round(a, 1) # round() first converts to binary floating point
- 1.3
+ >>> round(a, 1)
+ Decimal('1.3')
>>> int(a)
1
>>> a * 5
@@ -251,7 +245,7 @@ enabled:
>>> ExtendedContext
Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
- capitals=1, flags=[], traps=[])
+ capitals=1, clamp=0, flags=[], traps=[])
>>> setcontext(ExtendedContext)
>>> Decimal(1) / Decimal(7)
Decimal('0.142857143')
@@ -276,7 +270,7 @@ using the :meth:`clear_flags` method. ::
Decimal('3.14159292')
>>> getcontext()
Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
- capitals=1, flags=[Rounded, Inexact], traps=[])
+ capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[])
The *flags* entry shows that the rational approximation to :const:`Pi` was
rounded (digits beyond the context precision were thrown away) and that the
@@ -312,7 +306,7 @@ Decimal objects
---------------
-.. class:: Decimal([value [, context]])
+.. class:: Decimal(value="0", context=None)
Construct a new :class:`Decimal` object based from *value*.
@@ -332,11 +326,10 @@ Decimal objects
numeric-value ::= decimal-part [exponent-part] | infinity
numeric-string ::= [sign] numeric-value | [sign] nan
- If *value* is a unicode string then other Unicode decimal digits
- are also permitted where ``digit`` appears above. These include
- decimal digits from various other alphabets (for example,
- Arabic-Indic and DevanÄgarÄ« digits) along with the fullwidth digits
- ``u'\uff10'`` through ``u'\uff19'``.
+ Other Unicode decimal digits are also permitted where ``digit``
+ appears above. These include decimal digits from various other
+ alphabets (for example, Arabic-Indic and DevanÄgarÄ« digits) along
+ with the fullwidth digits ``'\uff10'`` through ``'\uff19'``.
If *value* is a :class:`tuple`, it should have three components, a sign
(:const:`0` for positive or :const:`1` for negative), a :class:`tuple` of
@@ -361,19 +354,16 @@ Decimal objects
Once constructed, :class:`Decimal` objects are immutable.
- .. versionchanged:: 2.6
- leading and trailing whitespace characters are permitted when
- creating a Decimal instance from a string.
-
- .. versionchanged:: 2.7
- The argument to the constructor is now permitted to be a :class:`float` instance.
+ .. versionchanged:: 3.2
+ The argument to the constructor is now permitted to be a :class:`float`
+ instance.
Decimal floating point objects share many properties with the other built-in
numeric types such as :class:`float` and :class:`int`. All of the usual math
operations and special methods apply. Likewise, decimal objects can be
copied, pickled, printed, used as dictionary keys, used as set elements,
compared, sorted, and coerced to another type (such as :class:`float` or
- :class:`long`).
+ :class:`int`).
There are some small differences between arithmetic on Decimal objects and
arithmetic on integers and floats. When the remainder operator ``%`` is
@@ -398,23 +388,17 @@ Decimal objects
``divide-integer`` operations (respectively) as described in the
specification.
- Decimal objects cannot generally be combined with floats in
- arithmetic operations: an attempt to add a :class:`Decimal` to a
- :class:`float`, for example, will raise a :exc:`TypeError`.
- There's one exception to this rule: it's possible to use Python's
- comparison operators to compare a :class:`float` instance ``x``
- with a :class:`Decimal` instance ``y``. Without this exception,
- comparisons between :class:`Decimal` and :class:`float` instances
- would follow the general rules for comparing objects of different
- types described in the :ref:`expressions` section of the reference
- manual, leading to confusing results.
-
- .. versionchanged:: 2.7
- A comparison between a :class:`float` instance ``x`` and a
- :class:`Decimal` instance ``y`` now returns a result based on
- the values of ``x`` and ``y``. In earlier versions ``x < y``
- returned the same (arbitrary) result for any :class:`Decimal`
- instance ``x`` and any :class:`float` instance ``y``.
+ Decimal objects cannot generally be combined with floats or
+ instances of :class:`fractions.Fraction` in arithmetic operations:
+ an attempt to add a :class:`Decimal` to a :class:`float`, for
+ example, will raise a :exc:`TypeError`. However, it is possible to
+ use Python's comparison operators to compare a :class:`Decimal`
+ instance ``x`` with another number ``y``. This avoids confusing results
+ when doing equality comparisons between numbers of different types.
+
+ .. versionchanged:: 3.2
+ Mixed-type comparisons between :class:`Decimal` instances and other
+ numeric types are now fully supported.
In addition to the standard numeric properties, decimal floating point
objects also have a number of specialized methods:
@@ -433,9 +417,6 @@ Decimal objects
Return a :term:`named tuple` representation of the number:
``DecimalTuple(sign, digits, exponent)``.
- .. versionchanged:: 2.6
- Use a named tuple.
-
.. method:: canonical()
@@ -443,19 +424,16 @@ Decimal objects
a :class:`Decimal` instance is always canonical, so this operation returns
its argument unchanged.
- .. versionadded:: 2.6
-
.. method:: compare(other[, context])
- Compare the values of two Decimal instances. This operation behaves in
- the same way as the usual comparison method :meth:`__cmp__`, except that
- :meth:`compare` returns a Decimal instance rather than an integer, and if
- either operand is a NaN then the result is a NaN::
+ Compare the values of two Decimal instances. :meth:`compare` returns a
+ Decimal instance, and if either operand is a NaN then the result is a
+ NaN::
- a or b is a NaN ==> Decimal('NaN')
- a < b ==> Decimal('-1')
- a == b ==> Decimal('0')
- a > b ==> Decimal('1')
+ a or b is a NaN ==> Decimal('NaN')
+ a < b ==> Decimal('-1')
+ a == b ==> Decimal('0')
+ a > b ==> Decimal('1')
.. method:: compare_signal(other[, context])
@@ -463,8 +441,6 @@ Decimal objects
NaNs signal. That is, if neither operand is a signaling NaN then any
quiet NaN operand is treated as though it were a signaling NaN.
- .. versionadded:: 2.6
-
.. method:: compare_total(other)
Compare two operands using their abstract representation rather than their
@@ -483,8 +459,6 @@ Decimal objects
higher in the total order than the second operand. See the specification
for details of the total order.
- .. versionadded:: 2.6
-
.. method:: compare_total_mag(other)
Compare two operands using their abstract representation rather than their
@@ -492,30 +466,22 @@ Decimal objects
``x.compare_total_mag(y)`` is equivalent to
``x.copy_abs().compare_total(y.copy_abs())``.
- .. versionadded:: 2.6
-
.. method:: conjugate()
Just returns self, this method is only to comply with the Decimal
Specification.
- .. versionadded:: 2.6
-
.. method:: copy_abs()
Return the absolute value of the argument. This operation is unaffected
by the context and is quiet: no flags are changed and no rounding is
performed.
- .. versionadded:: 2.6
-
.. method:: copy_negate()
Return the negation of the argument. This operation is unaffected by the
context and is quiet: no flags are changed and no rounding is performed.
- .. versionadded:: 2.6
-
.. method:: copy_sign(other)
Return a copy of the first operand with the sign set to be the same as the
@@ -527,8 +493,6 @@ Decimal objects
This operation is unaffected by the context and is quiet: no flags are
changed and no rounding is performed.
- .. versionadded:: 2.6
-
.. method:: exp([context])
Return the value of the (natural) exponential function ``e**x`` at the
@@ -540,8 +504,6 @@ Decimal objects
>>> Decimal(321).exp()
Decimal('2.561702493119680037517373933E+139')
- .. versionadded:: 2.6
-
.. method:: from_float(f)
Classmethod that converts a float to a decimal number, exactly.
@@ -552,7 +514,7 @@ Decimal objects
`0x1.999999999999ap-4`. That equivalent value in decimal is
`0.1000000000000000055511151231257827021181583404541015625`.
- .. note:: From Python 2.7 onwards, a :class:`Decimal` instance
+ .. note:: From Python 3.2 onwards, a :class:`Decimal` instance
can also be constructed directly from a :class:`float`.
.. doctest::
@@ -566,7 +528,7 @@ Decimal objects
>>> Decimal.from_float(float('-inf'))
Decimal('-Infinity')
- .. versionadded:: 2.7
+ .. versionadded:: 3.1
.. method:: fma(other, third[, context])
@@ -576,97 +538,67 @@ Decimal objects
>>> Decimal(2).fma(3, 5)
Decimal('11')
- .. versionadded:: 2.6
-
.. method:: is_canonical()
Return :const:`True` if the argument is canonical and :const:`False`
otherwise. Currently, a :class:`Decimal` instance is always canonical, so
this operation always returns :const:`True`.
- .. versionadded:: 2.6
-
.. method:: is_finite()
Return :const:`True` if the argument is a finite number, and
:const:`False` if the argument is an infinity or a NaN.
- .. versionadded:: 2.6
-
.. method:: is_infinite()
Return :const:`True` if the argument is either positive or negative
infinity and :const:`False` otherwise.
- .. versionadded:: 2.6
-
.. method:: is_nan()
Return :const:`True` if the argument is a (quiet or signaling) NaN and
:const:`False` otherwise.
- .. versionadded:: 2.6
-
.. method:: is_normal()
- Return :const:`True` if the argument is a *normal* finite non-zero
- number with an adjusted exponent greater than or equal to *Emin*.
- Return :const:`False` if the argument is zero, subnormal, infinite or a
- NaN. Note, the term *normal* is used here in a different sense with
- the :meth:`normalize` method which is used to create canonical values.
-
- .. versionadded:: 2.6
+ Return :const:`True` if the argument is a *normal* finite number. Return
+ :const:`False` if the argument is zero, subnormal, infinite or a NaN.
.. method:: is_qnan()
Return :const:`True` if the argument is a quiet NaN, and
:const:`False` otherwise.
- .. versionadded:: 2.6
-
.. method:: is_signed()
Return :const:`True` if the argument has a negative sign and
:const:`False` otherwise. Note that zeros and NaNs can both carry signs.
- .. versionadded:: 2.6
-
.. method:: is_snan()
Return :const:`True` if the argument is a signaling NaN and :const:`False`
otherwise.
- .. versionadded:: 2.6
-
.. method:: is_subnormal()
Return :const:`True` if the argument is subnormal, and :const:`False`
- otherwise. A number is subnormal is if it is nonzero, finite, and has an
- adjusted exponent less than *Emin*.
-
- .. versionadded:: 2.6
+ otherwise.
.. method:: is_zero()
Return :const:`True` if the argument is a (positive or negative) zero and
:const:`False` otherwise.
- .. versionadded:: 2.6
-
.. method:: ln([context])
Return the natural (base e) logarithm of the operand. The result is
correctly rounded using the :const:`ROUND_HALF_EVEN` rounding mode.
- .. versionadded:: 2.6
-
.. method:: log10([context])
Return the base ten logarithm of the operand. The result is correctly
rounded using the :const:`ROUND_HALF_EVEN` rounding mode.
- .. versionadded:: 2.6
-
.. method:: logb([context])
For a nonzero number, return the adjusted exponent of its operand as a
@@ -675,39 +607,29 @@ Decimal objects
is raised. If the operand is an infinity then ``Decimal('Infinity')`` is
returned.
- .. versionadded:: 2.6
-
.. method:: logical_and(other[, context])
:meth:`logical_and` is a logical operation which takes two *logical
operands* (see :ref:`logical_operands_label`). The result is the
digit-wise ``and`` of the two operands.
- .. versionadded:: 2.6
-
.. method:: logical_invert([context])
:meth:`logical_invert` is a logical operation. The
result is the digit-wise inversion of the operand.
- .. versionadded:: 2.6
-
.. method:: logical_or(other[, context])
:meth:`logical_or` is a logical operation which takes two *logical
operands* (see :ref:`logical_operands_label`). The result is the
digit-wise ``or`` of the two operands.
- .. versionadded:: 2.6
-
.. method:: logical_xor(other[, context])
:meth:`logical_xor` is a logical operation which takes two *logical
operands* (see :ref:`logical_operands_label`). The result is the
digit-wise exclusive or of the two operands.
- .. versionadded:: 2.6
-
.. method:: max(other[, context])
Like ``max(self, other)`` except that the context rounding rule is applied
@@ -720,8 +642,6 @@ Decimal objects
Similar to the :meth:`.max` method, but the comparison is done using the
absolute values of the operands.
- .. versionadded:: 2.6
-
.. method:: min(other[, context])
Like ``min(self, other)`` except that the context rounding rule is applied
@@ -734,24 +654,18 @@ Decimal objects
Similar to the :meth:`.min` method, but the comparison is done using the
absolute values of the operands.
- .. versionadded:: 2.6
-
.. method:: next_minus([context])
Return the largest number representable in the given context (or in the
current thread's context if no context is given) that is smaller than the
given operand.
- .. versionadded:: 2.6
-
.. method:: next_plus([context])
Return the smallest number representable in the given context (or in the
current thread's context if no context is given) that is larger than the
given operand.
- .. versionadded:: 2.6
-
.. method:: next_toward(other[, context])
If the two operands are unequal, return the number closest to the first
@@ -759,8 +673,6 @@ Decimal objects
numerically equal, return a copy of the first operand with the sign set to
be the same as the sign of the second operand.
- .. versionadded:: 2.6
-
.. method:: normalize([context])
Normalize the number by stripping the rightmost trailing zeros and
@@ -786,8 +698,6 @@ Decimal objects
* ``"NaN"``, indicating that the operand is a quiet NaN (Not a Number).
* ``"sNaN"``, indicating that the operand is a signaling NaN.
- .. versionadded:: 2.6
-
.. method:: quantize(exp[, rounding[, context[, watchexp]]])
Return a value equal to the first operand after rounding and having the
@@ -821,8 +731,6 @@ Decimal objects
class does all its arithmetic. Included for compatibility with the
specification.
- .. versionadded:: 2.6
-
.. method:: remainder_near(other[, context])
Return the remainder from dividing *self* by *other*. This differs from
@@ -852,8 +760,6 @@ Decimal objects
length precision if necessary. The sign and exponent of the first operand
are unchanged.
- .. versionadded:: 2.6
-
.. method:: same_quantum(other[, context])
Test whether self and other have the same exponent or whether both are
@@ -865,8 +771,6 @@ Decimal objects
Equivalently, return the first operand multiplied by ``10**other``. The
second operand must be an integer.
- .. versionadded:: 2.6
-
.. method:: shift(other[, context])
Return the result of shifting the digits of the first operand by an amount
@@ -877,8 +781,6 @@ Decimal objects
right. Digits shifted into the coefficient are zeros. The sign and
exponent of the first operand are unchanged.
- .. versionadded:: 2.6
-
.. method:: sqrt([context])
Return the square root of the argument to full precision.
@@ -905,17 +807,12 @@ Decimal objects
``context``. If neither parameter is given then the rounding mode of the
current context is used.
- .. versionadded:: 2.6
-
.. method:: to_integral_value([rounding[, context]])
Round to the nearest integer without signaling :const:`Inexact` or
:const:`Rounded`. If given, applies *rounding*; otherwise, uses the
rounding method in either the supplied *context* or the current context.
- .. versionchanged:: 2.6
- renamed from ``to_integral`` to ``to_integral_value``. The old name
- remains valid for compatibility.
.. _logical_operands_label:
@@ -953,9 +850,8 @@ Each thread has its own current context which is accessed or changed using the
Set the current context for the active thread to *c*.
-Beginning with Python 2.5, you can also use the :keyword:`with` statement and
-the :func:`localcontext` function to temporarily change the active context.
-
+You can also use the :keyword:`with` statement and the :func:`localcontext`
+function to temporarily change the active context.
.. function:: localcontext([c])
@@ -964,8 +860,6 @@ the :func:`localcontext` function to temporarily change the active context.
when exiting the with-statement. If no context is specified, a copy of the
current context is used.
- .. versionadded:: 2.5
-
For example, the following code sets the current decimal precision to 42 places,
performs a calculation, and then automatically restores the previous context::
@@ -976,10 +870,6 @@ the :func:`localcontext` function to temporarily change the active context.
s = calculate_something()
s = +s # Round the final result back to the default precision
- with localcontext(BasicContext): # temporarily use the BasicContext
- print Decimal(1) / Decimal(7)
- print Decimal(355) / Decimal(113)
-
New contexts can also be created using the :class:`Context` constructor
described below. In addition, the module provides three pre-made contexts:
@@ -1029,7 +919,7 @@ In addition to the three supplied contexts, new contexts can be created with the
:class:`Context` constructor.
-.. class:: Context(prec=None, rounding=None, traps=None, flags=None, Emin=None, Emax=None, capitals=1)
+.. class:: Context(prec=None, rounding=None, traps=None, flags=None, Emin=None, Emax=None, capitals=None, clamp=None)
Creates a new context. If a field is not specified or is :const:`None`, the
default values are copied from the :const:`DefaultContext`. If the *flags*
@@ -1060,8 +950,23 @@ In addition to the three supplied contexts, new contexts can be created with the
:const:`1`, exponents are printed with a capital :const:`E`; otherwise, a
lowercase :const:`e` is used: :const:`Decimal('6.02e+23')`.
- .. versionchanged:: 2.6
- The :const:`ROUND_05UP` rounding mode was added.
+ The *clamp* field is either :const:`0` (the default) or :const:`1`.
+ If set to :const:`1`, the exponent ``e`` of a :class:`Decimal`
+ instance representable in this context is strictly limited to the
+ range ``Emin - prec + 1 <= e <= Emax - prec + 1``. If *clamp* is
+ :const:`0` then a weaker condition holds: the adjusted exponent of
+ the :class:`Decimal` instance is at most ``Emax``. When *clamp* is
+ :const:`1`, a large normal number will, where possible, have its
+ exponent reduced and a corresponding number of zeros added to its
+ coefficient, in order to fit the exponent constraints; this
+ preserves the value of the number but loses information about
+ significant trailing zeros. For example::
+
+ >>> Context(prec=6, Emax=999, clamp=1).create_decimal('1.23e999')
+ Decimal('1.23000E+999')
+
+ A *clamp* value of :const:`1` allows compatibility with the
+ fixed-width decimal interchange formats specified in IEEE 754.
The :class:`Context` class defines several general purpose methods as well as
a large number of methods for doing arithmetic directly in a given context.
@@ -1070,7 +975,7 @@ In addition to the three supplied contexts, new contexts can be created with the
a corresponding :class:`Context` method. For example, for a :class:`Context`
instance ``C`` and :class:`Decimal` instance ``x``, ``C.exp(x)`` is
equivalent to ``x.exp(context=C)``. Each :class:`Context` method accepts a
- Python integer (an instance of :class:`int` or :class:`long`) anywhere that a
+ Python integer (an instance of :class:`int`) anywhere that a
Decimal instance is accepted.
@@ -1126,9 +1031,9 @@ In addition to the three supplied contexts, new contexts can be created with the
>>> context.create_decimal_from_float(math.pi)
Traceback (most recent call last):
...
- Inexact: None
+ decimal.Inexact: None
- .. versionadded:: 2.7
+ .. versionadded:: 3.1
.. method:: Etiny()
@@ -1136,7 +1041,6 @@ In addition to the three supplied contexts, new contexts can be created with the
value for subnormal results. When underflow occurs, the exponent is set
to :const:`Etiny`.
-
.. method:: Etop()
Returns a value equal to ``Emax - prec + 1``.
@@ -1396,10 +1300,6 @@ In addition to the three supplied contexts, new contexts can be created with the
the exponents of ``x``, ``y`` and ``modulo``. The result is
always exact.
- .. versionchanged:: 2.6
- ``y`` may now be nonintegral in ``x**y``.
- Stricter requirements for the three-argument version.
-
.. method:: quantize(x, y)
@@ -1418,6 +1318,7 @@ In addition to the three supplied contexts, new contexts can be created with the
The sign of the result, if non-zero, is the same as that of the original
dividend.
+
.. method:: remainder_near(x, y)
Returns ``x - y * n``, where *n* is the integer nearest the exact value
@@ -1579,7 +1480,7 @@ condition.
The following table summarizes the hierarchy of signals::
- exceptions.ArithmeticError(exceptions.StandardError)
+ exceptions.ArithmeticError(exceptions.Exception)
DecimalException
Clamped
DivisionByZero(DecimalException, exceptions.ZeroDivisionError)
@@ -1782,13 +1683,14 @@ to work with the :class:`Decimal` class::
q = Decimal(10) ** -places # 2 places --> '0.01'
sign, digits, exp = value.quantize(q).as_tuple()
result = []
- digits = map(str, digits)
+ digits = list(map(str, digits))
build, next = result.append, digits.pop
if sign:
build(trailneg)
for i in range(places):
build(next() if digits else '0')
- build(dp)
+ if places:
+ build(dp)
if not digits:
build('0')
i = 0
@@ -1805,7 +1707,7 @@ to work with the :class:`Decimal` class::
def pi():
"""Compute Pi to the current precision.
- >>> print pi()
+ >>> print(pi())
3.141592653589793238462643383
"""
@@ -1824,13 +1726,13 @@ to work with the :class:`Decimal` class::
def exp(x):
"""Return e raised to the power of x. Result type matches input type.
- >>> print exp(Decimal(1))
+ >>> print(exp(Decimal(1)))
2.718281828459045235360287471
- >>> print exp(Decimal(2))
+ >>> print(exp(Decimal(2)))
7.389056098930650227230427461
- >>> print exp(2.0)
+ >>> print(exp(2.0))
7.38905609893
- >>> print exp(2+0j)
+ >>> print(exp(2+0j))
(7.38905609893+0j)
"""
@@ -1848,11 +1750,14 @@ to work with the :class:`Decimal` class::
def cos(x):
"""Return the cosine of x as measured in radians.
- >>> print cos(Decimal('0.5'))
+ The Taylor series approximation works best for a small value of x.
+ For larger values, first compute x = x % (2 * pi).
+
+ >>> print(cos(Decimal('0.5')))
0.8775825618903727161162815826
- >>> print cos(0.5)
+ >>> print(cos(0.5))
0.87758256189
- >>> print cos(0.5+0j)
+ >>> print(cos(0.5+0j))
(0.87758256189+0j)
"""
@@ -1871,11 +1776,14 @@ to work with the :class:`Decimal` class::
def sin(x):
"""Return the sine of x as measured in radians.
- >>> print sin(Decimal('0.5'))
+ The Taylor series approximation works best for a small value of x.
+ For larger values, first compute x = x % (2 * pi).
+
+ >>> print(sin(Decimal('0.5')))
0.4794255386042030002732879352
- >>> print sin(0.5)
+ >>> print(sin(0.5))
0.479425538604
- >>> print sin(0.5+0j)
+ >>> print(sin(0.5+0j))
(0.479425538604+0j)
"""
@@ -1986,17 +1894,14 @@ of significant places in the coefficient. For example, expressing
original's two-place significance.
If an application does not care about tracking significance, it is easy to
-remove the exponent and trailing zeros, losing significance, but keeping the
-value unchanged::
-
- def remove_exponent(d):
- '''Remove exponent and trailing zeros.
+remove the exponent and trailing zeroes, losing significance, but keeping the
+value unchanged:
- >>> remove_exponent(Decimal('5E+3'))
- Decimal('5000')
+ >>> def remove_exponent(d):
+ ... return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()
- '''
- return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()
+ >>> remove_exponent(Decimal('5E+3'))
+ Decimal('5000')
Q. Is there a way to convert a regular float to a :class:`Decimal`?
diff --git a/Doc/library/development.rst b/Doc/library/development.rst
index 8cd3d0c..c822e08 100644
--- a/Doc/library/development.rst
+++ b/Doc/library/development.rst
@@ -1,4 +1,3 @@
-
.. _development:
*****************
diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst
index f3b23e0..bdc37b3 100644
--- a/Doc/library/difflib.rst
+++ b/Doc/library/difflib.rst
@@ -12,13 +12,12 @@
import sys
from difflib import *
-.. versionadded:: 2.1
-
This module provides classes and functions for comparing sequences. It
can be used for example, for comparing files, and can produce difference
information in various formats, including HTML and context and unified
diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
+
.. class:: SequenceMatcher
This is a flexible class for comparing pairs of sequences of any type, so long
@@ -45,9 +44,10 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
the purpose of sequence matching. This heuristic can be turned off by setting
the ``autojunk`` argument to ``False`` when creating the :class:`SequenceMatcher`.
- .. versionadded:: 2.7.1
+ .. versionadded:: 3.2
The *autojunk* parameter.
+
.. class:: Differ
This is a class for comparing sequences of lines of text, and producing
@@ -84,7 +84,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
The constructor for this class is:
- .. function:: __init__(tabsize=8, wrapcolumn=None, linejunk=None, charjunk=IS_CHARACTER_JUNK)
+ .. method:: __init__(tabsize=8, wrapcolumn=None, linejunk=None, charjunk=IS_CHARACTER_JUNK)
Initializes instance of :class:`HtmlDiff`.
@@ -100,8 +100,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
The following methods are public:
-
- .. function:: make_file(fromlines, tolines [, fromdesc][, todesc][, context][, numlines])
+ .. method:: make_file(fromlines, tolines, fromdesc='', todesc='', context=False, numlines=5)
Compares *fromlines* and *tolines* (lists of strings) and returns a string which
is a complete HTML file containing a table showing line by line differences with
@@ -120,8 +119,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
the next difference highlight at the top of the browser without any leading
context).
-
- .. function:: make_table(fromlines, tolines [, fromdesc][, todesc][, context][, numlines])
+ .. method:: make_table(fromlines, tolines, fromdesc='', todesc='', context=False, numlines=5)
Compares *fromlines* and *tolines* (lists of strings) and returns a string which
is a complete HTML table showing line by line differences with inter-line and
@@ -133,10 +131,8 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
:file:`Tools/scripts/diff.py` is a command-line front-end to this class and
contains a good example of its use.
- .. versionadded:: 2.4
-
-.. function:: context_diff(a, b[, fromfile][, tofile][, fromfiledate][, tofiledate][, n][, lineterm])
+.. function:: context_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\\n')
Compare *a* and *b* (lists of strings); return a delta (a :term:`generator`
generating the delta lines) in context diff format.
@@ -180,10 +176,8 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
See :ref:`difflib-interface` for a more detailed example.
- .. versionadded:: 2.3
-
-.. function:: get_close_matches(word, possibilities[, n][, cutoff])
+.. function:: get_close_matches(word, possibilities, n=3, cutoff=0.6)
Return a list of the best "good enough" matches. *word* is a sequence for which
close matches are desired (typically a string), and *possibilities* is a list of
@@ -209,7 +203,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
['except']
-.. function:: ndiff(a, b[, linejunk][, charjunk])
+.. function:: ndiff(a, b, linejunk=None, charjunk=IS_CHARACTER_JUNK)
Compare *a* and *b* (lists of strings); return a :class:`Differ`\ -style
delta (a :term:`generator` generating the delta lines).
@@ -217,14 +211,13 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
Optional keyword parameters *linejunk* and *charjunk* are for filter functions
(or ``None``):
- *linejunk*: A function that accepts a single string argument, and returns true
- if the string is junk, or false if not. The default is (``None``), starting with
- Python 2.3. Before then, the default was the module-level function
- :func:`IS_LINE_JUNK`, which filters out lines without visible characters, except
- for at most one pound character (``'#'``). As of Python 2.3, the underlying
- :class:`SequenceMatcher` class does a dynamic analysis of which lines are so
- frequent as to constitute noise, and this usually works better than the pre-2.3
- default.
+ *linejunk*: A function that accepts a single string argument, and returns
+ true if the string is junk, or false if not. The default is ``None``. There
+ is also a module-level function :func:`IS_LINE_JUNK`, which filters out lines
+ without visible characters, except for at most one pound character (``'#'``)
+ -- however the underlying :class:`SequenceMatcher` class does a dynamic
+ analysis of which lines are so frequent as to constitute noise, and this
+ usually works better than using this function.
*charjunk*: A function that accepts a character (a string of length 1), and
returns if the character is junk, or false if not. The default is module-level
@@ -235,7 +228,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
>>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1),
... 'ore\ntree\nemu\n'.splitlines(1))
- >>> print ''.join(diff),
+ >>> print(''.join(diff), end="")
- one
? ^
+ ore
@@ -260,17 +253,17 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
>>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1),
... 'ore\ntree\nemu\n'.splitlines(1))
>>> diff = list(diff) # materialize the generated delta into a list
- >>> print ''.join(restore(diff, 1)),
+ >>> print(''.join(restore(diff, 1)), end="")
one
two
three
- >>> print ''.join(restore(diff, 2)),
+ >>> print(''.join(restore(diff, 2)), end="")
ore
tree
emu
-.. function:: unified_diff(a, b[, fromfile][, tofile][, fromfiledate][, tofiledate][, n][, lineterm])
+.. function:: unified_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\\n')
Compare *a* and *b* (lists of strings); return a delta (a :term:`generator`
generating the delta lines) in unified diff format.
@@ -295,6 +288,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
expressed in the ISO 8601 format. If not specified, the
strings default to blanks.
+
>>> s1 = ['bacon\n', 'eggs\n', 'ham\n', 'guido\n']
>>> s2 = ['python\n', 'eggy\n', 'hamster\n', 'guido\n']
>>> for line in unified_diff(s1, s2, fromfile='before.py', tofile='after.py'):
@@ -312,14 +306,12 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
See :ref:`difflib-interface` for a more detailed example.
- .. versionadded:: 2.3
-
.. function:: IS_LINE_JUNK(line)
Return true for ignorable lines. The line *line* is ignorable if *line* is
blank or contains a single ``'#'``, otherwise it is not ignorable. Used as a
- default for parameter *linejunk* in :func:`ndiff` before Python 2.3.
+ default for parameter *linejunk* in :func:`ndiff` in older versions.
.. function:: IS_CHARACTER_JUNK(ch)
@@ -363,9 +355,19 @@ The :class:`SequenceMatcher` class has this constructor:
The optional argument *autojunk* can be used to disable the automatic junk
heuristic.
- .. versionadded:: 2.7.1
+ .. versionadded:: 3.2
The *autojunk* parameter.
+ SequenceMatcher objects get three data attributes: *bjunk* is the
+ set of elements of *b* for which *isjunk* is True; *bpopular* is the set of
+ non-junk elements considered popular by the heuristic (if it is not
+ disabled); *b2j* is a dict mapping the remaining elements of *b* to a list
+ of positions where they occur. All three are reset whenever *b* is reset
+ with :meth:`set_seqs` or :meth:`set_seq2`.
+
+ .. versionadded:: 3.2
+ The *bjunk* and *bpopular* attributes.
+
:class:`SequenceMatcher` objects have the following methods:
.. method:: set_seqs(a, b)
@@ -425,8 +427,7 @@ The :class:`SequenceMatcher` class has this constructor:
If no blocks match, this returns ``(alo, blo, 0)``.
- .. versionchanged:: 2.6
- This method returns a :term:`named tuple` ``Match(a, b, size)``.
+ This method returns a :term:`named tuple` ``Match(a, b, size)``.
.. method:: get_matching_blocks()
@@ -443,10 +444,6 @@ The :class:`SequenceMatcher` class has this constructor:
.. XXX Explain why a dummy is used!
- .. versionchanged:: 2.5
- The guarantee that adjacent triples always describe non-adjacent blocks
- was implemented.
-
.. doctest::
>>> s = SequenceMatcher(None, "abxcd", "abcd")
@@ -482,20 +479,22 @@ The :class:`SequenceMatcher` class has this constructor:
For example:
- >>> a = "qabxcd"
- >>> b = "abycdf"
- >>> s = SequenceMatcher(None, a, b)
- >>> for tag, i1, i2, j1, j2 in s.get_opcodes():
- ... print ("%7s a[%d:%d] (%s) b[%d:%d] (%s)" %
- ... (tag, i1, i2, a[i1:i2], j1, j2, b[j1:j2]))
- delete a[0:1] (q) b[0:0] ()
- equal a[1:3] (ab) b[0:2] (ab)
- replace a[3:4] (x) b[2:3] (y)
- equal a[4:6] (cd) b[3:5] (cd)
- insert a[6:6] () b[5:6] (f)
+ >>> a = "qabxcd"
+ >>> b = "abycdf"
+ >>> s = SequenceMatcher(None, a, b)
+ >>> for tag, i1, i2, j1, j2 in s.get_opcodes():
+ print('{:7} a[{}:{}] --> b[{}:{}] {!r:>8} --> {!r}'.format(
+ tag, i1, i2, j1, j2, a[i1:i2], b[j1:j2]))
+
+ delete a[0:1] --> b[0:0] 'q' --> ''
+ equal a[1:3] --> b[0:2] 'ab' --> 'ab'
+ replace a[3:4] --> b[2:3] 'x' --> 'y'
+ equal a[4:6] --> b[3:5] 'cd' --> 'cd'
+ insert a[6:6] --> b[5:6] '' --> 'f'
- .. method:: get_grouped_opcodes([n])
+
+ .. method:: get_grouped_opcodes(n=3)
Return a :term:`generator` of groups with up to *n* lines of context.
@@ -505,8 +504,6 @@ The :class:`SequenceMatcher` class has this constructor:
The groups are returned in the same format as :meth:`get_opcodes`.
- .. versionadded:: 2.3
-
.. method:: ratio()
@@ -552,7 +549,7 @@ different results due to differing levels of approximation, although
SequenceMatcher Examples
------------------------
-This example compares two strings, considering blanks to be "junk:"
+This example compares two strings, considering blanks to be "junk":
>>> s = SequenceMatcher(lambda x: x == " ",
... "private Thread currentThread;",
@@ -562,14 +559,14 @@ This example compares two strings, considering blanks to be "junk:"
sequences. As a rule of thumb, a :meth:`ratio` value over 0.6 means the
sequences are close matches:
- >>> print round(s.ratio(), 3)
+ >>> print(round(s.ratio(), 3))
0.866
If you're only interested in where the sequences match,
:meth:`get_matching_blocks` is handy:
>>> for block in s.get_matching_blocks():
- ... print "a[%d] and b[%d] match for %d elements" % block
+ ... print("a[%d] and b[%d] match for %d elements" % block)
a[0] and b[0] match for 8 elements
a[8] and b[17] match for 21 elements
a[29] and b[38] match for 0 elements
@@ -582,7 +579,7 @@ If you want to know how to change the first sequence into the second, use
:meth:`get_opcodes`:
>>> for opcode in s.get_opcodes():
- ... print "%6s a[%d:%d] b[%d:%d]" % opcode
+ ... print("%6s a[%d:%d] b[%d:%d]" % opcode)
equal a[0:8] b[0:8]
insert a[8:8] b[8:17]
equal a[8:29] b[17:38]
@@ -612,7 +609,7 @@ locality, at the occasional cost of producing a longer diff.
The :class:`Differ` class has this constructor:
-.. class:: Differ([linejunk[, charjunk]])
+.. class:: Differ(linejunk=None, charjunk=None)
Optional keyword parameters *linejunk* and *charjunk* are for filter functions
(or ``None``):
diff --git a/Doc/library/dircache.rst b/Doc/library/dircache.rst
deleted file mode 100644
index 632ddd5..0000000
--- a/Doc/library/dircache.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-
-:mod:`dircache` --- Cached directory listings
-=============================================
-
-.. module:: dircache
- :synopsis: Return directory listing, with cache mechanism.
- :deprecated:
-
-.. deprecated:: 2.6
- The :mod:`dircache` module has been removed in Python 3.
-
-
-.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
-
-
-The :mod:`dircache` module defines a function for reading directory listing
-using a cache, and cache invalidation using the *mtime* of the directory.
-Additionally, it defines a function to annotate directories by appending a
-slash.
-
-The :mod:`dircache` module defines the following functions:
-
-
-.. function:: reset()
-
- Resets the directory cache.
-
-
-.. function:: listdir(path)
-
- Return a directory listing of *path*, as gotten from :func:`os.listdir`. Note
- that unless *path* changes, further call to :func:`listdir` will not re-read the
- directory structure.
-
- Note that the list returned should be regarded as read-only. (Perhaps a future
- version should change it to return a tuple?)
-
-
-.. function:: opendir(path)
-
- Same as :func:`listdir`. Defined for backwards compatibility.
-
-
-.. function:: annotate(head, list)
-
- Assume *list* is a list of paths relative to *head*, and append, in place, a
- ``'/'`` to each path which points to a directory.
-
-::
-
- >>> import dircache
- >>> a = dircache.listdir('/')
- >>> a = a[:] # Copy the return value so we can change 'a'
- >>> a
- ['bin', 'boot', 'cdrom', 'dev', 'etc', 'floppy', 'home', 'initrd', 'lib', 'lost+
- found', 'mnt', 'proc', 'root', 'sbin', 'tmp', 'usr', 'var', 'vmlinuz']
- >>> dircache.annotate('/', a)
- >>> a
- ['bin/', 'boot/', 'cdrom/', 'dev/', 'etc/', 'floppy/', 'home/', 'initrd/', 'lib/
- ', 'lost+found/', 'mnt/', 'proc/', 'root/', 'sbin/', 'tmp/', 'usr/', 'var/', 'vm
- linuz']
-
diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index 8dee901..108cda7 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -15,11 +15,12 @@ and the interpreter.
.. impl-detail::
- Bytecode is an implementation detail of the CPython interpreter! No
+ Bytecode is an implementation detail of the CPython interpreter. No
guarantees are made that bytecode will not be added, removed, or changed
between versions of Python. Use of this module should not be considered to
work across Python VMs or Python releases.
+
Example: Given the function :func:`myfunc`::
def myfunc(alist):
@@ -38,24 +39,51 @@ the following command can be used to get the disassembly of :func:`myfunc`::
The :mod:`dis` module defines the following functions and constants:
-.. function:: dis([bytesource])
+.. function:: code_info(x)
+
+ Return a formatted multi-line string with detailed code object information
+ for the supplied function, method, source code string or code object.
+
+ Note that the exact contents of code info strings are highly implementation
+ dependent and they may change arbitrarily across Python VMs or Python
+ releases.
+
+ .. versionadded:: 3.2
+
+
+.. function:: show_code(x)
+
+ Print detailed code object information for the supplied function, method,
+ source code string or code object to stdout.
- Disassemble the *bytesource* object. *bytesource* can denote either a module, a
- class, a method, a function, or a code object. For a module, it disassembles
- all functions. For a class, it disassembles all methods. For a single code
- sequence, it prints one line per bytecode instruction. If no object is
- provided, it disassembles the last traceback.
+ This is a convenient shorthand for ``print(code_info(x))``, intended for
+ interactive exploration at the interpreter prompt.
+ .. versionadded:: 3.2
-.. function:: distb([tb])
+.. function:: dis(x=None)
- Disassembles the top-of-stack function of a traceback, using the last traceback
- if none was passed. The instruction causing the exception is indicated.
+ Disassemble the *x* object. *x* can denote either a module, a class, a
+ method, a function, a code object, a string of source code or a byte sequence
+ of raw bytecode. For a module, it disassembles all functions. For a class,
+ it disassembles all methods. For a code object or sequence of raw bytecode,
+ it prints one line per bytecode instruction. Strings are first compiled to
+ code objects with the :func:`compile` built-in function before being
+ disassembled. If no object is provided, this function disassembles the last
+ traceback.
-.. function:: disassemble(code[, lasti])
+.. function:: distb(tb=None)
- Disassembles a code object, indicating the last instruction if *lasti* was
+ Disassemble the top-of-stack function of a traceback, using the last
+ traceback if none was passed. The instruction causing the exception is
+ indicated.
+
+
+.. function:: disassemble(code, lasti=-1)
+ disco(code, lasti=-1)
+
+ Disassemble a code object, indicating the last instruction if *lasti* was
provided. The output is divided in the following columns:
#. the line number, for the first instruction of each line
@@ -70,12 +98,6 @@ The :mod:`dis` module defines the following functions and constants:
constant values, branch targets, and compare operators.
-.. function:: disco(code[, lasti])
-
- A synonym for :func:`disassemble`. It is more convenient to type, and kept
- for compatibility with earlier Python releases.
-
-
.. function:: findlinestarts(code)
This generator function uses the ``co_firstlineno`` and ``co_lnotab``
@@ -147,333 +169,233 @@ Python Bytecode Instructions
The Python compiler currently generates the following bytecode instructions.
-.. opcode:: STOP_CODE ()
+**General instructions**
+
+.. opcode:: STOP_CODE
Indicates end-of-code to the compiler, not used by the interpreter.
-.. opcode:: NOP ()
+.. opcode:: NOP
Do nothing code. Used as a placeholder by the bytecode optimizer.
-.. opcode:: POP_TOP ()
+.. opcode:: POP_TOP
Removes the top-of-stack (TOS) item.
-.. opcode:: ROT_TWO ()
+.. opcode:: ROT_TWO
Swaps the two top-most stack items.
-.. opcode:: ROT_THREE ()
+.. opcode:: ROT_THREE
Lifts second and third stack item one position up, moves top down to position
three.
-.. opcode:: ROT_FOUR ()
+.. opcode:: DUP_TOP
- Lifts second, third and forth stack item one position up, moves top down to
- position four.
+ Duplicates the reference on top of the stack.
-.. opcode:: DUP_TOP ()
+.. opcode:: DUP_TOP_TWO
- Duplicates the reference on top of the stack.
+ Duplicates the two references on top of the stack, leaving them in the
+ same order.
-Unary Operations take the top of the stack, apply the operation, and push the
-result back on the stack.
+**Unary operations**
+
+Unary operations take the top of the stack, apply the operation, and push the
+result back on the stack.
-.. opcode:: UNARY_POSITIVE ()
+.. opcode:: UNARY_POSITIVE
Implements ``TOS = +TOS``.
-.. opcode:: UNARY_NEGATIVE ()
+.. opcode:: UNARY_NEGATIVE
Implements ``TOS = -TOS``.
-.. opcode:: UNARY_NOT ()
+.. opcode:: UNARY_NOT
Implements ``TOS = not TOS``.
-.. opcode:: UNARY_CONVERT ()
-
- Implements ``TOS = `TOS```.
-
-
-.. opcode:: UNARY_INVERT ()
+.. opcode:: UNARY_INVERT
Implements ``TOS = ~TOS``.
-.. opcode:: GET_ITER ()
+.. opcode:: GET_ITER
Implements ``TOS = iter(TOS)``.
+
+**Binary operations**
+
Binary operations remove the top of the stack (TOS) and the second top-most
stack item (TOS1) from the stack. They perform the operation, and put the
result back on the stack.
-
-.. opcode:: BINARY_POWER ()
+.. opcode:: BINARY_POWER
Implements ``TOS = TOS1 ** TOS``.
-.. opcode:: BINARY_MULTIPLY ()
+.. opcode:: BINARY_MULTIPLY
Implements ``TOS = TOS1 * TOS``.
-.. opcode:: BINARY_DIVIDE ()
-
- Implements ``TOS = TOS1 / TOS`` when ``from __future__ import division`` is not
- in effect.
-
-
-.. opcode:: BINARY_FLOOR_DIVIDE ()
+.. opcode:: BINARY_FLOOR_DIVIDE
Implements ``TOS = TOS1 // TOS``.
-.. opcode:: BINARY_TRUE_DIVIDE ()
+.. opcode:: BINARY_TRUE_DIVIDE
- Implements ``TOS = TOS1 / TOS`` when ``from __future__ import division`` is in
- effect.
+ Implements ``TOS = TOS1 / TOS``.
-.. opcode:: BINARY_MODULO ()
+.. opcode:: BINARY_MODULO
Implements ``TOS = TOS1 % TOS``.
-.. opcode:: BINARY_ADD ()
+.. opcode:: BINARY_ADD
Implements ``TOS = TOS1 + TOS``.
-.. opcode:: BINARY_SUBTRACT ()
+.. opcode:: BINARY_SUBTRACT
Implements ``TOS = TOS1 - TOS``.
-.. opcode:: BINARY_SUBSCR ()
+.. opcode:: BINARY_SUBSCR
Implements ``TOS = TOS1[TOS]``.
-.. opcode:: BINARY_LSHIFT ()
+.. opcode:: BINARY_LSHIFT
Implements ``TOS = TOS1 << TOS``.
-.. opcode:: BINARY_RSHIFT ()
+.. opcode:: BINARY_RSHIFT
Implements ``TOS = TOS1 >> TOS``.
-.. opcode:: BINARY_AND ()
+.. opcode:: BINARY_AND
Implements ``TOS = TOS1 & TOS``.
-.. opcode:: BINARY_XOR ()
+.. opcode:: BINARY_XOR
Implements ``TOS = TOS1 ^ TOS``.
-.. opcode:: BINARY_OR ()
+.. opcode:: BINARY_OR
Implements ``TOS = TOS1 | TOS``.
+
+**In-place operations**
+
In-place operations are like binary operations, in that they remove TOS and
TOS1, and push the result back on the stack, but the operation is done in-place
when TOS1 supports it, and the resulting TOS may be (but does not have to be)
the original TOS1.
-
-.. opcode:: INPLACE_POWER ()
+.. opcode:: INPLACE_POWER
Implements in-place ``TOS = TOS1 ** TOS``.
-.. opcode:: INPLACE_MULTIPLY ()
+.. opcode:: INPLACE_MULTIPLY
Implements in-place ``TOS = TOS1 * TOS``.
-.. opcode:: INPLACE_DIVIDE ()
-
- Implements in-place ``TOS = TOS1 / TOS`` when ``from __future__ import
- division`` is not in effect.
-
-
-.. opcode:: INPLACE_FLOOR_DIVIDE ()
+.. opcode:: INPLACE_FLOOR_DIVIDE
Implements in-place ``TOS = TOS1 // TOS``.
-.. opcode:: INPLACE_TRUE_DIVIDE ()
+.. opcode:: INPLACE_TRUE_DIVIDE
- Implements in-place ``TOS = TOS1 / TOS`` when ``from __future__ import
- division`` is in effect.
+ Implements in-place ``TOS = TOS1 / TOS``.
-.. opcode:: INPLACE_MODULO ()
+.. opcode:: INPLACE_MODULO
Implements in-place ``TOS = TOS1 % TOS``.
-.. opcode:: INPLACE_ADD ()
+.. opcode:: INPLACE_ADD
Implements in-place ``TOS = TOS1 + TOS``.
-.. opcode:: INPLACE_SUBTRACT ()
+.. opcode:: INPLACE_SUBTRACT
Implements in-place ``TOS = TOS1 - TOS``.
-.. opcode:: INPLACE_LSHIFT ()
+.. opcode:: INPLACE_LSHIFT
Implements in-place ``TOS = TOS1 << TOS``.
-.. opcode:: INPLACE_RSHIFT ()
+.. opcode:: INPLACE_RSHIFT
Implements in-place ``TOS = TOS1 >> TOS``.
-.. opcode:: INPLACE_AND ()
+.. opcode:: INPLACE_AND
Implements in-place ``TOS = TOS1 & TOS``.
-.. opcode:: INPLACE_XOR ()
+.. opcode:: INPLACE_XOR
Implements in-place ``TOS = TOS1 ^ TOS``.
-.. opcode:: INPLACE_OR ()
+.. opcode:: INPLACE_OR
Implements in-place ``TOS = TOS1 | TOS``.
-The slice opcodes take up to three parameters.
-
-
-.. opcode:: SLICE+0 ()
-
- Implements ``TOS = TOS[:]``.
-
-
-.. opcode:: SLICE+1 ()
-
- Implements ``TOS = TOS1[TOS:]``.
-
-
-.. opcode:: SLICE+2 ()
-
- Implements ``TOS = TOS1[:TOS]``.
-
-
-.. opcode:: SLICE+3 ()
-
- Implements ``TOS = TOS2[TOS1:TOS]``.
-
-Slice assignment needs even an additional parameter. As any statement, they put
-nothing on the stack.
-
-
-.. opcode:: STORE_SLICE+0 ()
-
- Implements ``TOS[:] = TOS1``.
-
-.. opcode:: STORE_SLICE+1 ()
-
- Implements ``TOS1[TOS:] = TOS2``.
-
-
-.. opcode:: STORE_SLICE+2 ()
-
- Implements ``TOS1[:TOS] = TOS2``.
-
-
-.. opcode:: STORE_SLICE+3 ()
-
- Implements ``TOS2[TOS1:TOS] = TOS3``.
-
-
-.. opcode:: DELETE_SLICE+0 ()
-
- Implements ``del TOS[:]``.
-
-
-.. opcode:: DELETE_SLICE+1 ()
-
- Implements ``del TOS1[TOS:]``.
-
-
-.. opcode:: DELETE_SLICE+2 ()
-
- Implements ``del TOS1[:TOS]``.
-
-
-.. opcode:: DELETE_SLICE+3 ()
-
- Implements ``del TOS2[TOS1:TOS]``.
-
-
-.. opcode:: STORE_SUBSCR ()
+.. opcode:: STORE_SUBSCR
Implements ``TOS1[TOS] = TOS2``.
-.. opcode:: DELETE_SUBSCR ()
+.. opcode:: DELETE_SUBSCR
Implements ``del TOS1[TOS]``.
-Miscellaneous opcodes.
+**Miscellaneous opcodes**
-.. opcode:: PRINT_EXPR ()
+.. opcode:: PRINT_EXPR
Implements the expression statement for the interactive mode. TOS is removed
from the stack and printed. In non-interactive mode, an expression statement is
terminated with ``POP_STACK``.
-.. opcode:: PRINT_ITEM ()
-
- Prints TOS to the file-like object bound to ``sys.stdout``. There is one such
- instruction for each item in the :keyword:`print` statement.
-
-
-.. opcode:: PRINT_ITEM_TO ()
-
- Like ``PRINT_ITEM``, but prints the item second from TOS to the file-like object
- at TOS. This is used by the extended print statement.
-
-
-.. opcode:: PRINT_NEWLINE ()
-
- Prints a new line on ``sys.stdout``. This is generated as the last operation of
- a :keyword:`print` statement, unless the statement ends with a comma.
-
-
-.. opcode:: PRINT_NEWLINE_TO ()
-
- Like ``PRINT_NEWLINE``, but prints the new line on the file-like object on the
- TOS. This is used by the extended print statement.
-
-
-.. opcode:: BREAK_LOOP ()
+.. opcode:: BREAK_LOOP
Terminates a loop due to a :keyword:`break` statement.
@@ -484,60 +406,68 @@ Miscellaneous opcodes.
address to jump to (which should be a ``FOR_ITER`` instruction).
+.. opcode:: SET_ADD (i)
+
+ Calls ``set.add(TOS1[-i], TOS)``. Used to implement set comprehensions.
+
+
.. opcode:: LIST_APPEND (i)
Calls ``list.append(TOS[-i], TOS)``. Used to implement list comprehensions.
- While the appended value is popped off, the list object remains on the
- stack so that it is available for further iterations of the loop.
-.. opcode:: LOAD_LOCALS ()
+.. opcode:: MAP_ADD (i)
+
+ Calls ``dict.setitem(TOS1[-i], TOS, TOS1)``. Used to implement dict
+ comprehensions.
- Pushes a reference to the locals of the current scope on the stack. This is used
- in the code for a class definition: After the class body is evaluated, the
- locals are passed to the class definition.
+For all of the SET_ADD, LIST_APPEND and MAP_ADD instructions, while the
+added value or key/value pair is popped off, the container object remains on
+the stack so that it is available for further iterations of the loop.
-.. opcode:: RETURN_VALUE ()
+.. opcode:: RETURN_VALUE
Returns with TOS to the caller of the function.
-.. opcode:: YIELD_VALUE ()
+.. opcode:: YIELD_VALUE
Pops ``TOS`` and yields it from a :term:`generator`.
-.. opcode:: IMPORT_STAR ()
+.. opcode:: IMPORT_STAR
Loads all symbols not starting with ``'_'`` directly from the module TOS to the
local namespace. The module is popped after loading all names. This opcode
implements ``from module import *``.
-.. opcode:: EXEC_STMT ()
+.. opcode:: POP_BLOCK
- Implements ``exec TOS2,TOS1,TOS``. The compiler fills missing optional
- parameters with ``None``.
+ Removes one block from the block stack. Per frame, there is a stack of blocks,
+ denoting nested loops, try statements, and such.
-.. opcode:: POP_BLOCK ()
+.. opcode:: POP_EXCEPT
- Removes one block from the block stack. Per frame, there is a stack of blocks,
- denoting nested loops, try statements, and such.
+ Removes one block from the block stack. The popped block must be an exception
+ handler block, as implicitly created when entering an except handler.
+ In addition to popping extraneous values from the frame stack, the
+ last three popped values are used to restore the exception state.
-.. opcode:: END_FINALLY ()
+.. opcode:: END_FINALLY
Terminates a :keyword:`finally` clause. The interpreter recalls whether the
exception has to be re-raised, or whether the function returns, and continues
with the outer-next block.
-.. opcode:: BUILD_CLASS ()
+.. opcode:: LOAD_BUILD_CLASS
- Creates a new class object. TOS is the methods dictionary, TOS1 the tuple of
- the names of the base classes, and TOS2 the class name.
+ Pushes :func:`builtins.__build_class__` onto the stack. It is later called
+ by ``CALL_FUNCTION`` to construct a class.
.. opcode:: SETUP_WITH (delta)
@@ -552,30 +482,34 @@ Miscellaneous opcodes.
:opcode:`UNPACK_SEQUENCE`).
-.. opcode:: WITH_CLEANUP ()
-
- Cleans up the stack when a :keyword:`with` statement block exits. On top of
- the stack are 1--3 values indicating how/why the finally clause was entered:
+.. opcode:: WITH_CLEANUP
- * TOP = ``None``
- * (TOP, SECOND) = (``WHY_{RETURN,CONTINUE}``), retval
- * TOP = ``WHY_*``; no retval below it
- * (TOP, SECOND, THIRD) = exc_info()
+ Cleans up the stack when a :keyword:`with` statement block exits. TOS is
+ the context manager's :meth:`__exit__` bound method. Below TOS are 1--3
+ values indicating how/why the finally clause was entered:
- Under them is EXIT, the context manager's :meth:`__exit__` bound method.
+ * SECOND = ``None``
+ * (SECOND, THIRD) = (``WHY_{RETURN,CONTINUE}``), retval
+ * SECOND = ``WHY_*``; no retval below it
+ * (SECOND, THIRD, FOURTH) = exc_info()
- In the last case, ``EXIT(TOP, SECOND, THIRD)`` is called, otherwise
- ``EXIT(None, None, None)``.
+ In the last case, ``TOS(SECOND, THIRD, FOURTH)`` is called, otherwise
+ ``TOS(None, None, None)``. In addition, TOS is removed from the stack.
- EXIT is removed from the stack, leaving the values above it in the same
- order. In addition, if the stack represents an exception, *and* the function
- call returns a 'true' value, this information is "zapped", to prevent
- ``END_FINALLY`` from re-raising the exception. (But non-local gotos should
- still be resumed.)
+ If the stack represents an exception, *and* the function call returns
+ a 'true' value, this information is "zapped" and replaced with a single
+ ``WHY_SILENCED`` to prevent ``END_FINALLY`` from re-raising the exception.
+ (But non-local gotos will still be resumed.)
.. XXX explain the WHY stuff!
+.. opcode:: STORE_LOCALS
+
+ Pops TOS from the stack and stores it as the current frame's ``f_locals``.
+ This is used in class construction.
+
+
All of the following opcodes expect arguments. An argument is two bytes, with
the more significant byte last.
@@ -598,10 +532,16 @@ the more significant byte last.
right-to-left.
-.. opcode:: DUP_TOPX (count)
+.. opcode:: UNPACK_EX (counts)
+
+ Implements assignment with a starred target: Unpacks an iterable in TOS into
+ individual values, where the total number of values can be smaller than the
+ number of items in the iterable: one the new values will be a list of all
+ leftover items.
- Duplicate *count* items, keeping them in the same order. Due to implementation
- limits, *count* should be between 1 and 5 inclusive.
+ The low byte of *counts* is the number of values before the list value, the
+ high byte of *counts* the number of values after it. The resulting values
+ are put onto the stack right-to-left.
.. opcode:: STORE_ATTR (namei)
@@ -646,6 +586,11 @@ the more significant byte last.
Works as ``BUILD_TUPLE``, but creates a list.
+.. opcode:: BUILD_SET (count)
+
+ Works as ``BUILD_TUPLE``, but creates a set.
+
+
.. opcode:: BUILD_MAP (count)
Pushes a new dictionary object onto the stack. The dictionary is pre-sized
@@ -713,10 +658,10 @@ the more significant byte last.
.. opcode:: FOR_ITER (delta)
- ``TOS`` is an :term:`iterator`. Call its :meth:`!next` method. If this
- yields a new value, push it on the stack (leaving the iterator below it). If
- the iterator indicates it is exhausted ``TOS`` is popped, and the bytecode
- counter is incremented by *delta*.
+ ``TOS`` is an :term:`iterator`. Call its :meth:`~iterator.__next__` method.
+ If this yields a new value, push it on the stack (leaving the iterator below
+ it). If the iterator indicates it is exhausted ``TOS`` is popped, and the
+ byte code counter is incremented by *delta*.
.. opcode:: LOAD_GLOBAL (namei)
@@ -741,7 +686,7 @@ the more significant byte last.
Pushes a try block from a try-except clause onto the block stack. *delta* points
to the finally block.
-.. opcode:: STORE_MAP ()
+.. opcode:: STORE_MAP
Store a key and value pair in a dictionary. Pops the key and value while leaving
the dictionary on the stack.
@@ -781,9 +726,10 @@ the more significant byte last.
storage.
-.. opcode:: SET_LINENO (lineno)
+.. opcode:: DELETE_DEREF (i)
- This opcode is obsolete.
+ Empties the cell contained in slot *i* of the cell and free variable storage.
+ Used by the :keyword:`del` statement.
.. opcode:: RAISE_VARARGS (argc)
@@ -813,7 +759,7 @@ the more significant byte last.
.. opcode:: MAKE_CLOSURE (argc)
- Creates a new function object, sets its *func_closure* slot, and pushes it on
+ Creates a new function object, sets its *__closure__* slot, and pushes it on
the stack. TOS is the code associated with the function, TOS1 the tuple
containing cells for the closure's free variables. The function also has
*argc* default parameters, which are found below the cells.
@@ -857,7 +803,7 @@ the more significant byte last.
variable-arguments tuple, followed by explicit keyword and positional arguments.
-.. opcode:: HAVE_ARGUMENT ()
+.. opcode:: HAVE_ARGUMENT
This is not really an opcode. It identifies the dividing line between opcodes
which don't take arguments ``< HAVE_ARGUMENT`` and those which do ``>=
diff --git a/Doc/library/distutils.rst b/Doc/library/distutils.rst
index 534faab..238b79d 100644
--- a/Doc/library/distutils.rst
+++ b/Doc/library/distutils.rst
@@ -1,10 +1,9 @@
-
:mod:`distutils` --- Building and installing Python modules
===========================================================
.. module:: distutils
- :synopsis: Support for building and installing Python modules into an existing Python
- installation.
+ :synopsis: Support for building and installing Python modules into an
+ existing Python installation.
.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
@@ -19,12 +18,12 @@ This package is discussed in two separate chapters:
.. seealso::
:ref:`distutils-index`
- The manual for developers and packagers of Python modules. This describes how
- to prepare :mod:`distutils`\ -based packages so that they may be easily
- installed into an existing Python installation.
+ The manual for developers and packagers of Python modules. This describes
+ how to prepare :mod:`distutils`\ -based packages so that they may be
+ easily installed into an existing Python installation.
:ref:`install-index`
- An "administrators" manual which includes information on installing modules into
- an existing Python installation. You do not need to be a Python programmer to
- read this manual.
+ An "administrators" manual which includes information on installing
+ modules into an existing Python installation. You do not need to be a
+ Python programmer to read this manual.
diff --git a/Doc/library/dl.rst b/Doc/library/dl.rst
deleted file mode 100644
index 40556cc..0000000
--- a/Doc/library/dl.rst
+++ /dev/null
@@ -1,114 +0,0 @@
-
-:mod:`dl` --- Call C functions in shared objects
-================================================
-
-.. module:: dl
- :platform: Unix
- :synopsis: Call C functions in shared objects.
- :deprecated:
-
-.. deprecated:: 2.6
- The :mod:`dl` module has been removed in Python 3. Use the :mod:`ctypes`
- module instead.
-
-.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
-
-The :mod:`dl` module defines an interface to the :c:func:`dlopen` function, which
-is the most common interface on Unix platforms for handling dynamically linked
-libraries. It allows the program to call arbitrary functions in such a library.
-
-.. warning::
-
- The :mod:`dl` module bypasses the Python type system and error handling. If
- used incorrectly it may cause segmentation faults, crashes or other incorrect
- behaviour.
-
-.. note::
-
- This module will not work unless ``sizeof(int) == sizeof(long) == sizeof(char
- *)`` If this is not the case, :exc:`SystemError` will be raised on import.
-
-The :mod:`dl` module defines the following function:
-
-
-.. function:: open(name[, mode=RTLD_LAZY])
-
- Open a shared object file, and return a handle. Mode signifies late binding
- (:const:`RTLD_LAZY`) or immediate binding (:const:`RTLD_NOW`). Default is
- :const:`RTLD_LAZY`. Note that some systems do not support :const:`RTLD_NOW`.
-
- Return value is a :class:`dlobject`.
-
-The :mod:`dl` module defines the following constants:
-
-
-.. data:: RTLD_LAZY
-
- Useful as an argument to :func:`.open`.
-
-
-.. data:: RTLD_NOW
-
- Useful as an argument to :func:`.open`. Note that on systems which do not
- support immediate binding, this constant will not appear in the module. For
- maximum portability, use :func:`hasattr` to determine if the system supports
- immediate binding.
-
-The :mod:`dl` module defines the following exception:
-
-
-.. exception:: error
-
- Exception raised when an error has occurred inside the dynamic loading and
- linking routines.
-
-Example::
-
- >>> import dl, time
- >>> a=dl.open('/lib/libc.so.6')
- >>> a.call('time'), time.time()
- (929723914, 929723914.498)
-
-This example was tried on a Debian GNU/Linux system, and is a good example of
-the fact that using this module is usually a bad alternative.
-
-
-.. _dl-objects:
-
-Dl Objects
-----------
-
-Dl objects, as returned by :func:`.open` above, have the following methods:
-
-
-.. method:: dl.close()
-
- Free all resources, except the memory.
-
-
-.. method:: dl.sym(name)
-
- Return the pointer for the function named *name*, as a number, if it exists in
- the referenced shared object, otherwise ``None``. This is useful in code like::
-
- >>> if a.sym('time'):
- ... a.call('time')
- ... else:
- ... time.time()
-
- (Note that this function will return a non-zero number, as zero is the *NULL*
- pointer)
-
-
-.. method:: dl.call(name[, arg1[, arg2...]])
-
- Call the function named *name* in the referenced shared object. The arguments
- must be either Python integers, which will be passed as is, Python strings, to
- which a pointer will be passed, or ``None``, which will be passed as *NULL*.
- Note that strings should only be passed to functions as :c:type:`const char\*`,
- as Python will not like its string mutated.
-
- There must be at most 10 arguments, and arguments not given will be treated as
- ``None``. The function's return value must be a C :c:type:`long`, which is a
- Python integer.
-
diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst
index a1e270d..ec8edbe 100644
--- a/Doc/library/doctest.rst
+++ b/Doc/library/doctest.rst
@@ -40,17 +40,10 @@ Here's a complete but small example module::
def factorial(n):
"""Return the factorial of n, an exact integer >= 0.
- If the result is small enough to fit in an int, return an int.
- Else return a long.
-
>>> [factorial(n) for n in range(6)]
[1, 1, 2, 6, 24, 120]
- >>> [factorial(long(n)) for n in range(6)]
- [1, 1, 2, 6, 24, 120]
>>> factorial(30)
- 265252859812191058636308480000000L
- >>> factorial(30L)
- 265252859812191058636308480000000L
+ 265252859812191058636308480000000
>>> factorial(-1)
Traceback (most recent call last):
...
@@ -62,7 +55,7 @@ Here's a complete but small example module::
...
ValueError: n must be exact integer
>>> factorial(30.0)
- 265252859812191058636308480000000L
+ 265252859812191058636308480000000
It must also not be ridiculously large:
>>> factorial(1e100)
@@ -111,11 +104,6 @@ it's trying, and prints a summary at the end::
Expecting:
[1, 1, 2, 6, 24, 120]
ok
- Trying:
- [factorial(long(n)) for n in range(6)]
- Expecting:
- [1, 1, 2, 6, 24, 120]
- ok
And so on, eventually ending with::
@@ -177,10 +165,9 @@ prohibit it by passing ``verbose=False``. In either of those cases,
``sys.argv`` is not examined by :func:`testmod` (so passing ``-v`` or not
has no effect).
-Since Python 2.6, there is also a command line shortcut for running
-:func:`testmod`. You can instruct the Python interpreter to run the doctest
-module directly from the standard library and pass the module name(s) on the
-command line::
+There is also a command line shortcut for running :func:`testmod`. You can
+instruct the Python interpreter to run the doctest module directly from the
+standard library and pass the module name(s) on the command line::
python -m doctest -v example.py
@@ -247,10 +234,9 @@ Like :func:`testmod`, :func:`testfile`'s verbosity can be set with the
``-v`` command-line switch or with the optional keyword argument
*verbose*.
-Since Python 2.6, there is also a command line shortcut for running
-:func:`testfile`. You can instruct the Python interpreter to run the doctest
-module directly from the standard library and pass the file name(s) on the
-command line::
+There is also a command line shortcut for running :func:`testfile`. You can
+instruct the Python interpreter to run the doctest module directly from the
+standard library and pass the file name(s) on the command line::
python -m doctest -v example.txt
@@ -292,9 +278,6 @@ strings are treated as if they were docstrings. In output, a key ``K`` in
Any classes found are recursively searched similarly, to test docstrings in
their contained methods and nested classes.
-.. versionchanged:: 2.4
- A "private name" concept is deprecated and no longer documented.
-
.. _doctest-finding-examples:
@@ -311,11 +294,11 @@ but doctest isn't trying to do an exact emulation of any specific Python shell.
>>> x
12
>>> if x == 13:
- ... print "yes"
+ ... print("yes")
... else:
- ... print "no"
- ... print "NO"
- ... print "NO!!!"
+ ... print("no")
+ ... print("NO")
+ ... print("NO!!!")
...
no
NO
@@ -333,26 +316,17 @@ The fine print:
blank line, put ``<BLANKLINE>`` in your doctest example each place a blank line
is expected.
- .. versionadded:: 2.4
- ``<BLANKLINE>`` was added; there was no way to use expected output containing
- empty lines in previous versions.
-
* All hard tab characters are expanded to spaces, using 8-column tab stops.
Tabs in output generated by the tested code are not modified. Because any
hard tabs in the sample output *are* expanded, this means that if the code
output includes hard tabs, the only way the doctest can pass is if the
- :const:`NORMALIZE_WHITESPACE` option or :ref:`directive <doctest-directives>`
- is in effect.
+ :const:`NORMALIZE_WHITESPACE` option or directive is in effect.
Alternatively, the test can be rewritten to capture the output and compare it
to an expected value as part of the test. This handling of tabs in the
source was arrived at through trial and error, and has proven to be the least
error prone way of handling them. It is possible to use a different
algorithm for handling tabs by writing a custom :class:`DocTestParser` class.
- .. versionchanged:: 2.4
- Expanding tabs to spaces is new; previous versions tried to preserve hard tabs,
- with confusing results.
-
* Output to stdout is captured, but not output to stderr (exception tracebacks
are captured via a different means).
@@ -362,7 +336,7 @@ The fine print:
>>> def f(x):
... r'''Backslashes in a raw docstring: m\n'''
- >>> print f.__doc__
+ >>> print(f.__doc__)
Backslashes in a raw docstring: m\n
Otherwise, the backslash will be interpreted as part of the string. For example,
@@ -371,7 +345,7 @@ The fine print:
>>> def f(x):
... '''Backslashes in a raw docstring: m\\n'''
- >>> print f.__doc__
+ >>> print(f.__doc__)
Backslashes in a raw docstring: m\n
* The starting column doesn't matter::
@@ -379,7 +353,7 @@ The fine print:
>>> assert "Easy!"
>>> import math
>>> math.floor(1.9)
- 1.0
+ 1
and as many leading whitespace characters are stripped from the expected output
as appeared in the initial ``'>>> '`` line that started the example.
@@ -449,9 +423,6 @@ multi-line detail::
The last three lines (starting with :exc:`ValueError`) are compared against the
exception's type and detail, and the rest are ignored.
-.. versionchanged:: 2.4
- Previous versions were unable to handle multi-line exception details.
-
Best practice is to omit the traceback stack, unless it adds significant
documentation value to the example. So the last example is probably better as::
@@ -514,16 +485,15 @@ Some details you should read once, but won't need to remember:
SyntaxError: invalid syntax
-.. _option-flags-and-directives:
.. _doctest-options:
-Option Flags
-^^^^^^^^^^^^
+Option Flags and Directives
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
A number of option flags control various aspects of doctest's behavior.
Symbolic names for the flags are supplied as module constants, which can be
or'ed together and passed to various functions. The names can also be used in
-:ref:`doctest directives <doctest-directives>`.
+doctest directives (see below).
The first group of options define test semantics, controlling aspects of how
doctest decides whether actual output matches an example's expected output:
@@ -577,14 +547,14 @@ doctest decides whether actual output matches an example's expected output:
:exc:`TypeError` is raised.
It will also ignore the module name used in Python 3 doctest reports. Hence
- both of these variations will work with the flag specified, regardless of
- whether the test is run under Python 2.7 or Python 3.2 (or later versions)::
+ both these variations will work regardless of whether the test is run under
+ Python 2.7 or Python 3.2 (or later versions):
- >>> raise CustomError('message')
+ >>> raise CustomError('message') #doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
CustomError: message
- >>> raise CustomError('message')
+ >>> raise CustomError('message') #doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
my_module.CustomError: message
@@ -594,21 +564,20 @@ doctest decides whether actual output matches an example's expected output:
exception name. Using :const:`IGNORE_EXCEPTION_DETAIL` and the details
from Python 2.3 is also the only clear way to write a doctest that doesn't
care about the exception detail yet continues to pass under Python 2.3 or
- earlier (those releases do not support :ref:`doctest directives
- <doctest-directives>` and ignore them as irrelevant comments). For example::
+ earlier (those releases do not support doctest directives and ignore them
+ as irrelevant comments). For example, ::
- >>> (1, 2)[3] = 'moo'
+ >>> (1, 2)[3] = 'moo' #doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment
- passes under Python 2.3 and later Python versions with the flag specified,
- even though the detail
+ passes under Python 2.3 and later Python versions, even though the detail
changed in Python 2.4 to say "does not" instead of "doesn't".
- .. versionchanged:: 2.7
- :const:`IGNORE_EXCEPTION_DETAIL` now also ignores any information
- relating to the module containing the exception under test
+ .. versionchanged:: 3.2
+ :const:`IGNORE_EXCEPTION_DETAIL` now also ignores any information relating
+ to the module containing the exception under test.
.. data:: SKIP
@@ -621,8 +590,6 @@ doctest decides whether actual output matches an example's expected output:
The SKIP flag can also be used for temporarily "commenting out" examples.
-.. versionadded:: 2.5
-
.. data:: COMPARISON_FLAGS
@@ -667,40 +634,9 @@ The second group of options controls how test failures are reported:
A bitmask or'ing together all the reporting flags above.
-
-.. versionadded:: 2.4
- The constants
- :const:`DONT_ACCEPT_BLANKLINE`, :const:`NORMALIZE_WHITESPACE`,
- :const:`ELLIPSIS`, :const:`IGNORE_EXCEPTION_DETAIL`, :const:`REPORT_UDIFF`,
- :const:`REPORT_CDIFF`, :const:`REPORT_NDIFF`,
- :const:`REPORT_ONLY_FIRST_FAILURE`, :const:`COMPARISON_FLAGS` and
- :const:`REPORTING_FLAGS` were added.
-
-There's also a way to register new option flag names, although this isn't useful
-unless you intend to extend :mod:`doctest` internals via subclassing:
-
-
-.. function:: register_optionflag(name)
-
- Create a new option flag with a given name, and return the new flag's integer
- value. :func:`register_optionflag` can be used when subclassing
- :class:`OutputChecker` or :class:`DocTestRunner` to create new options that are
- supported by your subclasses. :func:`register_optionflag` should always be
- called using the following idiom::
-
- MY_FLAG = register_optionflag('MY_FLAG')
-
- .. versionadded:: 2.4
-
-
-.. _doctest-directives:
-
-Directives
-^^^^^^^^^^
-
-Doctest directives may be used to modify the :ref:`option flags
-<doctest-options>` for an individual example. Doctest directives are
-special Python comments following an example's source code:
+"Doctest directives" may be used to modify the option flags for individual
+examples. Doctest directives are expressed as a special Python comment
+following an example's source code:
.. productionlist:: doctest
directive: "#" "doctest:" `directive_options`
@@ -718,7 +654,7 @@ example. Use ``+`` to enable the named behavior, or ``-`` to disable it.
For example, this test passes::
- >>> print range(20) # doctest: +NORMALIZE_WHITESPACE
+ >>> print(list(range(20))) # doctest: +NORMALIZE_WHITESPACE
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
@@ -727,29 +663,29 @@ two blanks before the single-digit list elements, and because the actual output
is on a single line. This test also passes, and also requires a directive to do
so::
- >>> print range(20) # doctest: +ELLIPSIS
+ >>> print(list(range(20))) # doctest: +ELLIPSIS
[0, 1, ..., 18, 19]
Multiple directives can be used on a single physical line, separated by
commas::
- >>> print range(20) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
+ >>> print(list(range(20))) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
[0, 1, ..., 18, 19]
If multiple directive comments are used for a single example, then they are
combined::
- >>> print range(20) # doctest: +ELLIPSIS
- ... # doctest: +NORMALIZE_WHITESPACE
+ >>> print(list(range(20))) # doctest: +ELLIPSIS
+ ... # doctest: +NORMALIZE_WHITESPACE
[0, 1, ..., 18, 19]
As the previous example shows, you can add ``...`` lines to your example
containing only directives. This can be useful when an example is too long for
a directive to comfortably fit on the same line::
- >>> print range(5) + range(10,20) + range(30,40) + range(50,60)
+ >>> print(list(range(5)) + list(range(10, 20)) + list(range(30, 40)))
... # doctest: +ELLIPSIS
- [0, ..., 4, 10, ..., 19, 30, ..., 39, 50, ..., 59]
+ [0, ..., 4, 10, ..., 19, 30, ..., 39]
Note that since all options are disabled by default, and directives apply only
to the example they appear in, enabling options (via ``+`` in a directive) is
@@ -757,8 +693,19 @@ usually the only meaningful choice. However, option flags can also be passed to
functions that run doctests, establishing different defaults. In such cases,
disabling an option via ``-`` in a directive can be useful.
-.. versionadded:: 2.4
- Support for doctest directives was added.
+There's also a way to register new option flag names, although this isn't useful
+unless you intend to extend :mod:`doctest` internals via subclassing:
+
+
+.. function:: register_optionflag(name)
+
+ Create a new option flag with a given name, and return the new flag's integer
+ value. :func:`register_optionflag` can be used when subclassing
+ :class:`OutputChecker` or :class:`DocTestRunner` to create new options that are
+ supported by your subclasses. :func:`register_optionflag` should always be
+ called using the following idiom::
+
+ MY_FLAG = register_optionflag('MY_FLAG')
.. _doctest-warnings:
@@ -783,8 +730,7 @@ is vulnerable! One workaround is to do ::
instead. Another is to do ::
- >>> d = foo().items()
- >>> d.sort()
+ >>> d = sorted(foo().items())
>>> d
[('Harry', 'broomstick'), ('Hermione', 'hippogryph')]
@@ -809,9 +755,9 @@ and C libraries vary widely in quality here. ::
>>> 1./7 # risky
0.14285714285714285
- >>> print 1./7 # safer
+ >>> print(1./7) # safer
0.142857142857
- >>> print round(1./7, 6) # much safer
+ >>> print(round(1./7, 6)) # much safer
0.142857
Numbers of the form ``I/2.**J`` are safe across all platforms, and I often
@@ -835,7 +781,7 @@ introduction to these two functions, see sections :ref:`doctest-simple-testmod`
and :ref:`doctest-simple-testfile`.
-.. function:: testfile(filename[, module_relative][, name][, package][, globs][, verbose][, report][, optionflags][, extraglobs][, raise_on_error][, parser][, encoding])
+.. function:: testfile(filename, module_relative=True, name=None, package=None, globs=None, verbose=None, report=True, optionflags=0, extraglobs=None, raise_on_error=False, parser=DocTestParser(), encoding=None)
All arguments except *filename* are optional, and should be specified in keyword
form.
@@ -903,13 +849,8 @@ and :ref:`doctest-simple-testfile`.
Optional argument *encoding* specifies an encoding that should be used to
convert the file to unicode.
- .. versionadded:: 2.4
- .. versionchanged:: 2.5
- The parameter *encoding* was added.
-
-
-.. function:: testmod([m][, name][, globs][, verbose][, report][, optionflags][, extraglobs][, raise_on_error][, exclude_empty])
+.. function:: testmod(m=None, name=None, globs=None, verbose=None, report=True, optionflags=0, extraglobs=None, raise_on_error=False, exclude_empty=False)
All arguments are optional, and all except for *m* should be specified in
keyword form.
@@ -941,21 +882,13 @@ and :ref:`doctest-simple-testfile`.
*raise_on_error*, and *globs* are the same as for function :func:`testfile`
above, except that *globs* defaults to ``m.__dict__``.
- .. versionchanged:: 2.3
- The parameter *optionflags* was added.
-
- .. versionchanged:: 2.4
- The parameters *extraglobs*, *raise_on_error* and *exclude_empty* were added.
-
- .. versionchanged:: 2.5
- The optional argument *isprivate*, deprecated in 2.4, was removed.
There's also a function to run the doctests associated with a single object.
This function is provided for backward compatibility. There are no plans to
deprecate it, but it's rarely useful:
-.. function:: run_docstring_examples(f, globs[, verbose][, name][, compileflags][, optionflags])
+.. function:: run_docstring_examples(f, globs, verbose=False, name="NoName", compileflags=None, optionflags=0)
Test examples associated with object *f*; for example, *f* may be a module,
function, or class object.
@@ -981,16 +914,10 @@ Unittest API
------------
As your collection of doctest'ed modules grows, you'll want a way to run all
-their doctests systematically. Prior to Python 2.4, :mod:`doctest` had a barely
-documented :class:`Tester` class that supplied a rudimentary way to combine
-doctests from multiple modules. :class:`Tester` was feeble, and in practice most
-serious Python testing frameworks build on the :mod:`unittest` module, which
-supplies many flexible ways to combine tests from multiple sources. So, in
-Python 2.4, :mod:`doctest`'s :class:`Tester` class is deprecated, and
-:mod:`doctest` provides two functions that can be used to create :mod:`unittest`
-test suites from modules and text files containing doctests. To integrate with
-:mod:`unittest` test discovery, include a :func:`load_tests` function in your
-test module::
+their doctests systematically. :mod:`doctest` provides two functions that can
+be used to create :mod:`unittest` test suites from modules and text files
+containing doctests. To integrate with :mod:`unittest` test discovery, include
+a :func:`load_tests` function in your test module::
import unittest
import doctest
@@ -1004,7 +931,7 @@ There are two main functions for creating :class:`unittest.TestSuite` instances
from text files and modules with doctests:
-.. function:: DocFileSuite(*paths, [module_relative][, package][, setUp][, tearDown][, globs][, optionflags][, parser][, encoding])
+.. function:: DocFileSuite(*paths, module_relative=True, package=None, setUp=None, tearDown=None, globs=None, optionflags=0, parser=DocTestParser(), encoding=None)
Convert doctest tests from one or more text files to a
:class:`unittest.TestSuite`.
@@ -1067,27 +994,11 @@ from text files and modules with doctests:
Optional argument *encoding* specifies an encoding that should be used to
convert the file to unicode.
- .. versionadded:: 2.4
-
- .. versionchanged:: 2.5
- The global ``__file__`` was added to the globals provided to doctests
- loaded from a text file using :func:`DocFileSuite`.
+ The global ``__file__`` is added to the globals provided to doctests loaded
+ from a text file using :func:`DocFileSuite`.
- .. versionchanged:: 2.5
- The parameter *encoding* was added.
-
- .. note::
- Unlike :func:`testmod` and :class:`DocTestFinder`, this function raises
- a :exc:`ValueError` if *module* contains no docstrings. You can prevent
- this error by passing a :class:`DocTestFinder` instance as the
- *test_finder* argument with its *exclude_empty* keyword argument set
- to ``False``::
-
- >>> finder = doctest.DocTestFinder(exclude_empty=False)
- >>> suite = doctest.DocTestSuite(test_finder=finder)
-
-.. function:: DocTestSuite([module][, globs][, extraglobs][, test_finder][, setUp][, tearDown][, checker])
+.. function:: DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, setUp=None, tearDown=None, checker=None)
Convert doctest tests for a module to a :class:`unittest.TestSuite`.
@@ -1114,12 +1025,18 @@ from text files and modules with doctests:
Optional arguments *setUp*, *tearDown*, and *optionflags* are the same as for
function :func:`DocFileSuite` above.
- .. versionadded:: 2.3
+ This function uses the same search technique as :func:`testmod`.
+
+ .. note::
+ Unlike :func:`testmod` and :class:`DocTestFinder`, this function raises
+ a :exc:`ValueError` if *module* contains no docstrings. You can prevent
+ this error by passing a :class:`DocTestFinder` instance as the
+ *test_finder* argument with its *exclude_empty* keyword argument set
+ to ``False``::
+
+ >>> finder = doctest.DocTestFinder(exclude_empty=False)
+ >>> suite = doctest.DocTestSuite(test_finder=finder)
- .. versionchanged:: 2.4
- The parameters *globs*, *extraglobs*, *test_finder*, *setUp*, *tearDown*, and
- *optionflags* were added; this function now uses the same search technique as
- :func:`testmod`.
Under the covers, :func:`DocTestSuite` creates a :class:`unittest.TestSuite` out
of :class:`doctest.DocTestCase` instances, and :class:`DocTestCase` is a
@@ -1165,8 +1082,6 @@ reporting flags specific to :mod:`unittest` support, via this function:
The value of the :mod:`unittest` reporting flags in effect before the function
was called is returned by the function.
- .. versionadded:: 2.4
-
.. _doctest-advanced-api:
@@ -1227,7 +1142,6 @@ DocTest Objects
A collection of doctest examples that should be run in a single namespace. The
constructor arguments are used to initialize the attributes of the same names.
- .. versionadded:: 2.4
:class:`DocTest` defines the following attributes. They are initialized by
the constructor, and should not be modified directly.
@@ -1279,13 +1193,12 @@ Example Objects
^^^^^^^^^^^^^^^
-.. class:: Example(source, want[, exc_msg][, lineno][, indent][, options])
+.. class:: Example(source, want, exc_msg=None, lineno=0, indent=0, options=None)
A single interactive example, consisting of a Python statement and its expected
- output. The constructor arguments are used to initialize the attributes of the
- same names.
+ output. The constructor arguments are used to initialize the attributes of
+ the same names.
- .. versionadded:: 2.4
:class:`Example` defines the following attributes. They are initialized by
the constructor, and should not be modified directly.
@@ -1342,7 +1255,7 @@ DocTestFinder objects
^^^^^^^^^^^^^^^^^^^^^
-.. class:: DocTestFinder([verbose][, parser][, recurse][, exclude_empty])
+.. class:: DocTestFinder(verbose=False, parser=DocTestParser(), recurse=True, exclude_empty=True)
A processing class used to extract the :class:`DocTest`\ s that are relevant to
a given object, from its docstring and the docstrings of its contained objects.
@@ -1362,7 +1275,6 @@ DocTestFinder objects
If the optional argument *exclude_empty* is false, then
:meth:`DocTestFinder.find` will include tests for objects with empty docstrings.
- .. versionadded:: 2.4
:class:`DocTestFinder` defines the following method:
@@ -1415,7 +1327,6 @@ DocTestParser objects
A processing class used to extract interactive examples from a string, and use
them to create a :class:`DocTest` object.
- .. versionadded:: 2.4
:class:`DocTestParser` defines the following methods:
@@ -1430,14 +1341,14 @@ DocTestParser objects
information.
- .. method:: get_examples(string[, name])
+ .. method:: get_examples(string, name='<string>')
Extract all doctest examples from the given string, and return them as a list
of :class:`Example` objects. Line numbers are 0-based. The optional argument
*name* is a name identifying this string, and is only used for error messages.
- .. method:: parse(string[, name])
+ .. method:: parse(string, name='<string>')
Divide the given string into examples and intervening text, and return them as
a list of alternating :class:`Example`\ s and strings. Line numbers for the
@@ -1451,7 +1362,7 @@ DocTestRunner objects
^^^^^^^^^^^^^^^^^^^^^
-.. class:: DocTestRunner([checker][, verbose][, optionflags])
+.. class:: DocTestRunner(checker=None, verbose=None, optionflags=0)
A processing class used to execute and verify the interactive examples in a
:class:`DocTest`.
@@ -1484,7 +1395,6 @@ DocTestRunner objects
runner compares expected output to actual output, and how it displays failures.
For more information, see section :ref:`doctest-options`.
- .. versionadded:: 2.4
:class:`DocTestParser` defines the following methods:
@@ -1534,7 +1444,7 @@ DocTestRunner objects
output function that was passed to :meth:`DocTestRunner.run`.
- .. method:: run(test[, compileflags][, out][, clear_globs])
+ .. method:: run(test, compileflags=None, out=None, clear_globs=True)
Run the examples in *test* (a :class:`DocTest` object), and display the
results using the writer function *out*.
@@ -1553,7 +1463,7 @@ DocTestRunner objects
:meth:`DocTestRunner.report_\*` methods.
- .. method:: summarize([verbose])
+ .. method:: summarize(verbose=None)
Print a summary of all the test cases that have been run by this DocTestRunner,
and return a :term:`named tuple` ``TestResults(failed, attempted)``.
@@ -1562,10 +1472,6 @@ DocTestRunner objects
verbosity is not specified, then the :class:`DocTestRunner`'s verbosity is
used.
- .. versionchanged:: 2.6
- Use a named tuple.
-
-
.. _doctest-outputchecker:
OutputChecker objects
@@ -1580,11 +1486,9 @@ OutputChecker objects
if they match; and :meth:`output_difference`, which returns a string describing
the differences between two outputs.
- .. versionadded:: 2.4
:class:`OutputChecker` defines the following methods:
-
.. method:: check_output(want, got, optionflags)
Return ``True`` iff the actual output from an example (*got*) matches the
@@ -1628,7 +1532,7 @@ Doctest provides several mechanisms for debugging doctest examples:
>>> def f(x):
... g(x*2)
>>> def g(x):
- ... print x+3
+ ... print(x+3)
... import pdb; pdb.set_trace()
>>> f(3)
9
@@ -1643,10 +1547,10 @@ Doctest provides several mechanisms for debugging doctest examples:
-> import pdb; pdb.set_trace()
(Pdb) list
1 def g(x):
- 2 print x+3
+ 2 print(x+3)
3 -> import pdb; pdb.set_trace()
[EOF]
- (Pdb) print x
+ (Pdb) p x
6
(Pdb) step
--Return--
@@ -1656,7 +1560,7 @@ Doctest provides several mechanisms for debugging doctest examples:
1 def f(x):
2 -> g(x*2)
[EOF]
- (Pdb) print x
+ (Pdb) p x
3
(Pdb) step
--Return--
@@ -1666,8 +1570,6 @@ Doctest provides several mechanisms for debugging doctest examples:
(0, 3)
>>>
- .. versionchanged:: 2.4
- The ability to use :func:`pdb.set_trace` usefully inside doctests was added.
Functions that convert doctests to Python code, and possibly run the synthesized
code under the debugger:
@@ -1683,14 +1585,14 @@ code under the debugger:
returned as a string. For example, ::
import doctest
- print doctest.script_from_examples(r"""
+ print(doctest.script_from_examples(r"""
Set x and y to 1 and 2.
>>> x, y = 1, 2
Print their sum:
- >>> print x+y
+ >>> print(x+y)
3
- """)
+ """))
displays::
@@ -1698,7 +1600,7 @@ code under the debugger:
x, y = 1, 2
#
# Print their sum:
- print x+y
+ print(x+y)
# Expected:
## 3
@@ -1706,8 +1608,6 @@ code under the debugger:
useful when you want to transform an interactive Python session into a Python
script.
- .. versionadded:: 2.4
-
.. function:: testsource(module, name)
@@ -1721,15 +1621,13 @@ code under the debugger:
contains a top-level function :func:`f`, then ::
import a, doctest
- print doctest.testsource(a, "a.f")
+ print(doctest.testsource(a, "a.f"))
prints a script version of function :func:`f`'s docstring, with doctests
converted to code, and the rest placed in comments.
- .. versionadded:: 2.3
-
-.. function:: debug(module, name[, pm])
+.. function:: debug(module, name, pm=False)
Debug the doctests for an object.
@@ -1747,15 +1645,10 @@ code under the debugger:
it does, then post-mortem debugging is invoked, via :func:`pdb.post_mortem`,
passing the traceback object from the unhandled exception. If *pm* is not
specified, or is false, the script is run under the debugger from the start, via
- passing an appropriate :func:`execfile` call to :func:`pdb.run`.
-
- .. versionadded:: 2.3
-
- .. versionchanged:: 2.4
- The *pm* argument was added.
+ passing an appropriate :func:`exec` call to :func:`pdb.run`.
-.. function:: debug_src(src[, pm][, globs])
+.. function:: debug_src(src, pm=False, globs=None)
Debug the doctests in a string.
@@ -1768,7 +1661,6 @@ code under the debugger:
execution context. If not specified, or ``None``, an empty dictionary is used.
If specified, a shallow copy of the dictionary is used.
- .. versionadded:: 2.4
The :class:`DebugRunner` class, and the special exceptions it may raise, are of
most interest to testing framework authors, and will only be sketched here. See
@@ -1776,7 +1668,7 @@ the source code, and especially :class:`DebugRunner`'s docstring (which is a
doctest!) for more details:
-.. class:: DebugRunner([checker][, verbose][, optionflags])
+.. class:: DebugRunner(checker=None, verbose=None, optionflags=0)
A subclass of :class:`DocTestRunner` that raises an exception as soon as a
failure is encountered. If an unexpected exception occurs, an
diff --git a/Doc/library/docxmlrpcserver.rst b/Doc/library/docxmlrpcserver.rst
deleted file mode 100644
index 08e4e4b..0000000
--- a/Doc/library/docxmlrpcserver.rst
+++ /dev/null
@@ -1,101 +0,0 @@
-:mod:`DocXMLRPCServer` --- Self-documenting XML-RPC server
-==========================================================
-
-.. module:: DocXMLRPCServer
- :synopsis: Self-documenting XML-RPC server implementation.
-.. moduleauthor:: Brian Quinlan <brianq@activestate.com>
-.. sectionauthor:: Brian Quinlan <brianq@activestate.com>
-
-.. note::
- The :mod:`DocXMLRPCServer` module has been merged into :mod:`xmlrpc.server`
- in Python 3. The :term:`2to3` tool will automatically adapt imports when
- converting your sources to Python 3.
-
-
-.. versionadded:: 2.3
-
-The :mod:`DocXMLRPCServer` module extends the classes found in
-:mod:`SimpleXMLRPCServer` to serve HTML documentation in response to HTTP GET
-requests. Servers can either be free standing, using :class:`DocXMLRPCServer`,
-or embedded in a CGI environment, using :class:`DocCGIXMLRPCRequestHandler`.
-
-
-.. class:: DocXMLRPCServer(addr[, requestHandler[, logRequests[, allow_none[, encoding[, bind_and_activate]]]]])
-
- Create a new server instance. All parameters have the same meaning as for
- :class:`SimpleXMLRPCServer.SimpleXMLRPCServer`; *requestHandler* defaults to
- :class:`DocXMLRPCRequestHandler`.
-
-
-.. class:: DocCGIXMLRPCRequestHandler()
-
- Create a new instance to handle XML-RPC requests in a CGI environment.
-
-
-.. class:: DocXMLRPCRequestHandler()
-
- Create a new request handler instance. This request handler supports XML-RPC
- POST requests, documentation GET requests, and modifies logging so that the
- *logRequests* parameter to the :class:`DocXMLRPCServer` constructor parameter is
- honored.
-
-
-.. _doc-xmlrpc-servers:
-
-DocXMLRPCServer Objects
------------------------
-
-The :class:`DocXMLRPCServer` class is derived from
-:class:`SimpleXMLRPCServer.SimpleXMLRPCServer` and provides a means of creating
-self-documenting, stand alone XML-RPC servers. HTTP POST requests are handled as
-XML-RPC method calls. HTTP GET requests are handled by generating pydoc-style
-HTML documentation. This allows a server to provide its own web-based
-documentation.
-
-
-.. method:: DocXMLRPCServer.set_server_title(server_title)
-
- Set the title used in the generated HTML documentation. This title will be used
- inside the HTML "title" element.
-
-
-.. method:: DocXMLRPCServer.set_server_name(server_name)
-
- Set the name used in the generated HTML documentation. This name will appear at
- the top of the generated documentation inside a "h1" element.
-
-
-.. method:: DocXMLRPCServer.set_server_documentation(server_documentation)
-
- Set the description used in the generated HTML documentation. This description
- will appear as a paragraph, below the server name, in the documentation.
-
-
-DocCGIXMLRPCRequestHandler
---------------------------
-
-The :class:`DocCGIXMLRPCRequestHandler` class is derived from
-:class:`SimpleXMLRPCServer.CGIXMLRPCRequestHandler` and provides a means of
-creating self-documenting, XML-RPC CGI scripts. HTTP POST requests are handled
-as XML-RPC method calls. HTTP GET requests are handled by generating pydoc-style
-HTML documentation. This allows a server to provide its own web-based
-documentation.
-
-
-.. method:: DocCGIXMLRPCRequestHandler.set_server_title(server_title)
-
- Set the title used in the generated HTML documentation. This title will be used
- inside the HTML "title" element.
-
-
-.. method:: DocCGIXMLRPCRequestHandler.set_server_name(server_name)
-
- Set the name used in the generated HTML documentation. This name will appear at
- the top of the generated documentation inside a "h1" element.
-
-
-.. method:: DocCGIXMLRPCRequestHandler.set_server_documentation(server_documentation)
-
- Set the description used in the generated HTML documentation. This description
- will appear as a paragraph, below the server name, in the documentation.
-
diff --git a/Doc/library/dumbdbm.rst b/Doc/library/dumbdbm.rst
deleted file mode 100644
index 965710a..0000000
--- a/Doc/library/dumbdbm.rst
+++ /dev/null
@@ -1,84 +0,0 @@
-:mod:`dumbdbm` --- Portable DBM implementation
-==============================================
-
-.. module:: dumbdbm
- :synopsis: Portable implementation of the simple DBM interface.
-
-.. note::
- The :mod:`dumbdbm` module has been renamed to :mod:`dbm.dumb` in Python 3.
- The :term:`2to3` tool will automatically adapt imports when converting your
- sources to Python 3.
-
-.. index:: single: databases
-
-.. note::
-
- The :mod:`dumbdbm` module is intended as a last resort fallback for the
- :mod:`anydbm` module when no more robust module is available. The :mod:`dumbdbm`
- module is not written for speed and is not nearly as heavily used as the other
- database modules.
-
-The :mod:`dumbdbm` module provides a persistent dictionary-like interface which
-is written entirely in Python. Unlike other modules such as :mod:`gdbm` and
-:mod:`bsddb`, no external library is required. As with other persistent
-mappings, the keys and values must always be strings.
-
-The module defines the following:
-
-
-.. exception:: error
-
- Raised on dumbdbm-specific errors, such as I/O errors. :exc:`KeyError` is
- raised for general mapping errors like specifying an incorrect key.
-
-
-.. function:: open(filename[, flag[, mode]])
-
- Open a dumbdbm database and return a dumbdbm object. The *filename* argument is
- the basename of the database file (without any specific extensions). When a
- dumbdbm database is created, files with :file:`.dat` and :file:`.dir` extensions
- are created.
-
- The optional *flag* argument is currently ignored; the database is always opened
- for update, and will be created if it does not exist.
-
- The optional *mode* argument is the Unix mode of the file, used only when the
- database has to be created. It defaults to octal ``0666`` (and will be modified
- by the prevailing umask).
-
- .. versionchanged:: 2.2
- The *mode* argument was ignored in earlier versions.
-
-
-.. seealso::
-
- Module :mod:`anydbm`
- Generic interface to ``dbm``\ -style databases.
-
- Module :mod:`dbm`
- Similar interface to the DBM/NDBM library.
-
- Module :mod:`gdbm`
- Similar interface to the GNU GDBM library.
-
- Module :mod:`shelve`
- Persistence module which stores non-string data.
-
- Module :mod:`whichdb`
- Utility module used to determine the type of an existing database.
-
-
-.. _dumbdbm-objects:
-
-Dumbdbm Objects
----------------
-
-In addition to the methods provided by the :class:`UserDict.DictMixin` class,
-:class:`dumbdbm` objects provide the following methods.
-
-
-.. method:: dumbdbm.sync()
-
- Synchronize the on-disk directory and data files. This method is called by the
- :meth:`sync` method of :class:`Shelve` objects.
-
diff --git a/Doc/library/dummy_thread.rst b/Doc/library/dummy_thread.rst
deleted file mode 100644
index a1d977d..0000000
--- a/Doc/library/dummy_thread.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-:mod:`dummy_thread` --- Drop-in replacement for the :mod:`thread` module
-========================================================================
-
-.. module:: dummy_thread
- :synopsis: Drop-in replacement for the thread module.
-
-.. note::
- The :mod:`dummy_thread` module has been renamed to :mod:`_dummy_thread` in
- Python 3. The :term:`2to3` tool will automatically adapt imports when
- converting your sources to Python 3; however, you should consider using the
- high-lever :mod:`dummy_threading` module instead.
-
-**Source code:** :source:`Lib/dummy_thread.py`
-
---------------
-
-This module provides a duplicate interface to the :mod:`thread` module. It is
-meant to be imported when the :mod:`thread` module is not provided on a
-platform.
-
-Suggested usage is::
-
- try:
- import thread as _thread
- except ImportError:
- import dummy_thread as _thread
-
-Be careful to not use this module where deadlock might occur from a thread
-being created that blocks waiting for another thread to be created. This often
-occurs with blocking I/O.
-
diff --git a/Doc/library/dummy_threading.rst b/Doc/library/dummy_threading.rst
index 39ca061..30a3ebb 100644
--- a/Doc/library/dummy_threading.rst
+++ b/Doc/library/dummy_threading.rst
@@ -9,17 +9,17 @@
--------------
This module provides a duplicate interface to the :mod:`threading` module. It
-is meant to be imported when the :mod:`thread` module is not provided on a
+is meant to be imported when the :mod:`_thread` module is not provided on a
platform.
Suggested usage is::
try:
- import threading as _threading
+ import threading
except ImportError:
- import dummy_threading as _threading
+ import dummy_threading as threading
-Be careful to not use this module where deadlock might occur from a thread
-being created that blocks waiting for another thread to be created. This often
-occurs with blocking I/O.
+Be careful to not use this module where deadlock might occur from a thread being
+created that blocks waiting for another thread to be created. This often occurs
+with blocking I/O.
diff --git a/Doc/library/easydialogs.rst b/Doc/library/easydialogs.rst
deleted file mode 100644
index a042b0f..0000000
--- a/Doc/library/easydialogs.rst
+++ /dev/null
@@ -1,215 +0,0 @@
-
-:mod:`EasyDialogs` --- Basic Macintosh dialogs
-==============================================
-
-.. module:: EasyDialogs
- :platform: Mac
- :synopsis: Basic Macintosh dialogs.
- :deprecated:
-
-
-The :mod:`EasyDialogs` module contains some simple dialogs for the Macintosh.
-The dialogs get launched in a separate application which appears in the dock and
-must be clicked on for the dialogs be displayed. All routines take an optional
-resource ID parameter *id* with which one can override the :const:`DLOG`
-resource used for the dialog, provided that the dialog items correspond (both
-type and item number) to those in the default :const:`DLOG` resource. See source
-code for details.
-
-.. note::
-
- This module has been removed in Python 3.x.
-
-
-The :mod:`EasyDialogs` module defines the following functions:
-
-
-.. function:: Message(str[, id[, ok]])
-
- Displays a modal dialog with the message text *str*, which should be at most 255
- characters long. The button text defaults to "OK", but is set to the string
- argument *ok* if the latter is supplied. Control is returned when the user
- clicks the "OK" button.
-
-
-.. function:: AskString(prompt[, default[, id[, ok[, cancel]]]])
-
- Asks the user to input a string value via a modal dialog. *prompt* is the prompt
- message, and the optional *default* supplies the initial value for the string
- (otherwise ``""`` is used). The text of the "OK" and "Cancel" buttons can be
- changed with the *ok* and *cancel* arguments. All strings can be at most 255
- bytes long. :func:`AskString` returns the string entered or :const:`None` in
- case the user cancelled.
-
-
-.. function:: AskPassword(prompt[, default[, id[, ok[, cancel]]]])
-
- Asks the user to input a string value via a modal dialog. Like
- :func:`AskString`, but with the text shown as bullets. The arguments have the
- same meaning as for :func:`AskString`.
-
-
-.. function:: AskYesNoCancel(question[, default[, yes[, no[, cancel[, id]]]]])
-
- Presents a dialog with prompt *question* and three buttons labelled "Yes", "No",
- and "Cancel". Returns ``1`` for "Yes", ``0`` for "No" and ``-1`` for "Cancel".
- The value of *default* (or ``0`` if *default* is not supplied) is returned when
- the :kbd:`RETURN` key is pressed. The text of the buttons can be changed with
- the *yes*, *no*, and *cancel* arguments; to prevent a button from appearing,
- supply ``""`` for the corresponding argument.
-
-
-.. function:: ProgressBar([title[, maxval[, label[, id]]]])
-
- Displays a modeless progress-bar dialog. This is the constructor for the
- :class:`ProgressBar` class described below. *title* is the text string displayed
- (default "Working..."), *maxval* is the value at which progress is complete
- (default ``0``, indicating that an indeterminate amount of work remains to be
- done), and *label* is the text that is displayed above the progress bar itself.
-
-
-.. function:: GetArgv([optionlist[ commandlist[, addoldfile[, addnewfile[, addfolder[, id]]]]]])
-
- Displays a dialog which aids the user in constructing a command-line argument
- list. Returns the list in ``sys.argv`` format, suitable for passing as an
- argument to :func:`getopt.getopt`. *addoldfile*, *addnewfile*, and *addfolder*
- are boolean arguments. When nonzero, they enable the user to insert into the
- command line paths to an existing file, a (possibly) not-yet-existent file, and
- a folder, respectively. (Note: Option arguments must appear in the command line
- before file and folder arguments in order to be recognized by
- :func:`getopt.getopt`.) Arguments containing spaces can be specified by
- enclosing them within single or double quotes. A :exc:`SystemExit` exception is
- raised if the user presses the "Cancel" button.
-
- *optionlist* is a list that determines a popup menu from which the allowed
- options are selected. Its items can take one of two forms: *optstr* or
- ``(optstr, descr)``. When present, *descr* is a short descriptive string that
- is displayed in the dialog while this option is selected in the popup menu. The
- correspondence between *optstr*\s and command-line arguments is:
-
- +----------------------+------------------------------------------+
- | *optstr* format | Command-line format |
- +======================+==========================================+
- | ``x`` | :option:`-x` (short option) |
- +----------------------+------------------------------------------+
- | ``x:`` or ``x=`` | :option:`-x` (short option with value) |
- +----------------------+------------------------------------------+
- | ``xyz`` | :option:`--xyz` (long option) |
- +----------------------+------------------------------------------+
- | ``xyz:`` or ``xyz=`` | :option:`--xyz` (long option with value) |
- +----------------------+------------------------------------------+
-
- *commandlist* is a list of items of the form *cmdstr* or ``(cmdstr, descr)``,
- where *descr* is as above. The *cmdstr*\ s will appear in a popup menu. When
- chosen, the text of *cmdstr* will be appended to the command line as is, except
- that a trailing ``':'`` or ``'='`` (if present) will be trimmed off.
-
- .. versionadded:: 2.0
-
-
-.. function:: AskFileForOpen( [message] [, typeList] [, defaultLocation] [, defaultOptionFlags] [, location] [, clientName] [, windowTitle] [, actionButtonLabel] [, cancelButtonLabel] [, preferenceKey] [, popupExtension] [, eventProc] [, previewProc] [, filterProc] [, wanted] )
-
- Post a dialog asking the user for a file to open, and return the file selected
- or :const:`None` if the user cancelled. *message* is a text message to display,
- *typeList* is a list of 4-char filetypes allowable, *defaultLocation* is the
- pathname, :class:`FSSpec` or :class:`FSRef` of the folder to show initially,
- *location* is the ``(x, y)`` position on the screen where the dialog is shown,
- *actionButtonLabel* is a string to show instead of "Open" in the OK button,
- *cancelButtonLabel* is a string to show instead of "Cancel" in the cancel
- button, *wanted* is the type of value wanted as a return: :class:`str`,
- :class:`unicode`, :class:`FSSpec`, :class:`FSRef` and subtypes thereof are
- acceptable.
-
- .. index:: single: Navigation Services
-
- For a description of the other arguments please see the Apple Navigation
- Services documentation and the :mod:`EasyDialogs` source code.
-
-
-.. function:: AskFileForSave( [message] [, savedFileName] [, defaultLocation] [, defaultOptionFlags] [, location] [, clientName] [, windowTitle] [, actionButtonLabel] [, cancelButtonLabel] [, preferenceKey] [, popupExtension] [, fileType] [, fileCreator] [, eventProc] [, wanted] )
-
- Post a dialog asking the user for a file to save to, and return the file
- selected or :const:`None` if the user cancelled. *savedFileName* is the default
- for the file name to save to (the return value). See :func:`AskFileForOpen` for
- a description of the other arguments.
-
-
-.. function:: AskFolder( [message] [, defaultLocation] [, defaultOptionFlags] [, location] [, clientName] [, windowTitle] [, actionButtonLabel] [, cancelButtonLabel] [, preferenceKey] [, popupExtension] [, eventProc] [, filterProc] [, wanted] )
-
- Post a dialog asking the user to select a folder, and return the folder selected
- or :const:`None` if the user cancelled. See :func:`AskFileForOpen` for a
- description of the arguments.
-
-
-.. seealso::
-
- `Navigation Services Reference <http://developer.apple.com/legacy/mac/library/#documentation/Carbon/Conceptual/NavServicesIntro/ns_intro_carb/ns_into_carb.html>`_
- Programmer's reference documentation for the Navigation Services, a part of the
- Carbon framework.
-
-
-.. _progressbar-objects:
-
-ProgressBar Objects
--------------------
-
-:class:`ProgressBar` objects provide support for modeless progress-bar dialogs.
-Both determinate (thermometer style) and indeterminate (barber-pole style)
-progress bars are supported. The bar will be determinate if its maximum value
-is greater than zero; otherwise it will be indeterminate.
-
-.. versionchanged:: 2.2
- Support for indeterminate-style progress bars was added.
-
-The dialog is displayed immediately after creation. If the dialog's "Cancel"
-button is pressed, or if :kbd:`Cmd-.` or :kbd:`ESC` is typed, the dialog window
-is hidden and :exc:`KeyboardInterrupt` is raised (but note that this response
-does not occur until the progress bar is next updated, typically via a call to
-:meth:`inc` or :meth:`set`). Otherwise, the bar remains visible until the
-:class:`ProgressBar` object is discarded.
-
-:class:`ProgressBar` objects possess the following attributes and methods:
-
-
-.. attribute:: ProgressBar.curval
-
- The current value (of type integer or long integer) of the progress bar. The
- normal access methods coerce :attr:`curval` between ``0`` and :attr:`maxval`.
- This attribute should not be altered directly.
-
-
-.. attribute:: ProgressBar.maxval
-
- The maximum value (of type integer or long integer) of the progress bar; the
- progress bar (thermometer style) is full when :attr:`curval` equals
- :attr:`maxval`. If :attr:`maxval` is ``0``, the bar will be indeterminate
- (barber-pole). This attribute should not be altered directly.
-
-
-.. method:: ProgressBar.title([newstr])
-
- Sets the text in the title bar of the progress dialog to *newstr*.
-
-
-.. method:: ProgressBar.label([newstr])
-
- Sets the text in the progress box of the progress dialog to *newstr*.
-
-
-.. method:: ProgressBar.set(value[, max])
-
- Sets the progress bar's :attr:`curval` to *value*, and also :attr:`maxval` to
- *max* if the latter is provided. *value* is first coerced between 0 and
- :attr:`maxval`. The thermometer bar is updated to reflect the changes,
- including a change from indeterminate to determinate or vice versa.
-
-
-.. method:: ProgressBar.inc([n])
-
- Increments the progress bar's :attr:`curval` by *n*, or by ``1`` if *n* is not
- provided. (Note that *n* may be negative, in which case the effect is a
- decrement.) The progress bar is updated to reflect the change. If the bar is
- indeterminate, this causes one "spin" of the barber pole. The resulting
- :attr:`curval` is coerced between 0 and :attr:`maxval` if incrementing causes it
- to fall outside this range.
-
diff --git a/Doc/library/email.charset.rst b/Doc/library/email.charset.rst
index 840aec6..a828f3c 100644
--- a/Doc/library/email.charset.rst
+++ b/Doc/library/email.charset.rst
@@ -13,10 +13,8 @@ Instances of :class:`Charset` are used in several other modules within the
Import this class from the :mod:`email.charset` module.
-.. versionadded:: 2.2.2
-
-.. class:: Charset([input_charset])
+.. class:: Charset(input_charset=DEFAULT_CHARSET)
Map character sets to their email properties.
@@ -42,7 +40,6 @@ Import this class from the :mod:`email.charset` module.
:class:`Charset` instances have the following data attributes:
-
.. attribute:: input_charset
The initial character set specified. Common aliases are converted to
@@ -68,10 +65,10 @@ Import this class from the :mod:`email.charset` module.
.. attribute:: output_charset
- Some character sets must be converted before they can be used in email headers
- or bodies. If the *input_charset* is one of them, this attribute will
- contain the name of the character set output will be converted to. Otherwise, it will
- be ``None``.
+ Some character sets must be converted before they can be used in email
+ headers or bodies. If the *input_charset* is one of them, this attribute
+ will contain the name of the character set output will be converted to.
+ Otherwise, it will be ``None``.
.. attribute:: input_codec
@@ -87,8 +84,8 @@ Import this class from the :mod:`email.charset` module.
*output_charset*. If no conversion codec is necessary, this attribute
will have the same value as the *input_codec*.
- :class:`Charset` instances also have the following methods:
+ :class:`Charset` instances also have the following methods:
.. method:: get_body_encoding()
@@ -104,13 +101,9 @@ Import this class from the :mod:`email.charset` module.
returns the string ``base64`` if *body_encoding* is ``BASE64``, and
returns the string ``7bit`` otherwise.
+ .. XXX to_splittable and from_splittable are not there anymore!
- .. method:: convert(s)
-
- Convert the string *s* from the *input_codec* to the *output_codec*.
-
-
- .. method:: to_splittable(s)
+ .. method to_splittable(s)
Convert a possibly multibyte string to a safely splittable format. *s* is
the string to split.
@@ -125,7 +118,7 @@ Import this class from the :mod:`email.charset` module.
the Unicode replacement character ``'U+FFFD'``.
- .. method:: from_splittable(ustr[, to_output])
+ .. method from_splittable(ustr[, to_output])
Convert a splittable string back into an encoded string. *ustr* is a
Unicode string to "unsplit".
@@ -149,35 +142,27 @@ Import this class from the :mod:`email.charset` module.
it is *input_charset*.
- .. method:: encoded_header_len()
-
- Return the length of the encoded header string, properly calculating for
- quoted-printable or base64 encoding.
+ .. method:: header_encode(string)
+ Header-encode the string *string*.
- .. method:: header_encode(s[, convert])
+ The type of encoding (base64 or quoted-printable) will be based on the
+ *header_encoding* attribute.
- Header-encode the string *s*.
- If *convert* is ``True``, the string will be converted from the input
- charset to the output charset automatically. This is not useful for
- multibyte character sets, which have line length issues (multibyte
- characters must be split on a character, not a byte boundary); use the
- higher-level :class:`~email.header.Header` class to deal with these issues
- (see :mod:`email.header`). *convert* defaults to ``False``.
+ .. method:: header_encode_lines(string, maxlengths)
- The type of encoding (base64 or quoted-printable) will be based on the
- *header_encoding* attribute.
+ Header-encode a *string* by converting it first to bytes.
+ This is similar to :meth:`header_encode` except that the string is fit
+ into maximum line lengths as given by the argument *maxlengths*, which
+ must be an iterator: each element returned from this iterator will provide
+ the next maximum line length.
- .. method:: body_encode(s[, convert])
- Body-encode the string *s*.
+ .. method:: body_encode(string)
- If *convert* is ``True`` (the default), the string will be converted from
- the input charset to output charset automatically. Unlike
- :meth:`header_encode`, there are no issues with byte boundaries and
- multibyte charsets in email bodies, so this is usually pretty safe.
+ Body-encode the string *string*.
The type of encoding (base64 or quoted-printable) will be based on the
*body_encoding* attribute.
@@ -207,7 +192,7 @@ The :mod:`email.charset` module also provides the following functions for adding
new entries to the global character set, alias, and codec registries:
-.. function:: add_charset(charset[, header_enc[, body_enc[, output_charset]]])
+.. function:: add_charset(charset, header_enc=None, body_enc=None, output_charset=None)
Add character properties to the global registry.
@@ -248,6 +233,6 @@ new entries to the global character set, alias, and codec registries:
Add a codec that map characters in the given character set to and from Unicode.
*charset* is the canonical name of a character set. *codecname* is the name of a
- Python codec, as appropriate for the second argument to the :func:`unicode`
- built-in, or to the :meth:`encode` method of a Unicode string.
+ Python codec, as appropriate for the second argument to the :class:`str`'s
+ :func:`decode` method
diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst
index 628fac9..d8f330f 100644
--- a/Doc/library/email.errors.rst
+++ b/Doc/library/email.errors.rst
@@ -67,9 +67,6 @@ object would have a defect, but the containing messages would not.
All defect classes are subclassed from :class:`email.errors.MessageDefect`, but
this class is *not* an exception!
-.. versionadded:: 2.4
- All the defect classes were added.
-
* :class:`NoBoundaryInMultipartDefect` -- A message claimed to be a multipart,
but had no :mimetype:`boundary` parameter.
diff --git a/Doc/library/email.generator.rst b/Doc/library/email.generator.rst
index 4ea7e6a..88c62a2 100644
--- a/Doc/library/email.generator.rst
+++ b/Doc/library/email.generator.rst
@@ -22,15 +22,21 @@ using the Generator on a :class:`~email.message.Message` constructed by program
may result in changes to the :class:`~email.message.Message` object as defaults
are filled in.
+:class:`bytes` output can be generated using the :class:`BytesGenerator` class.
+If the message object structure contains non-ASCII bytes, this generator's
+:meth:`~BytesGenerator.flatten` method will emit the original bytes. Parsing a
+binary message and then flattening it with :class:`BytesGenerator` should be
+idempotent for standards compliant messages.
+
Here are the public methods of the :class:`Generator` class, imported from the
:mod:`email.generator` module:
-.. class:: Generator(outfp[, mangle_from_[, maxheaderlen]])
+.. class:: Generator(outfp, mangle_from_=True, maxheaderlen=78)
- The constructor for the :class:`Generator` class takes a file-like object called
- *outfp* for an argument. *outfp* must support the :meth:`write` method and be
- usable as the output file in a Python extended print statement.
+ The constructor for the :class:`Generator` class takes a :term:`file-like object`
+ called *outfp* for an argument. *outfp* must support the :meth:`write` method
+ and be usable as the output file for the :func:`print` function.
Optional *mangle_from_* is a flag that, when ``True``, puts a ``>`` character in
front of any line in the body that starts exactly as ``From``, i.e. ``From``
@@ -50,7 +56,7 @@ Here are the public methods of the :class:`Generator` class, imported from the
The other public :class:`Generator` methods are:
- .. method:: flatten(msg[, unixfrom])
+ .. method:: flatten(msg, unixfrom=False, linesep='\\n')
Print the textual representation of the message object structure rooted at
*msg* to the output file specified when the :class:`Generator` instance
@@ -65,35 +71,114 @@ Here are the public methods of the :class:`Generator` class, imported from the
Note that for subparts, no envelope header is ever printed.
- .. versionadded:: 2.2.2
+ Optional *linesep* specifies the line separator character used to
+ terminate lines in the output. It defaults to ``\n`` because that is
+ the most useful value for Python application code (other library packages
+ expect ``\n`` separated lines). ``linesep=\r\n`` can be used to
+ generate output with RFC-compliant line separators.
+
+ Messages parsed with a Bytes parser that have a
+ :mailheader:`Content-Transfer-Encoding` of 8bit will be converted to a
+ use a 7bit Content-Transfer-Encoding. Non-ASCII bytes in the headers
+ will be :rfc:`2047` encoded with a charset of `unknown-8bit`.
+ .. versionchanged:: 3.2
+ Added support for re-encoding 8bit message bodies, and the *linesep*
+ argument.
.. method:: clone(fp)
Return an independent clone of this :class:`Generator` instance with the
exact same options.
- .. versionadded:: 2.2.2
-
-
.. method:: write(s)
Write the string *s* to the underlying file object, i.e. *outfp* passed to
:class:`Generator`'s constructor. This provides just enough file-like API
- for :class:`Generator` instances to be used in extended print statements.
+ for :class:`Generator` instances to be used in the :func:`print` function.
-As a convenience, see the methods :meth:`Message.as_string` and
-``str(aMessage)``, a.k.a. :meth:`Message.__str__`, which simplify the generation
-of a formatted string representation of a message object. For more detail, see
+As a convenience, see the :class:`~email.message.Message` methods
+:meth:`~email.message.Message.as_string` and ``str(aMessage)``, a.k.a.
+:meth:`~email.message.Message.__str__`, which simplify the generation of a
+formatted string representation of a message object. For more detail, see
:mod:`email.message`.
+.. class:: BytesGenerator(outfp, mangle_from_=True, maxheaderlen=78)
+
+ The constructor for the :class:`BytesGenerator` class takes a binary
+ :term:`file-like object` called *outfp* for an argument. *outfp* must
+ support a :meth:`write` method that accepts binary data.
+
+ Optional *mangle_from_* is a flag that, when ``True``, puts a ``>``
+ character in front of any line in the body that starts exactly as ``From``,
+ i.e. ``From`` followed by a space at the beginning of the line. This is the
+ only guaranteed portable way to avoid having such lines be mistaken for a
+ Unix mailbox format envelope header separator (see `WHY THE CONTENT-LENGTH
+ FORMAT IS BAD <http://www.jwz.org/doc/content-length.html>`_ for details).
+ *mangle_from_* defaults to ``True``, but you might want to set this to
+ ``False`` if you are not writing Unix mailbox format files.
+
+ Optional *maxheaderlen* specifies the longest length for a non-continued
+ header. When a header line is longer than *maxheaderlen* (in characters,
+ with tabs expanded to 8 spaces), the header will be split as defined in the
+ :class:`~email.header.Header` class. Set to zero to disable header
+ wrapping. The default is 78, as recommended (but not required) by
+ :rfc:`2822`.
+
+ The other public :class:`BytesGenerator` methods are:
+
+
+ .. method:: flatten(msg, unixfrom=False, linesep='\n')
+
+ Print the textual representation of the message object structure rooted
+ at *msg* to the output file specified when the :class:`BytesGenerator`
+ instance was created. Subparts are visited depth-first and the resulting
+ text will be properly MIME encoded. If the input that created the *msg*
+ contained bytes with the high bit set and those bytes have not been
+ modified, they will be copied faithfully to the output, even if doing so
+ is not strictly RFC compliant. (To produce strictly RFC compliant
+ output, use the :class:`Generator` class.)
+
+ Messages parsed with a Bytes parser that have a
+ :mailheader:`Content-Transfer-Encoding` of 8bit will be reconstructed
+ as 8bit if they have not been modified.
+
+ Optional *unixfrom* is a flag that forces the printing of the envelope
+ header delimiter before the first :rfc:`2822` header of the root message
+ object. If the root object has no envelope header, a standard one is
+ crafted. By default, this is set to ``False`` to inhibit the printing of
+ the envelope delimiter.
+
+ Note that for subparts, no envelope header is ever printed.
+
+ Optional *linesep* specifies the line separator character used to
+ terminate lines in the output. It defaults to ``\n`` because that is
+ the most useful value for Python application code (other library packages
+ expect ``\n`` separated lines). ``linesep=\r\n`` can be used to
+ generate output with RFC-compliant line separators.
+
+ .. method:: clone(fp)
+
+ Return an independent clone of this :class:`BytesGenerator` instance with
+ the exact same options.
+
+ .. method:: write(s)
+
+ Write the string *s* to the underlying file object. *s* is encoded using
+ the ``ASCII`` codec and written to the *write* method of the *outfp*
+ *outfp* passed to the :class:`BytesGenerator`'s constructor. This
+ provides just enough file-like API for :class:`BytesGenerator` instances
+ to be used in the :func:`print` function.
+
+ .. versionadded:: 3.2
+
The :mod:`email.generator` module also provides a derived class, called
:class:`DecodedGenerator` which is like the :class:`Generator` base class,
except that non-\ :mimetype:`text` parts are substituted with a format string
representing the part.
-.. class:: DecodedGenerator(outfp[, mangle_from_[, maxheaderlen[, fmt]]])
+.. class:: DecodedGenerator(outfp, mangle_from_=True, maxheaderlen=78, fmt=None)
This class, derived from :class:`Generator` walks through all the subparts of a
message. If the subpart is of main type :mimetype:`text`, then it prints the
@@ -120,11 +205,6 @@ representing the part.
[Non-text (%(type)s) part of message omitted, filename %(filename)s]
- .. versionadded:: 2.2.2
-
-.. versionchanged:: 2.5
- The previously deprecated method :meth:`__call__` was removed.
-
.. rubric:: Footnotes
diff --git a/Doc/library/email.header.rst b/Doc/library/email.header.rst
index cb9cd1e..7d2dc2e 100644
--- a/Doc/library/email.header.rst
+++ b/Doc/library/email.header.rst
@@ -31,7 +31,7 @@ For example::
>>> msg = Message()
>>> h = Header('p\xf6stal', 'iso-8859-1')
>>> msg['Subject'] = h
- >>> print msg.as_string()
+ >>> print(msg.as_string())
Subject: =?iso-8859-1?q?p=F6stal?=
@@ -43,20 +43,18 @@ the character set that the byte string was encoded in. When the subsequent
field was properly :rfc:`2047` encoded. MIME-aware mail readers would show this
header using the embedded ISO-8859-1 character.
-.. versionadded:: 2.2.2
-
Here is the :class:`Header` class description:
-.. class:: Header([s[, charset[, maxlinelen[, header_name[, continuation_ws[, errors]]]]]])
+.. class:: Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')
Create a MIME-compliant header that can contain strings in different character
sets.
Optional *s* is the initial header value. If ``None`` (the default), the
initial header value is not set. You can later append to the header with
- :meth:`append` method calls. *s* may be a byte string or a Unicode string, but
- see the :meth:`append` documentation for semantics.
+ :meth:`append` method calls. *s* may be an instance of :class:`bytes` or
+ :class:`str`, but see the :meth:`append` documentation for semantics.
Optional *charset* serves two purposes: it has the same meaning as the *charset*
argument to the :meth:`append` method. It also sets the default character set
@@ -72,15 +70,15 @@ Here is the :class:`Header` class description:
for *header_name* is ``None``, meaning it is not taken into account for the
first line of a long, split header.
- Optional *continuation_ws* must be :rfc:`2822`\ -compliant folding whitespace,
- and is usually either a space or a hard tab character. This character will be
- prepended to continuation lines. *continuation_ws* defaults to a single
- space character (" ").
+ Optional *continuation_ws* must be :rfc:`2822`\ -compliant folding
+ whitespace, and is usually either a space or a hard tab character. This
+ character will be prepended to continuation lines. *continuation_ws*
+ defaults to a single space character.
Optional *errors* is passed straight through to the :meth:`append` method.
- .. method:: append(s[, charset[, errors]])
+ .. method:: append(s, charset=None, errors='strict')
Append the string *s* to the MIME header.
@@ -90,43 +88,64 @@ Here is the :class:`Header` class description:
of ``None`` (the default) means that the *charset* given in the constructor
is used.
- *s* may be a byte string or a Unicode string. If it is a byte string
- (i.e. ``isinstance(s, str)`` is true), then *charset* is the encoding of
- that byte string, and a :exc:`UnicodeError` will be raised if the string
- cannot be decoded with that character set.
+ *s* may be an instance of :class:`bytes` or :class:`str`. If it is an
+ instance of :class:`bytes`, then *charset* is the encoding of that byte
+ string, and a :exc:`UnicodeError` will be raised if the string cannot be
+ decoded with that character set.
+
+ If *s* is an instance of :class:`str`, then *charset* is a hint specifying
+ the character set of the characters in the string.
- If *s* is a Unicode string, then *charset* is a hint specifying the
- character set of the characters in the string. In this case, when
- producing an :rfc:`2822`\ -compliant header using :rfc:`2047` rules, the
- Unicode string will be encoded using the following charsets in order:
- ``us-ascii``, the *charset* hint, ``utf-8``. The first character set to
- not provoke a :exc:`UnicodeError` is used.
+ In either case, when producing an :rfc:`2822`\ -compliant header using
+ :rfc:`2047` rules, the string will be encoded using the output codec of
+ the charset. If the string cannot be encoded using the output codec, a
+ UnicodeError will be raised.
- Optional *errors* is passed through to any :func:`unicode` or
- :func:`ustr.encode` call, and defaults to "strict".
+ Optional *errors* is passed as the errors argument to the decode call
+ if *s* is a byte string.
- .. method:: encode([splitchars])
+ .. method:: encode(splitchars=';, \\t', maxlinelen=None, linesep='\\n')
Encode a message header into an RFC-compliant format, possibly wrapping
long lines and encapsulating non-ASCII parts in base64 or quoted-printable
- encodings. Optional *splitchars* is a string containing characters to
- split long ASCII lines on, in rough support of :rfc:`2822`'s *highest
- level syntactic breaks*. This doesn't affect :rfc:`2047` encoded lines.
+ encodings.
- The :class:`Header` class also provides a number of methods to support
- standard operators and built-in functions.
+ Optional *splitchars* is a string containing characters which should be
+ given extra weight by the splitting algorithm during normal header
+ wrapping. This is in very rough support of :RFC:`2822`\'s 'higher level
+ syntactic breaks': split points preceded by a splitchar are preferred
+ during line splitting, with the characters preferred in the order in
+ which they appear in the string. Space and tab may be included in the
+ string to indicate whether preference should be given to one over the
+ other as a split point when other split chars do not appear in the line
+ being split. Splitchars does not affect :RFC:`2047` encoded lines.
+ *maxlinelen*, if given, overrides the instance's value for the maximum
+ line length.
- .. method:: __str__()
+ *linesep* specifies the characters used to separate the lines of the
+ folded header. It defaults to the most useful value for Python
+ application code (``\n``), but ``\r\n`` can be specified in order
+ to produce headers with RFC-compliant line separators.
- A synonym for :meth:`Header.encode`. Useful for ``str(aHeader)``.
+ .. versionchanged:: 3.2
+ Added the *linesep* argument.
- .. method:: __unicode__()
+ The :class:`Header` class also provides a number of methods to support
+ standard operators and built-in functions.
+
+ .. method:: __str__()
+
+ Returns an approximation of the :class:`Header` as a string, using an
+ unlimited line length. All pieces are converted to unicode using the
+ specified encoding and joined together appropriately. Any pieces with a
+ charset of ``'unknown-8bit'`` are decoded as ASCII using the ``'replace'``
+ error handler.
- A helper for the built-in :func:`unicode` function. Returns the header as
- a Unicode string.
+ .. versionchanged:: 3.2
+ Added handling for the ``'unknown-8bit'`` charset.
.. method:: __eq__(other)
@@ -160,7 +179,7 @@ The :mod:`email.header` module also provides the following convenient functions.
[('p\xf6stal', 'iso-8859-1')]
-.. function:: make_header(decoded_seq[, maxlinelen[, header_name[, continuation_ws]]])
+.. function:: make_header(decoded_seq, maxlinelen=None, header_name=None, continuation_ws=' ')
Create a :class:`Header` instance from a sequence of pairs as returned by
:func:`decode_header`.
@@ -169,7 +188,7 @@ The :mod:`email.header` module also provides the following convenient functions.
pairs of the format ``(decoded_string, charset)`` where *charset* is the name of
the character set.
- This function takes one of those sequence of pairs and returns a :class:`Header`
- instance. Optional *maxlinelen*, *header_name*, and *continuation_ws* are as in
- the :class:`Header` constructor.
+ This function takes one of those sequence of pairs and returns a
+ :class:`Header` instance. Optional *maxlinelen*, *header_name*, and
+ *continuation_ws* are as in the :class:`Header` constructor.
diff --git a/Doc/library/email.iterators.rst b/Doc/library/email.iterators.rst
index e1a3533..d1f1797 100644
--- a/Doc/library/email.iterators.rst
+++ b/Doc/library/email.iterators.rst
@@ -10,7 +10,7 @@ Iterating over a message object tree is fairly easy with the
useful higher level iterations over message object trees.
-.. function:: body_line_iterator(msg[, decode])
+.. function:: body_line_iterator(msg, decode=False)
This iterates over all the payloads in all the subparts of *msg*, returning the
string payloads line-by-line. It skips over all the subpart headers, and it
@@ -21,7 +21,7 @@ useful higher level iterations over message object trees.
Optional *decode* is passed through to :meth:`Message.get_payload`.
-.. function:: typed_subpart_iterator(msg[, maintype[, subtype]])
+.. function:: typed_subpart_iterator(msg, maintype='text', subtype=None)
This iterates over all the subparts of *msg*, returning only those subparts that
match the MIME type specified by *maintype* and *subtype*.
@@ -37,7 +37,7 @@ The following function has been added as a useful debugging tool. It should
*not* be considered part of the supported public interface for the package.
-.. function:: _structure(msg[, fp[, level]])
+.. function:: _structure(msg, fp=None, level=0, include_default=False)
Prints an indented representation of the content types of the message object
structure. For example::
@@ -60,6 +60,6 @@ The following function has been added as a useful debugging tool. It should
text/plain
text/plain
- Optional *fp* is a file-like object to print the output to. It must be suitable
- for Python's extended print statement. *level* is used internally.
-
+ Optional *fp* is a file-like object to print the output to. It must be
+ suitable for Python's :func:`print` function. *level* is used internally.
+ *include_default*, if true, prints the default type as well.
diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst
index da8e41c..f685e54 100644
--- a/Doc/library/email.message.rst
+++ b/Doc/library/email.message.rst
@@ -36,7 +36,7 @@ Here are the methods of the :class:`Message` class:
The constructor takes no arguments.
- .. method:: as_string([unixfrom])
+ .. method:: as_string(unixfrom=False, maxheaderlen=0)
Return the entire message flattened as a string. When optional *unixfrom*
is ``True``, the envelope header is included in the returned string.
@@ -46,15 +46,16 @@ Here are the methods of the :class:`Message` class:
be generated or modified).
Note that this method is provided as a convenience and may not always
- format the message the way you want. For example, by default it mangles
- lines that begin with ``From``. For more flexibility, instantiate a
+ format the message the way you want. For example, by default it does
+ not do the mangling of lines that begin with ``From`` that is
+ required by the unix mbox format. For more flexibility, instantiate a
:class:`~email.generator.Generator` instance and use its :meth:`flatten`
method directly. For example::
- from cStringIO import StringIO
+ from io import StringIO
from email.generator import Generator
fp = StringIO()
- g = Generator(fp, mangle_from_=False, maxheaderlen=60)
+ g = Generator(fp, mangle_from_=True, maxheaderlen=60)
g.flatten(msg)
text = fp.getvalue()
@@ -91,7 +92,7 @@ Here are the methods of the :class:`Message` class:
:meth:`set_payload` instead.
- .. method:: get_payload([i[, decode]])
+ .. method:: get_payload(i=None, decode=False)
Return the current payload, which will be a list of
:class:`Message` objects when :meth:`is_multipart` is ``True``, or a
@@ -111,21 +112,26 @@ Here are the methods of the :class:`Message` class:
be decoded if this header's value is ``quoted-printable`` or ``base64``.
If some other encoding is used, or :mailheader:`Content-Transfer-Encoding`
header is missing, or if the payload has bogus base64 data, the payload is
- returned as-is (undecoded). If the message is a multipart and the
- *decode* flag is ``True``, then ``None`` is returned. The default for
- *decode* is ``False``.
+ returned as-is (undecoded). In all cases the returned value is binary
+ data. If the message is a multipart and the *decode* flag is ``True``,
+ then ``None`` is returned.
+ When *decode* is ``False`` (the default) the body is returned as a string
+ without decoding the :mailheader:`Content-Transfer-Encoding`. However,
+ for a :mailheader:`Content-Transfer-Encoding` of 8bit, an attempt is made
+ to decode the original bytes using the ``charset`` specified by the
+ :mailheader:`Content-Type` header, using the ``replace`` error handler.
+ If no ``charset`` is specified, or if the ``charset`` given is not
+ recognized by the email package, the body is decoded using the default
+ ASCII charset.
- .. method:: set_payload(payload[, charset])
+
+ .. method:: set_payload(payload, charset=None)
Set the entire message object's payload to *payload*. It is the client's
responsibility to ensure the payload invariants. Optional *charset* sets
the message's default character set; see :meth:`set_charset` for details.
- .. versionchanged:: 2.2.2
- *charset* argument added.
-
-
.. method:: set_charset(charset)
Set the character set of the payload to *charset*, which can either be a
@@ -150,24 +156,11 @@ Here are the methods of the :class:`Message` class:
already exists, the payload is assumed to already be correctly encoded
using that :mailheader:`Content-Transfer-Encoding` and is not modified.
- The message will be assumed to be of type :mimetype:`text/\*`, with the
- payload either in unicode or encoded with *charset.input_charset*.
- It will be encoded or converted to *charset.output_charset*
- and transfer encoded properly, if needed, when generating the plain text
- representation of the message. MIME headers (:mailheader:`MIME-Version`,
- :mailheader:`Content-Type`, :mailheader:`Content-Transfer-Encoding`) will
- be added as needed.
-
- .. versionadded:: 2.2.2
-
-
.. method:: get_charset()
Return the :class:`~email.charset.Charset` instance associated with the
message's payload.
- .. versionadded:: 2.2.2
-
The following methods implement a mapping-like interface for accessing the
message's :rfc:`2822` headers. Note that there are some semantic differences
between these methods and a normal mapping (i.e. dictionary) interface. For
@@ -184,6 +177,11 @@ Here are the methods of the :class:`Message` class:
Note that in all cases, any envelope header present in the message is not
included in the mapping interface.
+ In a model generated from bytes, any header values that (in contravention of
+ the RFCs) contain non-ASCII bytes will, when retrieved through this
+ interface, be represented as :class:`~email.header.Header` objects with
+ a charset of `unknown-8bit`.
+
.. method:: __len__()
@@ -196,8 +194,8 @@ Here are the methods of the :class:`Message` class:
done case-insensitively and *name* should not include the trailing colon.
Used for the ``in`` operator, e.g.::
- if 'message-id' in myMessage:
- print 'Message-ID:', myMessage['message-id']
+ if 'message-id' in myMessage:
+ print('Message-ID:', myMessage['message-id'])
.. method:: __getitem__(name)
@@ -228,13 +226,8 @@ Here are the methods of the :class:`Message` class:
.. method:: __delitem__(name)
Delete all occurrences of the field with name *name* from the message's
- headers. No exception is raised if the named field isn't present in the headers.
-
-
- .. method:: has_key(name)
-
- Return true if the message contains a header field named *name*, otherwise
- return false.
+ headers. No exception is raised if the named field isn't present in the
+ headers.
.. method:: keys()
@@ -253,7 +246,7 @@ Here are the methods of the :class:`Message` class:
values.
- .. method:: get(name[, failobj])
+ .. method:: get(name, failobj=None)
Return the value of the named header field. This is identical to
:meth:`__getitem__` except that optional *failobj* is returned if the
@@ -262,7 +255,7 @@ Here are the methods of the :class:`Message` class:
Here are some additional useful methods:
- .. method:: get_all(name[, failobj])
+ .. method:: get_all(name, failobj=None)
Return a list of all the values for the field named *name*. If there are
no such named headers in the message, *failobj* is returned (defaults to
@@ -281,11 +274,14 @@ Here are the methods of the :class:`Message` class:
dashes are illegal in Python identifiers). Normally, the parameter will
be added as ``key="value"`` unless the value is ``None``, in which case
only the key will be added. If the value contains non-ASCII characters,
- it must be specified as a three tuple in the format
+ it can be specified as a three tuple in the format
``(CHARSET, LANGUAGE, VALUE)``, where ``CHARSET`` is a string naming the
charset to be used to encode the value, ``LANGUAGE`` can usually be set
- to ``None`` or the empty string (see :RFC:`2231` for other possibilities),
- and ``VALUE`` is the string value containing non-ASCII code points.
+ to ``None`` or the empty string (see :rfc:`2231` for other possibilities),
+ and ``VALUE`` is the string value containing non-ASCII code points. If
+ a three tuple is not passed and the value contains non-ASCII characters,
+ it is automatically encoded in :rfc:`2231` format using a ``CHARSET``
+ of ``utf-8`` and a ``LANGUAGE`` of ``None``.
Here's an example::
@@ -311,8 +307,6 @@ Here are the methods of the :class:`Message` class:
matches *_name*, retaining header order and field name case. If no
matching header was found, a :exc:`KeyError` is raised.
- .. versionadded:: 2.2.2
-
.. method:: get_content_type()
@@ -329,24 +323,18 @@ Here are the methods of the :class:`Message` class:
:mailheader:`Content-Type` header has an invalid type specification,
:rfc:`2045` mandates that the default type be :mimetype:`text/plain`.
- .. versionadded:: 2.2.2
-
.. method:: get_content_maintype()
Return the message's main content type. This is the :mimetype:`maintype`
part of the string returned by :meth:`get_content_type`.
- .. versionadded:: 2.2.2
-
.. method:: get_content_subtype()
Return the message's sub-content type. This is the :mimetype:`subtype`
part of the string returned by :meth:`get_content_type`.
- .. versionadded:: 2.2.2
-
.. method:: get_default_type()
@@ -355,8 +343,6 @@ Here are the methods of the :class:`Message` class:
:mimetype:`multipart/digest` containers. Such subparts have a default
content type of :mimetype:`message/rfc822`.
- .. versionadded:: 2.2.2
-
.. method:: set_default_type(ctype)
@@ -365,10 +351,8 @@ Here are the methods of the :class:`Message` class:
enforced. The default content type is not stored in the
:mailheader:`Content-Type` header.
- .. versionadded:: 2.2.2
-
- .. method:: get_params([failobj[, header[, unquote]]])
+ .. method:: get_params(failobj=None, header='content-type', unquote=True)
Return the message's :mailheader:`Content-Type` parameters, as a list.
The elements of the returned list are 2-tuples of key/value pairs, as
@@ -382,11 +366,8 @@ Here are the methods of the :class:`Message` class:
:mailheader:`Content-Type` header. Optional *header* is the header to
search instead of :mailheader:`Content-Type`.
- .. versionchanged:: 2.2.2
- *unquote* argument added.
-
- .. method:: get_param(param[, failobj[, header[, unquote]]])
+ .. method:: get_param(param, failobj=None, header='content-type', unquote=True)
Return the value of the :mailheader:`Content-Type` header's parameter
*param* as a string. If the message has no :mailheader:`Content-Type`
@@ -418,11 +399,8 @@ Here are the methods of the :class:`Message` class:
``VALUE`` item in the 3-tuple) is always unquoted, unless *unquote* is set
to ``False``.
- .. versionchanged:: 2.2.2
- *unquote* argument added, and 3-tuple return value possible.
-
- .. method:: set_param(param, value[, header[, requote[, charset[, language]]]])
+ .. method:: set_param(param, value, header='Content-Type', requote=True, charset=None, language='')
Set a parameter in the :mailheader:`Content-Type` header. If the
parameter already exists in the header, its value will be replaced with
@@ -439,10 +417,8 @@ Here are the methods of the :class:`Message` class:
language, defaulting to the empty string. Both *charset* and *language*
should be strings.
- .. versionadded:: 2.2.2
-
- .. method:: del_param(param[, header[, requote]])
+ .. method:: del_param(param, header='content-type', requote=True)
Remove the given parameter completely from the :mailheader:`Content-Type`
header. The header will be re-written in place without the parameter or
@@ -450,10 +426,8 @@ Here are the methods of the :class:`Message` class:
``False`` (the default is ``True``). Optional *header* specifies an
alternative to :mailheader:`Content-Type`.
- .. versionadded:: 2.2.2
-
- .. method:: set_type(type[, header][, requote])
+ .. method:: set_type(type, header='Content-Type', requote=True)
Set the main type and subtype for the :mailheader:`Content-Type`
header. *type* must be a string in the form :mimetype:`maintype/subtype`,
@@ -468,10 +442,8 @@ Here are the methods of the :class:`Message` class:
:mailheader:`Content-Type` header is set a :mailheader:`MIME-Version`
header is also added.
- .. versionadded:: 2.2.2
-
- .. method:: get_filename([failobj])
+ .. method:: get_filename(failobj=None)
Return the value of the ``filename`` parameter of the
:mailheader:`Content-Disposition` header of the message. If the header
@@ -482,7 +454,7 @@ Here are the methods of the :class:`Message` class:
:func:`email.utils.unquote`.
- .. method:: get_boundary([failobj])
+ .. method:: get_boundary(failobj=None)
Return the value of the ``boundary`` parameter of the
:mailheader:`Content-Type` header of the message, or *failobj* if either
@@ -505,7 +477,7 @@ Here are the methods of the :class:`Message` class:
have been present in the original :mailheader:`Content-Type` header.
- .. method:: get_content_charset([failobj])
+ .. method:: get_content_charset(failobj=None)
Return the ``charset`` parameter of the :mailheader:`Content-Type` header,
coerced to lower case. If there is no :mailheader:`Content-Type` header, or if
@@ -514,10 +486,8 @@ Here are the methods of the :class:`Message` class:
Note that this method differs from :meth:`get_charset` which returns the
:class:`~email.charset.Charset` instance for the default encoding of the message body.
- .. versionadded:: 2.2.2
-
- .. method:: get_charsets([failobj])
+ .. method:: get_charsets(failobj=None)
Return a list containing the character set names in the message. If the
message is a :mimetype:`multipart`, then the list will contain one element
@@ -541,18 +511,14 @@ Here are the methods of the :class:`Message` class:
Here's an example that prints the MIME type of every part of a multipart
message structure::
- >>> for part in msg.walk():
- ... print part.get_content_type()
- multipart/report
- text/plain
- message/delivery-status
- text/plain
- text/plain
- message/rfc822
-
- .. versionchanged:: 2.5
- The previously deprecated methods :meth:`get_type`, :meth:`get_main_type`, and
- :meth:`get_subtype` were removed.
+ >>> for part in msg.walk():
+ ... print(part.get_content_type())
+ multipart/report
+ text/plain
+ message/delivery-status
+ text/plain
+ text/plain
+ message/rfc822
:class:`Message` objects can also optionally contain two instance attributes,
which can be used when generating the plain text of a MIME message.
@@ -587,9 +553,8 @@ Here are the methods of the :class:`Message` class:
except that it contains text that appears between the last boundary and
the end of the message.
- .. versionchanged:: 2.5
- You do not need to set the epilogue to the empty string in order for the
- :class:`Generator` to print a newline at the end of the file.
+ You do not need to set the epilogue to the empty string in order for the
+ :class:`Generator` to print a newline at the end of the file.
.. attribute:: defects
@@ -597,6 +562,3 @@ Here are the methods of the :class:`Message` class:
The *defects* attribute contains a list of all the problems found when
parsing this message. See :mod:`email.errors` for a detailed description
of the possible parsing defects.
-
- .. versionadded:: 2.4
-
diff --git a/Doc/library/email.mime.rst b/Doc/library/email.mime.rst
index 5fa82d0..ae340f7 100644
--- a/Doc/library/email.mime.rst
+++ b/Doc/library/email.mime.rst
@@ -54,12 +54,10 @@ Here are the classes:
which only makes sense for :mimetype:`multipart` messages. If :meth:`attach`
is called, a :exc:`~email.errors.MultipartConversionError` exception is raised.
- .. versionadded:: 2.2.2
-
.. currentmodule:: email.mime.multipart
-.. class:: MIMEMultipart([_subtype[, boundary[, _subparts[, _params]]]])
+.. class:: MIMEMultipart(_subtype='mixed', boundary=None, _subparts=None, **_params)
Module: :mod:`email.mime.multipart`
@@ -82,12 +80,10 @@ Here are the classes:
the keyword arguments, or passed into the *_params* argument, which is a keyword
dictionary.
- .. versionadded:: 2.2.2
-
.. currentmodule:: email.mime.application
-.. class:: MIMEApplication(_data[, _subtype[, _encoder[, **_params]]])
+.. class:: MIMEApplication(_data, _subtype='octet-stream', _encoder=email.encoders.encode_base64, **_params)
Module: :mod:`email.mime.application`
@@ -107,12 +103,10 @@ Here are the classes:
*_params* are passed straight through to the base class constructor.
- .. versionadded:: 2.5
-
.. currentmodule:: email.mime.audio
-.. class:: MIMEAudio(_audiodata[, _subtype[, _encoder[, **_params]]])
+.. class:: MIMEAudio(_audiodata, _subtype=None, _encoder=email.encoders.encode_base64, **_params)
Module: :mod:`email.mime.audio`
@@ -138,7 +132,7 @@ Here are the classes:
.. currentmodule:: email.mime.image
-.. class:: MIMEImage(_imagedata[, _subtype[, _encoder[, **_params]]])
+.. class:: MIMEImage(_imagedata, _subtype=None, _encoder=email.encoders.encode_base64, **_params)
Module: :mod:`email.mime.image`
@@ -165,7 +159,7 @@ Here are the classes:
.. currentmodule:: email.mime.message
-.. class:: MIMEMessage(_msg[, _subtype])
+.. class:: MIMEMessage(_msg, _subtype='rfc822')
Module: :mod:`email.mime.message`
@@ -181,7 +175,7 @@ Here are the classes:
.. currentmodule:: email.mime.text
-.. class:: MIMEText(_text[, _subtype[, _charset]])
+.. class:: MIMEText(_text, _subtype='plain', _charset='us-ascii')
Module: :mod:`email.mime.text`
@@ -191,11 +185,5 @@ Here are the classes:
minor type and defaults to :mimetype:`plain`. *_charset* is the character
set of the text and is passed as a parameter to the
:class:`~email.mime.nonmultipart.MIMENonMultipart` constructor; it defaults
- to ``us-ascii``. If *_text* is unicode, it is encoded using the
- *output_charset* of *_charset*, otherwise it is used as-is.
-
- .. versionchanged:: 2.4
- The previously deprecated *_encoding* argument has been removed. Content
- Transfer Encoding now happens implicitly based on the *_charset*
- argument.
+ to ``us-ascii``. No guessing or encoding is performed on the text data.
diff --git a/Doc/library/email.parser.rst b/Doc/library/email.parser.rst
index a91a770..49a59c0 100644
--- a/Doc/library/email.parser.rst
+++ b/Doc/library/email.parser.rst
@@ -38,8 +38,6 @@ object trees any way it finds necessary.
FeedParser API
^^^^^^^^^^^^^^
-.. versionadded:: 2.4
-
The :class:`FeedParser`, imported from the :mod:`email.feedparser` module,
provides an API that is conducive to incremental parsing of email messages, such
as would be necessary when reading the text of an email message from a source
@@ -60,13 +58,12 @@ list of defects that it can find.
Here is the API for the :class:`FeedParser`:
-.. class:: FeedParser([_factory])
+.. class:: FeedParser(_factory=email.message.Message)
Create a :class:`FeedParser` instance. Optional *_factory* is a no-argument
callable that will be called whenever a new message object is needed. It
defaults to the :class:`email.message.Message` class.
-
.. method:: feed(data)
Feed the :class:`FeedParser` some more data. *data* should be a string
@@ -76,7 +73,6 @@ Here is the API for the :class:`FeedParser`:
carriage return, newline, or carriage return and newline (they can even be
mixed).
-
.. method:: close()
Closing a :class:`FeedParser` completes the parsing of all previously fed
@@ -84,6 +80,14 @@ Here is the API for the :class:`FeedParser`:
if you feed more data to a closed :class:`FeedParser`.
+.. class:: BytesFeedParser(_factory=email.message.Message)
+
+ Works exactly like :class:`FeedParser` except that the input to the
+ :meth:`~FeedParser.feed` method must be bytes and not string.
+
+ .. versionadded:: 3.2
+
+
Parser class API
^^^^^^^^^^^^^^^^
@@ -98,7 +102,7 @@ as a string. :class:`HeaderParser` has the same API as the :class:`Parser`
class.
-.. class:: Parser([_class])
+.. class:: Parser(_class=email.message.Message, strict=None)
The constructor for the :class:`Parser` class takes an optional argument
*_class*. This must be a callable factory (such as a function or a class), and
@@ -114,16 +118,10 @@ class.
effectively non-strict. You should simply stop passing a *strict* flag to
the :class:`Parser` constructor.
- .. versionchanged:: 2.2.2
- The *strict* flag was added.
-
- .. versionchanged:: 2.4
- The *strict* flag was deprecated.
-
The other public :class:`Parser` methods are:
- .. method:: parse(fp[, headersonly])
+ .. method:: parse(fp, headersonly=False)
Read all the data from the file-like object *fp*, parse the resulting
text, and return the root message object. *fp* must support both the
@@ -139,46 +137,87 @@ class.
reading the headers or not. The default is ``False``, meaning it parses
the entire contents of the file.
- .. versionchanged:: 2.2.2
- The *headersonly* flag was added.
-
-
- .. method:: parsestr(text[, headersonly])
+ .. method:: parsestr(text, headersonly=False)
Similar to the :meth:`parse` method, except it takes a string object
instead of a file-like object. Calling this method on a string is exactly
- equivalent to wrapping *text* in a :class:`StringIO` instance first and
+ equivalent to wrapping *text* in a :class:`~io.StringIO` instance first and
calling :meth:`parse`.
Optional *headersonly* is as with the :meth:`parse` method.
- .. versionchanged:: 2.2.2
- The *headersonly* flag was added.
+
+.. class:: BytesParser(_class=email.message.Message, strict=None)
+
+ This class is exactly parallel to :class:`Parser`, but handles bytes input.
+ The *_class* and *strict* arguments are interpreted in the same way as for
+ the :class:`Parser` constructor. *strict* is supported only to make porting
+ code easier; it is deprecated.
+
+ .. method:: parse(fp, headeronly=False)
+
+ Read all the data from the binary file-like object *fp*, parse the
+ resulting bytes, and return the message object. *fp* must support
+ both the :meth:`readline` and the :meth:`read` methods on file-like
+ objects.
+
+ The bytes contained in *fp* must be formatted as a block of :rfc:`2822`
+ style headers and header continuation lines, optionally preceded by a
+ envelope header. The header block is terminated either by the end of the
+ data or by a blank line. Following the header block is the body of the
+ message (which may contain MIME-encoded subparts, including subparts
+ with a :mailheader:`Content-Transfer-Encoding` of ``8bit``.
+
+ Optional *headersonly* is a flag specifying whether to stop parsing after
+ reading the headers or not. The default is ``False``, meaning it parses
+ the entire contents of the file.
+
+ .. method:: parsebytes(bytes, headersonly=False)
+
+ Similar to the :meth:`parse` method, except it takes a byte string object
+ instead of a file-like object. Calling this method on a byte string is
+ exactly equivalent to wrapping *text* in a :class:`~io.BytesIO` instance
+ first and calling :meth:`parse`.
+
+ Optional *headersonly* is as with the :meth:`parse` method.
+
+ .. versionadded:: 3.2
+
Since creating a message object structure from a string or a file object is such
-a common task, two functions are provided as a convenience. They are available
+a common task, four functions are provided as a convenience. They are available
in the top-level :mod:`email` package namespace.
.. currentmodule:: email
-.. function:: message_from_string(s[, _class[, strict]])
+.. function:: message_from_string(s, _class=email.message.Message, strict=None)
Return a message object structure from a string. This is exactly equivalent to
``Parser().parsestr(s)``. Optional *_class* and *strict* are interpreted as
with the :class:`Parser` class constructor.
- .. versionchanged:: 2.2.2
- The *strict* flag was added.
+.. function:: message_from_bytes(s, _class=email.message.Message, strict=None)
+
+ Return a message object structure from a byte string. This is exactly
+ equivalent to ``BytesParser().parsebytes(s)``. Optional *_class* and
+ *strict* are interpreted as with the :class:`Parser` class constructor.
+
+ .. versionadded:: 3.2
+
+.. function:: message_from_file(fp, _class=email.message.Message, strict=None)
+ Return a message object structure tree from an open :term:`file object`.
+ This is exactly equivalent to ``Parser().parse(fp)``. Optional *_class*
+ and *strict* are interpreted as with the :class:`Parser` class constructor.
-.. function:: message_from_file(fp[, _class[, strict]])
+.. function:: message_from_binary_file(fp, _class=email.message.Message, strict=None)
- Return a message object structure tree from an open file object. This is
- exactly equivalent to ``Parser().parse(fp)``. Optional *_class* and *strict*
- are interpreted as with the :class:`Parser` class constructor.
+ Return a message object structure tree from an open binary :term:`file
+ object`. This is exactly equivalent to ``BytesParser().parse(fp)``.
+ Optional *_class* and *strict* are interpreted as with the :class:`Parser`
+ class constructor.
- .. versionchanged:: 2.2.2
- The *strict* flag was added.
+ .. versionadded:: 3.2
Here's an example of how you might use this at an interactive Python prompt::
diff --git a/Doc/library/email.rst b/Doc/library/email.rst
index aaff153..4530b95 100644
--- a/Doc/library/email.rst
+++ b/Doc/library/email.rst
@@ -2,25 +2,20 @@
===================================================
.. module:: email
- :synopsis: Package supporting the parsing, manipulating, and generating email messages,
- including MIME documents.
+ :synopsis: Package supporting the parsing, manipulating, and generating
+ email messages, including MIME documents.
.. moduleauthor:: Barry A. Warsaw <barry@python.org>
.. sectionauthor:: Barry A. Warsaw <barry@python.org>
-.. Copyright (C) 2001-2007 Python Software Foundation
+.. Copyright (C) 2001-2010 Python Software Foundation
-.. versionadded:: 2.2
-
The :mod:`email` package is a library for managing email messages, including
-MIME and other :rfc:`2822`\ -based message documents. It subsumes most of the
-functionality in several older standard modules such as :mod:`rfc822`,
-:mod:`mimetools`, :mod:`multifile`, and other non-standard packages such as
-:mod:`mimecntl`. It is specifically *not* designed to do any sending of email
-messages to SMTP (:rfc:`2821`), NNTP, or other servers; those are functions of
-modules such as :mod:`smtplib` and :mod:`nntplib`. The :mod:`email` package
-attempts to be as RFC-compliant as possible, supporting in addition to
-:rfc:`2822`, such MIME-related RFCs as :rfc:`2045`, :rfc:`2046`, :rfc:`2047`,
-and :rfc:`2231`.
+MIME and other :rfc:`2822`\ -based message documents. It is specifically *not*
+designed to do any sending of email messages to SMTP (:rfc:`2821`), NNTP, or
+other servers; those are functions of modules such as :mod:`smtplib` and
+:mod:`nntplib`. The :mod:`email` package attempts to be as RFC-compliant as
+possible, supporting in addition to :rfc:`2822`, such MIME-related RFCs as
+:rfc:`2045`, :rfc:`2046`, :rfc:`2047`, and :rfc:`2231`.
The primary distinguishing feature of the :mod:`email` package is that it splits
the parsing and generating of email messages from the internal *object model*
@@ -97,6 +92,44 @@ table also describes the Python compatibility of each version of the package.
+---------------+------------------------------+-----------------------+
| :const:`4.0` | Python 2.5 | Python 2.3 to 2.5 |
+---------------+------------------------------+-----------------------+
+| :const:`5.0` | Python 3.0 and Python 3.1 | Python 3.0 to 3.2 |
++---------------+------------------------------+-----------------------+
+| :const:`5.1` | Python 3.2 | Python 3.0 to 3.2 |
++---------------+------------------------------+-----------------------+
+
+Here are the major differences between :mod:`email` version 5.1 and
+version 5.0:
+
+* It is once again possible to parse messages containing non-ASCII bytes,
+ and to reproduce such messages if the data containing the non-ASCII
+ bytes is not modified.
+
+* New functions :func:`message_from_bytes` and :func:`message_from_binary_file`,
+ and new classes :class:`~email.parser.BytesFeedParser` and
+ :class:`~email.parser.BytesParser` allow binary message data to be parsed
+ into model objects.
+
+* Given bytes input to the model, :meth:`~email.message.Message.get_payload`
+ will by default decode a message body that has a
+ :mailheader:`Content-Transfer-Encoding` of ``8bit`` using the charset
+ specified in the MIME headers and return the resulting string.
+
+* Given bytes input to the model, :class:`~email.generator.Generator` will
+ convert message bodies that have a :mailheader:`Content-Transfer-Encoding` of
+ 8bit to instead have a 7bit Content-Transfer-Encoding.
+
+* New class :class:`~email.generator.BytesGenerator` produces bytes
+ as output, preserving any unchanged non-ASCII data that was
+ present in the input used to build the model, including message bodies
+ with a :mailheader:`Content-Transfer-Encoding` of 8bit.
+
+Here are the major differences between :mod:`email` version 5.0 and version 4:
+
+* All operations are on unicode strings. Text inputs must be strings,
+ text outputs are strings. Outputs are limited to the ASCII character
+ set and so can be encoded to ASCII for transmission. Inputs are also
+ limited to ASCII; this is an acknowledged limitation of email 5.0 and
+ means it can only be used to parse email that is 7bit clean.
Here are the major differences between :mod:`email` version 4 and version 3:
diff --git a/Doc/library/email.util.rst b/Doc/library/email.util.rst
index 744f1da..11bf3b2 100644
--- a/Doc/library/email.util.rst
+++ b/Doc/library/email.util.rst
@@ -84,7 +84,7 @@ There are several useful utilities provided in the :mod:`email.utils` module:
about for common use.
-.. function:: formatdate([timeval[, localtime][, usegmt]])
+.. function:: formatdate(timeval=None, localtime=False, usegmt=False)
Returns a date string as per :rfc:`2822`, e.g.::
@@ -104,14 +104,18 @@ There are several useful utilities provided in the :mod:`email.utils` module:
needed for some protocols (such as HTTP). This only applies when *localtime* is
``False``. The default is ``False``.
- .. versionadded:: 2.4
-
-.. function:: make_msgid([idstring])
+.. function:: make_msgid(idstring=None, domain=None)
Returns a string suitable for an :rfc:`2822`\ -compliant
- :mailheader:`Message-ID` header. Optional *idstring* if given, is a string used
- to strengthen the uniqueness of the message id.
+ :mailheader:`Message-ID` header. Optional *idstring* if given, is a string
+ used to strengthen the uniqueness of the message id. Optional *domain* if
+ given provides the portion of the msgid after the '@'. The default is the
+ local hostname. It is not normally necessary to override this default, but
+ may be useful certain cases, such as a constructing distributed system that
+ uses a consistent domain name across multiple hosts.
+
+ .. versionchanged:: 3.2 domain keyword added
.. function:: decode_rfc2231(s)
@@ -119,7 +123,7 @@ There are several useful utilities provided in the :mod:`email.utils` module:
Decode the string *s* according to :rfc:`2231`.
-.. function:: encode_rfc2231(s[, charset[, language]])
+.. function:: encode_rfc2231(s, charset=None, language=None)
Encode the string *s* according to :rfc:`2231`. Optional *charset* and
*language*, if given is the character set name and language name to use. If
@@ -127,15 +131,15 @@ There are several useful utilities provided in the :mod:`email.utils` module:
is not, the string is encoded using the empty string for *language*.
-.. function:: collapse_rfc2231_value(value[, errors[, fallback_charset]])
+.. function:: collapse_rfc2231_value(value, errors='replace', fallback_charset='us-ascii')
When a header parameter is encoded in :rfc:`2231` format,
:meth:`Message.get_param` may return a 3-tuple containing the character set,
language, and value. :func:`collapse_rfc2231_value` turns this into a unicode
- string. Optional *errors* is passed to the *errors* argument of the built-in
- :func:`unicode` function; it defaults to ``replace``. Optional
+ string. Optional *errors* is passed to the *errors* argument of :class:`str`'s
+ :func:`encode` method; it defaults to ``'replace'``. Optional
*fallback_charset* specifies the character set to use if the one in the
- :rfc:`2231` header is not known by Python; it defaults to ``us-ascii``.
+ :rfc:`2231` header is not known by Python; it defaults to ``'us-ascii'``.
For convenience, if the *value* passed to :func:`collapse_rfc2231_value` is not
a tuple, it should be a string and it is returned unquoted.
@@ -146,17 +150,6 @@ There are several useful utilities provided in the :mod:`email.utils` module:
Decode parameters list according to :rfc:`2231`. *params* is a sequence of
2-tuples containing elements of the form ``(content-type, string-value)``.
-.. versionchanged:: 2.4
- The :func:`dump_address_pair` function has been removed; use :func:`formataddr`
- instead.
-
-.. versionchanged:: 2.4
- The :func:`decode` function has been removed; use the
- :meth:`Header.decode_header` method instead.
-
-.. versionchanged:: 2.4
- The :func:`encode` function has been removed; use the :meth:`Header.encode`
- method instead.
.. rubric:: Footnotes
diff --git a/Doc/library/errno.rst b/Doc/library/errno.rst
index daf9ff0..d2163b6 100644
--- a/Doc/library/errno.rst
+++ b/Doc/library/errno.rst
@@ -1,4 +1,3 @@
-
:mod:`errno` --- Standard errno system symbols
==============================================
diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst
index c12e874..7d622c2 100644
--- a/Doc/library/exceptions.rst
+++ b/Doc/library/exceptions.rst
@@ -3,20 +3,12 @@
Built-in Exceptions
===================
-.. module:: exceptions
- :synopsis: Standard exception classes.
-
-
-Exceptions should be class objects. The exceptions are defined in the module
-:mod:`exceptions`. This module never needs to be imported explicitly: the
-exceptions are provided in the built-in namespace as well as the
-:mod:`exceptions` module.
-
.. index::
statement: try
statement: except
-For class exceptions, in a :keyword:`try` statement with an :keyword:`except`
+In Python, all exceptions must be instances of a class that derives from
+:class:`BaseException`. In a :keyword:`try` statement with an :keyword:`except`
clause that mentions a particular class, that clause also handles any exception
classes derived from that class (but not exception classes from which *it* is
derived). Two exception classes that are not related via subclassing are never
@@ -26,12 +18,10 @@ equivalent, even if they have the same name.
The built-in exceptions listed below can be generated by the interpreter or
built-in functions. Except where mentioned, they have an "associated value"
-indicating the detailed cause of the error. This may be a string or a tuple
-containing several items of information (e.g., an error code and a string
-explaining the code). The associated value is the second argument to the
-:keyword:`raise` statement. If the exception class is derived from the standard
-root class :exc:`BaseException`, the associated value is present as the
-exception instance's :attr:`args` attribute.
+indicating the detailed cause of the error. This may be a string or a tuple of
+several items of information (e.g., an error code and a string explaining the
+code). The associated value is usually passed as arguments to the exception
+class's constructor.
User code can raise built-in exceptions. This can be used to test an exception
handler or to report an error condition "just like" the situation in which the
@@ -44,17 +34,15 @@ programmers are encouraged to at least derive new exceptions from the
defining exceptions is available in the Python Tutorial under
:ref:`tut-userexceptions`.
-The following exceptions are only used as base classes for other exceptions.
+The following exceptions are used mostly as base classes for other exceptions.
.. exception:: BaseException
The base class for all built-in exceptions. It is not meant to be directly
inherited by user-defined classes (for that, use :exc:`Exception`). If
- :func:`str` or :func:`unicode` is called on an instance of this class, the
- representation of the argument(s) to the instance are returned, or the empty
- string when there were no arguments.
-
- .. versionadded:: 2.5
+ :func:`str` is called on an instance of this class, the representation of
+ the argument(s) to the instance are returned, or the empty string when
+ there were no arguments.
.. attribute:: args
@@ -63,21 +51,23 @@ The following exceptions are only used as base classes for other exceptions.
assign a special meaning to the elements of this tuple, while others are
usually called only with a single string giving an error message.
+ .. method:: with_traceback(tb)
-.. exception:: Exception
-
- All built-in, non-system-exiting exceptions are derived from this class. All
- user-defined exceptions should also be derived from this class.
+ This method sets *tb* as the new traceback for the exception and returns
+ the exception object. It is usually used in exception handling code like
+ this::
- .. versionchanged:: 2.5
- Changed to inherit from :exc:`BaseException`.
+ try:
+ ...
+ except SomeException:
+ tb = sys.exc_info()[2]
+ raise OtherException(...).with_traceback(tb)
-.. exception:: StandardError
+.. exception:: Exception
- The base class for all built-in exceptions except :exc:`StopIteration`,
- :exc:`GeneratorExit`, :exc:`KeyboardInterrupt` and :exc:`SystemExit`.
- :exc:`StandardError` itself is derived from :exc:`Exception`.
+ All built-in, non-system-exiting exceptions are derived from this class. All
+ user-defined exceptions should also be derived from this class.
.. exception:: ArithmeticError
@@ -109,8 +99,6 @@ The following exceptions are only used as base classes for other exceptions.
:attr:`strerror` attribute (it is usually the associated error message). The
tuple itself is also available on the :attr:`args` attribute.
- .. versionadded:: 1.5.2
-
When an :exc:`EnvironmentError` exception is instantiated with a 3-tuple, the
first two items are available as above, while the third item is available on the
:attr:`filename` attribute. However, for backwards compatibility, the
@@ -123,8 +111,8 @@ The following exceptions are only used as base classes for other exceptions.
In this last case, :attr:`args` contains the verbatim constructor arguments as a
tuple.
-The following exceptions are the exceptions that are actually raised.
+The following exceptions are the exceptions that are usually raised.
.. exception:: AssertionError
@@ -159,26 +147,19 @@ The following exceptions are the exceptions that are actually raised.
.. exception:: GeneratorExit
Raise when a :term:`generator`\'s :meth:`close` method is called. It
- directly inherits from :exc:`BaseException` instead of :exc:`StandardError` since
+ directly inherits from :exc:`BaseException` instead of :exc:`Exception` since
it is technically not an error.
- .. versionadded:: 2.5
-
- .. versionchanged:: 2.6
- Changed to inherit from :exc:`BaseException`.
.. exception:: IOError
- Raised when an I/O operation (such as a :keyword:`print` statement, the built-in
- :func:`open` function or a method of a file object) fails for an I/O-related
- reason, e.g., "file not found" or "disk full".
+ Raised when an I/O operation (such as the built-in :func:`print` or
+ :func:`open` functions or a method of a :term:`file object`) fails for an
+ I/O-related reason, e.g., "file not found" or "disk full".
This class is derived from :exc:`EnvironmentError`. See the discussion above
for more information on exception instance attributes.
- .. versionchanged:: 2.6
- Changed :exc:`socket.error` to use this as a base class.
-
.. exception:: ImportError
@@ -188,9 +169,9 @@ The following exceptions are the exceptions that are actually raised.
.. exception:: IndexError
- Raised when a sequence subscript is out of range. (Slice indices are silently
- truncated to fall in the allowed range; if an index is not a plain integer,
- :exc:`TypeError` is raised.)
+ Raised when a sequence subscript is out of range. (Slice indices are
+ silently truncated to fall in the allowed range; if an index is not an
+ integer, :exc:`TypeError` is raised.)
.. XXX xref to sequences
@@ -205,14 +186,10 @@ The following exceptions are the exceptions that are actually raised.
.. exception:: KeyboardInterrupt
Raised when the user hits the interrupt key (normally :kbd:`Control-C` or
- :kbd:`Delete`). During execution, a check for interrupts is made regularly.
- Interrupts typed when a built-in function :func:`input` or :func:`raw_input` is
- waiting for input also raise this exception. The exception inherits from
- :exc:`BaseException` so as to not be accidentally caught by code that catches
- :exc:`Exception` and thus prevent the interpreter from exiting.
-
- .. versionchanged:: 2.5
- Changed to inherit from :exc:`BaseException`.
+ :kbd:`Delete`). During execution, a check for interrupts is made
+ regularly. The exception inherits from :exc:`BaseException` so as to not be
+ accidentally caught by code that catches :exc:`Exception` and thus prevent
+ the interpreter from exiting.
.. exception:: MemoryError
@@ -239,8 +216,6 @@ The following exceptions are the exceptions that are actually raised.
classes, abstract methods should raise this exception when they require derived
classes to override the method.
- .. versionadded:: 1.5.2
-
.. exception:: OSError
@@ -258,17 +233,14 @@ The following exceptions are the exceptions that are actually raised.
:func:`unlink`), the exception instance will contain a third attribute,
:attr:`filename`, which is the file name passed to the function.
- .. versionadded:: 1.5.2
-
.. exception:: OverflowError
Raised when the result of an arithmetic operation is too large to be
- represented. This cannot occur for long integers (which would rather raise
- :exc:`MemoryError` than give up) and for most operations with plain integers,
- which return a long integer instead. Because of the lack of standardization
- of floating point exception handling in C, most floating point operations
- also aren't checked.
+ represented. This cannot occur for integers (which would rather raise
+ :exc:`MemoryError` than give up). Because of the lack of standardization of
+ floating point exception handling in C, most floating point operations also
+ aren't checked.
.. exception:: ReferenceError
@@ -278,9 +250,6 @@ The following exceptions are the exceptions that are actually raised.
after it has been garbage collected. For more information on weak references,
see the :mod:`weakref` module.
- .. versionadded:: 2.2
- Previously known as the :exc:`weakref.ReferenceError` exception.
-
.. exception:: RuntimeError
@@ -292,20 +261,16 @@ The following exceptions are the exceptions that are actually raised.
.. exception:: StopIteration
- Raised by an :term:`iterator`\'s :meth:`~iterator.next` method to signal that
- there are no further values. This is derived from :exc:`Exception` rather
- than :exc:`StandardError`, since this is not considered an error in its
- normal application.
-
- .. versionadded:: 2.2
+ Raised by built-in function :func:`next` and an :term:`iterator`\'s
+ :meth:`~iterator.__next__` method to signal that there are no further values.
.. exception:: SyntaxError
Raised when the parser encounters a syntax error. This may occur in an
- :keyword:`import` statement, in an :keyword:`exec` statement, in a call to the
- built-in function :func:`eval` or :func:`input`, or when reading the initial
- script or standard input (also interactively).
+ :keyword:`import` statement, in a call to the built-in functions :func:`exec`
+ or :func:`eval`, or when reading the initial script or standard input
+ (also interactively).
Instances of this class have attributes :attr:`filename`, :attr:`lineno`,
:attr:`offset` and :attr:`text` for easier access to the details. :func:`str`
@@ -341,14 +306,14 @@ The following exceptions are the exceptions that are actually raised.
This exception is raised by the :func:`sys.exit` function. When it is not
handled, the Python interpreter exits; no stack traceback is printed. If the
- associated value is a plain integer, it specifies the system exit status (passed
- to C's :c:func:`exit` function); if it is ``None``, the exit status is zero; if
- it has another type (such as a string), the object's value is printed and the
- exit status is one.
+ associated value is an integer, it specifies the system exit status (passed
+ to C's :c:func:`exit` function); if it is ``None``, the exit status is zero;
+ if it has another type (such as a string), the object's value is printed and
+ the exit status is one.
Instances have an attribute :attr:`code` which is set to the proposed exit
status or error message (defaulting to ``None``). Also, this exception derives
- directly from :exc:`BaseException` and not :exc:`StandardError`, since it is not
+ directly from :exc:`BaseException` and not :exc:`Exception`, since it is not
technically an error.
A call to :func:`sys.exit` is translated into an exception so that clean-up
@@ -358,13 +323,9 @@ The following exceptions are the exceptions that are actually raised.
absolutely positively necessary to exit immediately (for example, in the child
process after a call to :func:`fork`).
- The exception inherits from :exc:`BaseException` instead of :exc:`StandardError`
- or :exc:`Exception` so that it is not accidentally caught by code that catches
- :exc:`Exception`. This allows the exception to properly propagate up and cause
- the interpreter to exit.
-
- .. versionchanged:: 2.5
- Changed to inherit from :exc:`BaseException`.
+ The exception inherits from :exc:`BaseException` instead of :exc:`Exception` so
+ that it is not accidentally caught by code that catches :exc:`Exception`. This
+ allows the exception to properly propagate up and cause the interpreter to exit.
.. exception:: TypeError
@@ -379,64 +340,30 @@ The following exceptions are the exceptions that are actually raised.
no value has been bound to that variable. This is a subclass of
:exc:`NameError`.
- .. versionadded:: 2.0
-
.. exception:: UnicodeError
Raised when a Unicode-related encoding or decoding error occurs. It is a
subclass of :exc:`ValueError`.
- :exc:`UnicodeError` has attributes that describe the encoding or decoding
- error. For example, ``err.object[err.start:err.end]`` gives the particular
- invalid input that the codec failed on.
-
- .. attribute:: encoding
-
- The name of the encoding that raised the error.
-
- .. attribute:: reason
-
- A string describing the specific codec error.
-
- .. attribute:: object
-
- The object the codec was attempting to encode or decode.
-
- .. attribute:: start
-
- The first index of invalid data in :attr:`object`.
-
- .. attribute:: end
-
- The index after the last invalid data in :attr:`object`.
-
- .. versionadded:: 2.0
-
.. exception:: UnicodeEncodeError
Raised when a Unicode-related error occurs during encoding. It is a subclass of
:exc:`UnicodeError`.
- .. versionadded:: 2.3
-
.. exception:: UnicodeDecodeError
Raised when a Unicode-related error occurs during decoding. It is a subclass of
:exc:`UnicodeError`.
- .. versionadded:: 2.3
-
.. exception:: UnicodeTranslateError
Raised when a Unicode-related error occurs during translating. It is a subclass
of :exc:`UnicodeError`.
- .. versionadded:: 2.3
-
.. exception:: ValueError
@@ -459,11 +386,6 @@ The following exceptions are the exceptions that are actually raised.
Platform API. The :attr:`errno` value maps the :attr:`winerror` value to
corresponding ``errno.h`` values. This is a subclass of :exc:`OSError`.
- .. versionadded:: 2.0
-
- .. versionchanged:: 2.5
- Previous versions put the :c:func:`GetLastError` codes into :attr:`errno`.
-
.. exception:: ZeroDivisionError
@@ -471,10 +393,10 @@ The following exceptions are the exceptions that are actually raised.
associated value is a string indicating the type of the operands and the
operation.
+
The following exceptions are used as warning categories; see the :mod:`warnings`
module for more information.
-
.. exception:: Warning
Base class for warning categories.
@@ -515,14 +437,23 @@ module for more information.
Base class for warnings about probable mistakes in module imports.
- .. versionadded:: 2.5
-
.. exception:: UnicodeWarning
Base class for warnings related to Unicode.
- .. versionadded:: 2.5
+
+.. exception:: BytesWarning
+
+ Base class for warnings related to :class:`bytes` and :class:`buffer`.
+
+
+.. exception:: ResourceWarning
+
+ Base class for warnings related to resource usage.
+
+ .. versionadded:: 3.2
+
Exception hierarchy
diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst
index 40ae08b..6192400 100644
--- a/Doc/library/fcntl.rst
+++ b/Doc/library/fcntl.rst
@@ -1,4 +1,3 @@
-
:mod:`fcntl` --- The :func:`fcntl` and :func:`ioctl` system calls
=================================================================
@@ -17,8 +16,8 @@ interface to the :c:func:`fcntl` and :c:func:`ioctl` Unix routines.
All functions in this module take a file descriptor *fd* as their first
argument. This can be an integer file descriptor, such as returned by
-``sys.stdin.fileno()``, or a file object, such as ``sys.stdin`` itself, which
-provides a :meth:`fileno` which returns a genuine file descriptor.
+``sys.stdin.fileno()``, or a :class:`io.IOBase` object, such as ``sys.stdin``
+itself, which provides a :meth:`fileno` that returns a genuine file descriptor.
The module defines the following functions:
@@ -47,7 +46,6 @@ The module defines the following functions:
.. function:: ioctl(fd, op[, arg[, mutate_flag]])
This function is identical to the :func:`fcntl` function, except that the
- operations are typically defined in the library module :mod:`termios` and the
argument handling is even more complicated.
The op parameter is limited to values that can fit in 32-bits.
@@ -66,17 +64,13 @@ The module defines the following functions:
so long as the buffer you pass is as least as long as what the operating system
wants to put there, things should work.
- If *mutate_flag* is true, then the buffer is (in effect) passed to the
- underlying :func:`ioctl` system call, the latter's return code is passed back to
- the calling Python, and the buffer's new contents reflect the action of the
- :func:`ioctl`. This is a slight simplification, because if the supplied buffer
- is less than 1024 bytes long it is first copied into a static buffer 1024 bytes
- long which is then passed to :func:`ioctl` and copied back into the supplied
- buffer.
-
- If *mutate_flag* is not supplied, then from Python 2.5 it defaults to true,
- which is a change from versions 2.3 and 2.4. Supply the argument explicitly if
- version portability is a priority.
+ If *mutate_flag* is true (the default), then the buffer is (in effect) passed
+ to the underlying :func:`ioctl` system call, the latter's return code is
+ passed back to the calling Python, and the buffer's new contents reflect the
+ action of the :func:`ioctl`. This is a slight simplification, because if the
+ supplied buffer is less than 1024 bytes long it is first copied into a static
+ buffer 1024 bytes long which is then passed to :func:`ioctl` and copied back
+ into the supplied buffer.
An example::
diff --git a/Doc/library/filecmp.rst b/Doc/library/filecmp.rst
index 6881969..de20fb1 100644
--- a/Doc/library/filecmp.rst
+++ b/Doc/library/filecmp.rst
@@ -16,7 +16,7 @@ see also the :mod:`difflib` module.
The :mod:`filecmp` module defines the following functions:
-.. function:: cmp(f1, f2[, shallow])
+.. function:: cmp(f1, f2, shallow=True)
Compare the files named *f1* and *f2*, returning ``True`` if they seem equal,
``False`` otherwise.
@@ -31,7 +31,7 @@ The :mod:`filecmp` module defines the following functions:
portability and efficiency.
-.. function:: cmpfiles(dir1, dir2, common[, shallow])
+.. function:: cmpfiles(dir1, dir2, common, shallow=True)
Compare the files in the two directories *dir1* and *dir2* whose names are
given by *common*.
@@ -68,7 +68,7 @@ The :class:`dircmp` class
:class:`dircmp` instances are built using this constructor:
-.. class:: dircmp(a, b[, ignore[, hide]])
+.. class:: dircmp(a, b, ignore=None, hide=None)
Construct a new directory comparison object, to compare the directories *a* and
*b*. *ignore* is a list of names to ignore, and defaults to ``['RCS', 'CVS',
@@ -176,7 +176,8 @@ The :class:`dircmp` class
.. attribute:: subdirs
- A dictionary mapping names in :attr:`common_dirs` to :class:`dircmp` objects.
+ A dictionary mapping names in :attr:`common_dirs` to :class:`dircmp`
+ objects.
Here is a simplified example of using the ``subdirs`` attribute to search
@@ -185,8 +186,8 @@ recursively through two directories to show common different files::
>>> from filecmp import dircmp
>>> def print_diff_files(dcmp):
... for name in dcmp.diff_files:
- ... print "diff_file %s found in %s and %s" % (name, dcmp.left,
- ... dcmp.right)
+ ... print("diff_file %s found in %s and %s" % (name, dcmp.left,
+ ... dcmp.right))
... for sub_dcmp in dcmp.subdirs.values():
... print_diff_files(sub_dcmp)
...
diff --git a/Doc/library/fileformats.rst b/Doc/library/fileformats.rst
index d2f0639..e9c2e1f 100644
--- a/Doc/library/fileformats.rst
+++ b/Doc/library/fileformats.rst
@@ -1,4 +1,3 @@
-
.. _fileformats:
************
@@ -6,14 +5,13 @@ File Formats
************
The modules described in this chapter parse various miscellaneous file formats
-that aren't markup languages or are related to e-mail.
+that aren't markup languages and are not related to e-mail.
.. toctree::
csv.rst
configparser.rst
- robotparser.rst
netrc.rst
xdrlib.rst
plistlib.rst
diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst
index 172a643..ac44311 100644
--- a/Doc/library/fileinput.rst
+++ b/Doc/library/fileinput.rst
@@ -27,7 +27,7 @@ as the first argument to :func:`.input`. A single file name is also allowed.
All files are opened in text mode by default, but you can override this by
specifying the *mode* parameter in the call to :func:`.input` or
-:class:`FileInput()`. If an I/O error occurs during opening or reading a file,
+:class:`FileInput`. If an I/O error occurs during opening or reading a file,
:exc:`IOError` is raised.
If ``sys.stdin`` is used more than once, the second and further use will return
@@ -50,15 +50,24 @@ provided by this module.
The following function is the primary interface of this module:
-.. function:: input([files[, inplace[, backup[, mode[, openhook]]]]])
+.. function:: input(files=None, inplace=False, backup='', bufsize=0, mode='r', openhook=None)
Create an instance of the :class:`FileInput` class. The instance will be used
as global state for the functions of this module, and is also returned to use
during iteration. The parameters to this function will be passed along to the
constructor of the :class:`FileInput` class.
- .. versionchanged:: 2.5
- Added the *mode* and *openhook* parameters.
+ The :class:`FileInput` instance can be used as a context manager in the
+ :keyword:`with` statement. In this example, *input* is closed after the
+ :keyword:`with` statement is exited, even if an exception occurs::
+
+ with fileinput.input(files=('spam.txt', 'eggs.txt')) as f:
+ for line in f:
+ process(line)
+
+ .. versionchanged:: 3.2
+ Can be used as a context manager.
+
The following functions use the global state created by :func:`fileinput.input`;
if there is no active state, :exc:`RuntimeError` is raised.
@@ -75,8 +84,6 @@ if there is no active state, :exc:`RuntimeError` is raised.
Return the integer "file descriptor" for the current file. When no file is
opened (before the first line and between files), returns ``-1``.
- .. versionadded:: 2.5
-
.. function:: lineno()
@@ -122,7 +129,7 @@ The class which implements the sequence behavior provided by the module is
available for subclassing as well:
-.. class:: FileInput([files[, inplace[, backup[, mode[, openhook]]]]])
+.. class:: FileInput(files=None, inplace=False, backup='', bufsize=0, mode='r', openhook=None)
Class :class:`FileInput` is the implementation; its methods :meth:`filename`,
:meth:`fileno`, :meth:`lineno`, :meth:`filelineno`, :meth:`isfirstline`,
@@ -139,15 +146,23 @@ available for subclassing as well:
*filename* and *mode*, and returns an accordingly opened file-like object. You
cannot use *inplace* and *openhook* together.
- .. versionchanged:: 2.5
- Added the *mode* and *openhook* parameters.
+ A :class:`FileInput` instance can be used as a context manager in the
+ :keyword:`with` statement. In this example, *input* is closed after the
+ :keyword:`with` statement is exited, even if an exception occurs::
+
+ with FileInput(files=('spam.txt', 'eggs.txt')) as input:
+ process(input)
+
+ .. versionchanged:: 3.2
+ Can be used as a context manager.
-**Optional in-place filtering:** if the keyword argument ``inplace=1`` is passed
-to :func:`fileinput.input` or to the :class:`FileInput` constructor, the file is
-moved to a backup file and standard output is directed to the input file (if a
-file of the same name as the backup file already exists, it will be replaced
-silently). This makes it possible to write a filter that rewrites its input
-file in place. If the *backup* parameter is given (typically as
+
+**Optional in-place filtering:** if the keyword argument ``inplace=True`` is
+passed to :func:`fileinput.input` or to the :class:`FileInput` constructor, the
+file is moved to a backup file and standard output is directed to the input file
+(if a file of the same name as the backup file already exists, it will be
+replaced silently). This makes it possible to write a filter that rewrites its
+input file in place. If the *backup* parameter is given (typically as
``backup='.<some extension>'``), it specifies the extension for the backup file,
and the backup file remains around; by default, the extension is ``'.bak'`` and
it is deleted when the output file is closed. In-place filtering is disabled
@@ -169,8 +184,6 @@ The two following opening hooks are provided by this module:
Usage example: ``fi = fileinput.FileInput(openhook=fileinput.hook_compressed)``
- .. versionadded:: 2.5
-
.. function:: hook_encoded(encoding)
@@ -179,11 +192,3 @@ The two following opening hooks are provided by this module:
Usage example: ``fi =
fileinput.FileInput(openhook=fileinput.hook_encoded("iso-8859-1"))``
-
- .. note::
-
- With this hook, :class:`FileInput` might return Unicode strings depending on the
- specified *encoding*.
-
- .. versionadded:: 2.5
-
diff --git a/Doc/library/filesys.rst b/Doc/library/filesys.rst
index e5b5e44..58998a8 100644
--- a/Doc/library/filesys.rst
+++ b/Doc/library/filesys.rst
@@ -1,4 +1,3 @@
-
.. _filesys:
*************************
@@ -16,23 +15,24 @@ in this chapter is:
os.path.rst
fileinput.rst
stat.rst
- statvfs.rst
filecmp.rst
tempfile.rst
glob.rst
fnmatch.rst
linecache.rst
shutil.rst
- dircache.rst
macpath.rst
.. seealso::
- Section :ref:`bltin-file-objects`
- A description of Python's built-in file objects.
-
Module :mod:`os`
- Operating system interfaces, including functions to work with files at a lower
- level than the built-in file object.
+ Operating system interfaces, including functions to work with files at a
+ lower level than Python :term:`file objects <file object>`.
+
+ Module :mod:`io`
+ Python's built-in I/O library, including both abstract classes and
+ some concrete classes such as file I/O.
+ Built-in function :func:`open`
+ The standard way to open files for reading and writing with Python.
diff --git a/Doc/library/fl.rst b/Doc/library/fl.rst
deleted file mode 100644
index c689372..0000000
--- a/Doc/library/fl.rst
+++ /dev/null
@@ -1,523 +0,0 @@
-
-:mod:`fl` --- FORMS library for graphical user interfaces
-=========================================================
-
-.. module:: fl
- :platform: IRIX
- :synopsis: FORMS library for applications with graphical user interfaces.
- :deprecated:
-
-
-.. deprecated:: 2.6
- The :mod:`fl` module has been removed in Python 3.
-
-
-.. index::
- single: FORMS Library
- single: Overmars, Mark
-
-This module provides an interface to the FORMS Library by Mark Overmars. The
-source for the library can be retrieved by anonymous ftp from host
-``ftp.cs.ruu.nl``, directory :file:`SGI/FORMS`. It was last tested with version
-2.0b.
-
-Most functions are literal translations of their C equivalents, dropping the
-initial ``fl_`` from their name. Constants used by the library are defined in
-module :mod:`FL` described below.
-
-The creation of objects is a little different in Python than in C: instead of
-the 'current form' maintained by the library to which new FORMS objects are
-added, all functions that add a FORMS object to a form are methods of the Python
-object representing the form. Consequently, there are no Python equivalents for
-the C functions :c:func:`fl_addto_form` and :c:func:`fl_end_form`, and the
-equivalent of :c:func:`fl_bgn_form` is called :func:`fl.make_form`.
-
-Watch out for the somewhat confusing terminology: FORMS uses the word
-:dfn:`object` for the buttons, sliders etc. that you can place in a form. In
-Python, 'object' means any value. The Python interface to FORMS introduces two
-new Python object types: form objects (representing an entire form) and FORMS
-objects (representing one button, slider etc.). Hopefully this isn't too
-confusing.
-
-There are no 'free objects' in the Python interface to FORMS, nor is there an
-easy way to add object classes written in Python. The FORMS interface to GL
-event handling is available, though, so you can mix FORMS with pure GL windows.
-
-**Please note:** importing :mod:`fl` implies a call to the GL function
-:c:func:`foreground` and to the FORMS routine :c:func:`fl_init`.
-
-
-.. _fl-functions:
-
-Functions Defined in Module :mod:`fl`
--------------------------------------
-
-Module :mod:`fl` defines the following functions. For more information about
-what they do, see the description of the equivalent C function in the FORMS
-documentation:
-
-
-.. function:: make_form(type, width, height)
-
- Create a form with given type, width and height. This returns a :dfn:`form`
- object, whose methods are described below.
-
-
-.. function:: do_forms()
-
- The standard FORMS main loop. Returns a Python object representing the FORMS
- object needing interaction, or the special value :const:`FL.EVENT`.
-
-
-.. function:: check_forms()
-
- Check for FORMS events. Returns what :func:`do_forms` above returns, or
- ``None`` if there is no event that immediately needs interaction.
-
-
-.. function:: set_event_call_back(function)
-
- Set the event callback function.
-
-
-.. function:: set_graphics_mode(rgbmode, doublebuffering)
-
- Set the graphics modes.
-
-
-.. function:: get_rgbmode()
-
- Return the current rgb mode. This is the value of the C global variable
- :c:data:`fl_rgbmode`.
-
-
-.. function:: show_message(str1, str2, str3)
-
- Show a dialog box with a three-line message and an OK button.
-
-
-.. function:: show_question(str1, str2, str3)
-
- Show a dialog box with a three-line message and YES and NO buttons. It returns
- ``1`` if the user pressed YES, ``0`` if NO.
-
-
-.. function:: show_choice(str1, str2, str3, but1[, but2[, but3]])
-
- Show a dialog box with a three-line message and up to three buttons. It returns
- the number of the button clicked by the user (``1``, ``2`` or ``3``).
-
-
-.. function:: show_input(prompt, default)
-
- Show a dialog box with a one-line prompt message and text field in which the
- user can enter a string. The second argument is the default input string. It
- returns the string value as edited by the user.
-
-
-.. function:: show_file_selector(message, directory, pattern, default)
-
- Show a dialog box in which the user can select a file. It returns the absolute
- filename selected by the user, or ``None`` if the user presses Cancel.
-
-
-.. function:: get_directory()
- get_pattern()
- get_filename()
-
- These functions return the directory, pattern and filename (the tail part only)
- selected by the user in the last :func:`show_file_selector` call.
-
-
-.. function:: qdevice(dev)
- unqdevice(dev)
- isqueued(dev)
- qtest()
- qread()
- qreset()
- qenter(dev, val)
- get_mouse()
- tie(button, valuator1, valuator2)
-
- These functions are the FORMS interfaces to the corresponding GL functions. Use
- these if you want to handle some GL events yourself when using
- :func:`fl.do_events`. When a GL event is detected that FORMS cannot handle,
- :func:`fl.do_forms` returns the special value :const:`FL.EVENT` and you should
- call :func:`fl.qread` to read the event from the queue. Don't use the
- equivalent GL functions!
-
- .. \funcline{blkqread}{?}
-
-
-.. function:: color()
- mapcolor()
- getmcolor()
-
- See the description in the FORMS documentation of :c:func:`fl_color`,
- :c:func:`fl_mapcolor` and :c:func:`fl_getmcolor`.
-
-
-.. _form-objects:
-
-Form Objects
-------------
-
-Form objects (returned by :func:`make_form` above) have the following methods.
-Each method corresponds to a C function whose name is prefixed with ``fl_``; and
-whose first argument is a form pointer; please refer to the official FORMS
-documentation for descriptions.
-
-All the :meth:`add_\*` methods return a Python object representing the FORMS
-object. Methods of FORMS objects are described below. Most kinds of FORMS
-object also have some methods specific to that kind; these methods are listed
-here.
-
-
-.. method:: form.show_form(placement, bordertype, name)
-
- Show the form.
-
-
-.. method:: form.hide_form()
-
- Hide the form.
-
-
-.. method:: form.redraw_form()
-
- Redraw the form.
-
-
-.. method:: form.set_form_position(x, y)
-
- Set the form's position.
-
-
-.. method:: form.freeze_form()
-
- Freeze the form.
-
-
-.. method:: form.unfreeze_form()
-
- Unfreeze the form.
-
-
-.. method:: form.activate_form()
-
- Activate the form.
-
-
-.. method:: form.deactivate_form()
-
- Deactivate the form.
-
-
-.. method:: form.bgn_group()
-
- Begin a new group of objects; return a group object.
-
-
-.. method:: form.end_group()
-
- End the current group of objects.
-
-
-.. method:: form.find_first()
-
- Find the first object in the form.
-
-
-.. method:: form.find_last()
-
- Find the last object in the form.
-
-
-.. method:: form.add_box(type, x, y, w, h, name)
-
- Add a box object to the form. No extra methods.
-
-
-.. method:: form.add_text(type, x, y, w, h, name)
-
- Add a text object to the form. No extra methods.
-
-.. \begin{methoddesc}[form]{add_bitmap}{type, x, y, w, h, name}
-.. Add a bitmap object to the form.
-.. \end{methoddesc}
-
-
-.. method:: form.add_clock(type, x, y, w, h, name)
-
- Add a clock object to the form. --- Method: :meth:`get_clock`.
-
-
-.. method:: form.add_button(type, x, y, w, h, name)
-
- Add a button object to the form. --- Methods: :meth:`get_button`,
- :meth:`set_button`.
-
-
-.. method:: form.add_lightbutton(type, x, y, w, h, name)
-
- Add a lightbutton object to the form. --- Methods: :meth:`get_button`,
- :meth:`set_button`.
-
-
-.. method:: form.add_roundbutton(type, x, y, w, h, name)
-
- Add a roundbutton object to the form. --- Methods: :meth:`get_button`,
- :meth:`set_button`.
-
-
-.. method:: form.add_slider(type, x, y, w, h, name)
-
- Add a slider object to the form. --- Methods: :meth:`set_slider_value`,
- :meth:`get_slider_value`, :meth:`set_slider_bounds`, :meth:`get_slider_bounds`,
- :meth:`set_slider_return`, :meth:`set_slider_size`,
- :meth:`set_slider_precision`, :meth:`set_slider_step`.
-
-
-.. method:: form.add_valslider(type, x, y, w, h, name)
-
- Add a valslider object to the form. --- Methods: :meth:`set_slider_value`,
- :meth:`get_slider_value`, :meth:`set_slider_bounds`, :meth:`get_slider_bounds`,
- :meth:`set_slider_return`, :meth:`set_slider_size`,
- :meth:`set_slider_precision`, :meth:`set_slider_step`.
-
-
-.. method:: form.add_dial(type, x, y, w, h, name)
-
- Add a dial object to the form. --- Methods: :meth:`set_dial_value`,
- :meth:`get_dial_value`, :meth:`set_dial_bounds`, :meth:`get_dial_bounds`.
-
-
-.. method:: form.add_positioner(type, x, y, w, h, name)
-
- Add a positioner object to the form. --- Methods:
- :meth:`set_positioner_xvalue`, :meth:`set_positioner_yvalue`,
- :meth:`set_positioner_xbounds`, :meth:`set_positioner_ybounds`,
- :meth:`get_positioner_xvalue`, :meth:`get_positioner_yvalue`,
- :meth:`get_positioner_xbounds`, :meth:`get_positioner_ybounds`.
-
-
-.. method:: form.add_counter(type, x, y, w, h, name)
-
- Add a counter object to the form. --- Methods: :meth:`set_counter_value`,
- :meth:`get_counter_value`, :meth:`set_counter_bounds`, :meth:`set_counter_step`,
- :meth:`set_counter_precision`, :meth:`set_counter_return`.
-
-
-.. method:: form.add_input(type, x, y, w, h, name)
-
- Add a input object to the form. --- Methods: :meth:`set_input`,
- :meth:`get_input`, :meth:`set_input_color`, :meth:`set_input_return`.
-
-
-.. method:: form.add_menu(type, x, y, w, h, name)
-
- Add a menu object to the form. --- Methods: :meth:`set_menu`,
- :meth:`get_menu`, :meth:`addto_menu`.
-
-
-.. method:: form.add_choice(type, x, y, w, h, name)
-
- Add a choice object to the form. --- Methods: :meth:`set_choice`,
- :meth:`get_choice`, :meth:`clear_choice`, :meth:`addto_choice`,
- :meth:`replace_choice`, :meth:`delete_choice`, :meth:`get_choice_text`,
- :meth:`set_choice_fontsize`, :meth:`set_choice_fontstyle`.
-
-
-.. method:: form.add_browser(type, x, y, w, h, name)
-
- Add a browser object to the form. --- Methods: :meth:`set_browser_topline`,
- :meth:`clear_browser`, :meth:`add_browser_line`, :meth:`addto_browser`,
- :meth:`insert_browser_line`, :meth:`delete_browser_line`,
- :meth:`replace_browser_line`, :meth:`get_browser_line`, :meth:`load_browser`,
- :meth:`get_browser_maxline`, :meth:`select_browser_line`,
- :meth:`deselect_browser_line`, :meth:`deselect_browser`,
- :meth:`isselected_browser_line`, :meth:`get_browser`,
- :meth:`set_browser_fontsize`, :meth:`set_browser_fontstyle`,
- :meth:`set_browser_specialkey`.
-
-
-.. method:: form.add_timer(type, x, y, w, h, name)
-
- Add a timer object to the form. --- Methods: :meth:`set_timer`,
- :meth:`get_timer`.
-
-Form objects have the following data attributes; see the FORMS documentation:
-
-+---------------------+-----------------+--------------------------------+
-| Name | C Type | Meaning |
-+=====================+=================+================================+
-| :attr:`window` | int (read-only) | GL window id |
-+---------------------+-----------------+--------------------------------+
-| :attr:`w` | float | form width |
-+---------------------+-----------------+--------------------------------+
-| :attr:`h` | float | form height |
-+---------------------+-----------------+--------------------------------+
-| :attr:`x` | float | form x origin |
-+---------------------+-----------------+--------------------------------+
-| :attr:`y` | float | form y origin |
-+---------------------+-----------------+--------------------------------+
-| :attr:`deactivated` | int | nonzero if form is deactivated |
-+---------------------+-----------------+--------------------------------+
-| :attr:`visible` | int | nonzero if form is visible |
-+---------------------+-----------------+--------------------------------+
-| :attr:`frozen` | int | nonzero if form is frozen |
-+---------------------+-----------------+--------------------------------+
-| :attr:`doublebuf` | int | nonzero if double buffering on |
-+---------------------+-----------------+--------------------------------+
-
-
-.. _forms-objects:
-
-FORMS Objects
--------------
-
-Besides methods specific to particular kinds of FORMS objects, all FORMS objects
-also have the following methods:
-
-
-.. method:: FORMS object.set_call_back(function, argument)
-
- Set the object's callback function and argument. When the object needs
- interaction, the callback function will be called with two arguments: the
- object, and the callback argument. (FORMS objects without a callback function
- are returned by :func:`fl.do_forms` or :func:`fl.check_forms` when they need
- interaction.) Call this method without arguments to remove the callback
- function.
-
-
-.. method:: FORMS object.delete_object()
-
- Delete the object.
-
-
-.. method:: FORMS object.show_object()
-
- Show the object.
-
-
-.. method:: FORMS object.hide_object()
-
- Hide the object.
-
-
-.. method:: FORMS object.redraw_object()
-
- Redraw the object.
-
-
-.. method:: FORMS object.freeze_object()
-
- Freeze the object.
-
-
-.. method:: FORMS object.unfreeze_object()
-
- Unfreeze the object.
-
-FORMS objects have these data attributes; see the FORMS documentation:
-
-.. \begin{methoddesc}[FORMS object]{handle_object}{} XXX
-.. \end{methoddesc}
-.. \begin{methoddesc}[FORMS object]{handle_object_direct}{} XXX
-.. \end{methoddesc}
-
-+--------------------+-----------------+------------------+
-| Name | C Type | Meaning |
-+====================+=================+==================+
-| :attr:`objclass` | int (read-only) | object class |
-+--------------------+-----------------+------------------+
-| :attr:`type` | int (read-only) | object type |
-+--------------------+-----------------+------------------+
-| :attr:`boxtype` | int | box type |
-+--------------------+-----------------+------------------+
-| :attr:`x` | float | x origin |
-+--------------------+-----------------+------------------+
-| :attr:`y` | float | y origin |
-+--------------------+-----------------+------------------+
-| :attr:`w` | float | width |
-+--------------------+-----------------+------------------+
-| :attr:`h` | float | height |
-+--------------------+-----------------+------------------+
-| :attr:`col1` | int | primary color |
-+--------------------+-----------------+------------------+
-| :attr:`col2` | int | secondary color |
-+--------------------+-----------------+------------------+
-| :attr:`align` | int | alignment |
-+--------------------+-----------------+------------------+
-| :attr:`lcol` | int | label color |
-+--------------------+-----------------+------------------+
-| :attr:`lsize` | float | label font size |
-+--------------------+-----------------+------------------+
-| :attr:`label` | string | label string |
-+--------------------+-----------------+------------------+
-| :attr:`lstyle` | int | label style |
-+--------------------+-----------------+------------------+
-| :attr:`pushed` | int (read-only) | (see FORMS docs) |
-+--------------------+-----------------+------------------+
-| :attr:`focus` | int (read-only) | (see FORMS docs) |
-+--------------------+-----------------+------------------+
-| :attr:`belowmouse` | int (read-only) | (see FORMS docs) |
-+--------------------+-----------------+------------------+
-| :attr:`frozen` | int (read-only) | (see FORMS docs) |
-+--------------------+-----------------+------------------+
-| :attr:`active` | int (read-only) | (see FORMS docs) |
-+--------------------+-----------------+------------------+
-| :attr:`input` | int (read-only) | (see FORMS docs) |
-+--------------------+-----------------+------------------+
-| :attr:`visible` | int (read-only) | (see FORMS docs) |
-+--------------------+-----------------+------------------+
-| :attr:`radio` | int (read-only) | (see FORMS docs) |
-+--------------------+-----------------+------------------+
-| :attr:`automatic` | int (read-only) | (see FORMS docs) |
-+--------------------+-----------------+------------------+
-
-
-:mod:`FL` --- Constants used with the :mod:`fl` module
-======================================================
-
-.. module:: FL
- :platform: IRIX
- :synopsis: Constants used with the fl module.
- :deprecated:
-
-
-.. deprecated:: 2.6
- The :mod:`FL` module has been removed in Python 3.
-
-
-This module defines symbolic constants needed to use the built-in module
-:mod:`fl` (see above); they are equivalent to those defined in the C header file
-``<forms.h>`` except that the name prefix ``FL_`` is omitted. Read the module
-source for a complete list of the defined names. Suggested use::
-
- import fl
- from FL import *
-
-
-:mod:`flp` --- Functions for loading stored FORMS designs
-=========================================================
-
-.. module:: flp
- :platform: IRIX
- :synopsis: Functions for loading stored FORMS designs.
- :deprecated:
-
-
-.. deprecated:: 2.6
- The :mod:`flp` module has been removed in Python 3.
-
-
-This module defines functions that can read form definitions created by the
-'form designer' (:program:`fdesign`) program that comes with the FORMS library
-(see module :mod:`fl` above).
-
-For now, see the file :file:`flp.doc` in the Python library source directory for
-a description.
-
-XXX A complete description should be inserted here!
-
diff --git a/Doc/library/fm.rst b/Doc/library/fm.rst
deleted file mode 100644
index c7eb4f3..0000000
--- a/Doc/library/fm.rst
+++ /dev/null
@@ -1,101 +0,0 @@
-
-:mod:`fm` --- *Font Manager* interface
-======================================
-
-.. module:: fm
- :platform: IRIX
- :synopsis: Font Manager interface for SGI workstations.
- :deprecated:
-
-.. deprecated:: 2.6
- The :mod:`fm` module has been removed in Python 3.
-
-
-
-.. index::
- single: Font Manager, IRIS
- single: IRIS Font Manager
-
-This module provides access to the IRIS *Font Manager* library. It is
-available only on Silicon Graphics machines. See also: *4Sight User's Guide*,
-section 1, chapter 5: "Using the IRIS Font Manager."
-
-This is not yet a full interface to the IRIS Font Manager. Among the unsupported
-features are: matrix operations; cache operations; character operations (use
-string operations instead); some details of font info; individual glyph metrics;
-and printer matching.
-
-It supports the following operations:
-
-
-.. function:: init()
-
- Initialization function. Calls :c:func:`fminit`. It is normally not necessary to
- call this function, since it is called automatically the first time the
- :mod:`fm` module is imported.
-
-
-.. function:: findfont(fontname)
-
- Return a font handle object. Calls ``fmfindfont(fontname)``.
-
-
-.. function:: enumerate()
-
- Returns a list of available font names. This is an interface to
- :c:func:`fmenumerate`.
-
-
-.. function:: prstr(string)
-
- Render a string using the current font (see the :func:`setfont` font handle
- method below). Calls ``fmprstr(string)``.
-
-
-.. function:: setpath(string)
-
- Sets the font search path. Calls ``fmsetpath(string)``. (XXX Does not work!?!)
-
-
-.. function:: fontpath()
-
- Returns the current font search path.
-
-Font handle objects support the following operations:
-
-
-.. method:: font handle.scalefont(factor)
-
- Returns a handle for a scaled version of this font. Calls ``fmscalefont(fh,
- factor)``.
-
-
-.. method:: font handle.setfont()
-
- Makes this font the current font. Note: the effect is undone silently when the
- font handle object is deleted. Calls ``fmsetfont(fh)``.
-
-
-.. method:: font handle.getfontname()
-
- Returns this font's name. Calls ``fmgetfontname(fh)``.
-
-
-.. method:: font handle.getcomment()
-
- Returns the comment string associated with this font. Raises an exception if
- there is none. Calls ``fmgetcomment(fh)``.
-
-
-.. method:: font handle.getfontinfo()
-
- Returns a tuple giving some pertinent data about this font. This is an interface
- to ``fmgetfontinfo()``. The returned tuple contains the following numbers:
- ``(printermatched, fixed_width, xorig, yorig, xsize, ysize, height, nglyphs)``.
-
-
-.. method:: font handle.getstrwidth(string)
-
- Returns the width, in pixels, of *string* when drawn in this font. Calls
- ``fmgetstrwidth(fh, string)``.
-
diff --git a/Doc/library/fnmatch.rst b/Doc/library/fnmatch.rst
index b14c5512..e0434b0 100644
--- a/Doc/library/fnmatch.rst
+++ b/Doc/library/fnmatch.rst
@@ -58,7 +58,7 @@ patterns.
for file in os.listdir('.'):
if fnmatch.fnmatch(file, '*.txt'):
- print file
+ print(file)
.. function:: fnmatchcase(filename, pattern)
@@ -72,8 +72,6 @@ patterns.
Return the subset of the list of *names* that match *pattern*. It is the same as
``[n for n in names if fnmatch(n, pattern)]``, but implemented more efficiently.
- .. versionadded:: 2.2
-
.. function:: translate(pattern)
diff --git a/Doc/library/formatter.rst b/Doc/library/formatter.rst
index e696fec..88be11c 100644
--- a/Doc/library/formatter.rst
+++ b/Doc/library/formatter.rst
@@ -1,4 +1,3 @@
-
:mod:`formatter` --- Generic output formatting
==============================================
@@ -6,12 +5,9 @@
:synopsis: Generic output formatter and device interface.
-.. index:: single: HTMLParser (class in htmllib)
-
This module supports two interface definitions, each with multiple
-implementations. The *formatter* interface is used by the :class:`HTMLParser`
-class of the :mod:`htmllib` module, and the *writer* interface is required by
-the formatter interface.
+implementations: The *formatter* interface, and the *writer* interface which is
+required by the formatter interface.
Formatter objects transform an abstract flow of formatting events into specific
output events on writer objects. Formatters manage several stack structures to
@@ -169,7 +165,7 @@ The following attributes are defined for formatter instance objects:
:const:`AS_IS` values, is passed to the writer's :meth:`new_styles` method.
-.. method:: formatter.pop_style([n=1])
+.. method:: formatter.pop_style(n=1)
Pop the last *n* style specifications passed to :meth:`push_style`. A tuple
representing the revised stack, including :const:`AS_IS` values, is passed to
@@ -181,7 +177,7 @@ The following attributes are defined for formatter instance objects:
Set the spacing style for the writer.
-.. method:: formatter.assert_line_data([flag=1])
+.. method:: formatter.assert_line_data(flag=1)
Inform the formatter that data has been added to the current paragraph
out-of-band. This should be used when the writer has been manipulated
@@ -198,7 +194,7 @@ Two implementations of formatter objects are provided by this module. Most
applications may use one of these classes without modification or subclassing.
-.. class:: NullFormatter([writer])
+.. class:: NullFormatter(writer=None)
A formatter which does nothing. If *writer* is omitted, a :class:`NullWriter`
instance is created. No methods of the writer are called by
@@ -343,8 +339,8 @@ this module. Most applications will need to derive new writer classes from the
.. class:: DumbWriter(file=None, maxcol=72)
- Simple writer class which writes output on the file object passed in as *file*
- or, if *file* is None, on standard output. The output is simply word-wrapped
- to the number of columns specified by *maxcol*. This class is suitable for
- reflowing a sequence of paragraphs.
+ Simple writer class which writes output on the :term:`file object` passed
+ in as *file* or, if *file* is omitted, on standard output. The output is
+ simply word-wrapped to the number of columns specified by *maxcol*. This
+ class is suitable for reflowing a sequence of paragraphs.
diff --git a/Doc/library/fpectl.rst b/Doc/library/fpectl.rst
index 8ca671b..fb15f69 100644
--- a/Doc/library/fpectl.rst
+++ b/Doc/library/fpectl.rst
@@ -1,4 +1,3 @@
-
:mod:`fpectl` --- Floating point exception control
==================================================
@@ -113,8 +112,8 @@ The :mod:`fpectl` module is not thread-safe.
.. seealso::
Some files in the source distribution may be interesting in learning more about
- how this module operates. The include file :source:`Include/pyfpe.h` discusses the
- implementation of this module at some length. :source:`Modules/fpetestmodule.c`
+ how this module operates. The include file :file:`Include/pyfpe.h` discusses the
+ implementation of this module at some length. :file:`Modules/fpetestmodule.c`
gives several examples of use. Many additional examples can be found in
- :source:`Objects/floatobject.c`.
+ :file:`Objects/floatobject.c`.
diff --git a/Doc/library/fpformat.rst b/Doc/library/fpformat.rst
deleted file mode 100644
index 1713301..0000000
--- a/Doc/library/fpformat.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-
-:mod:`fpformat` --- Floating point conversions
-==============================================
-
-.. module:: fpformat
- :synopsis: General floating point formatting functions.
- :deprecated:
-
-.. deprecated:: 2.6
- The :mod:`fpformat` module has been removed in Python 3.
-
-.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
-
-
-The :mod:`fpformat` module defines functions for dealing with floating point
-numbers representations in 100% pure Python.
-
-.. note::
-
- This module is unnecessary: everything here can be done using the ``%`` string
- interpolation operator described in the :ref:`string-formatting` section.
-
-The :mod:`fpformat` module defines the following functions and an exception:
-
-
-.. function:: fix(x, digs)
-
- Format *x* as ``[-]ddd.ddd`` with *digs* digits after the point and at least one
- digit before. If ``digs <= 0``, the decimal point is suppressed.
-
- *x* can be either a number or a string that looks like one. *digs* is an
- integer.
-
- Return value is a string.
-
-
-.. function:: sci(x, digs)
-
- Format *x* as ``[-]d.dddE[+-]ddd`` with *digs* digits after the point and
- exactly one digit before. If ``digs <= 0``, one digit is kept and the point is
- suppressed.
-
- *x* can be either a real number, or a string that looks like one. *digs* is an
- integer.
-
- Return value is a string.
-
-
-.. exception:: NotANumber
-
- Exception raised when a string passed to :func:`fix` or :func:`sci` as the *x*
- parameter does not look like a number. This is a subclass of :exc:`ValueError`
- when the standard exceptions are strings. The exception value is the improperly
- formatted string that caused the exception to be raised.
-
-Example::
-
- >>> import fpformat
- >>> fpformat.fix(1.23, 1)
- '1.2'
-
diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst
index 81b419e..59e6b1b 100644
--- a/Doc/library/fractions.rst
+++ b/Doc/library/fractions.rst
@@ -5,7 +5,6 @@
:synopsis: Rational numbers.
.. moduleauthor:: Jeffrey Yasskin <jyasskin at gmail.com>
.. sectionauthor:: Jeffrey Yasskin <jyasskin at gmail.com>
-.. versionadded:: 2.6
**Source code:** :source:`Lib/fractions.py`
@@ -80,7 +79,7 @@ another rational number, or from a string.
and should be treated as immutable. In addition,
:class:`Fraction` has the following methods:
- .. versionchanged:: 2.7
+ .. versionchanged:: 3.2
The :class:`Fraction` constructor now accepts :class:`float` and
:class:`decimal.Decimal` instances.
@@ -91,16 +90,16 @@ another rational number, or from a string.
value of *flt*, which must be a :class:`float`. Beware that
``Fraction.from_float(0.3)`` is not the same value as ``Fraction(3, 10)``
- .. note:: From Python 2.7 onwards, you can also construct a
+ .. note:: From Python 3.2 onwards, you can also construct a
:class:`Fraction` instance directly from a :class:`float`.
.. method:: from_decimal(dec)
This class method constructs a :class:`Fraction` representing the exact
- value of *dec*, which must be a :class:`decimal.Decimal`.
+ value of *dec*, which must be a :class:`decimal.Decimal` instance.
- .. note:: From Python 2.7 onwards, you can also construct a
+ .. note:: From Python 3.2 onwards, you can also construct a
:class:`Fraction` instance directly from a :class:`decimal.Decimal`
instance.
@@ -126,6 +125,32 @@ another rational number, or from a string.
Fraction(11, 10)
+ .. method:: __floor__()
+
+ Returns the greatest :class:`int` ``<= self``. This method can
+ also be accessed through the :func:`math.floor` function:
+
+ >>> from math import floor
+ >>> floor(Fraction(355, 113))
+ 3
+
+
+ .. method:: __ceil__()
+
+ Returns the least :class:`int` ``>= self``. This method can
+ also be accessed through the :func:`math.ceil` function.
+
+
+ .. method:: __round__()
+ __round__(ndigits)
+
+ The first version returns the nearest :class:`int` to ``self``,
+ rounding half to even. The second version rounds ``self`` to the
+ nearest multiple of ``Fraction(1, 10**ndigits)`` (logically, if
+ ``ndigits`` is negative), again rounding half toward even. This
+ method can also be accessed through the :func:`round` function.
+
+
.. function:: gcd(a, b)
Return the greatest common divisor of the integers *a* and *b*. If either
diff --git a/Doc/library/framework.rst b/Doc/library/framework.rst
deleted file mode 100644
index 1237e56..0000000
--- a/Doc/library/framework.rst
+++ /dev/null
@@ -1,340 +0,0 @@
-
-:mod:`FrameWork` --- Interactive application framework
-======================================================
-
-.. module:: FrameWork
- :platform: Mac
- :synopsis: Interactive application framework.
- :deprecated:
-
-
-The :mod:`FrameWork` module contains classes that together provide a framework
-for an interactive Macintosh application. The programmer builds an application
-by creating subclasses that override various methods of the bases classes,
-thereby implementing the functionality wanted. Overriding functionality can
-often be done on various different levels, i.e. to handle clicks in a single
-dialog window in a non-standard way it is not necessary to override the complete
-event handling.
-
-.. note::
-
- This module has been removed in Python 3.x.
-
-Work on the :mod:`FrameWork` has pretty much stopped, now that :mod:`PyObjC` is
-available for full Cocoa access from Python, and the documentation describes
-only the most important functionality, and not in the most logical manner at
-that. Examine the source or the examples for more details. The following are
-some comments posted on the MacPython newsgroup about the strengths and
-limitations of :mod:`FrameWork`:
-
-
-.. epigraph::
-
- The strong point of :mod:`FrameWork` is that it allows you to break into the
- control-flow at many different places. :mod:`W`, for instance, uses a different
- way to enable/disable menus and that plugs right in leaving the rest intact.
- The weak points of :mod:`FrameWork` are that it has no abstract command
- interface (but that shouldn't be difficult), that its dialog support is minimal
- and that its control/toolbar support is non-existent.
-
-The :mod:`FrameWork` module defines the following functions:
-
-
-.. function:: Application()
-
- An object representing the complete application. See below for a description of
- the methods. The default :meth:`__init__` routine creates an empty window
- dictionary and a menu bar with an apple menu.
-
-
-.. function:: MenuBar()
-
- An object representing the menubar. This object is usually not created by the
- user.
-
-
-.. function:: Menu(bar, title[, after])
-
- An object representing a menu. Upon creation you pass the ``MenuBar`` the menu
- appears in, the *title* string and a position (1-based) *after* where the menu
- should appear (default: at the end).
-
-
-.. function:: MenuItem(menu, title[, shortcut, callback])
-
- Create a menu item object. The arguments are the menu to create, the item title
- string and optionally the keyboard shortcut and a callback routine. The callback
- is called with the arguments menu-id, item number within menu (1-based), current
- front window and the event record.
-
- Instead of a callable object the callback can also be a string. In this case
- menu selection causes the lookup of a method in the topmost window and the
- application. The method name is the callback string with ``'domenu_'``
- prepended.
-
- Calling the ``MenuBar`` :meth:`fixmenudimstate` method sets the correct dimming
- for all menu items based on the current front window.
-
-
-.. function:: Separator(menu)
-
- Add a separator to the end of a menu.
-
-
-.. function:: SubMenu(menu, label)
-
- Create a submenu named *label* under menu *menu*. The menu object is returned.
-
-
-.. function:: Window(parent)
-
- Creates a (modeless) window. *Parent* is the application object to which the
- window belongs. The window is not displayed until later.
-
-
-.. function:: DialogWindow(parent)
-
- Creates a modeless dialog window.
-
-
-.. function:: windowbounds(width, height)
-
- Return a ``(left, top, right, bottom)`` tuple suitable for creation of a window
- of given width and height. The window will be staggered with respect to previous
- windows, and an attempt is made to keep the whole window on-screen. However, the
- window will however always be the exact size given, so parts may be offscreen.
-
-
-.. function:: setwatchcursor()
-
- Set the mouse cursor to a watch.
-
-
-.. function:: setarrowcursor()
-
- Set the mouse cursor to an arrow.
-
-
-.. _application-objects:
-
-Application Objects
--------------------
-
-Application objects have the following methods, among others:
-
-
-.. method:: Application.makeusermenus()
-
- Override this method if you need menus in your application. Append the menus to
- the attribute :attr:`menubar`.
-
-
-.. method:: Application.getabouttext()
-
- Override this method to return a text string describing your application.
- Alternatively, override the :meth:`do_about` method for more elaborate "about"
- messages.
-
-
-.. method:: Application.mainloop([mask[, wait]])
-
- This routine is the main event loop, call it to set your application rolling.
- *Mask* is the mask of events you want to handle, *wait* is the number of ticks
- you want to leave to other concurrent application (default 0, which is probably
- not a good idea). While raising *self* to exit the mainloop is still supported
- it is not recommended: call ``self._quit()`` instead.
-
- The event loop is split into many small parts, each of which can be overridden.
- The default methods take care of dispatching events to windows and dialogs,
- handling drags and resizes, Apple Events, events for non-FrameWork windows, etc.
-
- In general, all event handlers should return ``1`` if the event is fully handled
- and ``0`` otherwise (because the front window was not a FrameWork window, for
- instance). This is needed so that update events and such can be passed on to
- other windows like the Sioux console window. Calling :func:`MacOS.HandleEvent`
- is not allowed within *our_dispatch* or its callees, since this may result in an
- infinite loop if the code is called through the Python inner-loop event handler.
-
-
-.. method:: Application.asyncevents(onoff)
-
- Call this method with a nonzero parameter to enable asynchronous event handling.
- This will tell the inner interpreter loop to call the application event handler
- *async_dispatch* whenever events are available. This will cause FrameWork window
- updates and the user interface to remain working during long computations, but
- will slow the interpreter down and may cause surprising results in non-reentrant
- code (such as FrameWork itself). By default *async_dispatch* will immediately
- call *our_dispatch* but you may override this to handle only certain events
- asynchronously. Events you do not handle will be passed to Sioux and such.
-
- The old on/off value is returned.
-
-
-.. method:: Application._quit()
-
- Terminate the running :meth:`mainloop` call at the next convenient moment.
-
-
-.. method:: Application.do_char(c, event)
-
- The user typed character *c*. The complete details of the event can be found in
- the *event* structure. This method can also be provided in a ``Window`` object,
- which overrides the application-wide handler if the window is frontmost.
-
-
-.. method:: Application.do_dialogevent(event)
-
- Called early in the event loop to handle modeless dialog events. The default
- method simply dispatches the event to the relevant dialog (not through the
- ``DialogWindow`` object involved). Override if you need special handling of
- dialog events (keyboard shortcuts, etc).
-
-
-.. method:: Application.idle(event)
-
- Called by the main event loop when no events are available. The null-event is
- passed (so you can look at mouse position, etc).
-
-
-.. _window-objects:
-
-Window Objects
---------------
-
-Window objects have the following methods, among others:
-
-
-.. method:: Window.open()
-
- Override this method to open a window. Store the Mac OS window-id in
- :attr:`self.wid` and call the :meth:`do_postopen` method to register the window
- with the parent application.
-
-
-.. method:: Window.close()
-
- Override this method to do any special processing on window close. Call the
- :meth:`do_postclose` method to cleanup the parent state.
-
-
-.. method:: Window.do_postresize(width, height, macoswindowid)
-
- Called after the window is resized. Override if more needs to be done than
- calling ``InvalRect``.
-
-
-.. method:: Window.do_contentclick(local, modifiers, event)
-
- The user clicked in the content part of a window. The arguments are the
- coordinates (window-relative), the key modifiers and the raw event.
-
-
-.. method:: Window.do_update(macoswindowid, event)
-
- An update event for the window was received. Redraw the window.
-
-
-.. method:: Window.do_activate(activate, event)
-
- The window was activated (``activate == 1``) or deactivated (``activate == 0``).
- Handle things like focus highlighting, etc.
-
-
-.. _controlswindow-object:
-
-ControlsWindow Object
----------------------
-
-ControlsWindow objects have the following methods besides those of ``Window``
-objects:
-
-
-.. method:: ControlsWindow.do_controlhit(window, control, pcode, event)
-
- Part *pcode* of control *control* was hit by the user. Tracking and such has
- already been taken care of.
-
-
-.. _scrolledwindow-object:
-
-ScrolledWindow Object
----------------------
-
-ScrolledWindow objects are ControlsWindow objects with the following extra
-methods:
-
-
-.. method:: ScrolledWindow.scrollbars([wantx[, wanty]])
-
- Create (or destroy) horizontal and vertical scrollbars. The arguments specify
- which you want (default: both). The scrollbars always have minimum ``0`` and
- maximum ``32767``.
-
-
-.. method:: ScrolledWindow.getscrollbarvalues()
-
- You must supply this method. It should return a tuple ``(x, y)`` giving the
- current position of the scrollbars (between ``0`` and ``32767``). You can return
- ``None`` for either to indicate the whole document is visible in that direction.
-
-
-.. method:: ScrolledWindow.updatescrollbars()
-
- Call this method when the document has changed. It will call
- :meth:`getscrollbarvalues` and update the scrollbars.
-
-
-.. method:: ScrolledWindow.scrollbar_callback(which, what, value)
-
- Supplied by you and called after user interaction. *which* will be ``'x'`` or
- ``'y'``, *what* will be ``'-'``, ``'--'``, ``'set'``, ``'++'`` or ``'+'``. For
- ``'set'``, *value* will contain the new scrollbar position.
-
-
-.. method:: ScrolledWindow.scalebarvalues(absmin, absmax, curmin, curmax)
-
- Auxiliary method to help you calculate values to return from
- :meth:`getscrollbarvalues`. You pass document minimum and maximum value and
- topmost (leftmost) and bottommost (rightmost) visible values and it returns the
- correct number or ``None``.
-
-
-.. method:: ScrolledWindow.do_activate(onoff, event)
-
- Takes care of dimming/highlighting scrollbars when a window becomes frontmost.
- If you override this method, call this one at the end of your method.
-
-
-.. method:: ScrolledWindow.do_postresize(width, height, window)
-
- Moves scrollbars to the correct position. Call this method initially if you
- override it.
-
-
-.. method:: ScrolledWindow.do_controlhit(window, control, pcode, event)
-
- Handles scrollbar interaction. If you override it call this method first, a
- nonzero return value indicates the hit was in the scrollbars and has been
- handled.
-
-
-.. _dialogwindow-objects:
-
-DialogWindow Objects
---------------------
-
-DialogWindow objects have the following methods besides those of ``Window``
-objects:
-
-
-.. method:: DialogWindow.open(resid)
-
- Create the dialog window, from the DLOG resource with id *resid*. The dialog
- object is stored in :attr:`self.wid`.
-
-
-.. method:: DialogWindow.do_itemhit(item, event)
-
- Item number *item* was hit. You are responsible for redrawing toggle buttons,
- etc.
-
diff --git a/Doc/library/frameworks.rst b/Doc/library/frameworks.rst
index 5d8dad5..15ceeec 100644
--- a/Doc/library/frameworks.rst
+++ b/Doc/library/frameworks.rst
@@ -1,4 +1,3 @@
-
.. _frameworks:
******************
@@ -14,5 +13,6 @@ The full list of modules described in this chapter is:
.. toctree::
+ turtle.rst
cmd.rst
shlex.rst
diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst
index 9882789..3274f19 100644
--- a/Doc/library/ftplib.rst
+++ b/Doc/library/ftplib.rst
@@ -16,9 +16,9 @@
This module defines the class :class:`FTP` and a few related items. The
:class:`FTP` class implements the client side of the FTP protocol. You can use
this to write Python programs that perform a variety of automated FTP jobs, such
-as mirroring other ftp servers. It is also used by the module :mod:`urllib` to
-handle URLs that use FTP. For more information on FTP (File Transfer Protocol),
-see Internet :rfc:`959`.
+as mirroring other ftp servers. It is also used by the module
+:mod:`urllib.request` to handle URLs that use FTP. For more information on FTP
+(File Transfer Protocol), see Internet :rfc:`959`.
Here's a sample session using the :mod:`ftplib` module::
@@ -40,7 +40,7 @@ Here's a sample session using the :mod:`ftplib` module::
The module defines the following items:
-.. class:: FTP([host[, user[, passwd[, acct[, timeout]]]]])
+.. class:: FTP(host='', user='', passwd='', acct=''[, timeout])
Return a new instance of the :class:`FTP` class. When *host* is given, the
method call ``connect(host)`` is made. When *user* is given, additionally
@@ -50,11 +50,26 @@ The module defines the following items:
connection attempt (if is not specified, the global default timeout setting
will be used).
- .. versionchanged:: 2.6
- *timeout* was added.
+ :class:`FTP` class supports the :keyword:`with` statement. Here is a sample
+ on how using it:
+ >>> from ftplib import FTP
+ >>> with FTP("ftp1.at.proftpd.org") as ftp:
+ ... ftp.login()
+ ... ftp.dir()
+ ...
+ '230 Anonymous login ok, restrictions apply.'
+ dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 .
+ dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 ..
+ dr-xr-xr-x 5 ftp ftp 4096 May 6 10:43 CentOS
+ dr-xr-xr-x 3 ftp ftp 18 Jul 10 2008 Fedora
+ >>>
-.. class:: FTP_TLS([host[, user[, passwd[, acct[, keyfile[, certfile[, timeout]]]]]]])
+ .. versionchanged:: 3.2
+ Support for the :keyword:`with` statement was added.
+
+
+.. class:: FTP_TLS(host='', user='', passwd='', acct='', [keyfile[, certfile[, context[, timeout]]]])
A :class:`FTP` subclass which adds TLS support to FTP as described in
:rfc:`4217`.
@@ -63,8 +78,11 @@ The module defines the following items:
explicitly ask for it by calling the :meth:`prot_p` method.
*keyfile* and *certfile* are optional -- they can contain a PEM formatted
private key and certificate chain file name for the SSL connection.
+ *context* parameter is a :class:`ssl.SSLContext` object which allows
+ bundling SSL configuration options, certificates and private keys into a
+ single (potentially long-lived) structure.
- .. versionadded:: 2.7
+ .. versionadded:: 3.2
Here's a sample session using the :class:`FTP_TLS` class:
@@ -156,7 +174,7 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
debugging output, logging each line sent and received on the control connection.
-.. method:: FTP.connect(host[, port[, timeout]])
+.. method:: FTP.connect(host='', port=0[, timeout])
Connect to the given host and port. The default port number is ``21``, as
specified by the FTP protocol specification. It is rarely needed to specify a
@@ -169,9 +187,6 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
connection attempt. If no *timeout* is passed, the global default timeout
setting will be used.
- .. versionchanged:: 2.6
- *timeout* was added.
-
.. method:: FTP.getwelcome()
@@ -180,7 +195,7 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
that may be relevant to the user.)
-.. method:: FTP.login([user[, passwd[, acct]]])
+.. method:: FTP.login(user='anonymous', passwd='', acct='')
Log in as the given *user*. The *passwd* and *acct* parameters are optional and
default to the empty string. If no *user* is specified, it defaults to
@@ -198,81 +213,73 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
it's worth a try.
-.. method:: FTP.sendcmd(command)
+.. method:: FTP.sendcmd(cmd)
Send a simple command string to the server and return the response string.
-.. method:: FTP.voidcmd(command)
+.. method:: FTP.voidcmd(cmd)
Send a simple command string to the server and handle the response. Return
nothing if a response code corresponding to success (codes in the range
200--299) is received. Raise :exc:`error_reply` otherwise.
-.. method:: FTP.retrbinary(command, callback[, maxblocksize[, rest]])
+.. method:: FTP.retrbinary(cmd, callback, blocksize=8192, rest=None)
- Retrieve a file in binary transfer mode. *command* should be an appropriate
+ Retrieve a file in binary transfer mode. *cmd* should be an appropriate
``RETR`` command: ``'RETR filename'``. The *callback* function is called for
each block of data received, with a single string argument giving the data
- block. The optional *maxblocksize* argument specifies the maximum chunk size to
+ block. The optional *blocksize* argument specifies the maximum chunk size to
read on the low-level socket object created to do the actual transfer (which
will also be the largest size of the data blocks passed to *callback*). A
reasonable default is chosen. *rest* means the same thing as in the
:meth:`transfercmd` method.
-.. method:: FTP.retrlines(command[, callback])
+.. method:: FTP.retrlines(cmd, callback=None)
- Retrieve a file or directory listing in ASCII transfer mode. *command*
- should be an appropriate ``RETR`` command (see :meth:`retrbinary`) or a
- command such as ``LIST``, ``NLST`` or ``MLSD`` (usually just the string
- ``'LIST'``). ``LIST`` retrieves a list of files and information about those files.
+ Retrieve a file or directory listing in ASCII transfer mode. *cmd* should be
+ an appropriate ``RETR`` command (see :meth:`retrbinary`) or a command such as
+ ``LIST``, ``NLST`` or ``MLSD`` (usually just the string ``'LIST'``).
+ ``LIST`` retrieves a list of files and information about those files.
``NLST`` retrieves a list of file names. On some servers, ``MLSD`` retrieves
- a machine readable list of files and information about those files. The *callback*
- function is called for each line with a string argument containing the line with
- the trailing CRLF stripped. The default *callback* prints the line to ``sys.stdout``.
+ a machine readable list of files and information about those files. The
+ *callback* function is called for each line with a string argument containing
+ the line with the trailing CRLF stripped. The default *callback* prints the
+ line to ``sys.stdout``.
.. method:: FTP.set_pasv(boolean)
- Enable "passive" mode if *boolean* is true, other disable passive mode. (In
- Python 2.0 and before, passive mode was off by default; in Python 2.1 and later,
- it is on by default.)
-
+ Enable "passive" mode if *boolean* is true, other disable passive mode.
+ Passive mode is on by default.
-.. method:: FTP.storbinary(command, file[, blocksize, callback, rest])
- Store a file in binary transfer mode. *command* should be an appropriate
- ``STOR`` command: ``"STOR filename"``. *file* is an open file object which is
- read until EOF using its :meth:`read` method in blocks of size *blocksize* to
- provide the data to be stored. The *blocksize* argument defaults to 8192.
- *callback* is an optional single parameter callable that is called
- on each block of data after it is sent. *rest* means the same thing as in
- the :meth:`transfercmd` method.
+.. method:: FTP.storbinary(cmd, file, blocksize=8192, callback=None, rest=None)
- .. versionchanged:: 2.1
- default for *blocksize* added.
+ Store a file in binary transfer mode. *cmd* should be an appropriate
+ ``STOR`` command: ``"STOR filename"``. *file* is a :term:`file object`
+ (opened in binary mode) which is read until EOF using its :meth:`read`
+ method in blocks of size *blocksize* to provide the data to be stored.
+ The *blocksize* argument defaults to 8192. *callback* is an optional single
+ parameter callable that is called on each block of data after it is sent.
+ *rest* means the same thing as in the :meth:`transfercmd` method.
- .. versionchanged:: 2.6
- *callback* parameter added.
-
- .. versionchanged:: 2.7
+ .. versionchanged:: 3.2
*rest* parameter added.
-.. method:: FTP.storlines(command, file[, callback])
- Store a file in ASCII transfer mode. *command* should be an appropriate
- ``STOR`` command (see :meth:`storbinary`). Lines are read until EOF from the
- open file object *file* using its :meth:`readline` method to provide the data to
- be stored. *callback* is an optional single parameter callable
- that is called on each line after it is sent.
+.. method:: FTP.storlines(cmd, file, callback=None)
- .. versionchanged:: 2.6
- *callback* parameter added.
+ Store a file in ASCII transfer mode. *cmd* should be an appropriate
+ ``STOR`` command (see :meth:`storbinary`). Lines are read until EOF from the
+ :term:`file object` *file* (opened in binary mode) using its :meth:`readline`
+ method to provide the data to be stored. *callback* is an optional single
+ parameter callable that is called on each line after it is sent.
-.. method:: FTP.transfercmd(cmd[, rest])
+.. method:: FTP.transfercmd(cmd, rest=None)
Initiate a transfer over the data connection. If the transfer is active, send a
``EPRT`` or ``PORT`` command and the transfer command specified by *cmd*, and
@@ -292,7 +299,7 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
*rest* argument.
-.. method:: FTP.ntransfercmd(cmd[, rest])
+.. method:: FTP.ntransfercmd(cmd, rest=None)
Like :meth:`transfercmd`, but returns a tuple of the data connection and the
expected size of the data. If the expected size could not be computed, ``None``
diff --git a/Doc/library/functional.rst b/Doc/library/functional.rst
new file mode 100644
index 0000000..5b6185a
--- /dev/null
+++ b/Doc/library/functional.rst
@@ -0,0 +1,15 @@
+******************************
+Functional Programming Modules
+******************************
+
+The modules described in this chapter provide functions and classes that support
+a functional programming style, and general operations on callables.
+
+The following modules are documented in this chapter:
+
+
+.. toctree::
+
+ itertools.rst
+ functools.rst
+ operator.rst
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index ec3b1d6..0d8f61c 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -1,32 +1,30 @@
-
+.. XXX document all delegations to __special__ methods
.. _built-in-funcs:
Built-in Functions
==================
-The Python interpreter has a number of functions built into it that are always
-available. They are listed here in alphabetical order.
-
-=================== ================= ================== ================= ====================
-.. .. Built-in Functions .. ..
-=================== ================= ================== ================= ====================
-:func:`abs` :func:`divmod` :func:`input` :func:`open` :func:`staticmethod`
-:func:`all` :func:`enumerate` :func:`int` :func:`ord` :func:`str`
-:func:`any` :func:`eval` :func:`isinstance` :func:`pow` :func:`sum`
-:func:`basestring` :func:`execfile` :func:`issubclass` :func:`print` :func:`super`
-:func:`bin` :func:`file` :func:`iter` :func:`property` :func:`tuple`
-:func:`bool` :func:`filter` :func:`len` :func:`range` :func:`type`
-:func:`bytearray` :func:`float` :func:`list` :func:`raw_input` :func:`unichr`
-:func:`callable` :func:`format` :func:`locals` :func:`reduce` :func:`unicode`
-:func:`chr` |func-frozenset|_ :func:`long` :func:`reload` :func:`vars`
-:func:`classmethod` :func:`getattr` :func:`map` :func:`repr` :func:`xrange`
-:func:`cmp` :func:`globals` :func:`max` :func:`reversed` :func:`zip`
-:func:`compile` :func:`hasattr` |func-memoryview|_ :func:`round` :func:`__import__`
-:func:`complex` :func:`hash` :func:`min` |func-set|_ :func:`apply`
-:func:`delattr` :func:`help` :func:`next` :func:`setattr` :func:`buffer`
-|func-dict|_ :func:`hex` :func:`object` :func:`slice` :func:`coerce`
-:func:`dir` :func:`id` :func:`oct` :func:`sorted` :func:`intern`
-=================== ================= ================== ================= ====================
+The Python interpreter has a number of functions and types built into it that
+are always available. They are listed here in alphabetical order.
+
+=================== ================= ================== ================ ====================
+.. .. Built-in Functions .. ..
+=================== ================= ================== ================ ====================
+:func:`abs` |func-dict|_ :func:`help` :func:`min` :func:`setattr`
+:func:`all` :func:`dir` :func:`hex` :func:`next` :func:`slice`
+:func:`any` :func:`divmod` :func:`id` :func:`object` :func:`sorted`
+:func:`ascii` :func:`enumerate` :func:`input` :func:`oct` :func:`staticmethod`
+:func:`bin` :func:`eval` :func:`int` :func:`open` :func:`str`
+:func:`bool` :func:`exec` :func:`isinstance` :func:`ord` :func:`sum`
+:func:`bytearray` :func:`filter` :func:`issubclass` :func:`pow` :func:`super`
+:func:`bytes` :func:`float` :func:`iter` :func:`print` :func:`tuple`
+:func:`callable` :func:`format` :func:`len` :func:`property` :func:`type`
+:func:`chr` |func-frozenset|_ :func:`list` :func:`range` :func:`vars`
+:func:`classmethod` :func:`getattr` :func:`locals` :func:`repr` :func:`zip`
+:func:`compile` :func:`globals` :func:`map` :func:`reversed` :func:`__import__`
+:func:`complex` :func:`hasattr` :func:`max` :func:`round`
+:func:`delattr` :func:`hash` |func-memoryview|_ |func-set|_
+=================== ================= ================== ================ ====================
.. using :func:`dict` would create a link to another page, so local targets are
used, with replacement texts to make the output in the table consistent
@@ -39,7 +37,7 @@ available. They are listed here in alphabetical order.
.. function:: abs(x)
- Return the absolute value of a number. The argument may be a plain or long
+ Return the absolute value of a number. The argument may be an
integer or a floating point number. If the argument is a complex number, its
magnitude is returned.
@@ -55,8 +53,6 @@ available. They are listed here in alphabetical order.
return False
return True
- .. versionadded:: 2.5
-
.. function:: any(iterable)
@@ -69,17 +65,13 @@ available. They are listed here in alphabetical order.
return True
return False
- .. versionadded:: 2.5
-
-.. function:: basestring()
+.. function:: ascii(object)
- This abstract type is the superclass for :class:`str` and :class:`unicode`. It
- cannot be called or instantiated, but it can be used to test whether an object
- is an instance of :class:`str` or :class:`unicode`. ``isinstance(obj,
- basestring)`` is equivalent to ``isinstance(obj, (str, unicode))``.
-
- .. versionadded:: 2.3
+ As :func:`repr`, return a string containing a printable representation of an
+ object, but escape the non-ASCII characters in the string returned by
+ :func:`repr` using ``\x``, ``\u`` or ``\U`` escapes. This generates a string
+ similar to that returned by :func:`repr` in Python 2.
.. function:: bin(x)
@@ -88,31 +80,25 @@ available. They are listed here in alphabetical order.
expression. If *x* is not a Python :class:`int` object, it has to define an
:meth:`__index__` method that returns an integer.
- .. versionadded:: 2.6
-
.. function:: bool([x])
- Convert a value to a Boolean, using the standard truth testing procedure. If
- *x* is false or omitted, this returns :const:`False`; otherwise it returns
- :const:`True`. :class:`bool` is also a class, which is a subclass of
- :class:`int`. Class :class:`bool` cannot be subclassed further. Its only
- instances are :const:`False` and :const:`True`.
+ Convert a value to a Boolean, using the standard :ref:`truth testing
+ procedure <truth>`. If *x* is false or omitted, this returns ``False``;
+ otherwise it returns ``True``. :class:`bool` is also a class, which is a
+ subclass of :class:`int` (see :ref:`typesnumeric`). Class :class:`bool`
+ cannot be subclassed further. Its only instances are ``False`` and
+ ``True`` (see :ref:`bltin-boolean-values`).
.. index:: pair: Boolean; type
- .. versionadded:: 2.2.1
-
- .. versionchanged:: 2.3
- If no argument is given, this function returns :const:`False`.
-
.. function:: bytearray([source[, encoding[, errors]]])
Return a new array of bytes. The :class:`bytearray` type is a mutable
sequence of integers in the range 0 <= x < 256. It has most of the usual
methods of mutable sequences, described in :ref:`typesseq-mutable`, as well
- as most methods that the :class:`str` type has, see :ref:`string-methods`.
+ as most methods that the :class:`bytes` type has, see :ref:`bytes-methods`.
The optional *source* parameter can be used to initialize the array in a few
different ways:
@@ -132,26 +118,43 @@ available. They are listed here in alphabetical order.
Without an argument, an array of size 0 is created.
- .. versionadded:: 2.6
+
+.. function:: bytes([source[, encoding[, errors]]])
+
+ Return a new "bytes" object, which is an immutable sequence of integers in
+ the range ``0 <= x < 256``. :class:`bytes` is an immutable version of
+ :class:`bytearray` -- it has the same non-mutating methods and the same
+ indexing and slicing behavior.
+
+ Accordingly, constructor arguments are interpreted as for :func:`bytearray`.
+
+ Bytes objects can also be created with literals, see :ref:`strings`.
.. function:: callable(object)
Return :const:`True` if the *object* argument appears callable,
- :const:`False` if not. If this
- returns true, it is still possible that a call fails, but if it is false,
- calling *object* will never succeed. Note that classes are callable (calling a
- class returns a new instance); class instances are callable if they have a
- :meth:`__call__` method.
+ :const:`False` if not. If this returns true, it is still possible that a
+ call fails, but if it is false, calling *object* will never succeed.
+ Note that classes are callable (calling a class returns a new instance);
+ instances are callable if their class has a :meth:`__call__` method.
+
+ .. versionadded:: 3.2
+ This function was first removed in Python 3.0 and then brought back
+ in Python 3.2.
.. function:: chr(i)
- Return a string of one character whose ASCII code is the integer *i*. For
- example, ``chr(97)`` returns the string ``'a'``. This is the inverse of
- :func:`ord`. The argument must be in the range [0..255], inclusive;
- :exc:`ValueError` will be raised if *i* is outside that range. See
- also :func:`unichr`.
+ Return the string representing a character whose Unicode codepoint is the integer
+ *i*. For example, ``chr(97)`` returns the string ``'a'``. This is the
+ inverse of :func:`ord`. The valid range for the argument is from 0 through
+ 1,114,111 (0x10FFFF in base 16). :exc:`ValueError` will be raised if *i* is
+ outside that range.
+
+ Note that on narrow Unicode builds, the result is a string of
+ length two for *i* greater than 65,535 (0xFFFF in hexadecimal).
+
.. function:: classmethod(function)
@@ -180,25 +183,13 @@ available. They are listed here in alphabetical order.
For more information on class methods, consult the documentation on the standard
type hierarchy in :ref:`types`.
- .. versionadded:: 2.2
-
- .. versionchanged:: 2.4
- Function decorator syntax added.
-
-.. function:: cmp(x, y)
-
- Compare the two objects *x* and *y* and return an integer according to the
- outcome. The return value is negative if ``x < y``, zero if ``x == y`` and
- strictly positive if ``x > y``.
-
-
-.. function:: compile(source, filename, mode[, flags[, dont_inherit]])
+.. function:: compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)
Compile the *source* into a code or AST object. Code objects can be executed
- by an :keyword:`exec` statement or evaluated by a call to :func:`eval`.
- *source* can either be a string or an AST object. Refer to the :mod:`ast`
- module documentation for information on how to work with AST objects.
+ by :func:`exec` or :func:`eval`. *source* can either be a string or an AST
+ object. Refer to the :mod:`ast` module documentation for information on how
+ to work with AST objects.
The *filename* argument should give the file from which the code was read;
pass some recognizable value if it wasn't read from a file (``'<string>'`` is
@@ -225,6 +216,12 @@ available. They are listed here in alphabetical order.
can be found as the :attr:`compiler_flag` attribute on the :class:`_Feature`
instance in the :mod:`__future__` module.
+ The argument *optimize* specifies the optimization level of the compiler; the
+ default value of ``-1`` selects the optimization level of the interpreter as
+ given by :option:`-O` options. Explicit levels are ``0`` (no optimization;
+ ``__debug__`` is true), ``1`` (asserts are removed, ``__debug__`` is false)
+ or ``2`` (docstrings are removed too).
+
This function raises :exc:`SyntaxError` if the compiled source is invalid,
and :exc:`TypeError` if the source contains null bytes.
@@ -235,15 +232,9 @@ available. They are listed here in alphabetical order.
character. This is to facilitate detection of incomplete and complete
statements in the :mod:`code` module.
- .. versionchanged:: 2.3
- The *flags* and *dont_inherit* arguments were added.
-
- .. versionchanged:: 2.6
- Support for compiling AST objects.
-
- .. versionchanged:: 2.7
+ .. versionchanged:: 3.2
Allowed use of Windows and Mac newlines. Also input in ``'exec'`` mode
- does not have to end in a newline anymore.
+ does not have to end in a newline anymore. Added the *optimize* parameter.
.. function:: complex([real[, imag]])
@@ -253,8 +244,8 @@ available. They are listed here in alphabetical order.
interpreted as a complex number and the function must be called without a second
parameter. The second parameter can never be a string. Each argument may be any
numeric type (including complex). If *imag* is omitted, it defaults to zero and
- the function serves as a numeric conversion function like :func:`int`,
- :func:`long` and :func:`float`. If both arguments are omitted, returns ``0j``.
+ the function serves as a numeric conversion function like :func:`int`
+ and :func:`float`. If both arguments are omitted, returns ``0j``.
.. note::
@@ -336,34 +327,32 @@ available. They are listed here in alphabetical order.
.. note::
Because :func:`dir` is supplied primarily as a convenience for use at an
- interactive prompt, it tries to supply an interesting set of names more than it
- tries to supply a rigorously or consistently defined set of names, and its
- detailed behavior may change across releases. For example, metaclass attributes
- are not in the result list when the argument is a class.
+ interactive prompt, it tries to supply an interesting set of names more
+ than it tries to supply a rigorously or consistently defined set of names,
+ and its detailed behavior may change across releases. For example,
+ metaclass attributes are not in the result list when the argument is a
+ class.
.. function:: divmod(a, b)
Take two (non complex) numbers as arguments and return a pair of numbers
- consisting of their quotient and remainder when using long division. With mixed
- operand types, the rules for binary arithmetic operators apply. For plain and
- long integers, the result is the same as ``(a // b, a % b)``. For floating point
- numbers the result is ``(q, a % b)``, where *q* is usually ``math.floor(a / b)``
- but may be 1 less than that. In any case ``q * b + a % b`` is very close to
- *a*, if ``a % b`` is non-zero it has the same sign as *b*, and ``0 <= abs(a % b)
- < abs(b)``.
-
- .. versionchanged:: 2.3
- Using :func:`divmod` with complex numbers is deprecated.
+ consisting of their quotient and remainder when using integer division. With
+ mixed operand types, the rules for binary arithmetic operators apply. For
+ integers, the result is the same as ``(a // b, a % b)``. For floating point
+ numbers the result is ``(q, a % b)``, where *q* is usually ``math.floor(a /
+ b)`` but may be 1 less than that. In any case ``q * b + a % b`` is very
+ close to *a*, if ``a % b`` is non-zero it has the same sign as *b*, and ``0
+ <= abs(a % b) < abs(b)``.
-.. function:: enumerate(sequence, start=0)
+.. function:: enumerate(iterable, start=0)
- Return an enumerate object. *sequence* must be a sequence, an
- :term:`iterator`, or some other object which supports iteration. The
- :meth:`!next` method of the iterator returned by :func:`enumerate` returns a
- tuple containing a count (from *start* which defaults to 0) and the
- values obtained from iterating over *sequence*::
+ Return an enumerate object. *iterable* must be a sequence, an
+ :term:`iterator`, or some other object which supports iteration.
+ The :meth:`~iterator.__next__` method of the iterator returned by
+ :func:`enumerate` returns a tuple containing a count (from *start* which
+ defaults to 0) and the values obtained from iterating over *iterable*.
>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> list(enumerate(seasons))
@@ -379,33 +368,26 @@ available. They are listed here in alphabetical order.
yield n, elem
n += 1
- .. versionadded:: 2.3
- .. versionchanged:: 2.6
- The *start* parameter was added.
-
-.. function:: eval(expression[, globals[, locals]])
+.. function:: eval(expression, globals=None, locals=None)
The arguments are a string and optional globals and locals. If provided,
*globals* must be a dictionary. If provided, *locals* can be any mapping
object.
- .. versionchanged:: 2.4
- formerly *locals* was required to be a dictionary.
-
The *expression* argument is parsed and evaluated as a Python expression
(technically speaking, a condition list) using the *globals* and *locals*
dictionaries as global and local namespace. If the *globals* dictionary is
present and lacks '__builtins__', the current globals are copied into *globals*
before *expression* is parsed. This means that *expression* normally has full
- access to the standard :mod:`__builtin__` module and restricted environments are
+ access to the standard :mod:`builtins` module and restricted environments are
propagated. If the *locals* dictionary is omitted it defaults to the *globals*
dictionary. If both dictionaries are omitted, the expression is executed in the
environment where :func:`eval` is called. The return value is the result of
the evaluated expression. Syntax errors are reported as exceptions. Example:
>>> x = 1
- >>> print eval('x+1')
+ >>> eval('x+1')
2
This function can also be used to execute arbitrary code objects (such as
@@ -413,99 +395,123 @@ available. They are listed here in alphabetical order.
of a string. If the code object has been compiled with ``'exec'`` as the
*mode* argument, :func:`eval`\'s return value will be ``None``.
- Hints: dynamic execution of statements is supported by the :keyword:`exec`
- statement. Execution of statements from a file is supported by the
- :func:`execfile` function. The :func:`globals` and :func:`locals` functions
+ Hints: dynamic execution of statements is supported by the :func:`exec`
+ function. The :func:`globals` and :func:`locals` functions
returns the current global and local dictionary, respectively, which may be
- useful to pass around for use by :func:`eval` or :func:`execfile`.
+ useful to pass around for use by :func:`eval` or :func:`exec`.
See :func:`ast.literal_eval` for a function that can safely evaluate strings
with expressions containing only literals.
-.. function:: execfile(filename[, globals[, locals]])
+.. function:: exec(object[, globals[, locals]])
+
+ This function supports dynamic execution of Python code. *object* must be
+ either a string or a code object. If it is a string, the string is parsed as
+ a suite of Python statements which is then executed (unless a syntax error
+ occurs). [#]_ If it is a code object, it is simply executed. In all cases,
+ the code that's executed is expected to be valid as file input (see the
+ section "File input" in the Reference Manual). Be aware that the
+ :keyword:`return` and :keyword:`yield` statements may not be used outside of
+ function definitions even within the context of code passed to the
+ :func:`exec` function. The return value is ``None``.
+
+ In all cases, if the optional parts are omitted, the code is executed in the
+ current scope. If only *globals* is provided, it must be a dictionary, which
+ will be used for both the global and the local variables. If *globals* and
+ *locals* are given, they are used for the global and local variables,
+ respectively. If provided, *locals* can be any mapping object. Remember
+ that at module level, globals and locals are the same dictionary. If exec
+ gets two separate objects as *globals* and *locals*, the code will be
+ executed as if it were embedded in a class definition.
+
+ If the *globals* dictionary does not contain a value for the key
+ ``__builtins__``, a reference to the dictionary of the built-in module
+ :mod:`builtins` is inserted under that key. That way you can control what
+ builtins are available to the executed code by inserting your own
+ ``__builtins__`` dictionary into *globals* before passing it to :func:`exec`.
- This function is similar to the :keyword:`exec` statement, but parses a file
- instead of a string. It is different from the :keyword:`import` statement in
- that it does not use the module administration --- it reads the file
- unconditionally and does not create a new module. [#]_
-
- The arguments are a file name and two optional dictionaries. The file is parsed
- and evaluated as a sequence of Python statements (similarly to a module) using
- the *globals* and *locals* dictionaries as global and local namespace. If
- provided, *locals* can be any mapping object. Remember that at module level,
- globals and locals are the same dictionary. If two separate objects are
- passed as *globals* and *locals*, the code will be executed as if it were
- embedded in a class definition.
-
- .. versionchanged:: 2.4
- formerly *locals* was required to be a dictionary.
+ .. note::
- If the *locals* dictionary is omitted it defaults to the *globals* dictionary.
- If both dictionaries are omitted, the expression is executed in the environment
- where :func:`execfile` is called. The return value is ``None``.
+ The built-in functions :func:`globals` and :func:`locals` return the current
+ global and local dictionary, respectively, which may be useful to pass around
+ for use as the second and third argument to :func:`exec`.
.. note::
The default *locals* act as described for function :func:`locals` below:
- modifications to the default *locals* dictionary should not be attempted. Pass
- an explicit *locals* dictionary if you need to see effects of the code on
- *locals* after function :func:`execfile` returns. :func:`execfile` cannot be
- used reliably to modify a function's locals.
-
-
-.. function:: file(name[, mode[, buffering]])
-
- Constructor function for the :class:`file` type, described further in section
- :ref:`bltin-file-objects`. The constructor's arguments are the same as those
- of the :func:`open` built-in function described below.
-
- When opening a file, it's preferable to use :func:`open` instead of invoking
- this constructor directly. :class:`file` is more suited to type testing (for
- example, writing ``isinstance(f, file)``).
-
- .. versionadded:: 2.2
+ modifications to the default *locals* dictionary should not be attempted.
+ Pass an explicit *locals* dictionary if you need to see effects of the
+ code on *locals* after function :func:`exec` returns.
.. function:: filter(function, iterable)
- Construct a list from those elements of *iterable* for which *function* returns
- true. *iterable* may be either a sequence, a container which supports
- iteration, or an iterator. If *iterable* is a string or a tuple, the result
- also has that type; otherwise it is always a list. If *function* is ``None``,
- the identity function is assumed, that is, all elements of *iterable* that are
- false are removed.
+ Construct an iterator from those elements of *iterable* for which *function*
+ returns true. *iterable* may be either a sequence, a container which
+ supports iteration, or an iterator. If *function* is ``None``, the identity
+ function is assumed, that is, all elements of *iterable* that are false are
+ removed.
- Note that ``filter(function, iterable)`` is equivalent to ``[item for item in
- iterable if function(item)]`` if function is not ``None`` and ``[item for item
- in iterable if item]`` if function is ``None``.
+ Note that ``filter(function, iterable)`` is equivalent to the generator
+ expression ``(item for item in iterable if function(item))`` if function is
+ not ``None`` and ``(item for item in iterable if item)`` if function is
+ ``None``.
- See :func:`itertools.ifilter` and :func:`itertools.ifilterfalse` for iterator
- versions of this function, including a variation that filters for elements
- where the *function* returns false.
+ See :func:`itertools.filterfalse` for the complementary function that returns
+ elements of *iterable* for which *function* returns false.
.. function:: float([x])
- Convert a string or a number to floating point. If the argument is a string, it
- must contain a possibly signed decimal or floating point number, possibly
- embedded in whitespace. The argument may also be [+|-]nan or [+|-]inf.
- Otherwise, the argument may be a plain or long integer
- or a floating point number, and a floating point number with the same value
- (within Python's floating point precision) is returned. If no argument is
- given, returns ``0.0``.
-
- .. note::
-
- .. index::
- single: NaN
- single: Infinity
-
- When passing in a string, values for NaN and Infinity may be returned, depending
- on the underlying C library. Float accepts the strings nan, inf and -inf for
- NaN and positive or negative infinity. The case and a leading + are ignored as
- well as a leading - is ignored for NaN. Float always represents NaN and infinity
- as nan, inf or -inf.
+ .. index::
+ single: NaN
+ single: Infinity
+
+ Convert a string or a number to floating point.
+
+ If the argument is a string, it should contain a decimal number, optionally
+ preceded by a sign, and optionally embedded in whitespace. The optional
+ sign may be ``'+'`` or ``'-'``; a ``'+'`` sign has no effect on the value
+ produced. The argument may also be a string representing a NaN
+ (not-a-number), or a positive or negative infinity. More precisely, the
+ input must conform to the following grammar after leading and trailing
+ whitespace characters are removed:
+
+ .. productionlist::
+ sign: "+" | "-"
+ infinity: "Infinity" | "inf"
+ nan: "nan"
+ numeric_value: `floatnumber` | `infinity` | `nan`
+ numeric_string: [`sign`] `numeric_value`
+
+ Here ``floatnumber`` is the form of a Python floating-point literal,
+ described in :ref:`floating`. Case is not significant, so, for example,
+ "inf", "Inf", "INFINITY" and "iNfINity" are all acceptable spellings for
+ positive infinity.
+
+ Otherwise, if the argument is an integer or a floating point number, a
+ floating point number with the same value (within Python's floating point
+ precision) is returned. If the argument is outside the range of a Python
+ float, an :exc:`OverflowError` will be raised.
+
+ For a general Python object ``x``, ``float(x)`` delegates to
+ ``x.__float__()``.
+
+ If no argument is given, ``0.0`` is returned.
+
+ Examples::
+
+ >>> float('+1.23')
+ 1.23
+ >>> float(' -12345\n')
+ -12345.0
+ >>> float('1e-003')
+ 0.001
+ >>> float('+1E6')
+ 1000000.0
+ >>> float('-Infinity')
+ -inf
The float type is described in :ref:`typesnumeric`.
@@ -521,12 +527,14 @@ available. They are listed here in alphabetical order.
of the *value* argument, however there is a standard formatting syntax that
is used by most built-in types: :ref:`formatspec`.
- .. note::
-
- ``format(value, format_spec)`` merely calls
- ``value.__format__(format_spec)``.
+ The default *format_spec* is an empty string which usually gives the same
+ effect as calling :func:`str(value) <str>`.
- .. versionadded:: 2.6
+ A call to ``format(value, format_spec)`` is translated to
+ ``type(value).__format__(format_spec)`` which bypasses the instance
+ dictionary when searching for the value's :meth:`__format__` method. A
+ :exc:`TypeError` exception is raised if the method is not found or if either
+ the *format_spec* or the return value are not strings.
.. _func-frozenset:
@@ -541,8 +549,6 @@ available. They are listed here in alphabetical order.
:class:`tuple`, and :class:`dict` classes, as well as the :mod:`collections`
module.
- .. versionadded:: 2.4
-
.. function:: getattr(object, name[, default])
@@ -562,10 +568,10 @@ available. They are listed here in alphabetical order.
.. function:: hasattr(object, name)
- The arguments are an object and a string. The result is ``True`` if the string
- is the name of one of the object's attributes, ``False`` if not. (This is
- implemented by calling ``getattr(object, name)`` and seeing whether it raises an
- exception or not.)
+ The arguments are an object and a string. The result is ``True`` if the
+ string is the name of one of the object's attributes, ``False`` if not. (This
+ is implemented by calling ``getattr(object, name)`` and seeing whether it
+ raises an :exc:`AttributeError` or not.)
.. function:: hash(object)
@@ -587,26 +593,22 @@ available. They are listed here in alphabetical order.
This function is added to the built-in namespace by the :mod:`site` module.
- .. versionadded:: 2.2
-
.. function:: hex(x)
- Convert an integer number (of any size) to a hexadecimal string. The result is a
- valid Python expression.
+ Convert an integer number to a hexadecimal string. The result is a valid Python
+ expression. If *x* is not a Python :class:`int` object, it has to define an
+ :meth:`__index__` method that returns an integer.
.. note::
To obtain a hexadecimal string representation for a float, use the
:meth:`float.hex` method.
- .. versionchanged:: 2.4
- Formerly only returned an unsigned literal.
-
.. function:: id(object)
- Return the "identity" of an object. This is an integer (or long integer) which
+ Return the "identity" of an object. This is an integer which
is guaranteed to be unique and constant for this object during its lifetime.
Two objects with non-overlapping lifetimes may have the same :func:`id`
value.
@@ -616,58 +618,53 @@ available. They are listed here in alphabetical order.
.. function:: input([prompt])
- Equivalent to ``eval(raw_input(prompt))``.
+ If the *prompt* argument is present, it is written to standard output without
+ a trailing newline. The function then reads a line from input, converts it
+ to a string (stripping a trailing newline), and returns that. When EOF is
+ read, :exc:`EOFError` is raised. Example::
- This function does not catch user errors. If the input is not syntactically
- valid, a :exc:`SyntaxError` will be raised. Other exceptions may be raised if
- there is an error during evaluation.
-
- If the :mod:`readline` module was loaded, then :func:`input` will use it to
- provide elaborate line editing and history features.
+ >>> s = input('--> ')
+ --> Monty Python's Flying Circus
+ >>> s
+ "Monty Python's Flying Circus"
- Consider using the :func:`raw_input` function for general input from users.
+ If the :mod:`readline` module was loaded, then :func:`input` will use it
+ to provide elaborate line editing and history features.
.. function:: int(x=0)
int(x, base=10)
Convert a number or string *x* to an integer, or return ``0`` if no
- arguments are given. If *x* is a number, it can be a plain integer, a long
- integer, or a floating point number. If *x* is floating point, the conversion
- truncates towards zero. If the argument is outside the integer range, the
- function returns a long object instead.
-
- If *x* is not a number or if *base* is given, then *x* must be a string or
- Unicode object representing an :ref:`integer literal <integers>` in radix
- *base*. Optionally, the literal can be
+ arguments are given. If *x* is a number, return :meth:`x.__int__()
+ <object.__int__>`. For floating point numbers, this truncates towards zero.
+
+ If *x* is not a number or if *base* is given, then *x* must be a string,
+ :class:`bytes`, or :class:`bytearray` instance representing an :ref:`integer
+ literal <integers>` in radix *base*. Optionally, the literal can be
preceded by ``+`` or ``-`` (with no space in between) and surrounded by
whitespace. A base-n literal consists of the digits 0 to n-1, with ``a``
to ``z`` (or ``A`` to ``Z``) having
values 10 to 35. The default *base* is 10. The allowed values are 0 and 2-36.
Base-2, -8, and -16 literals can be optionally prefixed with ``0b``/``0B``,
- ``0o``/``0O``/``0``, or ``0x``/``0X``, as with integer literals in code.
- Base 0 means to interpret the string exactly as an integer literal, so that
- the actual base is 2, 8, 10, or 16.
+ ``0o``/``0O``, or ``0x``/``0X``, as with integer literals in code. Base 0
+ means to interpret exactly as a code literal, so that the actual base is 2,
+ 8, 10, or 16, and so that ``int('010', 0)`` is not legal, while
+ ``int('010')`` is, as well as ``int('010', 8)``.
The integer type is described in :ref:`typesnumeric`.
.. function:: isinstance(object, classinfo)
- Return true if the *object* argument is an instance of the *classinfo* argument,
- or of a (direct, indirect or :term:`virtual <abstract base class>`) subclass
- thereof. Also return true if *classinfo*
- is a type object (new-style class) and *object* is an object of that type or of
- a (direct, indirect or :term:`virtual <abstract base class>`) subclass
- thereof. If *object* is not a class instance or
- an object of the given type, the function always returns false. If *classinfo*
- is neither a class object nor a type object, it may be a tuple of class or type
- objects, or may recursively contain other such tuples (other sequence types are
- not accepted). If *classinfo* is not a class, type, or tuple of classes, types,
- and such tuples, a :exc:`TypeError` exception is raised.
-
- .. versionchanged:: 2.2
- Support for a tuple of type information was added.
+ Return true if the *object* argument is an instance of the *classinfo*
+ argument, or of a (direct, indirect or :term:`virtual <abstract base
+ class>`) subclass thereof. If *object* is not
+ an object of the given type, the function always returns false. If
+ *classinfo* is not a class (type object), it may be a tuple of type objects,
+ or may recursively contain other such tuples (other sequence types are not
+ accepted). If *classinfo* is not a type or tuple of types and such tuples,
+ a :exc:`TypeError` exception is raised.
.. function:: issubclass(class, classinfo)
@@ -678,22 +675,21 @@ available. They are listed here in alphabetical order.
objects, in which case every entry in *classinfo* will be checked. In any other
case, a :exc:`TypeError` exception is raised.
- .. versionchanged:: 2.3
- Support for a tuple of type information was added.
-
-.. function:: iter(o[, sentinel])
+.. function:: iter(object[, sentinel])
- Return an :term:`iterator` object. The first argument is interpreted very differently
- depending on the presence of the second argument. Without a second argument, *o*
- must be a collection object which supports the iteration protocol (the
- :meth:`__iter__` method), or it must support the sequence protocol (the
- :meth:`__getitem__` method with integer arguments starting at ``0``). If it
- does not support either of those protocols, :exc:`TypeError` is raised. If the
- second argument, *sentinel*, is given, then *o* must be a callable object. The
- iterator created in this case will call *o* with no arguments for each call to
- its :meth:`~iterator.next` method; if the value returned is equal to *sentinel*,
- :exc:`StopIteration` will be raised, otherwise the value will be returned.
+ Return an :term:`iterator` object. The first argument is interpreted very
+ differently depending on the presence of the second argument. Without a
+ second argument, *object* must be a collection object which supports the
+ iteration protocol (the :meth:`__iter__` method), or it must support the
+ sequence protocol (the :meth:`__getitem__` method with integer arguments
+ starting at ``0``). If it does not support either of those protocols,
+ :exc:`TypeError` is raised. If the second argument, *sentinel*, is given,
+ then *object* must be a callable object. The iterator created in this case
+ will call *object* with no arguments for each call to its
+ :meth:`~iterator.__next__` method; if the value returned is equal to
+ *sentinel*, :exc:`StopIteration` will be raised, otherwise the value will
+ be returned.
One useful application of the second form of :func:`iter` is to read lines of
a file until a certain line is reached. The following example reads a file
@@ -703,8 +699,6 @@ available. They are listed here in alphabetical order.
for line in iter(fp.readline, ''):
process_line(line)
- .. versionadded:: 2.2
-
.. function:: len(s)
@@ -718,12 +712,10 @@ available. They are listed here in alphabetical order.
items. *iterable* may be either a sequence, a container that supports
iteration, or an iterator object. If *iterable* is already a list, a copy is
made and returned, similar to ``iterable[:]``. For instance, ``list('abc')``
- returns ``['a', 'b', 'c']`` and ``list( (1, 2, 3) )`` returns ``[1, 2, 3]``. If
- no argument is given, returns a new empty list, ``[]``.
+ returns ``['a', 'b', 'c']`` and ``list( (1, 2, 3) )`` returns ``[1, 2, 3]``.
+ If no argument is given, returns a new empty list, ``[]``.
- :class:`list` is a mutable sequence type, as documented in
- :ref:`typesseq`. For other containers see the built in :class:`dict`,
- :class:`set`, and :class:`tuple` classes, and the :mod:`collections` module.
+ :class:`list` is a mutable sequence type, as documented in :ref:`typesseq`.
.. function:: locals()
@@ -733,39 +725,20 @@ available. They are listed here in alphabetical order.
blocks, but not in class blocks.
.. note::
-
The contents of this dictionary should not be modified; changes may not
affect the values of local and free variables used by the interpreter.
-
-.. function:: long(x=0)
- long(x, base=10)
-
- Convert a string or number to a long integer. If the argument is a string, it
- must contain a possibly signed number of arbitrary size, possibly embedded in
- whitespace. The *base* argument is interpreted in the same way as for
- :func:`int`, and may only be given when *x* is a string. Otherwise, the argument
- may be a plain or long integer or a floating point number, and a long integer
- with the same value is returned. Conversion of floating point numbers to
- integers truncates (towards zero). If no arguments are given, returns ``0L``.
-
- The long type is described in :ref:`typesnumeric`.
-
-
.. function:: map(function, iterable, ...)
- Apply *function* to every item of *iterable* and return a list of the results.
- If additional *iterable* arguments are passed, *function* must take that many
- arguments and is applied to the items from all iterables in parallel. If one
- iterable is shorter than another it is assumed to be extended with ``None``
- items. If *function* is ``None``, the identity function is assumed; if there
- are multiple arguments, :func:`map` returns a list consisting of tuples
- containing the corresponding items from all iterables (a kind of transpose
- operation). The *iterable* arguments may be a sequence or any iterable object;
- the result is always a list.
+ Return an iterator that applies *function* to every item of *iterable*,
+ yielding the results. If additional *iterable* arguments are passed,
+ *function* must take that many arguments and is applied to the items from all
+ iterables in parallel. With multiple iterables, the iterator stops when the
+ shortest iterable is exhausted. For cases where the function inputs are
+ already arranged into argument tuples, see :func:`itertools.starmap`\.
-.. function:: max(iterable[, key])
+.. function:: max(iterable, *[, key])
max(arg1, arg2, *args[, key])
Return the largest item in an iterable or the largest of two or more
@@ -776,12 +749,14 @@ available. They are listed here in alphabetical order.
in the iterable is returned. If two or more positional arguments are
provided, the largest of the positional arguments is returned.
- The optional *key* argument specifies a one-argument ordering function like that
- used for :meth:`list.sort`. The *key* argument, if supplied, must be in keyword
- form (for example, ``max(a,b,c,key=func)``).
+ The optional keyword-only *key* argument specifies a one-argument ordering
+ function like that used for :meth:`list.sort`.
+
+ If multiple items are maximal, the function returns the first one
+ encountered. This is consistent with other sort-stability preserving tools
+ such as ``sorted(iterable, key=keyfunc, reverse=True)[0]`` and
+ ``heapq.nlargest(1, iterable, key=keyfunc)``.
- .. versionchanged:: 2.5
- Added support for the optional *key* argument.
.. _func-memoryview:
.. function:: memoryview(obj)
@@ -791,7 +766,7 @@ available. They are listed here in alphabetical order.
:ref:`typememoryview` for more information.
-.. function:: min(iterable[, key])
+.. function:: min(iterable, *[, key])
min(arg1, arg2, *args[, key])
Return the smallest item in an iterable or the smallest of two or more
@@ -802,122 +777,190 @@ available. They are listed here in alphabetical order.
in the iterable is returned. If two or more positional arguments are
provided, the smallest of the positional arguments is returned.
- The optional *key* argument specifies a one-argument ordering function like that
- used for :meth:`list.sort`. The *key* argument, if supplied, must be in keyword
- form (for example, ``min(a,b,c,key=func)``).
-
- .. versionchanged:: 2.5
- Added support for the optional *key* argument.
+ The optional keyword-only *key* argument specifies a one-argument ordering
+ function like that used for :meth:`list.sort`.
+ If multiple items are minimal, the function returns the first one
+ encountered. This is consistent with other sort-stability preserving tools
+ such as ``sorted(iterable, key=keyfunc)[0]`` and ``heapq.nsmallest(1,
+ iterable, key=keyfunc)``.
.. function:: next(iterator[, default])
Retrieve the next item from the *iterator* by calling its
- :meth:`~iterator.next` method. If *default* is given, it is returned if the
- iterator is exhausted, otherwise :exc:`StopIteration` is raised.
-
- .. versionadded:: 2.6
+ :meth:`~iterator.__next__` method. If *default* is given, it is returned
+ if the iterator is exhausted, otherwise :exc:`StopIteration` is raised.
.. function:: object()
- Return a new featureless object. :class:`object` is a base for all new style
- classes. It has the methods that are common to all instances of new style
- classes.
+ Return a new featureless object. :class:`object` is a base for all classes.
+ It has the methods that are common to all instances of Python classes. This
+ function does not accept any arguments.
- .. versionadded:: 2.2
+ .. note::
- .. versionchanged:: 2.3
- This function does not accept any arguments. Formerly, it accepted arguments but
- ignored them.
+ :class:`object` does *not* have a :attr:`__dict__`, so you can't assign
+ arbitrary attributes to an instance of the :class:`object` class.
.. function:: oct(x)
- Convert an integer number (of any size) to an octal string. The result is a
- valid Python expression.
+ Convert an integer number to an octal string. The result is a valid Python
+ expression. If *x* is not a Python :class:`int` object, it has to define an
+ :meth:`__index__` method that returns an integer.
- .. versionchanged:: 2.4
- Formerly only returned an unsigned literal.
+ .. index::
+ single: file object; open() built-in function
+
+.. function:: open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True)
+
+ Open *file* and return a corresponding :term:`file object`. If the file
+ cannot be opened, an :exc:`IOError` is raised.
+
+ *file* is either a string or bytes object giving the pathname (absolute or
+ relative to the current working directory) of the file to be opened or
+ an integer file descriptor of the file to be wrapped. (If a file descriptor
+ is given, it is closed when the returned I/O object is closed, unless
+ *closefd* is set to ``False``.)
+
+ *mode* is an optional string that specifies the mode in which the file is
+ opened. It defaults to ``'r'`` which means open for reading in text mode.
+ Other common values are ``'w'`` for writing (truncating the file if it
+ already exists), and ``'a'`` for appending (which on *some* Unix systems,
+ means that *all* writes append to the end of the file regardless of the
+ current seek position). In text mode, if *encoding* is not specified the
+ encoding used is platform dependent. (For reading and writing raw bytes use
+ binary mode and leave *encoding* unspecified.) The available modes are:
+
+ ========= ===============================================================
+ Character Meaning
+ --------- ---------------------------------------------------------------
+ ``'r'`` open for reading (default)
+ ``'w'`` open for writing, truncating the file first
+ ``'a'`` open for writing, appending to the end of the file if it exists
+ ``'b'`` binary mode
+ ``'t'`` text mode (default)
+ ``'+'`` open a disk file for updating (reading and writing)
+ ``'U'`` universal newlines mode (for backwards compatibility; should
+ not be used in new code)
+ ========= ===============================================================
+
+ The default mode is ``'r'`` (open for reading text, synonym of ``'rt'``).
+ For binary read-write access, the mode ``'w+b'`` opens and truncates the file
+ to 0 bytes. ``'r+b'`` opens the file without truncation.
+
+ As mentioned in the :ref:`io-overview`, Python distinguishes between binary
+ and text I/O. Files opened in binary mode (including ``'b'`` in the *mode*
+ argument) return contents as :class:`bytes` objects without any decoding. In
+ text mode (the default, or when ``'t'`` is included in the *mode* argument),
+ the contents of the file are returned as :class:`str`, the bytes having been
+ first decoded using a platform-dependent encoding or using the specified
+ *encoding* if given.
-.. function:: open(name[, mode[, buffering]])
+ .. note::
- Open a file, returning an object of the :class:`file` type described in
- section :ref:`bltin-file-objects`. If the file cannot be opened,
- :exc:`IOError` is raised. When opening a file, it's preferable to use
- :func:`open` instead of invoking the :class:`file` constructor directly.
+ Python doesn't depend on the underlying operating system's notion of text
+ files; all the processing is done by Python itself, and is therefore
+ platform-independent.
+
+ *buffering* is an optional integer used to set the buffering policy. Pass 0
+ to switch buffering off (only allowed in binary mode), 1 to select line
+ buffering (only usable in text mode), and an integer > 1 to indicate the size
+ of a fixed-size chunk buffer. When no *buffering* argument is given, the
+ default buffering policy works as follows:
+
+ * Binary files are buffered in fixed-size chunks; the size of the buffer is
+ chosen using a heuristic trying to determine the underlying device's "block
+ size" and falling back on :attr:`io.DEFAULT_BUFFER_SIZE`. On many systems,
+ the buffer will typically be 4096 or 8192 bytes long.
+
+ * "Interactive" text files (files for which :meth:`isatty` returns True) use
+ line buffering. Other text files use the policy described above for binary
+ files.
+
+ *encoding* is the name of the encoding used to decode or encode the file.
+ This should only be used in text mode. The default encoding is platform
+ dependent (whatever :func:`locale.getpreferredencoding` returns), but any
+ encoding supported by Python can be used. See the :mod:`codecs` module for
+ the list of supported encodings.
+
+ *errors* is an optional string that specifies how encoding and decoding
+ errors are to be handled--this cannot be used in binary mode. Pass
+ ``'strict'`` to raise a :exc:`ValueError` exception if there is an encoding
+ error (the default of ``None`` has the same effect), or pass ``'ignore'`` to
+ ignore errors. (Note that ignoring encoding errors can lead to data loss.)
+ ``'replace'`` causes a replacement marker (such as ``'?'``) to be inserted
+ where there is malformed data. When writing, ``'xmlcharrefreplace'``
+ (replace with the appropriate XML character reference) or
+ ``'backslashreplace'`` (replace with backslashed escape sequences) can be
+ used. Any other error handling name that has been registered with
+ :func:`codecs.register_error` is also valid.
- The first two arguments are the same as for ``stdio``'s :c:func:`fopen`:
- *name* is the file name to be opened, and *mode* is a string indicating how
- the file is to be opened.
+ .. index::
+ single: universal newlines; open() built-in function
- The most commonly-used values of *mode* are ``'r'`` for reading, ``'w'`` for
- writing (truncating the file if it already exists), and ``'a'`` for appending
- (which on *some* Unix systems means that *all* writes append to the end of the
- file regardless of the current seek position). If *mode* is omitted, it
- defaults to ``'r'``. The default is to use text mode, which may convert
- ``'\n'`` characters to a platform-specific representation on writing and back
- on reading. Thus, when opening a binary file, you should append ``'b'`` to
- the *mode* value to open the file in binary mode, which will improve
- portability. (Appending ``'b'`` is useful even on systems that don't treat
- binary and text files differently, where it serves as documentation.) See below
- for more possible values of *mode*.
+ *newline* controls how :term:`universal newlines` mode works (it only
+ applies to text mode). It can be ``None``, ``''``, ``'\n'``, ``'\r'``, and
+ ``'\r\n'``. It works as follows:
+
+ * When reading input from the stream, if *newline* is ``None``, universal
+ newlines mode is enabled. Lines in the input can end in ``'\n'``,
+ ``'\r'``, or ``'\r\n'``, and these are translated into ``'\n'`` before
+ being returned to the caller. If it is ``''``, universal newlines mode is
+ enabled, but line endings are returned to the caller untranslated. If it
+ has any of the other legal values, input lines are only terminated by the
+ given string, and the line ending is returned to the caller untranslated.
+
+ * When writing output to the stream, if *newline* is ``None``, any ``'\n'``
+ characters written are translated to the system default line separator,
+ :data:`os.linesep`. If *newline* is ``''`` or ``'\n'``, no translation
+ takes place. If *newline* is any of the other legal values, any ``'\n'``
+ characters written are translated to the given string.
+
+ If *closefd* is ``False`` and a file descriptor rather than a filename was
+ given, the underlying file descriptor will be kept open when the file is
+ closed. If a filename is given *closefd* has no effect and must be ``True``
+ (the default).
+
+ The type of :term:`file object` returned by the :func:`open` function
+ depends on the mode. When :func:`open` is used to open a file in a text
+ mode (``'w'``, ``'r'``, ``'wt'``, ``'rt'``, etc.), it returns a subclass of
+ :class:`io.TextIOBase` (specifically :class:`io.TextIOWrapper`). When used
+ to open a file in a binary mode with buffering, the returned class is a
+ subclass of :class:`io.BufferedIOBase`. The exact class varies: in read
+ binary mode, it returns a :class:`io.BufferedReader`; in write binary and
+ append binary modes, it returns a :class:`io.BufferedWriter`, and in
+ read/write mode, it returns a :class:`io.BufferedRandom`. When buffering is
+ disabled, the raw stream, a subclass of :class:`io.RawIOBase`,
+ :class:`io.FileIO`, is returned.
.. index::
single: line-buffered I/O
single: unbuffered I/O
single: buffer size, I/O
single: I/O control; buffering
+ single: binary mode
+ single: text mode
+ module: sys
- The optional *buffering* argument specifies the file's desired buffer size: 0
- means unbuffered, 1 means line buffered, any other positive value means use a
- buffer of (approximately) that size. A negative *buffering* means to use the
- system default, which is usually line buffered for tty devices and fully
- buffered for other files. If omitted, the system default is used. [#]_
-
- Modes ``'r+'``, ``'w+'`` and ``'a+'`` open the file for updating (note that
- ``'w+'`` truncates the file). Append ``'b'`` to the mode to open the file in
- binary mode, on systems that differentiate between binary and text files; on
- systems that don't have this distinction, adding the ``'b'`` has no effect.
-
- .. index::
- single: universal newlines; open() built-in function
-
- In addition to the standard :c:func:`fopen` values *mode* may be ``'U'`` or
- ``'rU'``. Python is usually built with :term:`universal newlines` support;
- supplying ``'U'`` opens the file as a text file, but lines may be terminated
- by any of the following: the Unix end-of-line convention ``'\n'``, the
- Macintosh convention ``'\r'``, or the Windows convention ``'\r\n'``. All of
- these external representations are seen as ``'\n'`` by the Python program.
- If Python is built without universal newlines support a *mode* with ``'U'``
- is the same as normal text mode. Note that file objects so opened also have
- an attribute called :attr:`newlines` which has a value of ``None`` (if no
- newlines have yet been seen), ``'\n'``, ``'\r'``, ``'\r\n'``, or a tuple
- containing all the newline types seen.
-
- Python enforces that the mode, after stripping ``'U'``, begins with ``'r'``,
- ``'w'`` or ``'a'``.
-
- Python provides many file handling modules including
- :mod:`fileinput`, :mod:`os`, :mod:`os.path`, :mod:`tempfile`, and
- :mod:`shutil`.
-
- .. versionchanged:: 2.5
- Restriction on first letter of mode string introduced.
+ See also the file handling modules, such as, :mod:`fileinput`, :mod:`io`
+ (where :func:`open` is declared), :mod:`os`, :mod:`os.path`, :mod:`tempfile`,
+ and :mod:`shutil`.
+.. XXX works for bytes too, but should it?
.. function:: ord(c)
- Given a string of length one, return an integer representing the Unicode code
- point of the character when the argument is a unicode object, or the value of
- the byte when the argument is an 8-bit string. For example, ``ord('a')`` returns
- the integer ``97``, ``ord(u'\u2020')`` returns ``8224``. This is the inverse of
- :func:`chr` for 8-bit strings and of :func:`unichr` for unicode objects. If a
- unicode argument is given and Python was built with UCS2 Unicode, then the
- character's code point must be in the range [0..65535] inclusive; otherwise the
- string length is two, and a :exc:`TypeError` will be raised.
+ Given a string representing one Unicode character, return an integer
+ representing the Unicode code
+ point of that character. For example, ``ord('a')`` returns the integer ``97``
+ and ``ord('\u2020')`` returns ``8224``. This is the inverse of :func:`chr`.
+ On wide Unicode builds, if the argument length is not one, a
+ :exc:`TypeError` will be raised. On narrow Unicode builds, strings
+ of length two are accepted when they form a UTF-16 surrogate pair.
.. function:: pow(x, y[, z])
@@ -925,19 +968,14 @@ available. They are listed here in alphabetical order.
modulo *z* (computed more efficiently than ``pow(x, y) % z``). The two-argument
form ``pow(x, y)`` is equivalent to using the power operator: ``x**y``.
- The arguments must have numeric types. With mixed operand types, the coercion
- rules for binary arithmetic operators apply. For int and long int operands, the
- result has the same type as the operands (after coercion) unless the second
- argument is negative; in that case, all arguments are converted to float and a
- float result is delivered. For example, ``10**2`` returns ``100``, but
- ``10**-2`` returns ``0.01``. (This last feature was added in Python 2.2. In
- Python 2.1 and before, if both arguments were of integer types and the second
- argument was negative, an exception was raised.) If the second argument is
- negative, the third argument must be omitted. If *z* is present, *x* and *y*
- must be of integer types, and *y* must be non-negative. (This restriction was
- added in Python 2.2. In Python 2.1 and before, floating 3-argument ``pow()``
- returned platform-dependent results depending on floating-point rounding
- accidents.)
+ The arguments must have numeric types. With mixed operand types, the
+ coercion rules for binary arithmetic operators apply. For :class:`int`
+ operands, the result has the same type as the operands (after coercion)
+ unless the second argument is negative; in that case, all arguments are
+ converted to float and a float result is delivered. For example, ``10**2``
+ returns ``100``, but ``10**-2`` returns ``0.01``. If the second argument is
+ negative, the third argument must be omitted. If *z* is present, *x* and *y*
+ must be of integer types, and *y* must be non-negative.
.. function:: print(*objects, sep=' ', end='\\n', file=sys.stdout)
@@ -953,32 +991,20 @@ available. They are listed here in alphabetical order.
*end*.
The *file* argument must be an object with a ``write(string)`` method; if it
- is not present or ``None``, :data:`sys.stdout` will be used. Output buffering
- is determined by *file*. Use ``file.flush()`` to ensure, for instance,
+ is not present or ``None``, :data:`sys.stdout` will be used. Output buffering
+ is determined by *file*. Use ``file.flush()`` to ensure, for instance,
immediate appearance on a screen.
- .. note::
-
- This function is not normally available as a built-in since the name
- ``print`` is recognized as the :keyword:`print` statement. To disable the
- statement and use the :func:`print` function, use this future statement at
- the top of your module::
-
- from __future__ import print_function
- .. versionadded:: 2.6
+.. function:: property(fget=None, fset=None, fdel=None, doc=None)
-
-.. function:: property([fget[, fset[, fdel[, doc]]]])
-
- Return a property attribute for :term:`new-style class`\es (classes that
- derive from :class:`object`).
+ Return a property attribute.
*fget* is a function for getting an attribute value, likewise *fset* is a
function for setting, and *fdel* a function for del'ing, an attribute. Typical
use is to define a managed attribute ``x``::
- class C(object):
+ class C:
def __init__(self):
self._x = None
@@ -997,7 +1023,7 @@ available. They are listed here in alphabetical order.
property will copy *fget*'s docstring (if it exists). This makes it possible to
create read-only properties easily using :func:`property` as a :term:`decorator`::
- class Parrot(object):
+ class Parrot:
def __init__(self):
self._voltage = 100000
@@ -1014,7 +1040,7 @@ available. They are listed here in alphabetical order.
corresponding accessor function set to the decorated function. This is
best explained with an example::
- class C(object):
+ class C:
def __init__(self):
self._x = None
@@ -1038,151 +1064,69 @@ available. They are listed here in alphabetical order.
The returned property also has the attributes ``fget``, ``fset``, and
``fdel`` corresponding to the constructor arguments.
- .. versionadded:: 2.2
-
- .. versionchanged:: 2.5
- Use *fget*'s docstring if no *doc* given.
-
- .. versionchanged:: 2.6
- The ``getter``, ``setter``, and ``deleter`` attributes were added.
-
+.. XXX does accept objects with __index__ too
.. function:: range(stop)
range(start, stop[, step])
- This is a versatile function to create lists containing arithmetic progressions.
- It is most often used in :keyword:`for` loops. The arguments must be plain
- integers. If the *step* argument is omitted, it defaults to ``1``. If the
- *start* argument is omitted, it defaults to ``0``. The full form returns a list
- of plain integers ``[start, start + step, start + 2 * step, ...]``. If *step*
- is positive, the last element is the largest ``start + i * step`` less than
- *stop*; if *step* is negative, the last element is the smallest ``start + i *
- step`` greater than *stop*. *step* must not be zero (or else :exc:`ValueError`
- is raised). Example:
-
- >>> range(10)
+ This is a versatile function to create iterables yielding arithmetic
+ progressions. It is most often used in :keyword:`for` loops. The arguments
+ must be integers. If the *step* argument is omitted, it defaults to ``1``.
+ If the *start* argument is omitted, it defaults to ``0``. The full form
+ returns an iterable of integers ``[start, start + step, start + 2 * step,
+ ...]``. If *step* is positive, the last element is the largest ``start + i *
+ step`` less than *stop*; if *step* is negative, the last element is the
+ smallest ``start + i * step`` greater than *stop*. *step* must not be zero
+ (or else :exc:`ValueError` is raised). Example:
+
+ >>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- >>> range(1, 11)
+ >>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- >>> range(0, 30, 5)
+ >>> list(range(0, 30, 5))
[0, 5, 10, 15, 20, 25]
- >>> range(0, 10, 3)
+ >>> list(range(0, 10, 3))
[0, 3, 6, 9]
- >>> range(0, -10, -1)
+ >>> list(range(0, -10, -1))
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
- >>> range(0)
+ >>> list(range(0))
[]
- >>> range(1, 0)
+ >>> list(range(1, 0))
[]
+ Range objects implement the :class:`collections.Sequence` ABC, and provide
+ features such as containment tests, element index lookup, slicing and
+ support for negative indices (see :ref:`typesseq`):
-.. function:: raw_input([prompt])
-
- If the *prompt* argument is present, it is written to standard output without a
- trailing newline. The function then reads a line from input, converts it to a
- string (stripping a trailing newline), and returns that. When EOF is read,
- :exc:`EOFError` is raised. Example::
+ >>> r = range(0, 20, 2)
+ >>> r
+ range(0, 20, 2)
+ >>> 11 in r
+ False
+ >>> 10 in r
+ True
+ >>> r.index(10)
+ 5
+ >>> r[5]
+ 10
+ >>> r[:5]
+ range(0, 10, 2)
+ >>> r[-1]
+ 18
- >>> s = raw_input('--> ')
- --> Monty Python's Flying Circus
- >>> s
- "Monty Python's Flying Circus"
+ Ranges containing absolute values larger than :data:`sys.maxsize` are permitted
+ but some features (such as :func:`len`) will raise :exc:`OverflowError`.
- If the :mod:`readline` module was loaded, then :func:`raw_input` will use it to
- provide elaborate line editing and history features.
-
-
-.. function:: reduce(function, iterable[, initializer])
-
- Apply *function* of two arguments cumulatively to the items of *iterable*, from
- left to right, so as to reduce the iterable to a single value. For example,
- ``reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])`` calculates ``((((1+2)+3)+4)+5)``.
- The left argument, *x*, is the accumulated value and the right argument, *y*, is
- the update value from the *iterable*. If the optional *initializer* is present,
- it is placed before the items of the iterable in the calculation, and serves as
- a default when the iterable is empty. If *initializer* is not given and
- *iterable* contains only one item, the first item is returned.
- Roughly equivalent to::
-
- def reduce(function, iterable, initializer=None):
- it = iter(iterable)
- if initializer is None:
- try:
- initializer = next(it)
- except StopIteration:
- raise TypeError('reduce() of empty sequence with no initial value')
- accum_value = initializer
- for x in it:
- accum_value = function(accum_value, x)
- return accum_value
-
-.. function:: reload(module)
-
- Reload a previously imported *module*. The argument must be a module object, so
- it must have been successfully imported before. This is useful if you have
- edited the module source file using an external editor and want to try out the
- new version without leaving the Python interpreter. The return value is the
- module object (the same as the *module* argument).
-
- When ``reload(module)`` is executed:
-
- * Python modules' code is recompiled and the module-level code reexecuted,
- defining a new set of objects which are bound to names in the module's
- dictionary. The ``init`` function of extension modules is not called a second
- time.
-
- * As with all other objects in Python the old objects are only reclaimed after
- their reference counts drop to zero.
-
- * The names in the module namespace are updated to point to any new or changed
- objects.
-
- * Other references to the old objects (such as names external to the module) are
- not rebound to refer to the new objects and must be updated in each namespace
- where they occur if that is desired.
-
- There are a number of other caveats:
-
- If a module is syntactically correct but its initialization fails, the first
- :keyword:`import` statement for it does not bind its name locally, but does
- store a (partially initialized) module object in ``sys.modules``. To reload the
- module you must first :keyword:`import` it again (this will bind the name to the
- partially initialized module object) before you can :func:`reload` it.
-
- When a module is reloaded, its dictionary (containing the module's global
- variables) is retained. Redefinitions of names will override the old
- definitions, so this is generally not a problem. If the new version of a module
- does not define a name that was defined by the old version, the old definition
- remains. This feature can be used to the module's advantage if it maintains a
- global table or cache of objects --- with a :keyword:`try` statement it can test
- for the table's presence and skip its initialization if desired::
-
- try:
- cache
- except NameError:
- cache = {}
-
- It is legal though generally not very useful to reload built-in or dynamically
- loaded modules, except for :mod:`sys`, :mod:`__main__` and :mod:`__builtin__`.
- In many cases, however, extension modules are not designed to be initialized
- more than once, and may fail in arbitrary ways when reloaded.
-
- If a module imports objects from another module using :keyword:`from` ...
- :keyword:`import` ..., calling :func:`reload` for the other module does not
- redefine the objects imported from it --- one way around this is to re-execute
- the :keyword:`from` statement, another is to use :keyword:`import` and qualified
- names (*module*.*name*) instead.
-
- If a module instantiates instances of a class, reloading the module that defines
- the class does not affect the method definitions of the instances --- they
- continue to use the old class definition. The same is true for derived classes.
+ .. versionchanged:: 3.2
+ Implement the Sequence ABC.
+ Support slicing and negative indices.
+ Test integers for membership in constant time instead of iterating
+ through all items.
.. function:: repr(object)
- Return a string containing a printable representation of an object. This is
- the same value yielded by conversions (reverse quotes). It is sometimes
- useful to be able to access this operation as an ordinary function. For many
+ Return a string containing a printable representation of an object. For many
types, this function makes an attempt to return a string that would yield an
object with the same value when passed to :func:`eval`, otherwise the
representation is a string enclosed in angle brackets that contains the name
@@ -1198,21 +1142,19 @@ available. They are listed here in alphabetical order.
:meth:`__len__` method and the :meth:`__getitem__` method with integer
arguments starting at ``0``).
- .. versionadded:: 2.4
-
- .. versionchanged:: 2.6
- Added the possibility to write a custom :meth:`__reversed__` method.
-
.. function:: round(number[, ndigits])
Return the floating point value *number* rounded to *ndigits* digits after
- the decimal point. If *ndigits* is omitted, it defaults to zero. The result
- is a floating point number. Values are rounded to the closest multiple of
- 10 to the power minus *ndigits*; if two multiples are equally close,
- rounding is done away from 0 (so. for example, ``round(0.5)`` is ``1.0`` and
- ``round(-0.5)`` is ``-1.0``).
+ the decimal point. If *ndigits* is omitted, it defaults to zero. Delegates
+ to ``number.__round__(ndigits)``.
+ For the built-in types supporting :func:`round`, values are rounded to the
+ closest multiple of 10 to the power minus *ndigits*; if two multiples are
+ equally close, rounding is done toward the even choice (so, for example,
+ both ``round(0.5)`` and ``round(-0.5)`` are ``0``, and ``round(1.5)`` is
+ ``2``). The return value is an integer if called with one argument,
+ otherwise of the same type as *number*.
.. note::
@@ -1235,8 +1177,6 @@ available. They are listed here in alphabetical order.
:class:`tuple`, and :class:`dict` classes, as well as the :mod:`collections`
module.
- .. versionadded:: 2.4
-
.. function:: setattr(object, name, value)
@@ -1263,19 +1203,11 @@ available. They are listed here in alphabetical order.
for an alternate version that returns an iterator.
-.. function:: sorted(iterable[, cmp[, key[, reverse]]])
+.. function:: sorted(iterable[, key][, reverse])
Return a new sorted list from the items in *iterable*.
- The optional arguments *cmp*, *key*, and *reverse* have the same meaning as
- those for the :meth:`list.sort` method (described in section
- :ref:`typesseq-mutable`).
-
- *cmp* specifies a custom comparison function of two arguments (iterable
- elements) which should return a negative, zero or positive number depending on
- whether the first argument is considered smaller than, equal to, or larger than
- the second argument: ``cmp=lambda x,y: cmp(x.lower(), y.lower())``. The default
- value is ``None``.
+ Has two optional arguments which must be specified as keyword arguments.
*key* specifies a function of one argument that is used to extract a comparison
key from each list element: ``key=str.lower``. The default value is ``None``
@@ -1284,18 +1216,12 @@ available. They are listed here in alphabetical order.
*reverse* is a boolean value. If set to ``True``, then the list elements are
sorted as if each comparison were reversed.
- In general, the *key* and *reverse* conversion processes are much faster
- than specifying an equivalent *cmp* function. This is because *cmp* is
- called multiple times for each list element while *key* and *reverse* touch
- each element only once. Use :func:`functools.cmp_to_key` to convert an
- old-style *cmp* function to a *key* function.
+ Use :func:`functools.cmp_to_key` to convert an old-style *cmp* function to a
+ *key* function.
For sorting examples and a brief sorting tutorial, see `Sorting HowTo
<http://wiki.python.org/moin/HowTo/Sorting/>`_\.
- .. versionadded:: 2.4
-
-
.. function:: staticmethod(function)
Return a static method for *function*.
@@ -1314,32 +1240,57 @@ available. They are listed here in alphabetical order.
as ``C().f()``). The instance is ignored except for its class.
Static methods in Python are similar to those found in Java or C++. Also see
- :func:`classmethod` for a variant that is useful for creating alternate
- class constructors.
+ :func:`classmethod` for a variant that is useful for creating alternate class
+ constructors.
For more information on static methods, consult the documentation on the
standard type hierarchy in :ref:`types`.
- .. versionadded:: 2.2
-
- .. versionchanged:: 2.4
- Function decorator syntax added.
+ .. index::
+ single: string; str() (built-in function)
.. function:: str(object='')
+ str(object=b'', encoding='utf-8', errors='strict')
- Return a string containing a nicely printable representation of an object. For
- strings, this returns the string itself. The difference with ``repr(object)``
- is that ``str(object)`` does not always attempt to return a string that is
- acceptable to :func:`eval`; its goal is to return a printable string. If no
- argument is given, returns the empty string, ``''``.
+ Return a :ref:`string <typesseq>` version of *object*. If *object* is not
+ provided, returns the empty string. Otherwise, the behavior of ``str()``
+ depends on whether *encoding* or *errors* is given, as follows.
- For more information on strings see :ref:`typesseq` which describes sequence
- functionality (strings are sequences), and also the string-specific methods
- described in the :ref:`string-methods` section. To output formatted strings
- use template strings or the ``%`` operator described in the
- :ref:`string-formatting` section. In addition see the :ref:`stringservices`
- section. See also :func:`unicode`.
+ If neither *encoding* nor *errors* is given, ``str(object)`` returns
+ :meth:`object.__str__() <object.__str__>`, which is the "informal" or nicely
+ printable string representation of *object*. For string objects, this is
+ the string itself. If *object* does not have a :meth:`~object.__str__`
+ method, then :func:`str` falls back to returning
+ :meth:`repr(object) <repr>`.
+
+ .. index::
+ single: buffer protocol; str() (built-in function)
+ single: bytes; str() (built-in function)
+
+ If at least one of *encoding* or *errors* is given, *object* should be a
+ :class:`bytes` or :class:`bytearray` object, or more generally any object
+ that supports the :ref:`buffer protocol <bufferobjects>`. In this case, if
+ *object* is a :class:`bytes` (or :class:`bytearray`) object, then
+ ``str(bytes, encoding, errors)`` is equivalent to
+ :meth:`bytes.decode(encoding, errors) <bytes.decode>`. Otherwise, the bytes
+ object underlying the buffer object is obtained before calling
+ :meth:`bytes.decode`. See the :ref:`typesseq` section, the
+ :ref:`typememoryview` section, and :ref:`bufferobjects` for information on
+ buffer objects.
+
+ Passing a :class:`bytes` object to :func:`str` without the *encoding*
+ or *errors* arguments falls under the first case of returning the informal
+ string representation (see also the :option:`-b` command-line option to
+ Python). For example::
+
+ >>> str(b'Zoot!')
+ "b'Zoot!'"
+
+ ``str`` is a built-in :term:`type`. For more information on the string
+ type and its methods, see the :ref:`typesseq` and :ref:`string-methods`
+ sections. To output formatted strings, see the :ref:`string-formatting`
+ section. In addition, see the :ref:`stringservices` section.
.. function:: sum(iterable[, start])
@@ -1354,10 +1305,7 @@ available. They are listed here in alphabetical order.
see :func:`math.fsum`\. To concatenate a series of iterables, consider using
:func:`itertools.chain`.
- .. versionadded:: 2.3
-
-
-.. function:: super(type[, object-or-type])
+.. function:: super([type[, object-or-type]])
Return a proxy object that delegates method calls to a parent or sibling
class of *type*. This is useful for accessing inherited methods that have
@@ -1373,9 +1321,6 @@ available. They are listed here in alphabetical order.
the second argument is a type, ``issubclass(type2, type)`` must be true (this
is useful for classmethods).
- .. note::
- :func:`super` only works for :term:`new-style class`\es.
-
There are two typical use cases for *super*. In a class hierarchy with
single inheritance, *super* can be used to refer to parent classes without
naming them explicitly, thus making the code more maintainable. This use
@@ -1395,7 +1340,8 @@ available. They are listed here in alphabetical order.
class C(B):
def method(self, arg):
- super(C, self).method(arg)
+ super().method(arg) # This does the same thing as:
+ # super(C, self).method(arg)
Note that :func:`super` is implemented as part of the binding process for
explicit dotted attribute lookups such as ``super().__getitem__(name)``.
@@ -1406,14 +1352,13 @@ available. They are listed here in alphabetical order.
Also note that :func:`super` is not limited to use inside methods. The two
argument form specifies the arguments exactly and makes the appropriate
- references.
+ references. The zero argument form automatically searches the stack frame
+ for the class (``__class__``) and the first argument.
For practical suggestions on how to design cooperative classes using
:func:`super`, see `guide to using super()
<http://rhettinger.wordpress.com/2011/05/26/super-considered-super/>`_.
- .. versionadded:: 2.2
-
.. function:: tuple([iterable])
@@ -1424,9 +1369,7 @@ available. They are listed here in alphabetical order.
3])`` returns ``(1, 2, 3)``. If no argument is given, returns a new empty
tuple, ``()``.
- :class:`tuple` is an immutable sequence type, as documented in
- :ref:`typesseq`. For other containers see the built in :class:`dict`,
- :class:`list`, and :class:`set` classes, and the :mod:`collections` module.
+ :class:`tuple` is an immutable sequence type, as documented in :ref:`typesseq`.
.. function:: type(object)
@@ -1434,151 +1377,84 @@ available. They are listed here in alphabetical order.
.. index:: object: type
+
With one argument, return the type of an *object*. The return value is a
- type object. The :func:`isinstance` built-in function is recommended for
- testing the type of an object.
+ type object and generally the same object as returned by ``object.__class__``.
+
+ The :func:`isinstance` built-in function is recommended for testing the type
+ of an object, because it takes subclasses into account.
+
With three arguments, return a new type object. This is essentially a
dynamic form of the :keyword:`class` statement. The *name* string is the
class name and becomes the :attr:`__name__` attribute; the *bases* tuple
itemizes the base classes and becomes the :attr:`__bases__` attribute;
and the *dict* dictionary is the namespace containing definitions for class
- body and becomes the :attr:`__dict__` attribute. For example, the
+ body and becomes the :attr:`__dict__` attribute. For example, the
following two statements create identical :class:`type` objects:
- >>> class X(object):
+ >>> class X:
... a = 1
...
>>> X = type('X', (object,), dict(a=1))
- .. versionadded:: 2.2
-
-
-.. function:: unichr(i)
-
- Return the Unicode string of one character whose Unicode code is the integer
- *i*. For example, ``unichr(97)`` returns the string ``u'a'``. This is the
- inverse of :func:`ord` for Unicode strings. The valid range for the argument
- depends how Python was configured -- it may be either UCS2 [0..0xFFFF] or UCS4
- [0..0x10FFFF]. :exc:`ValueError` is raised otherwise. For ASCII and 8-bit
- strings see :func:`chr`.
-
- .. versionadded:: 2.0
-
-
-.. function:: unicode(object='')
- unicode(object[, encoding [, errors]])
-
- Return the Unicode string version of *object* using one of the following modes:
-
- If *encoding* and/or *errors* are given, ``unicode()`` will decode the object
- which can either be an 8-bit string or a character buffer using the codec for
- *encoding*. The *encoding* parameter is a string giving the name of an encoding;
- if the encoding is not known, :exc:`LookupError` is raised. Error handling is
- done according to *errors*; this specifies the treatment of characters which are
- invalid in the input encoding. If *errors* is ``'strict'`` (the default), a
- :exc:`ValueError` is raised on errors, while a value of ``'ignore'`` causes
- errors to be silently ignored, and a value of ``'replace'`` causes the official
- Unicode replacement character, ``U+FFFD``, to be used to replace input
- characters which cannot be decoded. See also the :mod:`codecs` module.
-
- If no optional parameters are given, ``unicode()`` will mimic the behaviour of
- ``str()`` except that it returns Unicode strings instead of 8-bit strings. More
- precisely, if *object* is a Unicode string or subclass it will return that
- Unicode string without any additional decoding applied.
-
- For objects which provide a :meth:`__unicode__` method, it will call this method
- without arguments to create a Unicode string. For all other objects, the 8-bit
- string version or representation is requested and then converted to a Unicode
- string using the codec for the default encoding in ``'strict'`` mode.
-
- For more information on Unicode strings see :ref:`typesseq` which describes
- sequence functionality (Unicode strings are sequences), and also the
- string-specific methods described in the :ref:`string-methods` section. To
- output formatted strings use template strings or the ``%`` operator described
- in the :ref:`string-formatting` section. In addition see the
- :ref:`stringservices` section. See also :func:`str`.
-
- .. versionadded:: 2.0
-
- .. versionchanged:: 2.2
- Support for :meth:`__unicode__` added.
-
.. function:: vars([object])
- Return the :attr:`__dict__` attribute for a module, class, instance,
- or any other object with a :attr:`__dict__` attribute.
-
- Objects such as modules and instances have an updateable :attr:`__dict__`
- attribute; however, other objects may have write restrictions on their
- :attr:`__dict__` attributes (for example, new-style classes use a
- dictproxy to prevent direct dictionary updates).
-
- Without an argument, :func:`vars` acts like :func:`locals`. Note, the
- locals dictionary is only useful for reads since updates to the locals
- dictionary are ignored.
-
-
-.. function:: xrange(stop)
- xrange(start, stop[, step])
-
- This function is very similar to :func:`range`, but returns an :ref:`xrange
- object <typesseq-xrange>`
- instead of a list. This is an opaque sequence type which yields the same values
- as the corresponding list, without actually storing them all simultaneously.
- The advantage of :func:`xrange` over :func:`range` is minimal (since
- :func:`xrange` still has to create the values when asked for them) except when a
- very large range is used on a memory-starved machine or when all of the range's
- elements are never used (such as when the loop is usually terminated with
- :keyword:`break`). For more information on xrange objects, see
- :ref:`typesseq-xrange` and :ref:`typesseq`.
-
- .. impl-detail::
+ Without an argument, act like :func:`locals`.
- :func:`xrange` is intended to be simple and fast. Implementations may
- impose restrictions to achieve this. The C implementation of Python
- restricts all arguments to native C longs ("short" Python integers), and
- also requires that the number of elements fit in a native C long. If a
- larger range is needed, an alternate version can be crafted using the
- :mod:`itertools` module: ``islice(count(start, step),
- (stop-start+step-1+2*(step<0))//step)``.
+ With a module, class or class instance object as argument (or anything else that
+ has a :attr:`__dict__` attribute), return that attribute.
-
-.. function:: zip([iterable, ...])
-
- This function returns a list of tuples, where the *i*-th tuple contains the
- *i*-th element from each of the argument sequences or iterables. The returned
- list is truncated in length to the length of the shortest argument sequence.
- When there are multiple arguments which are all of the same length, :func:`zip`
- is similar to :func:`map` with an initial argument of ``None``. With a single
- sequence argument, it returns a list of 1-tuples. With no arguments, it returns
- an empty list.
+ .. note::
+ The returned dictionary should not be modified:
+ the effects on the corresponding symbol table are undefined. [#]_
+
+.. function:: zip(*iterables)
+
+ Make an iterator that aggregates elements from each of the iterables.
+
+ Returns an iterator of tuples, where the *i*-th tuple contains
+ the *i*-th element from each of the argument sequences or iterables. The
+ iterator stops when the shortest input iterable is exhausted. With a single
+ iterable argument, it returns an iterator of 1-tuples. With no arguments,
+ it returns an empty iterator. Equivalent to::
+
+ def zip(*iterables):
+ # zip('ABCD', 'xy') --> Ax By
+ sentinel = object()
+ iterators = [iter(it) for it in iterables]
+ while iterators:
+ result = []
+ for it in iterators:
+ elem = next(it, sentinel)
+ if elem is sentinel:
+ return
+ result.append(elem)
+ yield tuple(result)
The left-to-right evaluation order of the iterables is guaranteed. This
makes possible an idiom for clustering a data series into n-length groups
using ``zip(*[iter(s)]*n)``.
+ :func:`zip` should only be used with unequal length inputs when you don't
+ care about trailing, unmatched values from the longer iterables. If those
+ values are important, use :func:`itertools.zip_longest` instead.
+
:func:`zip` in conjunction with the ``*`` operator can be used to unzip a
list::
>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
- >>> zipped
+ >>> list(zipped)
[(1, 4), (2, 5), (3, 6)]
- >>> x2, y2 = zip(*zipped)
+ >>> x2, y2 = zip(*zip(x, y))
>>> x == list(x2) and y == list(y2)
True
- .. versionadded:: 2.0
-
- .. versionchanged:: 2.4
- Formerly, :func:`zip` required at least one argument and ``zip()`` raised a
- :exc:`TypeError` instead of returning an empty list.
-
-.. function:: __import__(name[, globals[, locals[, fromlist[, level]]]])
+.. function:: __import__(name, globals={}, locals={}, fromlist=[], level=-1)
.. index::
statement: import
@@ -1590,8 +1466,8 @@ available. They are listed here in alphabetical order.
programming, unlike :func:`importlib.import_module`.
This function is invoked by the :keyword:`import` statement. It can be
- replaced (by importing the :mod:`__builtin__` module and assigning to
- ``__builtin__.__import__``) in order to change semantics of the
+ replaced (by importing the :mod:`builtins` module and assigning to
+ ``builtins.__import__``) in order to change semantics of the
:keyword:`import` statement, but nowadays it is usually simpler to use import
hooks (see :pep:`302`). Direct use of :func:`__import__` is rare, except in
cases where you want to import a module whose name is only known at runtime.
@@ -1603,11 +1479,13 @@ available. They are listed here in alphabetical order.
not use its *locals* argument at all, and uses its *globals* only to
determine the package context of the :keyword:`import` statement.
- *level* specifies whether to use absolute or relative imports. The default
- is ``-1`` which indicates both absolute and relative imports will be
- attempted. ``0`` means only perform absolute imports. Positive values for
- *level* indicate the number of parent directories to search relative to the
- directory of the module calling :func:`__import__`.
+ *level* specifies whether to use absolute or relative imports. ``0``
+ means only perform absolute imports. Positive values for *level* indicate the
+ number of parent directories to search relative to the directory of the
+ module calling :func:`__import__`. Negative values attempt both an implicit
+ relative import and an absolute import (usage of negative values for *level*
+ are strongly discouraged as future versions of Python do not support such
+ values). Import statements only use values of 0 or greater.
When the *name* variable is of the form ``package.module``, normally, the
top-level package (the name up till the first dot) is returned, *not* the
@@ -1617,11 +1495,11 @@ available. They are listed here in alphabetical order.
For example, the statement ``import spam`` results in bytecode resembling the
following code::
- spam = __import__('spam', globals(), locals(), [], -1)
+ spam = __import__('spam', globals(), locals(), [], 0)
The statement ``import spam.ham`` results in this call::
- spam = __import__('spam.ham', globals(), locals(), [], -1)
+ spam = __import__('spam.ham', globals(), locals(), [], 0)
Note how :func:`__import__` returns the toplevel module here because this is
the object that is bound to a name by the :keyword:`import` statement.
@@ -1629,7 +1507,7 @@ available. They are listed here in alphabetical order.
On the other hand, the statement ``from spam.ham import eggs, sausage as
saus`` results in ::
- _temp = __import__('spam.ham', globals(), locals(), ['eggs', 'sausage'], -1)
+ _temp = __import__('spam.ham', globals(), locals(), ['eggs', 'sausage'], 0)
eggs = _temp.eggs
saus = _temp.sausage
@@ -1641,88 +1519,12 @@ available. They are listed here in alphabetical order.
use :func:`importlib.import_module`.
- .. versionchanged:: 2.5
- The level parameter was added.
-
- .. versionchanged:: 2.5
- Keyword support for parameters was added.
-
-.. ---------------------------------------------------------------------------
-
-
-.. _non-essential-built-in-funcs:
-
-Non-essential Built-in Functions
-================================
-
-There are several built-in functions that are no longer essential to learn, know
-or use in modern Python programming. They have been kept here to maintain
-backwards compatibility with programs written for older versions of Python.
-
-Python programmers, trainers, students and book writers should feel free to
-bypass these functions without concerns about missing something important.
-
-
-.. function:: apply(function, args[, keywords])
-
- The *function* argument must be a callable object (a user-defined or built-in
- function or method, or a class object) and the *args* argument must be a
- sequence. The *function* is called with *args* as the argument list; the number
- of arguments is the length of the tuple. If the optional *keywords* argument is
- present, it must be a dictionary whose keys are strings. It specifies keyword
- arguments to be added to the end of the argument list. Calling :func:`apply` is
- different from just calling ``function(args)``, since in that case there is
- always exactly one argument. The use of :func:`apply` is equivalent to
- ``function(*args, **keywords)``.
-
- .. deprecated:: 2.3
- Use ``function(*args, **keywords)`` instead of
- ``apply(function, args, keywords)`` (see :ref:`tut-unpacking-arguments`).
-
-
-.. function:: buffer(object[, offset[, size]])
-
- The *object* argument must be an object that supports the buffer call interface
- (such as strings, arrays, and buffers). A new buffer object will be created
- which references the *object* argument. The buffer object will be a slice from
- the beginning of *object* (or from the specified *offset*). The slice will
- extend to the end of *object* (or will have a length given by the *size*
- argument).
-
-
-.. function:: coerce(x, y)
-
- Return a tuple consisting of the two numeric arguments converted to a common
- type, using the same rules as used by arithmetic operations. If coercion is not
- possible, raise :exc:`TypeError`.
-
-
-.. function:: intern(string)
-
- Enter *string* in the table of "interned" strings and return the interned string
- -- which is *string* itself or a copy. Interning strings is useful to gain a
- little performance on dictionary lookup -- if the keys in a dictionary are
- interned, and the lookup key is interned, the key comparisons (after hashing)
- can be done by a pointer compare instead of a string compare. Normally, the
- names used in Python programs are automatically interned, and the dictionaries
- used to hold module, class or instance attributes have interned keys.
-
- .. versionchanged:: 2.3
- Interned strings are not immortal (like they used to be in Python 2.2 and
- before); you must keep a reference to the return value of :func:`intern` around
- to benefit from it.
-
.. rubric:: Footnotes
-.. [#] It is used relatively rarely so does not warrant being made into a statement.
-
-.. [#] Specifying a buffer size currently has no effect on systems that don't have
- :c:func:`setvbuf`. The interface to specify the buffer size is not done using a
- method that calls :c:func:`setvbuf`, because that may dump core when called after
- any I/O has been performed, and there's no reliable way to determine whether
- this is the case.
+.. [#] Note that the parser only accepts the Unix-style end of line convention.
+ If you are reading the code from a file, make sure to use newline conversion
+ mode to convert Windows or Mac-style newlines.
.. [#] In the current implementation, local variable bindings cannot normally be
affected this way, but variables retrieved from other scopes (such as modules)
can be. This may change.
-
diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst
index cc7ef34..04743d3 100644
--- a/Doc/library/functools.rst
+++ b/Doc/library/functools.rst
@@ -8,8 +8,6 @@
.. moduleauthor:: Nick Coghlan <ncoghlan@gmail.com>
.. sectionauthor:: Peter Harris <scav@blueyonder.co.uk>
-.. versionadded:: 2.5
-
**Source code:** :source:`Lib/functools.py`
--------------
@@ -20,28 +18,100 @@ function for the purposes of this module.
The :mod:`functools` module defines the following functions:
-.. function:: cmp_to_key(func)
+.. function:: cmp_to_key(func)
Transform an old-style comparison function to a key function. Used with
tools that accept key functions (such as :func:`sorted`, :func:`min`,
:func:`max`, :func:`heapq.nlargest`, :func:`heapq.nsmallest`,
:func:`itertools.groupby`). This function is primarily used as a transition
- tool for programs being converted to Python 3 where comparison functions are
- no longer supported.
+ tool for programs being converted from Python 2 which supported the use of
+ comparison functions.
A comparison function is any callable that accept two arguments, compares them,
and returns a negative number for less-than, zero for equality, or a positive
number for greater-than. A key function is a callable that accepts one
- argument and returns another value that indicates the position in the desired
+ argument and returns another value indicating the position in the desired
collation sequence.
Example::
sorted(iterable, key=cmp_to_key(locale.strcoll)) # locale-aware sort order
- .. versionadded:: 2.7
+ .. versionadded:: 3.2
+
+
+.. decorator:: lru_cache(maxsize=100)
+
+ Decorator to wrap a function with a memoizing callable that saves up to the
+ *maxsize* most recent calls. It can save time when an expensive or I/O bound
+ function is periodically called with the same arguments.
+
+ Since a dictionary is used to cache results, the positional and keyword
+ arguments to the function must be hashable.
+
+ If *maxsize* is set to None, the LRU feature is disabled and the cache
+ can grow without bound.
+
+ To help measure the effectiveness of the cache and tune the *maxsize*
+ parameter, the wrapped function is instrumented with a :func:`cache_info`
+ function that returns a :term:`named tuple` showing *hits*, *misses*,
+ *maxsize* and *currsize*. In a multi-threaded environment, the hits
+ and misses are approximate.
+
+ The decorator also provides a :func:`cache_clear` function for clearing or
+ invalidating the cache.
+
+ The original underlying function is accessible through the
+ :attr:`__wrapped__` attribute. This is useful for introspection, for
+ bypassing the cache, or for rewrapping the function with a different cache.
+
+ An `LRU (least recently used) cache
+ <http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used>`_ works
+ best when more recent calls are the best predictors of upcoming calls (for
+ example, the most popular articles on a news server tend to change daily).
+ The cache's size limit assures that the cache does not grow without bound on
+ long-running processes such as web servers.
+
+ Example of an LRU cache for static web content::
+
+ @lru_cache(maxsize=20)
+ def get_pep(num):
+ 'Retrieve text of a Python Enhancement Proposal'
+ resource = 'http://www.python.org/dev/peps/pep-%04d/' % num
+ try:
+ with urllib.request.urlopen(resource) as s:
+ return s.read()
+ except urllib.error.HTTPError:
+ return 'Not Found'
+
+ >>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
+ ... pep = get_pep(n)
+ ... print(n, len(pep))
+
+ >>> print(get_pep.cache_info())
+ CacheInfo(hits=3, misses=8, maxsize=20, currsize=8)
+
+ Example of efficiently computing
+ `Fibonacci numbers <http://en.wikipedia.org/wiki/Fibonacci_number>`_
+ using a cache to implement a
+ `dynamic programming <http://en.wikipedia.org/wiki/Dynamic_programming>`_
+ technique::
+
+ @lru_cache(maxsize=None)
+ def fib(n):
+ if n < 2:
+ return n
+ return fib(n-1) + fib(n-2)
-.. function:: total_ordering(cls)
+ >>> print([fib(n) for n in range(16)])
+ [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
+
+ >>> print(fib.cache_info())
+ CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)
+
+ .. versionadded:: 3.2
+
+.. decorator:: total_ordering
Given a class defining one or more rich comparison ordering methods, this
class decorator supplies the rest. This simplifies the effort involved
@@ -62,17 +132,10 @@ The :mod:`functools` module defines the following functions:
return ((self.lastname.lower(), self.firstname.lower()) <
(other.lastname.lower(), other.firstname.lower()))
- .. versionadded:: 2.7
-
-.. function:: reduce(function, iterable[, initializer])
-
- This is the same function as :func:`reduce`. It is made available in this module
- to allow writing code more forward-compatible with Python 3.
+ .. versionadded:: 3.2
- .. versionadded:: 2.6
-
-.. function:: partial(func[,*args][, **keywords])
+.. function:: partial(func, *args, **keywords)
Return a new :class:`partial` object which when called will behave like *func*
called with the positional arguments *args* and keyword arguments *keywords*. If
@@ -103,7 +166,19 @@ The :mod:`functools` module defines the following functions:
18
-.. function:: update_wrapper(wrapper, wrapped[, assigned][, updated])
+.. function:: reduce(function, iterable[, initializer])
+
+ Apply *function* of two arguments cumulatively to the items of *sequence*, from
+ left to right, so as to reduce the sequence to a single value. For example,
+ ``reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])`` calculates ``((((1+2)+3)+4)+5)``.
+ The left argument, *x*, is the accumulated value and the right argument, *y*, is
+ the update value from the *sequence*. If the optional *initializer* is present,
+ it is placed before the items of the sequence in the calculation, and serves as
+ a default when the sequence is empty. If *initializer* is not given and
+ *sequence* contains only one item, the first item is returned.
+
+
+.. function:: update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
Update a *wrapper* function to look like the *wrapped* function. The optional
arguments are tuples to specify which attributes of the original function are
@@ -111,9 +186,14 @@ The :mod:`functools` module defines the following functions:
attributes of the wrapper function are updated with the corresponding attributes
from the original function. The default values for these arguments are the
module level constants *WRAPPER_ASSIGNMENTS* (which assigns to the wrapper
- function's *__name__*, *__module__* and *__doc__*, the documentation string) and
- *WRAPPER_UPDATES* (which updates the wrapper function's *__dict__*, i.e. the
- instance dictionary).
+ function's *__name__*, *__module__*, *__annotations__* and *__doc__*, the
+ documentation string) and *WRAPPER_UPDATES* (which updates the wrapper
+ function's *__dict__*, i.e. the instance dictionary).
+
+ To allow access to the original function for introspection and other purposes
+ (e.g. bypassing a caching decorator such as :func:`lru_cache`), this function
+ automatically adds a __wrapped__ attribute to the wrapper that refers to
+ the original function.
The main intended use for this function is in :term:`decorator` functions which
wrap the decorated function and return the wrapper. If the wrapper function is
@@ -121,8 +201,23 @@ The :mod:`functools` module defines the following functions:
definition rather than the original function definition, which is typically less
than helpful.
+ :func:`update_wrapper` may be used with callables other than functions. Any
+ attributes named in *assigned* or *updated* that are missing from the object
+ being wrapped are ignored (i.e. this function will not attempt to set them
+ on the wrapper function). :exc:`AttributeError` is still raised if the
+ wrapper function itself is missing any attributes named in *updated*.
+
+ .. versionadded:: 3.2
+ Automatic addition of the ``__wrapped__`` attribute.
+
+ .. versionadded:: 3.2
+ Copying of the ``__annotations__`` attribute by default.
+
+ .. versionchanged:: 3.2
+ Missing attributes no longer trigger an :exc:`AttributeError`.
+
-.. function:: wraps(wrapped[, assigned][, updated])
+.. decorator:: wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
This is a convenience function for invoking ``partial(update_wrapper,
wrapped=wrapped, assigned=assigned, updated=updated)`` as a function decorator
@@ -132,14 +227,14 @@ The :mod:`functools` module defines the following functions:
>>> def my_decorator(f):
... @wraps(f)
... def wrapper(*args, **kwds):
- ... print 'Calling decorated function'
+ ... print('Calling decorated function')
... return f(*args, **kwds)
... return wrapper
...
>>> @my_decorator
... def example():
... """Docstring"""
- ... print 'Called example function'
+ ... print('Called example function')
...
>>> example()
Calling decorated function
diff --git a/Doc/library/future_builtins.rst b/Doc/library/future_builtins.rst
deleted file mode 100644
index 04f2052..0000000
--- a/Doc/library/future_builtins.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-:mod:`future_builtins` --- Python 3 builtins
-============================================
-
-.. module:: future_builtins
-.. sectionauthor:: Georg Brandl
-.. versionadded:: 2.6
-
-This module provides functions that exist in 2.x, but have different behavior in
-Python 3, so they cannot be put into the 2.x builtins namespace.
-
-Instead, if you want to write code compatible with Python 3 builtins, import
-them from this module, like this::
-
- from future_builtins import map, filter
-
- ... code using Python 3-style map and filter ...
-
-The :term:`2to3` tool that ports Python 2 code to Python 3 will recognize
-this usage and leave the new builtins alone.
-
-.. note::
-
- The Python 3 :func:`print` function is already in the builtins, but cannot be
- accessed from Python 2 code unless you use the appropriate future statement::
-
- from __future__ import print_function
-
-
-Available builtins are:
-
-.. function:: ascii(object)
-
- Returns the same as :func:`repr`. In Python 3, :func:`repr` will return
- printable Unicode characters unescaped, while :func:`ascii` will always
- backslash-escape them. Using :func:`future_builtins.ascii` instead of
- :func:`repr` in 2.6 code makes it clear that you need a pure ASCII return
- value.
-
-.. function:: filter(function, iterable)
-
- Works like :func:`itertools.ifilter`.
-
-.. function:: hex(object)
-
- Works like the built-in :func:`hex`, but instead of :meth:`__hex__` it will
- use the :meth:`__index__` method on its argument to get an integer that is
- then converted to hexadecimal.
-
-.. function:: map(function, iterable, ...)
-
- Works like :func:`itertools.imap`.
-
-.. function:: oct(object)
-
- Works like the built-in :func:`oct`, but instead of :meth:`__oct__` it will
- use the :meth:`__index__` method on its argument to get an integer that is
- then converted to octal.
-
-.. function:: zip(*iterables)
-
- Works like :func:`itertools.izip`.
diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst
index 80a2d92..0281bb7 100644
--- a/Doc/library/gc.rst
+++ b/Doc/library/gc.rst
@@ -1,4 +1,3 @@
-
:mod:`gc` --- Garbage Collector interface
=========================================
@@ -37,21 +36,17 @@ The :mod:`gc` module provides the following functions:
Returns true if automatic collection is enabled.
-.. function:: collect([generation])
+.. function:: collect(generations=2)
With no arguments, run a full collection. The optional argument *generation*
may be an integer specifying which generation to collect (from 0 to 2). A
:exc:`ValueError` is raised if the generation number is invalid. The number of
unreachable objects found is returned.
- .. versionchanged:: 2.5
- The optional *generation* argument was added.
-
- .. versionchanged:: 2.6
- The free lists maintained for a number of built-in types are cleared
- whenever a full collection or collection of the highest generation (2)
- is run. Not all items in some free lists may be freed due to the
- particular implementation, in particular :class:`int` and :class:`float`.
+ The free lists maintained for a number of built-in types are cleared
+ whenever a full collection or collection of the highest generation (2)
+ is run. Not all items in some free lists may be freed due to the
+ particular implementation, in particular :class:`float`.
.. function:: set_debug(flags)
@@ -71,8 +66,6 @@ The :mod:`gc` module provides the following functions:
Returns a list of all objects tracked by the collector, excluding the list
returned.
- .. versionadded:: 2.2
-
.. function:: set_threshold(threshold0[, threshold1[, threshold2]])
@@ -99,8 +92,6 @@ The :mod:`gc` module provides the following functions:
Return the current collection counts as a tuple of ``(count0, count1,
count2)``.
- .. versionadded:: 2.5
-
.. function:: get_threshold()
@@ -125,8 +116,6 @@ The :mod:`gc` module provides the following functions:
invalid state. Avoid using :func:`get_referrers` for any purpose other than
debugging.
- .. versionadded:: 2.2
-
.. function:: get_referents(*objs)
@@ -138,7 +127,6 @@ The :mod:`gc` module provides the following functions:
be involved in a cycle. So, for example, if an integer is directly reachable
from an argument, that integer object may or may not appear in the result list.
- .. versionadded:: 2.3
.. function:: is_tracked(obj)
@@ -162,18 +150,17 @@ The :mod:`gc` module provides the following functions:
>>> gc.is_tracked({"a": []})
True
- .. versionadded:: 2.7
+ .. versionadded:: 3.1
The following variable is provided for read-only access (you can mutate its
value but should not rebind it):
-
.. data:: garbage
A list of objects which the collector found to be unreachable but could not be
freed (uncollectable objects). By default, this list contains only objects with
- :meth:`__del__` methods. [#]_ Objects that have :meth:`__del__` methods and are
+ :meth:`__del__` methods. Objects that have :meth:`__del__` methods and are
part of a reference cycle cause the entire reference cycle to be uncollectable,
including objects not necessarily in the cycle but reachable only from it.
Python doesn't collect such cycles automatically because, in general, it isn't
@@ -187,8 +174,15 @@ value but should not rebind it):
with :meth:`__del__` methods, and *garbage* can be examined in that case to
verify that no such cycles are being created.
- If :const:`DEBUG_SAVEALL` is set, then all unreachable objects will be added to
- this list rather than freed.
+ If :const:`DEBUG_SAVEALL` is set, then all unreachable objects will be added
+ to this list rather than freed.
+
+ .. versionchanged:: 3.2
+ If this list is non-empty at interpreter shutdown, a
+ :exc:`ResourceWarning` is emitted, which is silent by default. If
+ :const:`DEBUG_UNCOLLECTABLE` is set, in addition all uncollectable objects
+ are printed.
+
The following constants are provided for use with :func:`set_debug`:
@@ -207,21 +201,12 @@ The following constants are provided for use with :func:`set_debug`:
.. data:: DEBUG_UNCOLLECTABLE
Print information of uncollectable objects found (objects which are not
- reachable but cannot be freed by the collector). These objects will be added to
- the ``garbage`` list.
-
-
-.. data:: DEBUG_INSTANCES
-
- When :const:`DEBUG_COLLECTABLE` or :const:`DEBUG_UNCOLLECTABLE` is set, print
- information about instance objects found.
-
-
-.. data:: DEBUG_OBJECTS
-
- When :const:`DEBUG_COLLECTABLE` or :const:`DEBUG_UNCOLLECTABLE` is set, print
- information about objects other than instance objects found.
+ reachable but cannot be freed by the collector). These objects will be added
+ to the ``garbage`` list.
+ .. versionchanged:: 3.2
+ Also print the contents of the :data:`garbage` list at interpreter
+ shutdown, if it isn't empty.
.. data:: DEBUG_SAVEALL
@@ -233,10 +218,4 @@ The following constants are provided for use with :func:`set_debug`:
The debugging flags necessary for the collector to print information about a
leaking program (equal to ``DEBUG_COLLECTABLE | DEBUG_UNCOLLECTABLE |
- DEBUG_INSTANCES | DEBUG_OBJECTS | DEBUG_SAVEALL``).
-
-.. rubric:: Footnotes
-
-.. [#] Prior to Python 2.2, the list contained all instance objects in unreachable
- cycles, not only those with :meth:`__del__` methods.
-
+ DEBUG_SAVEALL``).
diff --git a/Doc/library/gdbm.rst b/Doc/library/gdbm.rst
deleted file mode 100644
index 742c035..0000000
--- a/Doc/library/gdbm.rst
+++ /dev/null
@@ -1,126 +0,0 @@
-:mod:`gdbm` --- GNU's reinterpretation of dbm
-=============================================
-
-.. module:: gdbm
- :platform: Unix
- :synopsis: GNU's reinterpretation of dbm.
-
-.. note::
- The :mod:`gdbm` module has been renamed to :mod:`dbm.gnu` in Python 3. The
- :term:`2to3` tool will automatically adapt imports when converting your
- sources to Python 3.
-
-
-.. index:: module: dbm
-
-This module is quite similar to the :mod:`dbm` module, but uses ``gdbm`` instead
-to provide some additional functionality. Please note that the file formats
-created by ``gdbm`` and ``dbm`` are incompatible.
-
-The :mod:`gdbm` module provides an interface to the GNU DBM library. ``gdbm``
-objects behave like mappings (dictionaries), except that keys and values are
-always strings. Printing a ``gdbm`` object doesn't print the keys and values,
-and the :meth:`items` and :meth:`values` methods are not supported.
-
-The module defines the following constant and functions:
-
-
-.. exception:: error
-
- Raised on ``gdbm``\ -specific errors, such as I/O errors. :exc:`KeyError` is
- raised for general mapping errors like specifying an incorrect key.
-
-
-.. function:: open(filename, [flag, [mode]])
-
- Open a ``gdbm`` database and return a ``gdbm`` object. The *filename* argument
- is the name of the database file.
-
- The optional *flag* argument can be:
-
- +---------+-------------------------------------------+
- | Value | Meaning |
- +=========+===========================================+
- | ``'r'`` | Open existing database for reading only |
- | | (default) |
- +---------+-------------------------------------------+
- | ``'w'`` | Open existing database for reading and |
- | | writing |
- +---------+-------------------------------------------+
- | ``'c'`` | Open database for reading and writing, |
- | | creating it if it doesn't exist |
- +---------+-------------------------------------------+
- | ``'n'`` | Always create a new, empty database, open |
- | | for reading and writing |
- +---------+-------------------------------------------+
-
- The following additional characters may be appended to the flag to control
- how the database is opened:
-
- +---------+--------------------------------------------+
- | Value | Meaning |
- +=========+============================================+
- | ``'f'`` | Open the database in fast mode. Writes |
- | | to the database will not be synchronized. |
- +---------+--------------------------------------------+
- | ``'s'`` | Synchronized mode. This will cause changes |
- | | to the database to be immediately written |
- | | to the file. |
- +---------+--------------------------------------------+
- | ``'u'`` | Do not lock database. |
- +---------+--------------------------------------------+
-
- Not all flags are valid for all versions of ``gdbm``. The module constant
- :const:`open_flags` is a string of supported flag characters. The exception
- :exc:`error` is raised if an invalid flag is specified.
-
- The optional *mode* argument is the Unix mode of the file, used only when the
- database has to be created. It defaults to octal ``0666``.
-
-In addition to the dictionary-like methods, ``gdbm`` objects have the following
-methods:
-
-
-.. function:: firstkey()
-
- It's possible to loop over every key in the database using this method and the
- :meth:`nextkey` method. The traversal is ordered by ``gdbm``'s internal hash
- values, and won't be sorted by the key values. This method returns the starting
- key.
-
-
-.. function:: nextkey(key)
-
- Returns the key that follows *key* in the traversal. The following code prints
- every key in the database ``db``, without having to create a list in memory that
- contains them all::
-
- k = db.firstkey()
- while k != None:
- print k
- k = db.nextkey(k)
-
-
-.. function:: reorganize()
-
- If you have carried out a lot of deletions and would like to shrink the space
- used by the ``gdbm`` file, this routine will reorganize the database. ``gdbm``
- will not shorten the length of a database file except by using this
- reorganization; otherwise, deleted file space will be kept and reused as new
- (key, value) pairs are added.
-
-
-.. function:: sync()
-
- When the database has been opened in fast mode, this method forces any
- unwritten data to be written to the disk.
-
-
-.. seealso::
-
- Module :mod:`anydbm`
- Generic interface to ``dbm``\ -style databases.
-
- Module :mod:`whichdb`
- Utility module used to determine the type of an existing database.
-
diff --git a/Doc/library/gensuitemodule.rst b/Doc/library/gensuitemodule.rst
deleted file mode 100644
index dbbc3a0..0000000
--- a/Doc/library/gensuitemodule.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-
-:mod:`gensuitemodule` --- Generate OSA stub packages
-====================================================
-
-.. module:: gensuitemodule
- :platform: Mac
- :synopsis: Create a stub package from an OSA dictionary
-.. sectionauthor:: Jack Jansen <Jack.Jansen@cwi.nl>
-.. moduleauthor:: Jack Jansen
-
-The :mod:`gensuitemodule` module creates a Python package implementing stub code
-for the AppleScript suites that are implemented by a specific application,
-according to its AppleScript dictionary.
-
-It is usually invoked by the user through the :program:`PythonIDE`, but it can
-also be run as a script from the command line (pass :option:`--help` for help on
-the options) or imported from Python code. For an example of its use see
-:file:`Mac/scripts/genallsuites.py` in a source distribution, which generates
-the stub packages that are included in the standard library.
-
-It defines the following public functions:
-
-
-.. function:: is_scriptable(application)
-
- Returns true if ``application``, which should be passed as a pathname, appears
- to be scriptable. Take the return value with a grain of salt: :program:`Internet
- Explorer` appears not to be scriptable but definitely is.
-
-
-.. function:: processfile(application[, output, basepkgname, edit_modnames, creatorsignature, dump, verbose])
-
- Create a stub package for ``application``, which should be passed as a full
- pathname. For a :file:`.app` bundle this is the pathname to the bundle, not to
- the executable inside the bundle; for an unbundled CFM application you pass the
- filename of the application binary.
-
- This function asks the application for its OSA terminology resources, decodes
- these resources and uses the resultant data to create the Python code for the
- package implementing the client stubs.
-
- ``output`` is the pathname where the resulting package is stored, if not
- specified a standard "save file as" dialog is presented to the user.
- ``basepkgname`` is the base package on which this package will build, and
- defaults to :mod:`StdSuites`. Only when generating :mod:`StdSuites` itself do
- you need to specify this. ``edit_modnames`` is a dictionary that can be used to
- change modulenames that are too ugly after name mangling. ``creator_signature``
- can be used to override the 4-char creator code, which is normally obtained from
- the :file:`PkgInfo` file in the package or from the CFM file creator signature.
- When ``dump`` is given it should refer to a file object, and ``processfile``
- will stop after decoding the resources and dump the Python representation of the
- terminology resources to this file. ``verbose`` should also be a file object,
- and specifying it will cause ``processfile`` to tell you what it is doing.
-
-
-.. function:: processfile_fromresource(application[, output, basepkgname, edit_modnames, creatorsignature, dump, verbose])
-
- This function does the same as ``processfile``, except that it uses a different
- method to get the terminology resources. It opens ``application`` as a resource
- file and reads all ``"aete"`` and ``"aeut"`` resources from this file.
-
diff --git a/Doc/library/getopt.rst b/Doc/library/getopt.rst
index b454814..b6ab3df 100644
--- a/Doc/library/getopt.rst
+++ b/Doc/library/getopt.rst
@@ -2,8 +2,8 @@
=========================================================
.. module:: getopt
- :synopsis: Portable parser for command line options; support both short and long option
- names.
+ :synopsis: Portable parser for command line options; support both short and
+ long option names.
**Source code:** :source:`Lib/getopt.py`
@@ -26,11 +26,11 @@ This module provides two functions and an
exception:
-.. function:: getopt(args, options[, long_options])
+.. function:: getopt(args, shortopts, longopts=[])
Parses command line options and parameter list. *args* is the argument list to
be parsed, without the leading reference to the running program. Typically, this
- means ``sys.argv[1:]``. *options* is the string of option letters that the
+ means ``sys.argv[1:]``. *shortopts* is the string of option letters that the
script wants to recognize, with options that require an argument followed by a
colon (``':'``; i.e., the same format that Unix :c:func:`getopt` uses).
@@ -40,16 +40,16 @@ exception:
arguments are considered also non-options. This is similar to the way
non-GNU Unix systems work.
- *long_options*, if specified, must be a list of strings with the names of the
- long options which should be supported. The leading ``'--'``
- characters should not be included in the option name. Long options which
- require an argument should be followed by an equal sign (``'='``). Optional
- arguments are not supported. To accept only long options, *options* should
- be an empty string. Long options on the command line can be recognized so
- long as they provide a prefix of the option name that matches exactly one of
- the accepted options. For example, if *long_options* is ``['foo', 'frob']``,
- the option ``--fo`` will match as ``--foo``, but ``--f``
- will not match uniquely, so :exc:`GetoptError` will be raised.
+ *longopts*, if specified, must be a list of strings with the names of the
+ long options which should be supported. The leading ``'--'`` characters
+ should not be included in the option name. Long options which require an
+ argument should be followed by an equal sign (``'='``). Optional arguments
+ are not supported. To accept only long options, *shortopts* should be an
+ empty string. Long options on the command line can be recognized so long as
+ they provide a prefix of the option name that matches exactly one of the
+ accepted options. For example, if *longopts* is ``['foo', 'frob']``, the
+ option ``--fo`` will match as ``--foo``, but ``--f`` will
+ not match uniquely, so :exc:`GetoptError` will be raised.
The return value consists of two elements: the first is a list of ``(option,
value)`` pairs; the second is the list of program arguments left after the
@@ -62,7 +62,7 @@ exception:
allowing multiple occurrences. Long and short options may be mixed.
-.. function:: gnu_getopt(args, options[, long_options])
+.. function:: gnu_getopt(args, shortopts, longopts=[])
This function works like :func:`getopt`, except that GNU style scanning mode is
used by default. This means that option and non-option arguments may be
@@ -73,8 +73,6 @@ exception:
variable :envvar:`POSIXLY_CORRECT` is set, then option processing stops as
soon as a non-option argument is encountered.
- .. versionadded:: 2.3
-
.. exception:: GetoptError
@@ -86,10 +84,7 @@ exception:
related option; if there is no specific option to which the exception relates,
:attr:`opt` is an empty string.
- .. versionchanged:: 1.6
- Introduced :exc:`GetoptError` as a synonym for :exc:`error`.
-
-
+.. XXX deprecated?
.. exception:: error
Alias for :exc:`GetoptError`; for backward compatibility.
@@ -128,7 +123,7 @@ In a script, typical usage is something like this::
opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
except getopt.GetoptError as err:
# print help information and exit:
- print str(err) # will print something like "option -a not recognized"
+ print(err) # will print something like "option -a not recognized"
usage()
sys.exit(2)
output = None
diff --git a/Doc/library/getpass.rst b/Doc/library/getpass.rst
index 02c3fd8..ffe2b12 100644
--- a/Doc/library/getpass.rst
+++ b/Doc/library/getpass.rst
@@ -10,13 +10,13 @@
The :mod:`getpass` module provides two functions:
-.. function:: getpass([prompt[, stream]])
+.. function:: getpass(prompt='Password: ', stream=None)
- Prompt the user for a password without echoing. The user is prompted using the
- string *prompt*, which defaults to ``'Password: '``. On Unix, the prompt is
- written to the file-like object *stream*. *stream* defaults to the
- controlling terminal (/dev/tty) or if that is unavailable to ``sys.stderr``
- (this argument is ignored on Windows).
+ Prompt the user for a password without echoing. The user is prompted using
+ the string *prompt*, which defaults to ``'Password: '``. On Unix, the prompt
+ is written to the file-like object *stream*. *stream* defaults to the
+ controlling terminal (:file:`/dev/tty`) or if that is unavailable to
+ ``sys.stderr`` (this argument is ignored on Windows).
If echo free input is unavailable getpass() falls back to printing
a warning message to *stream* and reading from ``sys.stdin`` and
@@ -24,16 +24,10 @@ The :mod:`getpass` module provides two functions:
Availability: Macintosh, Unix, Windows.
- .. versionchanged:: 2.5
- The *stream* parameter was added.
- .. versionchanged:: 2.6
- On Unix it defaults to using /dev/tty before falling back
- to ``sys.stdin`` and ``sys.stderr``.
.. note::
If you call getpass from within IDLE, the input may be done in the
terminal you launched IDLE from rather than the idle window itself.
-
.. exception:: GetPassWarning
A :exc:`UserWarning` subclass issued when password input may be echoed.
diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst
index 9b4eb0c..0fa022c 100644
--- a/Doc/library/gettext.rst
+++ b/Doc/library/gettext.rst
@@ -33,7 +33,7 @@ application needs to switch languages on the fly, you probably want to use the
class-based API instead.
-.. function:: bindtextdomain(domain[, localedir])
+.. function:: bindtextdomain(domain, localedir=None)
Bind the *domain* to the locale directory *localedir*. More concretely,
:mod:`gettext` will look for binary :file:`.mo` files for the given domain using
@@ -45,16 +45,14 @@ class-based API instead.
returned. [#]_
-.. function:: bind_textdomain_codeset(domain[, codeset])
+.. function:: bind_textdomain_codeset(domain, codeset=None)
Bind the *domain* to *codeset*, changing the encoding of strings returned by the
:func:`gettext` family of functions. If *codeset* is omitted, then the current
binding is returned.
- .. versionadded:: 2.4
-
-.. function:: textdomain([domain])
+.. function:: textdomain(domain=None)
Change or query the current global domain. If *domain* is ``None``, then the
current global domain is returned, otherwise the global domain is set to
@@ -70,12 +68,10 @@ class-based API instead.
.. function:: lgettext(message)
- Equivalent to :func:`gettext`, but the translation is returned in the preferred
- system encoding, if no other encoding was explicitly set with
+ Equivalent to :func:`gettext`, but the translation is returned in the
+ preferred system encoding, if no other encoding was explicitly set with
:func:`bind_textdomain_codeset`.
- .. versionadded:: 2.4
-
.. function:: dgettext(domain, message)
@@ -84,12 +80,10 @@ class-based API instead.
.. function:: ldgettext(domain, message)
- Equivalent to :func:`dgettext`, but the translation is returned in the preferred
- system encoding, if no other encoding was explicitly set with
+ Equivalent to :func:`dgettext`, but the translation is returned in the
+ preferred system encoding, if no other encoding was explicitly set with
:func:`bind_textdomain_codeset`.
- .. versionadded:: 2.4
-
.. function:: ngettext(singular, plural, n)
@@ -104,24 +98,18 @@ class-based API instead.
syntax to be used in :file:`.po` files and the formulas for a variety of
languages.
- .. versionadded:: 2.3
-
.. function:: lngettext(singular, plural, n)
- Equivalent to :func:`ngettext`, but the translation is returned in the preferred
- system encoding, if no other encoding was explicitly set with
+ Equivalent to :func:`ngettext`, but the translation is returned in the
+ preferred system encoding, if no other encoding was explicitly set with
:func:`bind_textdomain_codeset`.
- .. versionadded:: 2.4
-
.. function:: dngettext(domain, singular, plural, n)
Like :func:`ngettext`, but look the message up in the specified *domain*.
- .. versionadded:: 2.3
-
.. function:: ldngettext(domain, singular, plural, n)
@@ -129,7 +117,6 @@ class-based API instead.
preferred system encoding, if no other encoding was explicitly set with
:func:`bind_textdomain_codeset`.
- .. versionadded:: 2.4
Note that GNU :program:`gettext` also defines a :func:`dcgettext` method, but
this was deemed not useful and so it is currently unimplemented.
@@ -141,7 +128,7 @@ Here's an example of typical usage for this API::
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
- print _('This is a translatable string.')
+ print(_('This is a translatable string.'))
Class-based API
@@ -151,12 +138,12 @@ The class-based API of the :mod:`gettext` module gives you more flexibility and
greater convenience than the GNU :program:`gettext` API. It is the recommended
way of localizing your Python applications and modules. :mod:`gettext` defines
a "translations" class which implements the parsing of GNU :file:`.mo` format
-files, and has methods for returning either standard 8-bit strings or Unicode
-strings. Instances of this "translations" class can also install themselves in
-the built-in namespace as the function :func:`_`.
+files, and has methods for returning strings. Instances of this "translations"
+class can also install themselves in the built-in namespace as the function
+:func:`_`.
-.. function:: find(domain[, localedir[, languages[, all]]])
+.. function:: find(domain, localedir=None, languages=None, all=False)
This function implements the standard :file:`.mo` file search algorithm. It
takes a *domain*, identical to what :func:`textdomain` takes. Optional
@@ -174,7 +161,7 @@ the built-in namespace as the function :func:`_`.
:func:`find` then expands and normalizes the languages, and then iterates
through them, searching for an existing file built of these components:
- :file:`localedir/language/LC_MESSAGES/domain.mo`
+ :file:`{localedir}/{language}/LC_MESSAGES/{domain}.mo`
The first such file name that exists is returned by :func:`find`. If no such
file is found, then ``None`` is returned. If *all* is given, it returns a list
@@ -182,15 +169,16 @@ the built-in namespace as the function :func:`_`.
the environment variables.
-.. function:: translation(domain[, localedir[, languages[, class_[, fallback[, codeset]]]]])
+.. function:: translation(domain, localedir=None, languages=None, class_=None, fallback=False, codeset=None)
- Return a :class:`Translations` instance based on the *domain*, *localedir*, and
- *languages*, which are first passed to :func:`find` to get a list of the
+ Return a :class:`Translations` instance based on the *domain*, *localedir*,
+ and *languages*, which are first passed to :func:`find` to get a list of the
associated :file:`.mo` file paths. Instances with identical :file:`.mo` file
- names are cached. The actual class instantiated is either *class_* if provided,
- otherwise :class:`GNUTranslations`. The class's constructor must take a single
- file object argument. If provided, *codeset* will change the charset used to
- encode translated strings.
+ names are cached. The actual class instantiated is either *class_* if
+ provided, otherwise :class:`GNUTranslations`. The class's constructor must
+ take a single :term:`file object` argument. If provided, *codeset* will change
+ the charset used to encode translated strings in the :meth:`lgettext` and
+ :meth:`lngettext` methods.
If multiple files are found, later files are used as fallbacks for earlier ones.
To allow setting the fallback, :func:`copy.copy` is used to clone each
@@ -201,16 +189,12 @@ the built-in namespace as the function :func:`_`.
*fallback* is false (which is the default), and returns a
:class:`NullTranslations` instance if *fallback* is true.
- .. versionchanged:: 2.4
- Added the *codeset* parameter.
-
-.. function:: install(domain[, localedir[, unicode [, codeset[, names]]]])
+.. function:: install(domain, localedir=None, codeset=None, names=None)
This installs the function :func:`_` in Python's builtins namespace, based on
*domain*, *localedir*, and *codeset* which are passed to the function
- :func:`translation`. The *unicode* flag is passed to the resulting translation
- object's :meth:`~NullTranslations.install` method.
+ :func:`translation`.
For the *names* parameter, please see the description of the translation
object's :meth:`~NullTranslations.install` method.
@@ -219,18 +203,12 @@ the built-in namespace as the function :func:`_`.
candidates for translation, by wrapping them in a call to the :func:`_`
function, like this::
- print _('This string will be translated.')
+ print(_('This string will be translated.'))
For convenience, you want the :func:`_` function to be installed in Python's
builtins namespace, so it is easily accessible in all modules of your
application.
- .. versionchanged:: 2.4
- Added the *codeset* parameter.
-
- .. versionchanged:: 2.5
- Added the *names* parameter.
-
The :class:`NullTranslations` class
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -242,15 +220,14 @@ interface you can use to write your own specialized translation classes. Here
are the methods of :class:`NullTranslations`:
-.. class:: NullTranslations([fp])
+.. class:: NullTranslations(fp=None)
- Takes an optional file object *fp*, which is ignored by the base class.
+ Takes an optional :term:`file object` *fp*, which is ignored by the base class.
Initializes "protected" instance variables *_info* and *_charset* which are set
by derived classes, as well as *_fallback*, which is set through
:meth:`add_fallback`. It then calls ``self._parse(fp)`` if *fp* is not
``None``.
-
.. method:: _parse(fp)
No-op'd in the base class, this method takes file object *fp*, and reads
@@ -261,59 +238,33 @@ are the methods of :class:`NullTranslations`:
.. method:: add_fallback(fallback)
- Add *fallback* as the fallback object for the current translation
- object. A translation object should consult the fallback if it cannot provide a
+ Add *fallback* as the fallback object for the current translation object.
+ A translation object should consult the fallback if it cannot provide a
translation for a given message.
.. method:: gettext(message)
- If a fallback has been set, forward :meth:`gettext` to the
- fallback. Otherwise, return the translated message. Overridden in derived
- classes.
+ If a fallback has been set, forward :meth:`gettext` to the fallback.
+ Otherwise, return the translated message. Overridden in derived classes.
.. method:: lgettext(message)
- If a fallback has been set, forward :meth:`lgettext` to the
- fallback. Otherwise, return the translated message. Overridden in derived
- classes.
-
- .. versionadded:: 2.4
-
-
- .. method:: ugettext(message)
-
- If a fallback has been set, forward :meth:`ugettext` to the
- fallback. Otherwise, return the translated message as a Unicode
- string. Overridden in derived classes.
+ If a fallback has been set, forward :meth:`lgettext` to the fallback.
+ Otherwise, return the translated message. Overridden in derived classes.
.. method:: ngettext(singular, plural, n)
- If a fallback has been set, forward :meth:`ngettext` to the
- fallback. Otherwise, return the translated message. Overridden in derived
- classes.
-
- .. versionadded:: 2.3
+ If a fallback has been set, forward :meth:`ngettext` to the fallback.
+ Otherwise, return the translated message. Overridden in derived classes.
.. method:: lngettext(singular, plural, n)
- If a fallback has been set, forward :meth:`lngettext` to the
- fallback. Otherwise, return the translated message. Overridden in derived
- classes.
-
- .. versionadded:: 2.4
-
-
- .. method:: ungettext(singular, plural, n)
-
- If a fallback has been set, forward :meth:`ungettext` to the fallback.
- Otherwise, return the translated message as a Unicode string. Overridden
- in derived classes.
-
- .. versionadded:: 2.3
+ If a fallback has been set, forward :meth:`lngettext` to the fallback.
+ Otherwise, return the translated message. Overridden in derived classes.
.. method:: info()
@@ -323,15 +274,15 @@ are the methods of :class:`NullTranslations`:
.. method:: charset()
- Return the "protected" :attr:`_charset` variable.
+ Return the "protected" :attr:`_charset` variable, which is the encoding of
+ the message catalog file.
.. method:: output_charset()
Return the "protected" :attr:`_output_charset` variable, which defines the
- encoding used to return translated messages.
-
- .. versionadded:: 2.4
+ encoding used to return translated messages in :meth:`lgettext` and
+ :meth:`lngettext`.
.. method:: set_output_charset(charset)
@@ -339,22 +290,17 @@ are the methods of :class:`NullTranslations`:
Change the "protected" :attr:`_output_charset` variable, which defines the
encoding used to return translated messages.
- .. versionadded:: 2.4
+ .. method:: install(names=None)
- .. method:: install([unicode [, names]])
-
- If the *unicode* flag is false, this method installs :meth:`self.gettext`
- into the built-in namespace, binding it to ``_``. If *unicode* is true,
- it binds :meth:`self.ugettext` instead. By default, *unicode* is false.
+ This method installs :meth:`self.gettext` into the built-in namespace,
+ binding it to ``_``.
If the *names* parameter is given, it must be a sequence containing the
names of functions you want to install in the builtins namespace in
addition to :func:`_`. Supported names are ``'gettext'`` (bound to
- :meth:`self.gettext` or :meth:`self.ugettext` according to the *unicode*
- flag), ``'ngettext'`` (bound to :meth:`self.ngettext` or
- :meth:`self.ungettext` according to the *unicode* flag), ``'lgettext'``
- and ``'lngettext'``.
+ :meth:`self.gettext`), ``'ngettext'`` (bound to :meth:`self.ngettext`),
+ ``'lgettext'`` and ``'lngettext'``.
Note that this is only one way, albeit the most convenient way, to make
the :func:`_` function available to your application. Because it affects
@@ -369,9 +315,6 @@ are the methods of :class:`NullTranslations`:
This puts :func:`_` only in the module's global namespace and so only
affects calls within this module.
- .. versionchanged:: 2.5
- Added the *names* parameter.
-
The :class:`GNUTranslations` class
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -379,8 +322,7 @@ The :class:`GNUTranslations` class
The :mod:`gettext` module provides one additional class derived from
:class:`NullTranslations`: :class:`GNUTranslations`. This class overrides
:meth:`_parse` to enable reading GNU :program:`gettext` format :file:`.mo` files
-in both big-endian and little-endian format. It also coerces both message ids
-and message strings to Unicode.
+in both big-endian and little-endian format.
:class:`GNUTranslations` parses optional meta-data out of the translation
catalog. It is convention with GNU :program:`gettext` to include meta-data as
@@ -390,12 +332,10 @@ key ``Content-Type`` is found, then the ``charset`` property is used to
initialize the "protected" :attr:`_charset` instance variable, defaulting to
``None`` if not found. If the charset encoding is specified, then all message
ids and message strings read from the catalog are converted to Unicode using
-this encoding. The :meth:`ugettext` method always returns a Unicode, while the
-:meth:`gettext` returns an encoded 8-bit string. For the message id arguments
-of both methods, either Unicode strings or 8-bit strings containing only
-US-ASCII characters are acceptable. Note that the Unicode version of the
-methods (i.e. :meth:`ugettext` and :meth:`ungettext`) are the recommended
-interface to use for internationalized Python programs.
+this encoding, else ASCII encoding is assumed.
+
+Since message ids are read as Unicode strings too, all :meth:`*gettext` methods
+will assume message ids as Unicode strings, not byte strings.
The entire set of key/value pairs are placed into a dictionary and set as the
"protected" :attr:`_info` instance variable.
@@ -410,73 +350,43 @@ The following methods are overridden from the base class implementation:
.. method:: GNUTranslations.gettext(message)
Look up the *message* id in the catalog and return the corresponding message
- string, as an 8-bit string encoded with the catalog's charset encoding, if
- known. If there is no entry in the catalog for the *message* id, and a fallback
- has been set, the look up is forwarded to the fallback's :meth:`gettext` method.
- Otherwise, the *message* id is returned.
+ string, as a Unicode string. If there is no entry in the catalog for the
+ *message* id, and a fallback has been set, the look up is forwarded to the
+ fallback's :meth:`gettext` method. Otherwise, the *message* id is returned.
.. method:: GNUTranslations.lgettext(message)
- Equivalent to :meth:`gettext`, but the translation is returned in the preferred
- system encoding, if no other encoding was explicitly set with
- :meth:`set_output_charset`.
-
- .. versionadded:: 2.4
-
-
-.. method:: GNUTranslations.ugettext(message)
-
- Look up the *message* id in the catalog and return the corresponding message
- string, as a Unicode string. If there is no entry in the catalog for the
- *message* id, and a fallback has been set, the look up is forwarded to the
- fallback's :meth:`ugettext` method. Otherwise, the *message* id is returned.
+ Equivalent to :meth:`gettext`, but the translation is returned as a
+ bytestring encoded in the selected output charset, or in the preferred system
+ encoding if no encoding was explicitly set with :meth:`set_output_charset`.
.. method:: GNUTranslations.ngettext(singular, plural, n)
Do a plural-forms lookup of a message id. *singular* is used as the message id
for purposes of lookup in the catalog, while *n* is used to determine which
- plural form to use. The returned message string is an 8-bit string encoded with
- the catalog's charset encoding, if known.
+ plural form to use. The returned message string is a Unicode string.
If the message id is not found in the catalog, and a fallback is specified, the
request is forwarded to the fallback's :meth:`ngettext` method. Otherwise, when
*n* is 1 *singular* is returned, and *plural* is returned in all other cases.
- .. versionadded:: 2.3
-
-
-.. method:: GNUTranslations.lngettext(singular, plural, n)
-
- Equivalent to :meth:`gettext`, but the translation is returned in the preferred
- system encoding, if no other encoding was explicitly set with
- :meth:`set_output_charset`.
-
- .. versionadded:: 2.4
-
-
-.. method:: GNUTranslations.ungettext(singular, plural, n)
-
- Do a plural-forms lookup of a message id. *singular* is used as the message id
- for purposes of lookup in the catalog, while *n* is used to determine which
- plural form to use. The returned message string is a Unicode string.
-
- If the message id is not found in the catalog, and a fallback is specified, the
- request is forwarded to the fallback's :meth:`ungettext` method. Otherwise,
- when *n* is 1 *singular* is returned, and *plural* is returned in all other
- cases.
-
Here is an example::
n = len(os.listdir('.'))
cat = GNUTranslations(somefile)
- message = cat.ungettext(
+ message = cat.ngettext(
'There is %(num)d file in this directory',
'There are %(num)d files in this directory',
n) % {'num': n}
- .. versionadded:: 2.3
+
+.. method:: GNUTranslations.lngettext(singular, plural, n)
+
+ Equivalent to :meth:`gettext`, but the translation is returned as a
+ bytestring encoded in the selected output charset, or in the preferred system
+ encoding if no encoding was explicitly set with :meth:`set_output_charset`.
Solaris message catalog support
@@ -498,7 +408,7 @@ version has a slightly different API. Its documented usage was::
import gettext
cat = gettext.Catalog(domain, localedir)
_ = cat.gettext
- print _('hello world')
+ print(_('hello world'))
For compatibility with this older module, the function :func:`Catalog` is an
alias for the :func:`translation` function described above.
@@ -589,13 +499,6 @@ module::
t = gettext.translation('spam', '/usr/share/locale')
_ = t.lgettext
-If your translators were providing you with Unicode strings in their :file:`.po`
-files, you'd instead do::
-
- import gettext
- t = gettext.translation('spam', '/usr/share/locale')
- _ = t.ugettext
-
Localizing your application
^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -611,11 +514,11 @@ driver file of your application::
import gettext
gettext.install('myapplication')
-If you need to set the locale directory or the *unicode* flag, you can pass
-these into the :func:`install` function::
+If you need to set the locale directory, you can pass these into the
+:func:`install` function::
import gettext
- gettext.install('myapplication', '/usr/share/locale', unicode=1)
+ gettext.install('myapplication', '/usr/share/locale')
Changing languages on the fly
@@ -655,7 +558,7 @@ translation until later. A classic example is::
'python', ]
# ...
for a in animals:
- print a
+ print(a)
Here, you want to mark the strings in the ``animals`` list as being
translatable, but you don't actually want to translate them until they are
@@ -675,7 +578,7 @@ Here is one way you can handle this situation::
# ...
for a in animals:
- print _(a)
+ print(_(a))
This works because the dummy definition of :func:`_` simply returns the string
unchanged. And this dummy definition will temporarily override any definition
@@ -698,7 +601,7 @@ Another way to handle this is with the following example::
# ...
for a in animals:
- print _(a)
+ print(_(a))
In this case, you are marking translatable strings with the function :func:`N_`,
[#]_ which won't conflict with any definition of :func:`_`. However, you will
@@ -707,21 +610,6 @@ marked with :func:`N_`. :program:`pygettext` and :program:`xpot` both support
this through the use of command line switches.
-:func:`gettext` vs. :func:`lgettext`
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-In Python 2.4 the :func:`lgettext` family of functions were introduced. The
-intention of these functions is to provide an alternative which is more
-compliant with the current implementation of GNU gettext. Unlike
-:func:`gettext`, which returns strings encoded with the same codeset used in the
-translation file, :func:`lgettext` will return strings encoded with the
-preferred system encoding, as returned by :func:`locale.getpreferredencoding`.
-Also notice that Python 2.4 introduces new functions to explicitly choose the
-codeset used in translated strings. If a codeset is explicitly set, even
-:func:`lgettext` will return translated strings in the requested codeset, as
-would be expected in the GNU gettext implementation.
-
-
Acknowledgements
----------------
diff --git a/Doc/library/gl.rst b/Doc/library/gl.rst
deleted file mode 100644
index 7ea9cf3..0000000
--- a/Doc/library/gl.rst
+++ /dev/null
@@ -1,193 +0,0 @@
-:mod:`gl` --- *Graphics Library* interface
-==========================================
-
-.. module:: gl
- :platform: IRIX
- :synopsis: Functions from the Silicon Graphics Graphics Library.
- :deprecated:
-
-
-.. deprecated:: 2.6
- The :mod:`gl` module has been removed in Python 3.
-
-
-This module provides access to the Silicon Graphics *Graphics Library*. It is
-available only on Silicon Graphics machines.
-
-.. warning::
-
- Some illegal calls to the GL library cause the Python interpreter to dump
- core. In particular, the use of most GL calls is unsafe before the first
- window is opened.
-
-The module is too large to document here in its entirety, but the following
-should help you to get started. The parameter conventions for the C functions
-are translated to Python as follows:
-
-* All (short, long, unsigned) int values are represented by Python integers.
-
-* All float and double values are represented by Python floating point numbers.
- In most cases, Python integers are also allowed.
-
-* All arrays are represented by one-dimensional Python lists. In most cases,
- tuples are also allowed.
-
-* All string and character arguments are represented by Python strings, for
- instance, ``winopen('Hi There!')`` and ``rotate(900, 'z')``.
-
-* All (short, long, unsigned) integer arguments or return values that are only
- used to specify the length of an array argument are omitted. For example, the C
- call ::
-
- lmdef(deftype, index, np, props)
-
- is translated to Python as ::
-
- lmdef(deftype, index, props)
-
-* Output arguments are omitted from the argument list; they are transmitted as
- function return values instead. If more than one value must be returned, the
- return value is a tuple. If the C function has both a regular return value (that
- is not omitted because of the previous rule) and an output argument, the return
- value comes first in the tuple. Examples: the C call ::
-
- getmcolor(i, &red, &green, &blue)
-
- is translated to Python as ::
-
- red, green, blue = getmcolor(i)
-
-The following functions are non-standard or have special argument conventions:
-
-
-.. function:: varray(argument)
-
- Equivalent to but faster than a number of ``v3d()`` calls. The *argument* is a
- list (or tuple) of points. Each point must be a tuple of coordinates ``(x, y,
- z)`` or ``(x, y)``. The points may be 2- or 3-dimensional but must all have the
- same dimension. Float and int values may be mixed however. The points are always
- converted to 3D double precision points by assuming ``z = 0.0`` if necessary (as
- indicated in the man page), and for each point ``v3d()`` is called.
-
- .. XXX the argument-argument added
-
-
-.. function:: nvarray()
-
- Equivalent to but faster than a number of ``n3f`` and ``v3f`` calls. The
- argument is an array (list or tuple) of pairs of normals and points. Each pair
- is a tuple of a point and a normal for that point. Each point or normal must be
- a tuple of coordinates ``(x, y, z)``. Three coordinates must be given. Float and
- int values may be mixed. For each pair, ``n3f()`` is called for the normal, and
- then ``v3f()`` is called for the point.
-
-
-.. function:: vnarray()
-
- Similar to ``nvarray()`` but the pairs have the point first and the normal
- second.
-
-
-.. function:: nurbssurface(s_k, t_k, ctl, s_ord, t_ord, type)
-
- Defines a nurbs surface. The dimensions of ``ctl[][]`` are computed as follows:
- ``[len(s_k) - s_ord]``, ``[len(t_k) - t_ord]``.
-
- .. XXX s_k[], t_k[], ctl[][]
-
-
-.. function:: nurbscurve(knots, ctlpoints, order, type)
-
- Defines a nurbs curve. The length of ctlpoints is ``len(knots) - order``.
-
-
-.. function:: pwlcurve(points, type)
-
- Defines a piecewise-linear curve. *points* is a list of points. *type* must be
- ``N_ST``.
-
-
-.. function:: pick(n)
- select(n)
-
- The only argument to these functions specifies the desired size of the pick or
- select buffer.
-
-
-.. function:: endpick()
- endselect()
-
- These functions have no arguments. They return a list of integers representing
- the used part of the pick/select buffer. No method is provided to detect buffer
- overrun.
-
-Here is a tiny but complete example GL program in Python::
-
- import gl, GL, time
-
- def main():
- gl.foreground()
- gl.prefposition(500, 900, 500, 900)
- w = gl.winopen('CrissCross')
- gl.ortho2(0.0, 400.0, 0.0, 400.0)
- gl.color(GL.WHITE)
- gl.clear()
- gl.color(GL.RED)
- gl.bgnline()
- gl.v2f(0.0, 0.0)
- gl.v2f(400.0, 400.0)
- gl.endline()
- gl.bgnline()
- gl.v2f(400.0, 0.0)
- gl.v2f(0.0, 400.0)
- gl.endline()
- time.sleep(5)
-
- main()
-
-
-.. seealso::
-
- `PyOpenGL: The Python OpenGL Binding <http://pyopengl.sourceforge.net/>`_
- .. index::
- single: OpenGL
- single: PyOpenGL
-
- An interface to OpenGL is also available; see information about the **PyOpenGL**
- project online at http://pyopengl.sourceforge.net/. This may be a better option
- if support for SGI hardware from before about 1996 is not required.
-
-
-:mod:`DEVICE` --- Constants used with the :mod:`gl` module
-==========================================================
-
-.. module:: DEVICE
- :platform: IRIX
- :synopsis: Constants used with the gl module.
- :deprecated:
-
-
-.. deprecated:: 2.6
- The :mod:`DEVICE` module has been removed in Python 3.
-
-
-This modules defines the constants used by the Silicon Graphics *Graphics
-Library* that C programmers find in the header file ``<gl/device.h>``. Read the
-module source file for details.
-
-
-:mod:`GL` --- Constants used with the :mod:`gl` module
-======================================================
-
-.. module:: GL
- :platform: IRIX
- :synopsis: Constants used with the gl module.
- :deprecated:
-
-
-.. deprecated:: 2.6
- The :mod:`GL` module has been removed in Python 3.
-
-This module contains constants used by the Silicon Graphics *Graphics Library*
-from the C header file ``<gl/gl.h>``. Read the module source file for details.
-
diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst
index b881a30..2584361 100644
--- a/Doc/library/glob.rst
+++ b/Doc/library/glob.rst
@@ -37,7 +37,6 @@ For example, ``'[?]'`` matches the character ``'?'``.
Return an :term:`iterator` which yields the same values as :func:`glob`
without actually storing them all simultaneously.
- .. versionadded:: 2.5
For example, consider a directory containing only the following files:
:file:`1.gif`, :file:`2.txt`, and :file:`card.gif`. :func:`glob` will produce
diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst
index f20a212..8882140 100644
--- a/Doc/library/grp.rst
+++ b/Doc/library/grp.rst
@@ -1,4 +1,3 @@
-
:mod:`grp` --- The group database
=================================
diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst
index 465510f..abbd018 100644
--- a/Doc/library/gzip.rst
+++ b/Doc/library/gzip.rst
@@ -13,10 +13,9 @@ like the GNU programs :program:`gzip` and :program:`gunzip` would.
The data compression is provided by the :mod:`zlib` module.
-The :mod:`gzip` module provides the :class:`GzipFile` class which is modeled
-after Python's File Object. The :class:`GzipFile` class reads and writes
-:program:`gzip`\ -format files, automatically compressing or decompressing the
-data so that it looks like an ordinary file object.
+The :mod:`gzip` module provides the :class:`GzipFile` class. The :class:`GzipFile`
+class reads and writes :program:`gzip`\ -format files, automatically compressing
+or decompressing the data so that it looks like an ordinary :term:`file object`.
Note that additional file formats which can be decompressed by the
:program:`gzip` and :program:`gunzip` programs, such as those produced by
@@ -25,12 +24,12 @@ Note that additional file formats which can be decompressed by the
The module defines the following items:
-.. class:: GzipFile([filename[, mode[, compresslevel[, fileobj[, mtime]]]]])
+.. class:: GzipFile(filename=None, mode=None, compresslevel=9, fileobj=None, mtime=None)
- Constructor for the :class:`GzipFile` class, which simulates most of the methods
- of a file object, with the exception of the :meth:`readinto` and
- :meth:`truncate` methods. At least one of *fileobj* and *filename* must be
- given a non-trivial value.
+ Constructor for the :class:`GzipFile` class, which simulates most of the
+ methods of a :term:`file object`, with the exception of the :meth:`truncate`
+ method. At least one of *fileobj* and *filename* must be given a non-trivial
+ value.
The new class instance is based on *fileobj*, which can be a regular file, a
:class:`StringIO` object, or any other object which simulates a file. It
@@ -45,9 +44,11 @@ The module defines the following items:
The *mode* argument can be any of ``'r'``, ``'rb'``, ``'a'``, ``'ab'``, ``'w'``,
or ``'wb'``, depending on whether the file will be read or written. The default
- is the mode of *fileobj* if discernible; otherwise, the default is ``'rb'``. If
- not given, the 'b' flag will be added to the mode to ensure the file is opened
- in binary mode for cross-platform portability.
+ is the mode of *fileobj* if discernible; otherwise, the default is ``'rb'``.
+
+ Note that the file is always opened in binary mode; text mode is not
+ supported. If you need to read a compressed file in text mode, wrap your
+ :class:`GzipFile` with an :class:`io.TextIOWrapper`.
The *compresslevel* argument is an integer from ``0`` to ``9`` controlling
the level of compression; ``1`` is fastest and produces the least
@@ -65,25 +66,56 @@ The module defines the following items:
Calling a :class:`GzipFile` object's :meth:`close` method does not close
*fileobj*, since you might wish to append more material after the compressed
- data. This also allows you to pass a :class:`StringIO` object opened for
+ data. This also allows you to pass a :class:`io.BytesIO` object opened for
writing as *fileobj*, and retrieve the resulting memory buffer using the
- :class:`StringIO` object's :meth:`getvalue` method.
+ :class:`io.BytesIO` object's :meth:`~io.BytesIO.getvalue` method.
+
+ :class:`GzipFile` supports the :class:`io.BufferedIOBase` interface,
+ including iteration and the :keyword:`with` statement. Only the
+ :meth:`read1` and :meth:`truncate` methods aren't implemented.
+
+ :class:`GzipFile` also provides the following method:
+
+ .. method:: peek([n])
- :class:`GzipFile` supports iteration and the :keyword:`with` statement.
+ Read *n* uncompressed bytes without advancing the file position.
+ At most one single read on the compressed stream is done to satisfy
+ the call. The number of bytes returned may be more or less than
+ requested.
- .. versionchanged:: 2.7
+ .. versionadded:: 3.2
+
+ .. versionchanged:: 3.1
Support for the :keyword:`with` statement was added.
- .. versionchanged:: 2.7
+ .. versionchanged:: 3.2
Support for zero-padded files was added.
+ .. versionchanged:: 3.2
+ Support for unseekable files was added.
+
-.. function:: open(filename[, mode[, compresslevel]])
+.. function:: open(filename, mode='rb', compresslevel=9)
This is a shorthand for ``GzipFile(filename,`` ``mode,`` ``compresslevel)``.
The *filename* argument is required; *mode* defaults to ``'rb'`` and
*compresslevel* defaults to ``9``.
+.. function:: compress(data, compresslevel=9)
+
+ Compress the *data*, returning a :class:`bytes` object containing
+ the compressed data. *compresslevel* has the same meaning as in
+ the :class:`GzipFile` constructor above.
+
+ .. versionadded:: 3.2
+
+.. function:: decompress(data)
+
+ Decompress the *data*, returning a :class:`bytes` object containing the
+ uncompressed data.
+
+ .. versionadded:: 3.2
+
.. _gzip-usage-examples:
@@ -93,27 +125,28 @@ Examples of usage
Example of how to read a compressed file::
import gzip
- f = gzip.open('/home/joe/file.txt.gz', 'rb')
- file_content = f.read()
- f.close()
+ with gzip.open('/home/joe/file.txt.gz', 'rb') as f:
+ file_content = f.read()
Example of how to create a compressed GZIP file::
import gzip
- content = "Lots of content here"
- f = gzip.open('/home/joe/file.txt.gz', 'wb')
- f.write(content)
- f.close()
+ content = b"Lots of content here"
+ with gzip.open('/home/joe/file.txt.gz', 'wb') as f:
+ f.write(content)
Example of how to GZIP compress an existing file::
import gzip
- f_in = open('/home/joe/file.txt', 'rb')
- f_out = gzip.open('/home/joe/file.txt.gz', 'wb')
- f_out.writelines(f_in)
- f_out.close()
- f_in.close()
+ with open('/home/joe/file.txt', 'rb') as f_in:
+ with gzip.open('/home/joe/file.txt.gz', 'wb') as f_out:
+ f_out.writelines(f_in)
+
+Example of how to GZIP compress a binary string::
+ import gzip
+ s_in = b"Lots of content here"
+ s_out = gzip.compress(s_in)
.. seealso::
diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst
index 063ad59..bc8ab2c 100644
--- a/Doc/library/hashlib.rst
+++ b/Doc/library/hashlib.rst
@@ -7,8 +7,6 @@
.. sectionauthor:: Gregory P. Smith <greg@krypto.org>
-.. versionadded:: 2.5
-
.. index::
single: message digest, MD5
single: secure hash algorithm, SHA1, SHA224, SHA256, SHA384, SHA512
@@ -20,9 +18,9 @@
This module implements a common interface to many different secure hash and
message digest algorithms. Included are the FIPS secure hash algorithms SHA1,
SHA224, SHA256, SHA384, and SHA512 (defined in FIPS 180-2) as well as RSA's MD5
-algorithm (defined in Internet :rfc:`1321`). The terms secure hash and message
-digest are interchangeable. Older algorithms were called message digests. The
-modern term is secure hash.
+algorithm (defined in Internet :rfc:`1321`). The terms "secure hash" and
+"message digest" are interchangeable. Older algorithms were called message
+digests. The modern term is secure hash.
.. note::
If you want the adler32 or crc32 hash functions they are available in
@@ -34,10 +32,21 @@ modern term is secure hash.
There is one constructor method named for each type of :dfn:`hash`. All return
a hash object with the same simple interface. For example: use :func:`sha1` to
-create a SHA1 hash object. You can now feed this object with arbitrary strings
-using the :meth:`update` method. At any point you can ask it for the
-:dfn:`digest` of the concatenation of the strings fed to it so far using the
-:meth:`digest` or :meth:`hexdigest` methods.
+create a SHA1 hash object. You can now feed this object with objects conforming
+to the buffer interface (normally :class:`bytes` objects) using the
+:meth:`update` method. At any point you can ask it for the :dfn:`digest` of the
+concatenation of the data fed to it so far using the :meth:`digest` or
+:meth:`hexdigest` methods.
+
+.. note::
+
+ For better multithreading performance, the Python GIL is released for
+ strings of more than 2047 bytes at object creation or on update.
+
+.. note::
+
+ Feeding string objects is to :meth:`update` is not supported, as hashes work
+ on bytes, not on characters.
.. index:: single: OpenSSL; (use in module hashlib)
@@ -46,15 +55,15 @@ Constructors for hash algorithms that are always present in this module are
:func:`sha512`. Additional algorithms may also be available depending upon the
OpenSSL library that Python uses on your platform.
-For example, to obtain the digest of the string ``'Nobody inspects the spammish
-repetition'``:
+For example, to obtain the digest of the byte string ``b'Nobody inspects the
+spammish repetition'``::
>>> import hashlib
>>> m = hashlib.md5()
- >>> m.update("Nobody inspects")
- >>> m.update(" the spammish repetition")
+ >>> m.update(b"Nobody inspects")
+ >>> m.update(b" the spammish repetition")
>>> m.digest()
- '\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
+ b'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
>>> m.digest_size
16
>>> m.block_size
@@ -62,29 +71,42 @@ repetition'``:
More condensed:
- >>> hashlib.sha224("Nobody inspects the spammish repetition").hexdigest()
+ >>> hashlib.sha224(b"Nobody inspects the spammish repetition").hexdigest()
'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
-A generic :func:`new` constructor that takes the string name of the desired
-algorithm as its first parameter also exists to allow access to the above listed
-hashes as well as any other algorithms that your OpenSSL library may offer. The
-named constructors are much faster than :func:`new` and should be preferred.
+.. function:: new(name[, data])
+
+ Is a generic constructor that takes the string name of the desired
+ algorithm as its first parameter. It also exists to allow access to the
+ above listed hashes as well as any other algorithms that your OpenSSL
+ library may offer. The named constructors are much faster than :func:`new`
+ and should be preferred.
Using :func:`new` with an algorithm provided by OpenSSL:
>>> h = hashlib.new('ripemd160')
- >>> h.update("Nobody inspects the spammish repetition")
+ >>> h.update(b"Nobody inspects the spammish repetition")
>>> h.hexdigest()
'cc4a5ce1b3df48aec5d22d1f16b894a0b894eccc'
-This module provides the following constant attribute:
+Hashlib provides the following constant attributes:
+
+.. data:: algorithms_guaranteed
-.. data:: hashlib.algorithms
+ Contains the names of the hash algorithms guaranteed to be supported
+ by this module on all platforms.
- A tuple providing the names of the hash algorithms guaranteed to be
- supported by this module.
+ .. versionadded:: 3.2
- .. versionadded:: 2.7
+.. data:: algorithms_available
+
+ Contains the names of the hash algorithms that are available
+ in the running Python interpreter. These names will be recognized
+ when passed to :func:`new`. :attr:`algorithms_guaranteed`
+ will always be a subset. Duplicate algorithms with different
+ name formats may appear in this set (thanks to OpenSSL).
+
+ .. versionadded:: 3.2
The following values are provided as constant attributes of the hash objects
returned by the constructors:
@@ -103,35 +125,35 @@ A hash object has the following methods:
.. method:: hash.update(arg)
- Update the hash object with the string *arg*. Repeated calls are equivalent to
- a single call with the concatenation of all the arguments: ``m.update(a);
- m.update(b)`` is equivalent to ``m.update(a+b)``.
-
- .. versionchanged:: 2.7
+ Update the hash object with the object *arg*, which must be interpretable as
+ a buffer of bytes. Repeated calls are equivalent to a single call with the
+ concatenation of all the arguments: ``m.update(a); m.update(b)`` is
+ equivalent to ``m.update(a+b)``.
- The Python GIL is released to allow other threads to run while
- hash updates on data larger than 2048 bytes is taking place when
- using hash algorithms supplied by OpenSSL.
+ .. versionchanged:: 3.1
+ The Python GIL is released to allow other threads to run while hash
+ updates on data larger than 2048 bytes is taking place when using hash
+ algorithms supplied by OpenSSL.
.. method:: hash.digest()
- Return the digest of the strings passed to the :meth:`update` method so far.
- This is a string of :attr:`digest_size` bytes which may contain non-ASCII
- characters, including null bytes.
+ Return the digest of the data passed to the :meth:`update` method so far.
+ This is a bytes object of size :attr:`digest_size` which may contain bytes in
+ the whole range from 0 to 255.
.. method:: hash.hexdigest()
- Like :meth:`digest` except the digest is returned as a string of double length,
- containing only hexadecimal digits. This may be used to exchange the value
- safely in email or other non-binary environments.
+ Like :meth:`digest` except the digest is returned as a string object of
+ double length, containing only hexadecimal digits. This may be used to
+ exchange the value safely in email or other non-binary environments.
.. method:: hash.copy()
Return a copy ("clone") of the hash object. This can be used to efficiently
- compute the digests of strings that share a common initial substring.
+ compute the digests of data sharing a common initial substring.
.. seealso::
diff --git a/Doc/library/heapq.rst b/Doc/library/heapq.rst
index f0723b7..768dfdc 100644
--- a/Doc/library/heapq.rst
+++ b/Doc/library/heapq.rst
@@ -8,8 +8,6 @@
.. sectionauthor:: François Pinard
.. sectionauthor:: Raymond Hettinger
-.. versionadded:: 2.3
-
**Source code:** :source:`Lib/heapq.py`
--------------
@@ -51,13 +49,13 @@ The following functions are provided:
Pop and return the smallest item from the *heap*, maintaining the heap
invariant. If the heap is empty, :exc:`IndexError` is raised.
+
.. function:: heappushpop(heap, item)
Push *item* on the heap, then pop and return the smallest item from the
*heap*. The combined action runs more efficiently than :func:`heappush`
followed by a separate call to :func:`heappop`.
- .. versionadded:: 2.6
.. function:: heapify(x)
@@ -93,10 +91,8 @@ The module also offers three general purpose functions based on heaps.
not pull the data into memory all at once, and assumes that each of the input
streams is already sorted (smallest to largest).
- .. versionadded:: 2.6
-
-.. function:: nlargest(n, iterable[, key])
+.. function:: nlargest(n, iterable, key=None)
Return a list with the *n* largest elements from the dataset defined by
*iterable*. *key*, if provided, specifies a function of one argument that is
@@ -104,23 +100,14 @@ The module also offers three general purpose functions based on heaps.
``key=str.lower`` Equivalent to: ``sorted(iterable, key=key,
reverse=True)[:n]``
- .. versionadded:: 2.4
- .. versionchanged:: 2.5
- Added the optional *key* argument.
-
-
-.. function:: nsmallest(n, iterable[, key])
+.. function:: nsmallest(n, iterable, key=None)
Return a list with the *n* smallest elements from the dataset defined by
*iterable*. *key*, if provided, specifies a function of one argument that is
used to extract a comparison key from each element in the iterable:
``key=str.lower`` Equivalent to: ``sorted(iterable, key=key)[:n]``
- .. versionadded:: 2.4
-
- .. versionchanged:: 2.5
- Added the optional *key* argument.
The latter two functions perform best for smaller values of *n*. For larger
values, it is more efficient to use the :func:`sorted` function. Also, when
@@ -166,9 +153,8 @@ for a heap, and it presents several implementation challenges:
* Sort stability: how do you get two tasks with equal priorities to be returned
in the order they were originally added?
-* In the future with Python 3, tuple comparison breaks for (priority, task)
- pairs if the priorities are equal and the tasks do not have a default
- comparison order.
+* Tuple comparison breaks for (priority, task) pairs if the priorities are equal
+ and the tasks do not have a default comparison order.
* If the priority of a task changes, how do you move it to a new position in
the heap?
@@ -188,7 +174,7 @@ with a dictionary pointing to an entry in the queue.
Removing the entry or changing its priority is more difficult because it would
break the heap structure invariants. So, a possible solution is to mark the
-existing entry as removed and add a new entry with the revised priority::
+entry as removed and add a new entry with the revised priority::
pq = [] # list of entries arranged in a heap
entry_finder = {} # mapping of tasks to entries
diff --git a/Doc/library/hmac.rst b/Doc/library/hmac.rst
index e962ff0..eff2724 100644
--- a/Doc/library/hmac.rst
+++ b/Doc/library/hmac.rst
@@ -2,13 +2,11 @@
========================================================
.. module:: hmac
- :synopsis: Keyed-Hashing for Message Authentication (HMAC) implementation for Python.
+ :synopsis: Keyed-Hashing for Message Authentication (HMAC) implementation
+ for Python.
.. moduleauthor:: Gerhard Häring <ghaering@users.sourceforge.net>
.. sectionauthor:: Gerhard Häring <ghaering@users.sourceforge.net>
-
-.. versionadded:: 2.2
-
**Source code:** :source:`Lib/hmac.py`
--------------
@@ -16,34 +14,36 @@
This module implements the HMAC algorithm as described by :rfc:`2104`.
-.. function:: new(key[, msg[, digestmod]])
+.. function:: new(key, msg=None, digestmod=None)
- Return a new hmac object. If *msg* is present, the method call ``update(msg)``
- is made. *digestmod* is the digest constructor or module for the HMAC object to
- use. It defaults to the :func:`hashlib.md5` constructor.
+ Return a new hmac object. *key* is a bytes object giving the secret key. If
+ *msg* is present, the method call ``update(msg)`` is made. *digestmod* is
+ the digest constructor or module for the HMAC object to use. It defaults to
+ the :func:`hashlib.md5` constructor.
An HMAC object has the following methods:
.. method:: HMAC.update(msg)
- Update the hmac object with the string *msg*. Repeated calls are equivalent to
- a single call with the concatenation of all the arguments: ``m.update(a);
- m.update(b)`` is equivalent to ``m.update(a + b)``.
+ Update the hmac object with the bytes object *msg*. Repeated calls are
+ equivalent to a single call with the concatenation of all the arguments:
+ ``m.update(a); m.update(b)`` is equivalent to ``m.update(a + b)``.
.. method:: HMAC.digest()
- Return the digest of the strings passed to the :meth:`update` method so far.
- This string will be the same length as the *digest_size* of the digest given to
- the constructor. It may contain non-ASCII characters, including NUL bytes.
+ Return the digest of the bytes passed to the :meth:`update` method so far.
+ This bytes object will be the same length as the *digest_size* of the digest
+ given to the constructor. It may contain non-ASCII bytes, including NUL
+ bytes.
.. method:: HMAC.hexdigest()
- Like :meth:`digest` except the digest is returned as a string twice the length
- containing only hexadecimal digits. This may be used to exchange the value
- safely in email or other non-binary environments.
+ Like :meth:`digest` except the digest is returned as a string twice the
+ length containing only hexadecimal digits. This may be used to exchange the
+ value safely in email or other non-binary environments.
.. method:: HMAC.copy()
@@ -56,4 +56,3 @@ An HMAC object has the following methods:
Module :mod:`hashlib`
The Python module providing secure hash functions.
-
diff --git a/Doc/library/hotshot.rst b/Doc/library/hotshot.rst
deleted file mode 100644
index 0ee0767..0000000
--- a/Doc/library/hotshot.rst
+++ /dev/null
@@ -1,152 +0,0 @@
-
-:mod:`hotshot` --- High performance logging profiler
-====================================================
-
-.. module:: hotshot
- :synopsis: High performance logging profiler, mostly written in C.
-.. moduleauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
-.. sectionauthor:: Anthony Baxter <anthony@interlink.com.au>
-
-
-.. versionadded:: 2.2
-
-This module provides a nicer interface to the :mod:`_hotshot` C module. Hotshot
-is a replacement for the existing :mod:`profile` module. As it's written mostly
-in C, it should result in a much smaller performance impact than the existing
-:mod:`profile` module.
-
-.. note::
-
- The :mod:`hotshot` module focuses on minimizing the overhead while profiling, at
- the expense of long data post-processing times. For common usage it is
- recommended to use :mod:`cProfile` instead. :mod:`hotshot` is not maintained and
- might be removed from the standard library in the future.
-
-.. versionchanged:: 2.5
- The results should be more meaningful than in the past: the timing core
- contained a critical bug.
-
-.. note::
-
- The :mod:`hotshot` profiler does not yet work well with threads. It is useful to
- use an unthreaded script to run the profiler over the code you're interested in
- measuring if at all possible.
-
-
-.. class:: Profile(logfile[, lineevents[, linetimings]])
-
- The profiler object. The argument *logfile* is the name of a log file to use for
- logged profile data. The argument *lineevents* specifies whether to generate
- events for every source line, or just on function call/return. It defaults to
- ``0`` (only log function call/return). The argument *linetimings* specifies
- whether to record timing information. It defaults to ``1`` (store timing
- information).
-
-
-.. _hotshot-objects:
-
-Profile Objects
----------------
-
-Profile objects have the following methods:
-
-
-.. method:: Profile.addinfo(key, value)
-
- Add an arbitrary labelled value to the profile output.
-
-
-.. method:: Profile.close()
-
- Close the logfile and terminate the profiler.
-
-
-.. method:: Profile.fileno()
-
- Return the file descriptor of the profiler's log file.
-
-
-.. method:: Profile.run(cmd)
-
- Profile an :keyword:`exec`\ -compatible string in the script environment. The
- globals from the :mod:`__main__` module are used as both the globals and locals
- for the script.
-
-
-.. method:: Profile.runcall(func, *args, **keywords)
-
- Profile a single call of a callable. Additional positional and keyword arguments
- may be passed along; the result of the call is returned, and exceptions are
- allowed to propagate cleanly, while ensuring that profiling is disabled on the
- way out.
-
-
-.. method:: Profile.runctx(cmd, globals, locals)
-
- Evaluate an :keyword:`exec`\ -compatible string in a specific environment. The
- string is compiled before profiling begins.
-
-
-.. method:: Profile.start()
-
- Start the profiler.
-
-
-.. method:: Profile.stop()
-
- Stop the profiler.
-
-
-Using hotshot data
-------------------
-
-.. module:: hotshot.stats
- :synopsis: Statistical analysis for Hotshot
-
-
-.. versionadded:: 2.2
-
-This module loads hotshot profiling data into the standard :mod:`pstats` Stats
-objects.
-
-
-.. function:: load(filename)
-
- Load hotshot data from *filename*. Returns an instance of the
- :class:`pstats.Stats` class.
-
-
-.. seealso::
-
- Module :mod:`profile`
- The :mod:`profile` module's :class:`Stats` class
-
-
-.. _hotshot-example:
-
-Example Usage
--------------
-
-Note that this example runs the Python "benchmark" pystones. It can take some
-time to run, and will produce large output files. ::
-
- >>> import hotshot, hotshot.stats, test.pystone
- >>> prof = hotshot.Profile("stones.prof")
- >>> benchtime, stones = prof.runcall(test.pystone.pystones)
- >>> prof.close()
- >>> stats = hotshot.stats.load("stones.prof")
- >>> stats.strip_dirs()
- >>> stats.sort_stats('time', 'calls')
- >>> stats.print_stats(20)
- 850004 function calls in 10.090 CPU seconds
-
- Ordered by: internal time, call count
-
- ncalls tottime percall cumtime percall filename:lineno(function)
- 1 3.295 3.295 10.090 10.090 pystone.py:79(Proc0)
- 150000 1.315 0.000 1.315 0.000 pystone.py:203(Proc7)
- 50000 1.313 0.000 1.463 0.000 pystone.py:229(Func2)
- .
- .
- .
-
diff --git a/Doc/library/html.entities.rst b/Doc/library/html.entities.rst
new file mode 100644
index 0000000..b8b4aa8
--- /dev/null
+++ b/Doc/library/html.entities.rst
@@ -0,0 +1,32 @@
+:mod:`html.entities` --- Definitions of HTML general entities
+=============================================================
+
+.. module:: html.entities
+ :synopsis: Definitions of HTML general entities.
+.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
+
+**Source code:** :source:`Lib/html/entities.py`
+
+--------------
+
+This module defines three dictionaries, ``name2codepoint``, ``codepoint2name``,
+and ``entitydefs``. ``entitydefs`` is used to provide the :attr:`entitydefs`
+attribute of the :class:`html.parser.HTMLParser` class. The definition provided
+here contains all the entities defined by XHTML 1.0 that can be handled using
+simple textual substitution in the Latin-1 character set (ISO-8859-1).
+
+
+.. data:: entitydefs
+
+ A dictionary mapping XHTML 1.0 entity definitions to their replacement text in
+ ISO Latin-1.
+
+
+.. data:: name2codepoint
+
+ A dictionary that maps HTML entity names to the Unicode codepoints.
+
+
+.. data:: codepoint2name
+
+ A dictionary that maps Unicode codepoints to HTML entity names.
diff --git a/Doc/library/html.parser.rst b/Doc/library/html.parser.rst
new file mode 100644
index 0000000..f3c36ec
--- /dev/null
+++ b/Doc/library/html.parser.rst
@@ -0,0 +1,343 @@
+:mod:`html.parser` --- Simple HTML and XHTML parser
+===================================================
+
+.. module:: html.parser
+ :synopsis: A simple parser that can handle HTML and XHTML.
+
+
+.. index::
+ single: HTML
+ single: XHTML
+
+**Source code:** :source:`Lib/html/parser.py`
+
+--------------
+
+This module defines a class :class:`HTMLParser` which serves as the basis for
+parsing text files formatted in HTML (HyperText Mark-up Language) and XHTML.
+
+.. class:: HTMLParser(strict=True)
+
+ Create a parser instance. If *strict* is ``True`` (the default), invalid
+ HTML results in :exc:`~html.parser.HTMLParseError` exceptions [#]_. If
+ *strict* is ``False``, the parser uses heuristics to make a best guess at
+ the intention of any invalid HTML it encounters, similar to the way most
+ browsers do. Using ``strict=False`` is advised.
+
+ An :class:`.HTMLParser` instance is fed HTML data and calls handler methods
+ when start tags, end tags, text, comments, and other markup elements are
+ encountered. The user should subclass :class:`.HTMLParser` and override its
+ methods to implement the desired behavior.
+
+ This parser does not check that end tags match start tags or call the end-tag
+ handler for elements which are closed implicitly by closing an outer element.
+
+ .. versionchanged:: 3.2 *strict* keyword added
+
+An exception is defined as well:
+
+
+.. exception:: HTMLParseError
+
+ Exception raised by the :class:`HTMLParser` class when it encounters an error
+ while parsing and *strict* is ``True``. This exception provides three
+ attributes: :attr:`msg` is a brief message explaining the error,
+ :attr:`lineno` is the number of the line on which the broken construct was
+ detected, and :attr:`offset` is the number of characters into the line at
+ which the construct starts.
+
+
+Example HTML Parser Application
+-------------------------------
+
+As a basic example, below is a simple HTML parser that uses the
+:class:`HTMLParser` class to print out start tags, end tags, and data
+as they are encountered::
+
+ from html.parser import HTMLParser
+
+ class MyHTMLParser(HTMLParser):
+ def handle_starttag(self, tag, attrs):
+ print("Encountered a start tag:", tag)
+ def handle_endtag(self, tag):
+ print("Encountered an end tag :", tag)
+ def handle_data(self, data):
+ print("Encountered some data :", data)
+
+ parser = MyHTMLParser(strict=False)
+ parser.feed('<html><head><title>Test</title></head>'
+ '<body><h1>Parse me!</h1></body></html>')
+
+The output will then be::
+
+ Encountered a start tag: html
+ Encountered a start tag: head
+ Encountered a start tag: title
+ Encountered some data : Test
+ Encountered an end tag : title
+ Encountered an end tag : head
+ Encountered a start tag: body
+ Encountered a start tag: h1
+ Encountered some data : Parse me!
+ Encountered an end tag : h1
+ Encountered an end tag : body
+ Encountered an end tag : html
+
+
+:class:`.HTMLParser` Methods
+----------------------------
+
+:class:`HTMLParser` instances have the following methods:
+
+
+.. method:: HTMLParser.feed(data)
+
+ Feed some text to the parser. It is processed insofar as it consists of
+ complete elements; incomplete data is buffered until more data is fed or
+ :meth:`close` is called. *data* must be :class:`str`.
+
+
+.. method:: HTMLParser.close()
+
+ Force processing of all buffered data as if it were followed by an end-of-file
+ mark. This method may be redefined by a derived class to define additional
+ processing at the end of the input, but the redefined version should always call
+ the :class:`HTMLParser` base class method :meth:`close`.
+
+
+.. method:: HTMLParser.reset()
+
+ Reset the instance. Loses all unprocessed data. This is called implicitly at
+ instantiation time.
+
+
+.. method:: HTMLParser.getpos()
+
+ Return current line number and offset.
+
+
+.. method:: HTMLParser.get_starttag_text()
+
+ Return the text of the most recently opened start tag. This should not normally
+ be needed for structured processing, but may be useful in dealing with HTML "as
+ deployed" or for re-generating input with minimal changes (whitespace between
+ attributes can be preserved, etc.).
+
+
+The following methods are called when data or markup elements are encountered
+and they are meant to be overridden in a subclass. The base class
+implementations do nothing (except for :meth:`~HTMLParser.handle_startendtag`):
+
+
+.. method:: HTMLParser.handle_starttag(tag, attrs)
+
+ This method is called to handle the start of a tag (e.g. ``<div id="main">``).
+
+ The *tag* argument is the name of the tag converted to lower case. The *attrs*
+ argument is a list of ``(name, value)`` pairs containing the attributes found
+ inside the tag's ``<>`` brackets. The *name* will be translated to lower case,
+ and quotes in the *value* have been removed, and character and entity references
+ have been replaced.
+
+ For instance, for the tag ``<A HREF="http://www.cwi.nl/">``, this method
+ would be called as ``handle_starttag('a', [('href', 'http://www.cwi.nl/')])``.
+
+ All entity references from :mod:`html.entities` are replaced in the attribute
+ values.
+
+
+.. method:: HTMLParser.handle_endtag(tag)
+
+ This method is called to handle the end tag of an element (e.g. ``</div>``).
+
+ The *tag* argument is the name of the tag converted to lower case.
+
+
+.. method:: HTMLParser.handle_startendtag(tag, attrs)
+
+ Similar to :meth:`handle_starttag`, but called when the parser encounters an
+ XHTML-style empty tag (``<img ... />``). This method may be overridden by
+ subclasses which require this particular lexical information; the default
+ implementation simply calls :meth:`handle_starttag` and :meth:`handle_endtag`.
+
+
+.. method:: HTMLParser.handle_data(data)
+
+ This method is called to process arbitrary data (e.g. text nodes and the
+ content of ``<script>...</script>`` and ``<style>...</style>``).
+
+
+.. method:: HTMLParser.handle_entityref(name)
+
+ This method is called to process a named character reference of the form
+ ``&name;`` (e.g. ``&gt;``), where *name* is a general entity reference
+ (e.g. ``'gt'``).
+
+
+.. method:: HTMLParser.handle_charref(name)
+
+ This method is called to process decimal and hexadecimal numeric character
+ references of the form ``&#NNN;`` and ``&#xNNN;``. For example, the decimal
+ equivalent for ``&gt;`` is ``&#62;``, whereas the hexadecimal is ``&#x3E;``;
+ in this case the method will receive ``'62'`` or ``'x3E'``.
+
+
+.. method:: HTMLParser.handle_comment(data)
+
+ This method is called when a comment is encountered (e.g. ``<!--comment-->``).
+
+ For example, the comment ``<!-- comment -->`` will cause this method to be
+ called with the argument ``' comment '``.
+
+ The content of Internet Explorer conditional comments (condcoms) will also be
+ sent to this method, so, for ``<!--[if IE 9]>IE9-specific content<![endif]-->``,
+ this method will receive ``'[if IE 9]>IE-specific content<![endif]'``.
+
+
+.. method:: HTMLParser.handle_decl(decl)
+
+ This method is called to handle an HTML doctype declaration (e.g.
+ ``<!DOCTYPE html>``).
+
+ The *decl* parameter will be the entire contents of the declaration inside
+ the ``<!...>`` markup (e.g. ``'DOCTYPE html'``).
+
+
+.. method:: HTMLParser.handle_pi(data)
+
+ Method called when a processing instruction is encountered. The *data*
+ parameter will contain the entire processing instruction. For example, for the
+ processing instruction ``<?proc color='red'>``, this method would be called as
+ ``handle_pi("proc color='red'")``. It is intended to be overridden by a derived
+ class; the base class implementation does nothing.
+
+ .. note::
+
+ The :class:`HTMLParser` class uses the SGML syntactic rules for processing
+ instructions. An XHTML processing instruction using the trailing ``'?'`` will
+ cause the ``'?'`` to be included in *data*.
+
+
+.. method:: HTMLParser.unknown_decl(data)
+
+ This method is called when an unrecognized declaration is read by the parser.
+
+ The *data* parameter will be the entire contents of the declaration inside
+ the ``<![...]>`` markup. It is sometimes useful to be overridden by a
+ derived class. The base class implementation raises an :exc:`HTMLParseError`
+ when *strict* is ``True``.
+
+
+.. _htmlparser-examples:
+
+Examples
+--------
+
+The following class implements a parser that will be used to illustrate more
+examples::
+
+ from html.parser import HTMLParser
+ from html.entities import name2codepoint
+
+ class MyHTMLParser(HTMLParser):
+ def handle_starttag(self, tag, attrs):
+ print("Start tag:", tag)
+ for attr in attrs:
+ print(" attr:", attr)
+ def handle_endtag(self, tag):
+ print("End tag :", tag)
+ def handle_data(self, data):
+ print("Data :", data)
+ def handle_comment(self, data):
+ print("Comment :", data)
+ def handle_entityref(self, name):
+ c = chr(name2codepoint[name])
+ print("Named ent:", c)
+ def handle_charref(self, name):
+ if name.startswith('x'):
+ c = chr(int(name[1:], 16))
+ else:
+ c = chr(int(name))
+ print("Num ent :", c)
+ def handle_decl(self, data):
+ print("Decl :", data)
+
+ parser = MyHTMLParser(strict=False)
+
+Parsing a doctype::
+
+ >>> parser.feed('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" '
+ ... '"http://www.w3.org/TR/html4/strict.dtd">')
+ Decl : DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"
+
+Parsing an element with a few attributes and a title::
+
+ >>> parser.feed('<img src="python-logo.png" alt="The Python logo">')
+ Start tag: img
+ attr: ('src', 'python-logo.png')
+ attr: ('alt', 'The Python logo')
+ >>>
+ >>> parser.feed('<h1>Python</h1>')
+ Start tag: h1
+ Data : Python
+ End tag : h1
+
+The content of ``script`` and ``style`` elements is returned as is, without
+further parsing::
+
+ >>> parser.feed('<style type="text/css">#python { color: green }</style>')
+ Start tag: style
+ attr: ('type', 'text/css')
+ Data : #python { color: green }
+ End tag : style
+ >>>
+ >>> parser.feed('<script type="text/javascript">'
+ ... 'alert("<strong>hello!</strong>");</script>')
+ Start tag: script
+ attr: ('type', 'text/javascript')
+ Data : alert("<strong>hello!</strong>");
+ End tag : script
+
+Parsing comments::
+
+ >>> parser.feed('<!-- a comment -->'
+ ... '<!--[if IE 9]>IE-specific content<![endif]-->')
+ Comment : a comment
+ Comment : [if IE 9]>IE-specific content<![endif]
+
+Parsing named and numeric character references and converting them to the
+correct char (note: these 3 references are all equivalent to ``'>'``)::
+
+ >>> parser.feed('&gt;&#62;&#x3E;')
+ Named ent: >
+ Num ent : >
+ Num ent : >
+
+Feeding incomplete chunks to :meth:`~HTMLParser.feed` works, but
+:meth:`~HTMLParser.handle_data` might be called more than once::
+
+ >>> for chunk in ['<sp', 'an>buff', 'ered ', 'text</s', 'pan>']:
+ ... parser.feed(chunk)
+ ...
+ Start tag: span
+ Data : buff
+ Data : ered
+ Data : text
+ End tag : span
+
+Parsing invalid HTML (e.g. unquoted attributes) also works::
+
+ >>> parser.feed('<p><a class=link href=#main>tag soup</p ></a>')
+ Start tag: p
+ Start tag: a
+ attr: ('class', 'link')
+ attr: ('href', '#main')
+ Data : tag soup
+ End tag : p
+ End tag : a
+
+.. rubric:: Footnotes
+
+.. [#] For backward compatibility reasons *strict* mode does not raise
+ exceptions for all non-compliant HTML. That is, some invalid HTML
+ is tolerated even in *strict* mode.
diff --git a/Doc/library/html.rst b/Doc/library/html.rst
new file mode 100644
index 0000000..3ad1c0c
--- /dev/null
+++ b/Doc/library/html.rst
@@ -0,0 +1,21 @@
+:mod:`html` --- HyperText Markup Language support
+=================================================
+
+.. module:: html
+ :synopsis: Helpers for manipulating HTML.
+
+**Source code:** :source:`Lib/html/__init__.py`
+
+--------------
+
+This module defines utilities to manipulate HTML.
+
+.. function:: escape(s, quote=True)
+
+ Convert the characters ``&``, ``<`` and ``>`` in string *s* to HTML-safe
+ sequences. Use this if you need to display text that might contain such
+ characters in HTML. If the optional flag *quote* is true, the characters
+ (``"``) and (``'``) are also translated; this helps for inclusion in an HTML
+ attribute value delimited by quotes, as in ``<a href="...">``.
+
+ .. versionadded:: 3.2
diff --git a/Doc/library/htmllib.rst b/Doc/library/htmllib.rst
deleted file mode 100644
index 9e68f45..0000000
--- a/Doc/library/htmllib.rst
+++ /dev/null
@@ -1,198 +0,0 @@
-:mod:`htmllib` --- A parser for HTML documents
-==============================================
-
-.. module:: htmllib
- :synopsis: A parser for HTML documents.
- :deprecated:
-
-.. deprecated:: 2.6
- The :mod:`htmllib` module has been removed in Python 3.
-
-
-.. index::
- single: HTML
- single: hypertext
-
-.. index::
- module: sgmllib
- module: formatter
- single: SGMLParser (in module sgmllib)
-
-This module defines a class which can serve as a base for parsing text files
-formatted in the HyperText Mark-up Language (HTML). The class is not directly
-concerned with I/O --- it must be provided with input in string form via a
-method, and makes calls to methods of a "formatter" object in order to produce
-output. The :class:`HTMLParser` class is designed to be used as a base class
-for other classes in order to add functionality, and allows most of its methods
-to be extended or overridden. In turn, this class is derived from and extends
-the :class:`SGMLParser` class defined in module :mod:`sgmllib`. The
-:class:`HTMLParser` implementation supports the HTML 2.0 language as described
-in :rfc:`1866`. Two implementations of formatter objects are provided in the
-:mod:`formatter` module; refer to the documentation for that module for
-information on the formatter interface.
-
-The following is a summary of the interface defined by
-:class:`sgmllib.SGMLParser`:
-
-* The interface to feed data to an instance is through the :meth:`feed` method,
- which takes a string argument. This can be called with as little or as much
- text at a time as desired; ``p.feed(a); p.feed(b)`` has the same effect as
- ``p.feed(a+b)``. When the data contains complete HTML markup constructs, these
- are processed immediately; incomplete constructs are saved in a buffer. To
- force processing of all unprocessed data, call the :meth:`close` method.
-
- For example, to parse the entire contents of a file, use::
-
- parser.feed(open('myfile.html').read())
- parser.close()
-
-* The interface to define semantics for HTML tags is very simple: derive a class
- and define methods called :meth:`start_tag`, :meth:`end_tag`, or :meth:`do_tag`.
- The parser will call these at appropriate moments: :meth:`start_tag` or
- :meth:`do_tag` is called when an opening tag of the form ``<tag ...>`` is
- encountered; :meth:`end_tag` is called when a closing tag of the form ``<tag>``
- is encountered. If an opening tag requires a corresponding closing tag, like
- ``<H1>`` ... ``</H1>``, the class should define the :meth:`start_tag` method; if
- a tag requires no closing tag, like ``<P>``, the class should define the
- :meth:`do_tag` method.
-
-The module defines a parser class and an exception:
-
-
-.. class:: HTMLParser(formatter)
-
- This is the basic HTML parser class. It supports all entity names required by
- the XHTML 1.0 Recommendation (http://www.w3.org/TR/xhtml1). It also defines
- handlers for all HTML 2.0 and many HTML 3.0 and 3.2 elements.
-
-
-.. exception:: HTMLParseError
-
- Exception raised by the :class:`HTMLParser` class when it encounters an error
- while parsing.
-
- .. versionadded:: 2.4
-
-
-.. seealso::
-
- Module :mod:`formatter`
- Interface definition for transforming an abstract flow of formatting events into
- specific output events on writer objects.
-
- Module :mod:`HTMLParser`
- Alternate HTML parser that offers a slightly lower-level view of the input, but
- is designed to work with XHTML, and does not implement some of the SGML syntax
- not used in "HTML as deployed" and which isn't legal for XHTML.
-
- Module :mod:`htmlentitydefs`
- Definition of replacement text for XHTML 1.0 entities.
-
- Module :mod:`sgmllib`
- Base class for :class:`HTMLParser`.
-
-
-.. _html-parser-objects:
-
-HTMLParser Objects
-------------------
-
-In addition to tag methods, the :class:`HTMLParser` class provides some
-additional methods and instance variables for use within tag methods.
-
-
-.. attribute:: HTMLParser.formatter
-
- This is the formatter instance associated with the parser.
-
-
-.. attribute:: HTMLParser.nofill
-
- Boolean flag which should be true when whitespace should not be collapsed, or
- false when it should be. In general, this should only be true when character
- data is to be treated as "preformatted" text, as within a ``<PRE>`` element.
- The default value is false. This affects the operation of :meth:`handle_data`
- and :meth:`save_end`.
-
-
-.. method:: HTMLParser.anchor_bgn(href, name, type)
-
- This method is called at the start of an anchor region. The arguments
- correspond to the attributes of the ``<A>`` tag with the same names. The
- default implementation maintains a list of hyperlinks (defined by the ``HREF``
- attribute for ``<A>`` tags) within the document. The list of hyperlinks is
- available as the data attribute :attr:`anchorlist`.
-
-
-.. method:: HTMLParser.anchor_end()
-
- This method is called at the end of an anchor region. The default
- implementation adds a textual footnote marker using an index into the list of
- hyperlinks created by :meth:`anchor_bgn`.
-
-
-.. method:: HTMLParser.handle_image(source, alt[, ismap[, align[, width[, height]]]])
-
- This method is called to handle images. The default implementation simply
- passes the *alt* value to the :meth:`handle_data` method.
-
-
-.. method:: HTMLParser.save_bgn()
-
- Begins saving character data in a buffer instead of sending it to the formatter
- object. Retrieve the stored data via :meth:`save_end`. Use of the
- :meth:`save_bgn` / :meth:`save_end` pair may not be nested.
-
-
-.. method:: HTMLParser.save_end()
-
- Ends buffering character data and returns all data saved since the preceding
- call to :meth:`save_bgn`. If the :attr:`nofill` flag is false, whitespace is
- collapsed to single spaces. A call to this method without a preceding call to
- :meth:`save_bgn` will raise a :exc:`TypeError` exception.
-
-
-:mod:`htmlentitydefs` --- Definitions of HTML general entities
-==============================================================
-
-.. module:: htmlentitydefs
- :synopsis: Definitions of HTML general entities.
-.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
-
-.. note::
-
- The :mod:`htmlentitydefs` module has been renamed to :mod:`html.entities` in
- Python 3. The :term:`2to3` tool will automatically adapt imports when
- converting your sources to Python 3.
-
-**Source code:** :source:`Lib/htmlentitydefs.py`
-
---------------
-
-This module defines three dictionaries, ``name2codepoint``, ``codepoint2name``,
-and ``entitydefs``. ``entitydefs`` is used by the :mod:`htmllib` module to
-provide the :attr:`entitydefs` attribute of the :class:`HTMLParser` class. The
-definition provided here contains all the entities defined by XHTML 1.0 that
-can be handled using simple textual substitution in the Latin-1 character set
-(ISO-8859-1).
-
-
-.. data:: entitydefs
-
- A dictionary mapping XHTML 1.0 entity definitions to their replacement text in
- ISO Latin-1.
-
-
-.. data:: name2codepoint
-
- A dictionary that maps HTML entity names to the Unicode codepoints.
-
- .. versionadded:: 2.3
-
-
-.. data:: codepoint2name
-
- A dictionary that maps Unicode codepoints to HTML entity names.
-
- .. versionadded:: 2.3
-
diff --git a/Doc/library/htmlparser.rst b/Doc/library/htmlparser.rst
deleted file mode 100644
index 3aba74e..0000000
--- a/Doc/library/htmlparser.rst
+++ /dev/null
@@ -1,345 +0,0 @@
-
-:mod:`HTMLParser` --- Simple HTML and XHTML parser
-==================================================
-
-.. module:: HTMLParser
- :synopsis: A simple parser that can handle HTML and XHTML.
-
-.. note::
-
- The :mod:`HTMLParser` module has been renamed to :mod:`html.parser` in Python
- 3. The :term:`2to3` tool will automatically adapt imports when converting
- your sources to Python 3.
-
-
-.. versionadded:: 2.2
-
-.. index::
- single: HTML
- single: XHTML
-
-**Source code:** :source:`Lib/HTMLParser.py`
-
---------------
-
-This module defines a class :class:`.HTMLParser` which serves as the basis for
-parsing text files formatted in HTML (HyperText Mark-up Language) and XHTML.
-Unlike the parser in :mod:`htmllib`, this parser is not based on the SGML parser
-in :mod:`sgmllib`.
-
-
-.. class:: HTMLParser()
-
- An :class:`.HTMLParser` instance is fed HTML data and calls handler methods
- when start tags, end tags, text, comments, and other markup elements are
- encountered. The user should subclass :class:`.HTMLParser` and override its
- methods to implement the desired behavior.
-
- The :class:`.HTMLParser` class is instantiated without arguments.
-
- Unlike the parser in :mod:`htmllib`, this parser does not check that end tags
- match start tags or call the end-tag handler for elements which are closed
- implicitly by closing an outer element.
-
-An exception is defined as well:
-
-.. exception:: HTMLParseError
-
- :class:`.HTMLParser` is able to handle broken markup, but in some cases it
- might raise this exception when it encounters an error while parsing.
- This exception provides three attributes: :attr:`msg` is a brief
- message explaining the error, :attr:`lineno` is the number of the line on
- which the broken construct was detected, and :attr:`offset` is the number of
- characters into the line at which the construct starts.
-
-
-Example HTML Parser Application
--------------------------------
-
-As a basic example, below is a simple HTML parser that uses the
-:class:`.HTMLParser` class to print out start tags, end tags and data
-as they are encountered::
-
- from HTMLParser import HTMLParser
-
- # create a subclass and override the handler methods
- class MyHTMLParser(HTMLParser):
- def handle_starttag(self, tag, attrs):
- print "Encountered a start tag:", tag
- def handle_endtag(self, tag):
- print "Encountered an end tag :", tag
- def handle_data(self, data):
- print "Encountered some data :", data
-
- # instantiate the parser and fed it some HTML
- parser = MyHTMLParser()
- parser.feed('<html><head><title>Test</title></head>'
- '<body><h1>Parse me!</h1></body></html>')
-
-The output will then be::
-
- Encountered a start tag: html
- Encountered a start tag: head
- Encountered a start tag: title
- Encountered some data : Test
- Encountered an end tag : title
- Encountered an end tag : head
- Encountered a start tag: body
- Encountered a start tag: h1
- Encountered some data : Parse me!
- Encountered an end tag : h1
- Encountered an end tag : body
- Encountered an end tag : html
-
-
-:class:`.HTMLParser` Methods
-----------------------------
-
-:class:`.HTMLParser` instances have the following methods:
-
-
-.. method:: HTMLParser.feed(data)
-
- Feed some text to the parser. It is processed insofar as it consists of
- complete elements; incomplete data is buffered until more data is fed or
- :meth:`close` is called. *data* can be either :class:`unicode` or
- :class:`str`, but passing :class:`unicode` is advised.
-
-
-.. method:: HTMLParser.close()
-
- Force processing of all buffered data as if it were followed by an end-of-file
- mark. This method may be redefined by a derived class to define additional
- processing at the end of the input, but the redefined version should always call
- the :class:`.HTMLParser` base class method :meth:`close`.
-
-
-.. method:: HTMLParser.reset()
-
- Reset the instance. Loses all unprocessed data. This is called implicitly at
- instantiation time.
-
-
-.. method:: HTMLParser.getpos()
-
- Return current line number and offset.
-
-
-.. method:: HTMLParser.get_starttag_text()
-
- Return the text of the most recently opened start tag. This should not normally
- be needed for structured processing, but may be useful in dealing with HTML "as
- deployed" or for re-generating input with minimal changes (whitespace between
- attributes can be preserved, etc.).
-
-
-The following methods are called when data or markup elements are encountered
-and they are meant to be overridden in a subclass. The base class
-implementations do nothing (except for :meth:`~HTMLParser.handle_startendtag`):
-
-
-.. method:: HTMLParser.handle_starttag(tag, attrs)
-
- This method is called to handle the start of a tag (e.g. ``<div id="main">``).
-
- The *tag* argument is the name of the tag converted to lower case. The *attrs*
- argument is a list of ``(name, value)`` pairs containing the attributes found
- inside the tag's ``<>`` brackets. The *name* will be translated to lower case,
- and quotes in the *value* have been removed, and character and entity references
- have been replaced.
-
- For instance, for the tag ``<A HREF="http://www.cwi.nl/">``, this method
- would be called as ``handle_starttag('a', [('href', 'http://www.cwi.nl/')])``.
-
- .. versionchanged:: 2.6
- All entity references from :mod:`htmlentitydefs` are now replaced in the
- attribute values.
-
-
-.. method:: HTMLParser.handle_endtag(tag)
-
- This method is called to handle the end tag of an element (e.g. ``</div>``).
-
- The *tag* argument is the name of the tag converted to lower case.
-
-
-.. method:: HTMLParser.handle_startendtag(tag, attrs)
-
- Similar to :meth:`handle_starttag`, but called when the parser encounters an
- XHTML-style empty tag (``<img ... />``). This method may be overridden by
- subclasses which require this particular lexical information; the default
- implementation simply calls :meth:`handle_starttag` and :meth:`handle_endtag`.
-
-
-.. method:: HTMLParser.handle_data(data)
-
- This method is called to process arbitrary data (e.g. text nodes and the
- content of ``<script>...</script>`` and ``<style>...</style>``).
-
-
-.. method:: HTMLParser.handle_entityref(name)
-
- This method is called to process a named character reference of the form
- ``&name;`` (e.g. ``&gt;``), where *name* is a general entity reference
- (e.g. ``'gt'``).
-
-
-.. method:: HTMLParser.handle_charref(name)
-
- This method is called to process decimal and hexadecimal numeric character
- references of the form ``&#NNN;`` and ``&#xNNN;``. For example, the decimal
- equivalent for ``&gt;`` is ``&#62;``, whereas the hexadecimal is ``&#x3E;``;
- in this case the method will receive ``'62'`` or ``'x3E'``.
-
-
-.. method:: HTMLParser.handle_comment(data)
-
- This method is called when a comment is encountered (e.g. ``<!--comment-->``).
-
- For example, the comment ``<!-- comment -->`` will cause this method to be
- called with the argument ``' comment '``.
-
- The content of Internet Explorer conditional comments (condcoms) will also be
- sent to this method, so, for ``<!--[if IE 9]>IE9-specific content<![endif]-->``,
- this method will receive ``'[if IE 9]>IE-specific content<![endif]'``.
-
-
-.. method:: HTMLParser.handle_decl(decl)
-
- This method is called to handle an HTML doctype declaration (e.g.
- ``<!DOCTYPE html>``).
-
- The *decl* parameter will be the entire contents of the declaration inside
- the ``<!...>`` markup (e.g. ``'DOCTYPE html'``).
-
-
-.. method:: HTMLParser.handle_pi(data)
-
- This method is called when a processing instruction is encountered. The *data*
- parameter will contain the entire processing instruction. For example, for the
- processing instruction ``<?proc color='red'>``, this method would be called as
- ``handle_pi("proc color='red'")``.
-
- .. note::
-
- The :class:`.HTMLParser` class uses the SGML syntactic rules for processing
- instructions. An XHTML processing instruction using the trailing ``'?'`` will
- cause the ``'?'`` to be included in *data*.
-
-
-.. method:: HTMLParser.unknown_decl(data)
-
- This method is called when an unrecognized declaration is read by the parser.
-
- The *data* parameter will be the entire contents of the declaration inside
- the ``<![...]>`` markup. It is sometimes useful to be overridden by a
- derived class.
-
-
-.. _htmlparser-examples:
-
-Examples
---------
-
-The following class implements a parser that will be used to illustrate more
-examples::
-
- from HTMLParser import HTMLParser
- from htmlentitydefs import name2codepoint
-
- class MyHTMLParser(HTMLParser):
- def handle_starttag(self, tag, attrs):
- print "Start tag:", tag
- for attr in attrs:
- print " attr:", attr
- def handle_endtag(self, tag):
- print "End tag :", tag
- def handle_data(self, data):
- print "Data :", data
- def handle_comment(self, data):
- print "Comment :", data
- def handle_entityref(self, name):
- c = unichr(name2codepoint[name])
- print "Named ent:", c
- def handle_charref(self, name):
- if name.startswith('x'):
- c = unichr(int(name[1:], 16))
- else:
- c = unichr(int(name))
- print "Num ent :", c
- def handle_decl(self, data):
- print "Decl :", data
-
- parser = MyHTMLParser()
-
-Parsing a doctype::
-
- >>> parser.feed('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" '
- ... '"http://www.w3.org/TR/html4/strict.dtd">')
- Decl : DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"
-
-Parsing an element with a few attributes and a title::
-
- >>> parser.feed('<img src="python-logo.png" alt="The Python logo">')
- Start tag: img
- attr: ('src', 'python-logo.png')
- attr: ('alt', 'The Python logo')
- >>>
- >>> parser.feed('<h1>Python</h1>')
- Start tag: h1
- Data : Python
- End tag : h1
-
-The content of ``script`` and ``style`` elements is returned as is, without
-further parsing::
-
- >>> parser.feed('<style type="text/css">#python { color: green }</style>')
- Start tag: style
- attr: ('type', 'text/css')
- Data : #python { color: green }
- End tag : style
- >>>
- >>> parser.feed('<script type="text/javascript">'
- ... 'alert("<strong>hello!</strong>");</script>')
- Start tag: script
- attr: ('type', 'text/javascript')
- Data : alert("<strong>hello!</strong>");
- End tag : script
-
-Parsing comments::
-
- >>> parser.feed('<!-- a comment -->'
- ... '<!--[if IE 9]>IE-specific content<![endif]-->')
- Comment : a comment
- Comment : [if IE 9]>IE-specific content<![endif]
-
-Parsing named and numeric character references and converting them to the
-correct char (note: these 3 references are all equivalent to ``'>'``)::
-
- >>> parser.feed('&gt;&#62;&#x3E;')
- Named ent: >
- Num ent : >
- Num ent : >
-
-Feeding incomplete chunks to :meth:`~HTMLParser.feed` works, but
-:meth:`~HTMLParser.handle_data` might be called more than once::
-
- >>> for chunk in ['<sp', 'an>buff', 'ered ', 'text</s', 'pan>']:
- ... parser.feed(chunk)
- ...
- Start tag: span
- Data : buff
- Data : ered
- Data : text
- End tag : span
-
-Parsing invalid HTML (e.g. unquoted attributes) also works::
-
- >>> parser.feed('<p><a class=link href=#main>tag soup</p ></a>')
- Start tag: p
- Start tag: a
- attr: ('class', 'link')
- attr: ('href', '#main')
- Data : tag soup
- End tag : p
- End tag : a
diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst
new file mode 100644
index 0000000..d439f24
--- /dev/null
+++ b/Doc/library/http.client.rst
@@ -0,0 +1,624 @@
+:mod:`http.client` --- HTTP protocol client
+===========================================
+
+.. module:: http.client
+ :synopsis: HTTP and HTTPS protocol client (requires sockets).
+
+
+.. index::
+ pair: HTTP; protocol
+ single: HTTP; http.client (standard module)
+
+.. index:: module: urllib.request
+
+**Source code:** :source:`Lib/http/client.py`
+
+--------------
+
+This module defines classes which implement the client side of the HTTP and
+HTTPS protocols. It is normally not used directly --- the module
+:mod:`urllib.request` uses it to handle URLs that use HTTP and HTTPS.
+
+.. note::
+
+ HTTPS support is only available if Python was compiled with SSL support
+ (through the :mod:`ssl` module).
+
+The module provides the following classes:
+
+
+.. class:: HTTPConnection(host, port=None[, strict][, timeout], \
+ source_address=None)
+
+ An :class:`HTTPConnection` instance represents one transaction with an HTTP
+ server. It should be instantiated passing it a host and optional port
+ number. If no port number is passed, the port is extracted from the host
+ string if it has the form ``host:port``, else the default HTTP port (80) is
+ used. If the optional *timeout* parameter is given, blocking
+ operations (like connection attempts) will timeout after that many seconds
+ (if it is not given, the global default timeout setting is used).
+ The optional *source_address* parameter may be a tuple of a (host, port)
+ to use as the source address the HTTP connection is made from.
+
+ For example, the following calls all create instances that connect to the server
+ at the same host and port::
+
+ >>> h1 = http.client.HTTPConnection('www.cwi.nl')
+ >>> h2 = http.client.HTTPConnection('www.cwi.nl:80')
+ >>> h3 = http.client.HTTPConnection('www.cwi.nl', 80)
+ >>> h3 = http.client.HTTPConnection('www.cwi.nl', 80, timeout=10)
+
+ .. versionchanged:: 3.2
+ *source_address* was added.
+
+ .. versionchanged:: 3.2
+ The *strict* parameter is deprecated. HTTP 0.9-style "Simple Responses"
+ are not supported anymore.
+
+
+.. class:: HTTPSConnection(host, port=None, key_file=None, \
+ cert_file=None[, strict][, timeout], \
+ source_address=None, *, context=None, \
+ check_hostname=None)
+
+ A subclass of :class:`HTTPConnection` that uses SSL for communication with
+ secure servers. Default port is ``443``. If *context* is specified, it
+ must be a :class:`ssl.SSLContext` instance describing the various SSL
+ options. If *context* is specified and has a :attr:`~ssl.SSLContext.verify_mode`
+ of either :data:`~ssl.CERT_OPTIONAL` or :data:`~ssl.CERT_REQUIRED`, then
+ by default *host* is matched against the host name(s) allowed by the
+ server's certificate. If you want to change that behaviour, you can
+ explicitly set *check_hostname* to False.
+
+ *key_file* and *cert_file* are deprecated, please use
+ :meth:`ssl.SSLContext.load_cert_chain` instead.
+
+ If you access arbitrary hosts on the Internet, it is recommended to
+ require certificate checking and feed the *context* with a set of
+ trusted CA certificates::
+
+ context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ context.verify_mode = ssl.CERT_REQUIRED
+ context.load_verify_locations('/etc/pki/tls/certs/ca-bundle.crt')
+ h = client.HTTPSConnection('svn.python.org', 443, context=context)
+
+ .. versionchanged:: 3.2
+ *source_address*, *context* and *check_hostname* were added.
+
+ .. versionchanged:: 3.2
+ This class now supports HTTPS virtual hosts if possible (that is,
+ if :data:`ssl.HAS_SNI` is true).
+
+ .. versionchanged:: 3.2
+ The *strict* parameter is deprecated. HTTP 0.9-style "Simple Responses"
+ are not supported anymore.
+
+
+.. class:: HTTPResponse(sock, debuglevel=0[, strict], method=None, url=None)
+
+ Class whose instances are returned upon successful connection. Not
+ instantiated directly by user.
+
+ .. versionchanged:: 3.2
+ The *strict* parameter is deprecated. HTTP 0.9-style "Simple Responses"
+ are not supported anymore.
+
+
+The following exceptions are raised as appropriate:
+
+
+.. exception:: HTTPException
+
+ The base class of the other exceptions in this module. It is a subclass of
+ :exc:`Exception`.
+
+
+.. exception:: NotConnected
+
+ A subclass of :exc:`HTTPException`.
+
+
+.. exception:: InvalidURL
+
+ A subclass of :exc:`HTTPException`, raised if a port is given and is either
+ non-numeric or empty.
+
+
+.. exception:: UnknownProtocol
+
+ A subclass of :exc:`HTTPException`.
+
+
+.. exception:: UnknownTransferEncoding
+
+ A subclass of :exc:`HTTPException`.
+
+
+.. exception:: UnimplementedFileMode
+
+ A subclass of :exc:`HTTPException`.
+
+
+.. exception:: IncompleteRead
+
+ A subclass of :exc:`HTTPException`.
+
+
+.. exception:: ImproperConnectionState
+
+ A subclass of :exc:`HTTPException`.
+
+
+.. exception:: CannotSendRequest
+
+ A subclass of :exc:`ImproperConnectionState`.
+
+
+.. exception:: CannotSendHeader
+
+ A subclass of :exc:`ImproperConnectionState`.
+
+
+.. exception:: ResponseNotReady
+
+ A subclass of :exc:`ImproperConnectionState`.
+
+
+.. exception:: BadStatusLine
+
+ A subclass of :exc:`HTTPException`. Raised if a server responds with a HTTP
+ status code that we don't understand.
+
+The constants defined in this module are:
+
+
+.. data:: HTTP_PORT
+
+ The default port for the HTTP protocol (always ``80``).
+
+
+.. data:: HTTPS_PORT
+
+ The default port for the HTTPS protocol (always ``443``).
+
+and also the following constants for integer status codes:
+
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| Constant | Value | Definition |
++==========================================+=========+=======================================================================+
+| :const:`CONTINUE` | ``100`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.1.1 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.1>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`SWITCHING_PROTOCOLS` | ``101`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.1.2 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.2>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`PROCESSING` | ``102`` | WEBDAV, `RFC 2518, Section 10.1 |
+| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_102>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`OK` | ``200`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.2.1 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`CREATED` | ``201`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.2.2 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`ACCEPTED` | ``202`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.2.3 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.3>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`NON_AUTHORITATIVE_INFORMATION` | ``203`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.2.4 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.4>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`NO_CONTENT` | ``204`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.2.5 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`RESET_CONTENT` | ``205`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.2.6 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.6>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`PARTIAL_CONTENT` | ``206`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.2.7 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`MULTI_STATUS` | ``207`` | WEBDAV `RFC 2518, Section 10.2 |
+| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_207>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`IM_USED` | ``226`` | Delta encoding in HTTP, |
+| | | :rfc:`3229`, Section 10.4.1 |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`MULTIPLE_CHOICES` | ``300`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.3.1 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`MOVED_PERMANENTLY` | ``301`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.3.2 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`FOUND` | ``302`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.3.3 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`SEE_OTHER` | ``303`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.3.4 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`NOT_MODIFIED` | ``304`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.3.5 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`USE_PROXY` | ``305`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.3.6 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.6>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`TEMPORARY_REDIRECT` | ``307`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.3.8 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.8>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`BAD_REQUEST` | ``400`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.1 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`UNAUTHORIZED` | ``401`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.2 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`PAYMENT_REQUIRED` | ``402`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.3 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`FORBIDDEN` | ``403`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.4 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`NOT_FOUND` | ``404`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.5 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`METHOD_NOT_ALLOWED` | ``405`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.6 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.6>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`NOT_ACCEPTABLE` | ``406`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.7 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.7>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`PROXY_AUTHENTICATION_REQUIRED` | ``407`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.8 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`REQUEST_TIMEOUT` | ``408`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.9 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.9>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`CONFLICT` | ``409`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.10 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`GONE` | ``410`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.11 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.11>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`LENGTH_REQUIRED` | ``411`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.12 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.12>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`PRECONDITION_FAILED` | ``412`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.13 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.13>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`REQUEST_ENTITY_TOO_LARGE` | ``413`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.14 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.14>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`REQUEST_URI_TOO_LONG` | ``414`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.15 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.15>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`UNSUPPORTED_MEDIA_TYPE` | ``415`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.16 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.16>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`REQUESTED_RANGE_NOT_SATISFIABLE` | ``416`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.17 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.17>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`EXPECTATION_FAILED` | ``417`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.4.18 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.18>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`UNPROCESSABLE_ENTITY` | ``422`` | WEBDAV, `RFC 2518, Section 10.3 |
+| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_422>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`LOCKED` | ``423`` | WEBDAV `RFC 2518, Section 10.4 |
+| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_423>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`FAILED_DEPENDENCY` | ``424`` | WEBDAV, `RFC 2518, Section 10.5 |
+| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_424>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`UPGRADE_REQUIRED` | ``426`` | HTTP Upgrade to TLS, |
+| | | :rfc:`2817`, Section 6 |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`INTERNAL_SERVER_ERROR` | ``500`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.5.1 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`NOT_IMPLEMENTED` | ``501`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.5.2 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.2>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`BAD_GATEWAY` | ``502`` | HTTP/1.1 `RFC 2616, Section |
+| | | 10.5.3 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.3>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`SERVICE_UNAVAILABLE` | ``503`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.5.4 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`GATEWAY_TIMEOUT` | ``504`` | HTTP/1.1 `RFC 2616, Section |
+| | | 10.5.5 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.5>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`HTTP_VERSION_NOT_SUPPORTED` | ``505`` | HTTP/1.1, `RFC 2616, Section |
+| | | 10.5.6 |
+| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.6>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`INSUFFICIENT_STORAGE` | ``507`` | WEBDAV, `RFC 2518, Section 10.6 |
+| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_507>`_ |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+| :const:`NOT_EXTENDED` | ``510`` | An HTTP Extension Framework, |
+| | | :rfc:`2774`, Section 7 |
++------------------------------------------+---------+-----------------------------------------------------------------------+
+
+
+.. data:: responses
+
+ This dictionary maps the HTTP 1.1 status codes to the W3C names.
+
+ Example: ``http.client.responses[http.client.NOT_FOUND]`` is ``'Not Found'``.
+
+
+.. _httpconnection-objects:
+
+HTTPConnection Objects
+----------------------
+
+:class:`HTTPConnection` instances have the following methods:
+
+
+.. method:: HTTPConnection.request(method, url, body=None, headers={})
+
+ This will send a request to the server using the HTTP request
+ method *method* and the selector *url*. If the *body* argument is
+ present, it should be string or bytes object of data to send after
+ the headers are finished. Strings are encoded as ISO-8859-1, the
+ default charset for HTTP. To use other encodings, pass a bytes
+ object. The Content-Length header is set to the length of the
+ string.
+
+ The *body* may also be an open :term:`file object`, in which case the
+ contents of the file is sent; this file object should support ``fileno()``
+ and ``read()`` methods. The header Content-Length is automatically set to
+ the length of the file as reported by stat. The *body* argument may also be
+ an iterable and Content-Length header should be explicitly provided when the
+ body is an iterable.
+
+ The *headers* argument should be a mapping of extra HTTP
+ headers to send with the request.
+
+ .. versionadded:: 3.2
+ *body* can now be an iterable.
+
+.. method:: HTTPConnection.getresponse()
+
+ Should be called after a request is sent to get the response from the server.
+ Returns an :class:`HTTPResponse` instance.
+
+ .. note::
+
+ Note that you must have read the whole response before you can send a new
+ request to the server.
+
+
+.. method:: HTTPConnection.set_debuglevel(level)
+
+ Set the debugging level. The default debug level is ``0``, meaning no
+ debugging output is printed. Any value greater than ``0`` will cause all
+ currently defined debug output to be printed to stdout. The ``debuglevel``
+ is passed to any new :class:`HTTPResponse` objects that are created.
+
+ .. versionadded:: 3.1
+
+
+.. method:: HTTPConnection.set_tunnel(host, port=None, headers=None)
+
+ Set the host and the port for HTTP Connect Tunnelling. Normally used when it
+ is required to a HTTPS Connection through a proxy server.
+
+ The headers argument should be a mapping of extra HTTP headers to send
+ with the CONNECT request.
+
+ .. versionadded:: 3.2
+
+
+.. method:: HTTPConnection.connect()
+
+ Connect to the server specified when the object was created.
+
+
+.. method:: HTTPConnection.close()
+
+ Close the connection to the server.
+
+As an alternative to using the :meth:`request` method described above, you can
+also send your request step by step, by using the four functions below.
+
+
+.. method:: HTTPConnection.putrequest(request, selector, skip_host=False, skip_accept_encoding=False)
+
+ This should be the first call after the connection to the server has been made.
+ It sends a line to the server consisting of the *request* string, the *selector*
+ string, and the HTTP version (``HTTP/1.1``). To disable automatic sending of
+ ``Host:`` or ``Accept-Encoding:`` headers (for example to accept additional
+ content encodings), specify *skip_host* or *skip_accept_encoding* with non-False
+ values.
+
+
+.. method:: HTTPConnection.putheader(header, argument[, ...])
+
+ Send an :rfc:`822`\ -style header to the server. It sends a line to the server
+ consisting of the header, a colon and a space, and the first argument. If more
+ arguments are given, continuation lines are sent, each consisting of a tab and
+ an argument.
+
+
+.. method:: HTTPConnection.endheaders(message_body=None)
+
+ Send a blank line to the server, signalling the end of the headers. The
+ optional *message_body* argument can be used to pass a message body
+ associated with the request. The message body will be sent in the same
+ packet as the message headers if it is string, otherwise it is sent in a
+ separate packet.
+
+.. method:: HTTPConnection.send(data)
+
+ Send data to the server. This should be used directly only after the
+ :meth:`endheaders` method has been called and before :meth:`getresponse` is
+ called.
+
+
+.. _httpresponse-objects:
+
+HTTPResponse Objects
+--------------------
+
+An :class:`HTTPResponse` instance wraps the HTTP response from the
+server. It provides access to the request headers and the entity
+body. The response is an iterable object and can be used in a with
+statement.
+
+
+.. method:: HTTPResponse.read([amt])
+
+ Reads and returns the response body, or up to the next *amt* bytes.
+
+
+.. method:: HTTPResponse.getheader(name, default=None)
+
+ Return the value of the header *name*, or *default* if there is no header
+ matching *name*. If there is more than one header with the name *name*,
+ return all of the values joined by ', '. If 'default' is any iterable other
+ than a single string, its elements are similarly returned joined by commas.
+
+
+.. method:: HTTPResponse.getheaders()
+
+ Return a list of (header, value) tuples.
+
+.. method:: HTTPResponse.fileno()
+
+ Return the ``fileno`` of the underlying socket.
+
+.. attribute:: HTTPResponse.msg
+
+ A :class:`http.client.HTTPMessage` instance containing the response
+ headers. :class:`http.client.HTTPMessage` is a subclass of
+ :class:`email.message.Message`.
+
+
+.. attribute:: HTTPResponse.version
+
+ HTTP protocol version used by server. 10 for HTTP/1.0, 11 for HTTP/1.1.
+
+
+.. attribute:: HTTPResponse.status
+
+ Status code returned by server.
+
+
+.. attribute:: HTTPResponse.reason
+
+ Reason phrase returned by server.
+
+
+.. attribute:: HTTPResponse.debuglevel
+
+ A debugging hook. If :attr:`debuglevel` is greater than zero, messages
+ will be printed to stdout as the response is read and parsed.
+
+.. attribute:: HTTPResponse.closed
+
+ Is True if the stream is closed.
+
+Examples
+--------
+
+Here is an example session that uses the ``GET`` method::
+
+ >>> import http.client
+ >>> conn = http.client.HTTPConnection("www.python.org")
+ >>> conn.request("GET", "/index.html")
+ >>> r1 = conn.getresponse()
+ >>> print(r1.status, r1.reason)
+ 200 OK
+ >>> data1 = r1.read() # This will return entire content.
+ >>> # The following example demonstrates reading data in chunks.
+ >>> conn.request("GET", "/index.html")
+ >>> r1 = conn.getresponse()
+ >>> while not r1.closed:
+ ... print(r1.read(200)) # 200 bytes
+ b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
+ ...
+ >>> # Example of an invalid request
+ >>> conn.request("GET", "/parrot.spam")
+ >>> r2 = conn.getresponse()
+ >>> print(r2.status, r2.reason)
+ 404 Not Found
+ >>> data2 = r2.read()
+ >>> conn.close()
+
+Here is an example session that uses the ``HEAD`` method. Note that the
+``HEAD`` method never returns any data. ::
+
+ >>> import http.client
+ >>> conn = http.client.HTTPConnection("www.python.org")
+ >>> conn.request("HEAD","/index.html")
+ >>> res = conn.getresponse()
+ >>> print(res.status, res.reason)
+ 200 OK
+ >>> data = res.read()
+ >>> print(len(data))
+ 0
+ >>> data == b''
+ True
+
+Here is an example session that shows how to ``POST`` requests::
+
+ >>> import http.client, urllib.parse
+ >>> params = urllib.parse.urlencode({'@number': 12524, '@type': 'issue', '@action': 'show'})
+ >>> headers = {"Content-type": "application/x-www-form-urlencoded",
+ ... "Accept": "text/plain"}
+ >>> conn = http.client.HTTPConnection("bugs.python.org")
+ >>> conn.request("POST", "", params, headers)
+ >>> response = conn.getresponse()
+ >>> print(response.status, response.reason)
+ 302 Found
+ >>> data = response.read()
+ >>> data
+ b'Redirecting to <a href="http://bugs.python.org/issue12524">http://bugs.python.org/issue12524</a>'
+ >>> conn.close()
+
+
+.. _httpmessage-objects:
+
+HTTPMessage Objects
+-------------------
+
+An :class:`http.client.HTTPMessage` instance holds the headers from an HTTP
+response. It is implemented using the :class:`email.message.Message` class.
+
+.. XXX Define the methods that clients can depend upon between versions.
diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst
new file mode 100644
index 0000000..cc8f251
--- /dev/null
+++ b/Doc/library/http.cookiejar.rst
@@ -0,0 +1,742 @@
+:mod:`http.cookiejar` --- Cookie handling for HTTP clients
+==========================================================
+
+.. module:: http.cookiejar
+ :synopsis: Classes for automatic handling of HTTP cookies.
+.. moduleauthor:: John J. Lee <jjl@pobox.com>
+.. sectionauthor:: John J. Lee <jjl@pobox.com>
+
+**Source code:** :source:`Lib/http/cookiejar.py`
+
+--------------
+
+The :mod:`http.cookiejar` module defines classes for automatic handling of HTTP
+cookies. It is useful for accessing web sites that require small pieces of data
+-- :dfn:`cookies` -- to be set on the client machine by an HTTP response from a
+web server, and then returned to the server in later HTTP requests.
+
+Both the regular Netscape cookie protocol and the protocol defined by
+:rfc:`2965` are handled. RFC 2965 handling is switched off by default.
+:rfc:`2109` cookies are parsed as Netscape cookies and subsequently treated
+either as Netscape or RFC 2965 cookies according to the 'policy' in effect.
+Note that the great majority of cookies on the Internet are Netscape cookies.
+:mod:`http.cookiejar` attempts to follow the de-facto Netscape cookie protocol (which
+differs substantially from that set out in the original Netscape specification),
+including taking note of the ``max-age`` and ``port`` cookie-attributes
+introduced with RFC 2965.
+
+.. note::
+
+ The various named parameters found in :mailheader:`Set-Cookie` and
+ :mailheader:`Set-Cookie2` headers (eg. ``domain`` and ``expires``) are
+ conventionally referred to as :dfn:`attributes`. To distinguish them from
+ Python attributes, the documentation for this module uses the term
+ :dfn:`cookie-attribute` instead.
+
+
+The module defines the following exception:
+
+
+.. exception:: LoadError
+
+ Instances of :class:`FileCookieJar` raise this exception on failure to load
+ cookies from a file. :exc:`LoadError` is a subclass of :exc:`IOError`.
+
+
+The following classes are provided:
+
+
+.. class:: CookieJar(policy=None)
+
+ *policy* is an object implementing the :class:`CookiePolicy` interface.
+
+ The :class:`CookieJar` class stores HTTP cookies. It extracts cookies from HTTP
+ requests, and returns them in HTTP responses. :class:`CookieJar` instances
+ automatically expire contained cookies when necessary. Subclasses are also
+ responsible for storing and retrieving cookies from a file or database.
+
+
+.. class:: FileCookieJar(filename, delayload=None, policy=None)
+
+ *policy* is an object implementing the :class:`CookiePolicy` interface. For the
+ other arguments, see the documentation for the corresponding attributes.
+
+ A :class:`CookieJar` which can load cookies from, and perhaps save cookies to, a
+ file on disk. Cookies are **NOT** loaded from the named file until either the
+ :meth:`load` or :meth:`revert` method is called. Subclasses of this class are
+ documented in section :ref:`file-cookie-jar-classes`.
+
+
+.. class:: CookiePolicy()
+
+ This class is responsible for deciding whether each cookie should be accepted
+ from / returned to the server.
+
+
+.. class:: DefaultCookiePolicy( blocked_domains=None, allowed_domains=None, netscape=True, rfc2965=False, rfc2109_as_netscape=None, hide_cookie2=False, strict_domain=False, strict_rfc2965_unverifiable=True, strict_ns_unverifiable=False, strict_ns_domain=DefaultCookiePolicy.DomainLiberal, strict_ns_set_initial_dollar=False, strict_ns_set_path=False )
+
+ Constructor arguments should be passed as keyword arguments only.
+ *blocked_domains* is a sequence of domain names that we never accept cookies
+ from, nor return cookies to. *allowed_domains* if not :const:`None`, this is a
+ sequence of the only domains for which we accept and return cookies. For all
+ other arguments, see the documentation for :class:`CookiePolicy` and
+ :class:`DefaultCookiePolicy` objects.
+
+ :class:`DefaultCookiePolicy` implements the standard accept / reject rules for
+ Netscape and RFC 2965 cookies. By default, RFC 2109 cookies (ie. cookies
+ received in a :mailheader:`Set-Cookie` header with a version cookie-attribute of
+ 1) are treated according to the RFC 2965 rules. However, if RFC 2965 handling
+ is turned off or :attr:`rfc2109_as_netscape` is True, RFC 2109 cookies are
+ 'downgraded' by the :class:`CookieJar` instance to Netscape cookies, by
+ setting the :attr:`version` attribute of the :class:`Cookie` instance to 0.
+ :class:`DefaultCookiePolicy` also provides some parameters to allow some
+ fine-tuning of policy.
+
+
+.. class:: Cookie()
+
+ This class represents Netscape, RFC 2109 and RFC 2965 cookies. It is not
+ expected that users of :mod:`http.cookiejar` construct their own :class:`Cookie`
+ instances. Instead, if necessary, call :meth:`make_cookies` on a
+ :class:`CookieJar` instance.
+
+
+.. seealso::
+
+ Module :mod:`urllib.request`
+ URL opening with automatic cookie handling.
+
+ Module :mod:`http.cookies`
+ HTTP cookie classes, principally useful for server-side code. The
+ :mod:`http.cookiejar` and :mod:`http.cookies` modules do not depend on each
+ other.
+
+ http://wp.netscape.com/newsref/std/cookie_spec.html
+ The specification of the original Netscape cookie protocol. Though this is
+ still the dominant protocol, the 'Netscape cookie protocol' implemented by all
+ the major browsers (and :mod:`http.cookiejar`) only bears a passing resemblance to
+ the one sketched out in ``cookie_spec.html``.
+
+ :rfc:`2109` - HTTP State Management Mechanism
+ Obsoleted by RFC 2965. Uses :mailheader:`Set-Cookie` with version=1.
+
+ :rfc:`2965` - HTTP State Management Mechanism
+ The Netscape protocol with the bugs fixed. Uses :mailheader:`Set-Cookie2` in
+ place of :mailheader:`Set-Cookie`. Not widely used.
+
+ http://kristol.org/cookie/errata.html
+ Unfinished errata to RFC 2965.
+
+ :rfc:`2964` - Use of HTTP State Management
+
+.. _cookie-jar-objects:
+
+CookieJar and FileCookieJar Objects
+-----------------------------------
+
+:class:`CookieJar` objects support the :term:`iterator` protocol for iterating over
+contained :class:`Cookie` objects.
+
+:class:`CookieJar` has the following methods:
+
+
+.. method:: CookieJar.add_cookie_header(request)
+
+ Add correct :mailheader:`Cookie` header to *request*.
+
+ If policy allows (ie. the :attr:`rfc2965` and :attr:`hide_cookie2` attributes of
+ the :class:`CookieJar`'s :class:`CookiePolicy` instance are true and false
+ respectively), the :mailheader:`Cookie2` header is also added when appropriate.
+
+ The *request* object (usually a :class:`urllib.request..Request` instance)
+ must support the methods :meth:`get_full_url`, :meth:`get_host`,
+ :meth:`get_type`, :meth:`unverifiable`, :meth:`get_origin_req_host`,
+ :meth:`has_header`, :meth:`get_header`, :meth:`header_items`, and
+ :meth:`add_unredirected_header`, as documented by :mod:`urllib.request`.
+
+
+.. method:: CookieJar.extract_cookies(response, request)
+
+ Extract cookies from HTTP *response* and store them in the :class:`CookieJar`,
+ where allowed by policy.
+
+ The :class:`CookieJar` will look for allowable :mailheader:`Set-Cookie` and
+ :mailheader:`Set-Cookie2` headers in the *response* argument, and store cookies
+ as appropriate (subject to the :meth:`CookiePolicy.set_ok` method's approval).
+
+ The *response* object (usually the result of a call to
+ :meth:`urllib.request.urlopen`, or similar) should support an :meth:`info`
+ method, which returns a :class:`email.message.Message` instance.
+
+ The *request* object (usually a :class:`urllib.request.Request` instance)
+ must support the methods :meth:`get_full_url`, :meth:`get_host`,
+ :meth:`unverifiable`, and :meth:`get_origin_req_host`, as documented by
+ :mod:`urllib.request`. The request is used to set default values for
+ cookie-attributes as well as for checking that the cookie is allowed to be
+ set.
+
+
+.. method:: CookieJar.set_policy(policy)
+
+ Set the :class:`CookiePolicy` instance to be used.
+
+
+.. method:: CookieJar.make_cookies(response, request)
+
+ Return sequence of :class:`Cookie` objects extracted from *response* object.
+
+ See the documentation for :meth:`extract_cookies` for the interfaces required of
+ the *response* and *request* arguments.
+
+
+.. method:: CookieJar.set_cookie_if_ok(cookie, request)
+
+ Set a :class:`Cookie` if policy says it's OK to do so.
+
+
+.. method:: CookieJar.set_cookie(cookie)
+
+ Set a :class:`Cookie`, without checking with policy to see whether or not it
+ should be set.
+
+
+.. method:: CookieJar.clear([domain[, path[, name]]])
+
+ Clear some cookies.
+
+ If invoked without arguments, clear all cookies. If given a single argument,
+ only cookies belonging to that *domain* will be removed. If given two arguments,
+ cookies belonging to the specified *domain* and URL *path* are removed. If
+ given three arguments, then the cookie with the specified *domain*, *path* and
+ *name* is removed.
+
+ Raises :exc:`KeyError` if no matching cookie exists.
+
+
+.. method:: CookieJar.clear_session_cookies()
+
+ Discard all session cookies.
+
+ Discards all contained cookies that have a true :attr:`discard` attribute
+ (usually because they had either no ``max-age`` or ``expires`` cookie-attribute,
+ or an explicit ``discard`` cookie-attribute). For interactive browsers, the end
+ of a session usually corresponds to closing the browser window.
+
+ Note that the :meth:`save` method won't save session cookies anyway, unless you
+ ask otherwise by passing a true *ignore_discard* argument.
+
+:class:`FileCookieJar` implements the following additional methods:
+
+
+.. method:: FileCookieJar.save(filename=None, ignore_discard=False, ignore_expires=False)
+
+ Save cookies to a file.
+
+ This base class raises :exc:`NotImplementedError`. Subclasses may leave this
+ method unimplemented.
+
+ *filename* is the name of file in which to save cookies. If *filename* is not
+ specified, :attr:`self.filename` is used (whose default is the value passed to
+ the constructor, if any); if :attr:`self.filename` is :const:`None`,
+ :exc:`ValueError` is raised.
+
+ *ignore_discard*: save even cookies set to be discarded. *ignore_expires*: save
+ even cookies that have expired
+
+ The file is overwritten if it already exists, thus wiping all the cookies it
+ contains. Saved cookies can be restored later using the :meth:`load` or
+ :meth:`revert` methods.
+
+
+.. method:: FileCookieJar.load(filename=None, ignore_discard=False, ignore_expires=False)
+
+ Load cookies from a file.
+
+ Old cookies are kept unless overwritten by newly loaded ones.
+
+ Arguments are as for :meth:`save`.
+
+ The named file must be in the format understood by the class, or
+ :exc:`LoadError` will be raised. Also, :exc:`IOError` may be raised, for
+ example if the file does not exist.
+
+
+.. method:: FileCookieJar.revert(filename=None, ignore_discard=False, ignore_expires=False)
+
+ Clear all cookies and reload cookies from a saved file.
+
+ :meth:`revert` can raise the same exceptions as :meth:`load`. If there is a
+ failure, the object's state will not be altered.
+
+:class:`FileCookieJar` instances have the following public attributes:
+
+
+.. attribute:: FileCookieJar.filename
+
+ Filename of default file in which to keep cookies. This attribute may be
+ assigned to.
+
+
+.. attribute:: FileCookieJar.delayload
+
+ If true, load cookies lazily from disk. This attribute should not be assigned
+ to. This is only a hint, since this only affects performance, not behaviour
+ (unless the cookies on disk are changing). A :class:`CookieJar` object may
+ ignore it. None of the :class:`FileCookieJar` classes included in the standard
+ library lazily loads cookies.
+
+
+.. _file-cookie-jar-classes:
+
+FileCookieJar subclasses and co-operation with web browsers
+-----------------------------------------------------------
+
+The following :class:`CookieJar` subclasses are provided for reading and
+writing .
+
+.. class:: MozillaCookieJar(filename, delayload=None, policy=None)
+
+ A :class:`FileCookieJar` that can load from and save cookies to disk in the
+ Mozilla ``cookies.txt`` file format (which is also used by the Lynx and Netscape
+ browsers).
+
+ .. note::
+
+ This loses information about RFC 2965 cookies, and also about newer or
+ non-standard cookie-attributes such as ``port``.
+
+ .. warning::
+
+ Back up your cookies before saving if you have cookies whose loss / corruption
+ would be inconvenient (there are some subtleties which may lead to slight
+ changes in the file over a load / save round-trip).
+
+ Also note that cookies saved while Mozilla is running will get clobbered by
+ Mozilla.
+
+
+.. class:: LWPCookieJar(filename, delayload=None, policy=None)
+
+ A :class:`FileCookieJar` that can load from and save cookies to disk in format
+ compatible with the libwww-perl library's ``Set-Cookie3`` file format. This is
+ convenient if you want to store cookies in a human-readable file.
+
+
+.. _cookie-policy-objects:
+
+CookiePolicy Objects
+--------------------
+
+Objects implementing the :class:`CookiePolicy` interface have the following
+methods:
+
+
+.. method:: CookiePolicy.set_ok(cookie, request)
+
+ Return boolean value indicating whether cookie should be accepted from server.
+
+ *cookie* is a :class:`Cookie` instance. *request* is an object
+ implementing the interface defined by the documentation for
+ :meth:`CookieJar.extract_cookies`.
+
+
+.. method:: CookiePolicy.return_ok(cookie, request)
+
+ Return boolean value indicating whether cookie should be returned to server.
+
+ *cookie* is a :class:`Cookie` instance. *request* is an object
+ implementing the interface defined by the documentation for
+ :meth:`CookieJar.add_cookie_header`.
+
+
+.. method:: CookiePolicy.domain_return_ok(domain, request)
+
+ Return false if cookies should not be returned, given cookie domain.
+
+ This method is an optimization. It removes the need for checking every cookie
+ with a particular domain (which might involve reading many files). Returning
+ true from :meth:`domain_return_ok` and :meth:`path_return_ok` leaves all the
+ work to :meth:`return_ok`.
+
+ If :meth:`domain_return_ok` returns true for the cookie domain,
+ :meth:`path_return_ok` is called for the cookie path. Otherwise,
+ :meth:`path_return_ok` and :meth:`return_ok` are never called for that cookie
+ domain. If :meth:`path_return_ok` returns true, :meth:`return_ok` is called
+ with the :class:`Cookie` object itself for a full check. Otherwise,
+ :meth:`return_ok` is never called for that cookie path.
+
+ Note that :meth:`domain_return_ok` is called for every *cookie* domain, not just
+ for the *request* domain. For example, the function might be called with both
+ ``".example.com"`` and ``"www.example.com"`` if the request domain is
+ ``"www.example.com"``. The same goes for :meth:`path_return_ok`.
+
+ The *request* argument is as documented for :meth:`return_ok`.
+
+
+.. method:: CookiePolicy.path_return_ok(path, request)
+
+ Return false if cookies should not be returned, given cookie path.
+
+ See the documentation for :meth:`domain_return_ok`.
+
+In addition to implementing the methods above, implementations of the
+:class:`CookiePolicy` interface must also supply the following attributes,
+indicating which protocols should be used, and how. All of these attributes may
+be assigned to.
+
+
+.. attribute:: CookiePolicy.netscape
+
+ Implement Netscape protocol.
+
+
+.. attribute:: CookiePolicy.rfc2965
+
+ Implement RFC 2965 protocol.
+
+
+.. attribute:: CookiePolicy.hide_cookie2
+
+ Don't add :mailheader:`Cookie2` header to requests (the presence of this header
+ indicates to the server that we understand RFC 2965 cookies).
+
+The most useful way to define a :class:`CookiePolicy` class is by subclassing
+from :class:`DefaultCookiePolicy` and overriding some or all of the methods
+above. :class:`CookiePolicy` itself may be used as a 'null policy' to allow
+setting and receiving any and all cookies (this is unlikely to be useful).
+
+
+.. _default-cookie-policy-objects:
+
+DefaultCookiePolicy Objects
+---------------------------
+
+Implements the standard rules for accepting and returning cookies.
+
+Both RFC 2965 and Netscape cookies are covered. RFC 2965 handling is switched
+off by default.
+
+The easiest way to provide your own policy is to override this class and call
+its methods in your overridden implementations before adding your own additional
+checks::
+
+ import http.cookiejar
+ class MyCookiePolicy(http.cookiejar.DefaultCookiePolicy):
+ def set_ok(self, cookie, request):
+ if not http.cookiejar.DefaultCookiePolicy.set_ok(self, cookie, request):
+ return False
+ if i_dont_want_to_store_this_cookie(cookie):
+ return False
+ return True
+
+In addition to the features required to implement the :class:`CookiePolicy`
+interface, this class allows you to block and allow domains from setting and
+receiving cookies. There are also some strictness switches that allow you to
+tighten up the rather loose Netscape protocol rules a little bit (at the cost of
+blocking some benign cookies).
+
+A domain blacklist and whitelist is provided (both off by default). Only domains
+not in the blacklist and present in the whitelist (if the whitelist is active)
+participate in cookie setting and returning. Use the *blocked_domains*
+constructor argument, and :meth:`blocked_domains` and
+:meth:`set_blocked_domains` methods (and the corresponding argument and methods
+for *allowed_domains*). If you set a whitelist, you can turn it off again by
+setting it to :const:`None`.
+
+Domains in block or allow lists that do not start with a dot must equal the
+cookie domain to be matched. For example, ``"example.com"`` matches a blacklist
+entry of ``"example.com"``, but ``"www.example.com"`` does not. Domains that do
+start with a dot are matched by more specific domains too. For example, both
+``"www.example.com"`` and ``"www.coyote.example.com"`` match ``".example.com"``
+(but ``"example.com"`` itself does not). IP addresses are an exception, and
+must match exactly. For example, if blocked_domains contains ``"192.168.1.2"``
+and ``".168.1.2"``, 192.168.1.2 is blocked, but 193.168.1.2 is not.
+
+:class:`DefaultCookiePolicy` implements the following additional methods:
+
+
+.. method:: DefaultCookiePolicy.blocked_domains()
+
+ Return the sequence of blocked domains (as a tuple).
+
+
+.. method:: DefaultCookiePolicy.set_blocked_domains(blocked_domains)
+
+ Set the sequence of blocked domains.
+
+
+.. method:: DefaultCookiePolicy.is_blocked(domain)
+
+ Return whether *domain* is on the blacklist for setting or receiving cookies.
+
+
+.. method:: DefaultCookiePolicy.allowed_domains()
+
+ Return :const:`None`, or the sequence of allowed domains (as a tuple).
+
+
+.. method:: DefaultCookiePolicy.set_allowed_domains(allowed_domains)
+
+ Set the sequence of allowed domains, or :const:`None`.
+
+
+.. method:: DefaultCookiePolicy.is_not_allowed(domain)
+
+ Return whether *domain* is not on the whitelist for setting or receiving
+ cookies.
+
+:class:`DefaultCookiePolicy` instances have the following attributes, which are
+all initialised from the constructor arguments of the same name, and which may
+all be assigned to.
+
+
+.. attribute:: DefaultCookiePolicy.rfc2109_as_netscape
+
+ If true, request that the :class:`CookieJar` instance downgrade RFC 2109 cookies
+ (ie. cookies received in a :mailheader:`Set-Cookie` header with a version
+ cookie-attribute of 1) to Netscape cookies by setting the version attribute of
+ the :class:`Cookie` instance to 0. The default value is :const:`None`, in which
+ case RFC 2109 cookies are downgraded if and only if RFC 2965 handling is turned
+ off. Therefore, RFC 2109 cookies are downgraded by default.
+
+
+General strictness switches:
+
+.. attribute:: DefaultCookiePolicy.strict_domain
+
+ Don't allow sites to set two-component domains with country-code top-level
+ domains like ``.co.uk``, ``.gov.uk``, ``.co.nz``.etc. This is far from perfect
+ and isn't guaranteed to work!
+
+
+RFC 2965 protocol strictness switches:
+
+.. attribute:: DefaultCookiePolicy.strict_rfc2965_unverifiable
+
+ Follow RFC 2965 rules on unverifiable transactions (usually, an unverifiable
+ transaction is one resulting from a redirect or a request for an image hosted on
+ another site). If this is false, cookies are *never* blocked on the basis of
+ verifiability
+
+
+Netscape protocol strictness switches:
+
+.. attribute:: DefaultCookiePolicy.strict_ns_unverifiable
+
+ apply RFC 2965 rules on unverifiable transactions even to Netscape cookies
+
+
+.. attribute:: DefaultCookiePolicy.strict_ns_domain
+
+ Flags indicating how strict to be with domain-matching rules for Netscape
+ cookies. See below for acceptable values.
+
+
+.. attribute:: DefaultCookiePolicy.strict_ns_set_initial_dollar
+
+ Ignore cookies in Set-Cookie: headers that have names starting with ``'$'``.
+
+
+.. attribute:: DefaultCookiePolicy.strict_ns_set_path
+
+ Don't allow setting cookies whose path doesn't path-match request URI.
+
+:attr:`strict_ns_domain` is a collection of flags. Its value is constructed by
+or-ing together (for example, ``DomainStrictNoDots|DomainStrictNonDomain`` means
+both flags are set).
+
+
+.. attribute:: DefaultCookiePolicy.DomainStrictNoDots
+
+ When setting cookies, the 'host prefix' must not contain a dot (eg.
+ ``www.foo.bar.com`` can't set a cookie for ``.bar.com``, because ``www.foo``
+ contains a dot).
+
+
+.. attribute:: DefaultCookiePolicy.DomainStrictNonDomain
+
+ Cookies that did not explicitly specify a ``domain`` cookie-attribute can only
+ be returned to a domain equal to the domain that set the cookie (eg.
+ ``spam.example.com`` won't be returned cookies from ``example.com`` that had no
+ ``domain`` cookie-attribute).
+
+
+.. attribute:: DefaultCookiePolicy.DomainRFC2965Match
+
+ When setting cookies, require a full RFC 2965 domain-match.
+
+The following attributes are provided for convenience, and are the most useful
+combinations of the above flags:
+
+
+.. attribute:: DefaultCookiePolicy.DomainLiberal
+
+ Equivalent to 0 (ie. all of the above Netscape domain strictness flags switched
+ off).
+
+
+.. attribute:: DefaultCookiePolicy.DomainStrict
+
+ Equivalent to ``DomainStrictNoDots|DomainStrictNonDomain``.
+
+
+Cookie Objects
+--------------
+
+:class:`Cookie` instances have Python attributes roughly corresponding to the
+standard cookie-attributes specified in the various cookie standards. The
+correspondence is not one-to-one, because there are complicated rules for
+assigning default values, because the ``max-age`` and ``expires``
+cookie-attributes contain equivalent information, and because RFC 2109 cookies
+may be 'downgraded' by :mod:`http.cookiejar` from version 1 to version 0 (Netscape)
+cookies.
+
+Assignment to these attributes should not be necessary other than in rare
+circumstances in a :class:`CookiePolicy` method. The class does not enforce
+internal consistency, so you should know what you're doing if you do that.
+
+
+.. attribute:: Cookie.version
+
+ Integer or :const:`None`. Netscape cookies have :attr:`version` 0. RFC 2965 and
+ RFC 2109 cookies have a ``version`` cookie-attribute of 1. However, note that
+ :mod:`http.cookiejar` may 'downgrade' RFC 2109 cookies to Netscape cookies, in which
+ case :attr:`version` is 0.
+
+
+.. attribute:: Cookie.name
+
+ Cookie name (a string).
+
+
+.. attribute:: Cookie.value
+
+ Cookie value (a string), or :const:`None`.
+
+
+.. attribute:: Cookie.port
+
+ String representing a port or a set of ports (eg. '80', or '80,8080'), or
+ :const:`None`.
+
+
+.. attribute:: Cookie.path
+
+ Cookie path (a string, eg. ``'/acme/rocket_launchers'``).
+
+
+.. attribute:: Cookie.secure
+
+ True if cookie should only be returned over a secure connection.
+
+
+.. attribute:: Cookie.expires
+
+ Integer expiry date in seconds since epoch, or :const:`None`. See also the
+ :meth:`is_expired` method.
+
+
+.. attribute:: Cookie.discard
+
+ True if this is a session cookie.
+
+
+.. attribute:: Cookie.comment
+
+ String comment from the server explaining the function of this cookie, or
+ :const:`None`.
+
+
+.. attribute:: Cookie.comment_url
+
+ URL linking to a comment from the server explaining the function of this cookie,
+ or :const:`None`.
+
+
+.. attribute:: Cookie.rfc2109
+
+ True if this cookie was received as an RFC 2109 cookie (ie. the cookie
+ arrived in a :mailheader:`Set-Cookie` header, and the value of the Version
+ cookie-attribute in that header was 1). This attribute is provided because
+ :mod:`http.cookiejar` may 'downgrade' RFC 2109 cookies to Netscape cookies, in
+ which case :attr:`version` is 0.
+
+
+.. attribute:: Cookie.port_specified
+
+ True if a port or set of ports was explicitly specified by the server (in the
+ :mailheader:`Set-Cookie` / :mailheader:`Set-Cookie2` header).
+
+
+.. attribute:: Cookie.domain_specified
+
+ True if a domain was explicitly specified by the server.
+
+
+.. attribute:: Cookie.domain_initial_dot
+
+ True if the domain explicitly specified by the server began with a dot
+ (``'.'``).
+
+Cookies may have additional non-standard cookie-attributes. These may be
+accessed using the following methods:
+
+
+.. method:: Cookie.has_nonstandard_attr(name)
+
+ Return true if cookie has the named cookie-attribute.
+
+
+.. method:: Cookie.get_nonstandard_attr(name, default=None)
+
+ If cookie has the named cookie-attribute, return its value. Otherwise, return
+ *default*.
+
+
+.. method:: Cookie.set_nonstandard_attr(name, value)
+
+ Set the value of the named cookie-attribute.
+
+The :class:`Cookie` class also defines the following method:
+
+
+.. method:: Cookie.is_expired(now=None)
+
+ True if cookie has passed the time at which the server requested it should
+ expire. If *now* is given (in seconds since the epoch), return whether the
+ cookie has expired at the specified time.
+
+
+Examples
+--------
+
+The first example shows the most common usage of :mod:`http.cookiejar`::
+
+ import http.cookiejar, urllib.request
+ cj = http.cookiejar.CookieJar()
+ opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
+ r = opener.open("http://example.com/")
+
+This example illustrates how to open a URL using your Netscape, Mozilla, or Lynx
+cookies (assumes Unix/Netscape convention for location of the cookies file)::
+
+ import os, http.cookiejar, urllib.request
+ cj = http.cookiejar.MozillaCookieJar()
+ cj.load(os.path.join(os.path.expanduser("~"), ".netscape", "cookies.txt"))
+ opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
+ r = opener.open("http://example.com/")
+
+The next example illustrates the use of :class:`DefaultCookiePolicy`. Turn on
+RFC 2965 cookies, be more strict about domains when setting and returning
+Netscape cookies, and block some domains from setting cookies or having them
+returned::
+
+ import urllib.request
+ from http.cookiejar import CookieJar, DefaultCookiePolicy
+ policy = DefaultCookiePolicy(
+ rfc2965=True, strict_ns_domain=Policy.DomainStrict,
+ blocked_domains=["ads.net", ".ads.net"])
+ cj = CookieJar(policy)
+ opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
+ r = opener.open("http://example.com/")
+
diff --git a/Doc/library/http.cookies.rst b/Doc/library/http.cookies.rst
new file mode 100644
index 0000000..5ae3fd4
--- /dev/null
+++ b/Doc/library/http.cookies.rst
@@ -0,0 +1,247 @@
+:mod:`http.cookies` --- HTTP state management
+=============================================
+
+.. module:: http.cookies
+ :synopsis: Support for HTTP state management (cookies).
+.. moduleauthor:: Timothy O'Malley <timo@alum.mit.edu>
+.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
+
+**Source code:** :source:`Lib/http/cookies.py`
+
+--------------
+
+The :mod:`http.cookies` module defines classes for abstracting the concept of
+cookies, an HTTP state management mechanism. It supports both simple string-only
+cookies, and provides an abstraction for having any serializable data-type as
+cookie value.
+
+The module formerly strictly applied the parsing rules described in the
+:rfc:`2109` and :rfc:`2068` specifications. It has since been discovered that
+MSIE 3.0x doesn't follow the character rules outlined in those specs and also
+many current day browsers and servers have relaxed parsing rules when comes to
+Cookie handling. As a result, the parsing rules used are a bit less strict.
+
+The character set, :data:`string.ascii_letters`, :data:`string.digits` and
+``!#$%&'*+-.^_`|~`` denote the set of valid characters allowed by this module
+in Cookie name (as :attr:`~Morsel.key`).
+
+
+.. note::
+
+ On encountering an invalid cookie, :exc:`CookieError` is raised, so if your
+ cookie data comes from a browser you should always prepare for invalid data
+ and catch :exc:`CookieError` on parsing.
+
+
+.. exception:: CookieError
+
+ Exception failing because of :rfc:`2109` invalidity: incorrect attributes,
+ incorrect :mailheader:`Set-Cookie` header, etc.
+
+
+.. class:: BaseCookie([input])
+
+ This class is a dictionary-like object whose keys are strings and whose values
+ are :class:`Morsel` instances. Note that upon setting a key to a value, the
+ value is first converted to a :class:`Morsel` containing the key and the value.
+
+ If *input* is given, it is passed to the :meth:`load` method.
+
+
+.. class:: SimpleCookie([input])
+
+ This class derives from :class:`BaseCookie` and overrides :meth:`value_decode`
+ and :meth:`value_encode` to be the identity and :func:`str` respectively.
+
+
+.. seealso::
+
+ Module :mod:`http.cookiejar`
+ HTTP cookie handling for web *clients*. The :mod:`http.cookiejar` and
+ :mod:`http.cookies` modules do not depend on each other.
+
+ :rfc:`2109` - HTTP State Management Mechanism
+ This is the state management specification implemented by this module.
+
+
+.. _cookie-objects:
+
+Cookie Objects
+--------------
+
+
+.. method:: BaseCookie.value_decode(val)
+
+ Return a decoded value from a string representation. Return value can be any
+ type. This method does nothing in :class:`BaseCookie` --- it exists so it can be
+ overridden.
+
+
+.. method:: BaseCookie.value_encode(val)
+
+ Return an encoded value. *val* can be any type, but return value must be a
+ string. This method does nothing in :class:`BaseCookie` --- it exists so it can
+ be overridden
+
+ In general, it should be the case that :meth:`value_encode` and
+ :meth:`value_decode` are inverses on the range of *value_decode*.
+
+
+.. method:: BaseCookie.output(attrs=None, header='Set-Cookie:', sep='\\r\\n')
+
+ Return a string representation suitable to be sent as HTTP headers. *attrs* and
+ *header* are sent to each :class:`Morsel`'s :meth:`output` method. *sep* is used
+ to join the headers together, and is by default the combination ``'\r\n'``
+ (CRLF).
+
+
+.. method:: BaseCookie.js_output(attrs=None)
+
+ Return an embeddable JavaScript snippet, which, if run on a browser which
+ supports JavaScript, will act the same as if the HTTP headers was sent.
+
+ The meaning for *attrs* is the same as in :meth:`output`.
+
+
+.. method:: BaseCookie.load(rawdata)
+
+ If *rawdata* is a string, parse it as an ``HTTP_COOKIE`` and add the values
+ found there as :class:`Morsel`\ s. If it is a dictionary, it is equivalent to::
+
+ for k, v in rawdata.items():
+ cookie[k] = v
+
+
+.. _morsel-objects:
+
+Morsel Objects
+--------------
+
+
+.. class:: Morsel
+
+ Abstract a key/value pair, which has some :rfc:`2109` attributes.
+
+ Morsels are dictionary-like objects, whose set of keys is constant --- the valid
+ :rfc:`2109` attributes, which are
+
+ * ``expires``
+ * ``path``
+ * ``comment``
+ * ``domain``
+ * ``max-age``
+ * ``secure``
+ * ``version``
+ * ``httponly``
+
+ The attribute :attr:`httponly` specifies that the cookie is only transferred
+ in HTTP requests, and is not accessible through JavaScript. This is intended
+ to mitigate some forms of cross-site scripting.
+
+ The keys are case-insensitive.
+
+
+.. attribute:: Morsel.value
+
+ The value of the cookie.
+
+
+.. attribute:: Morsel.coded_value
+
+ The encoded value of the cookie --- this is what should be sent.
+
+
+.. attribute:: Morsel.key
+
+ The name of the cookie.
+
+
+.. method:: Morsel.set(key, value, coded_value)
+
+ Set the *key*, *value* and *coded_value* attributes.
+
+
+.. method:: Morsel.isReservedKey(K)
+
+ Whether *K* is a member of the set of keys of a :class:`Morsel`.
+
+
+.. method:: Morsel.output(attrs=None, header='Set-Cookie:')
+
+ Return a string representation of the Morsel, suitable to be sent as an HTTP
+ header. By default, all the attributes are included, unless *attrs* is given, in
+ which case it should be a list of attributes to use. *header* is by default
+ ``"Set-Cookie:"``.
+
+
+.. method:: Morsel.js_output(attrs=None)
+
+ Return an embeddable JavaScript snippet, which, if run on a browser which
+ supports JavaScript, will act the same as if the HTTP header was sent.
+
+ The meaning for *attrs* is the same as in :meth:`output`.
+
+
+.. method:: Morsel.OutputString(attrs=None)
+
+ Return a string representing the Morsel, without any surrounding HTTP or
+ JavaScript.
+
+ The meaning for *attrs* is the same as in :meth:`output`.
+
+
+.. _cookie-example:
+
+Example
+-------
+
+The following example demonstrates how to use the :mod:`http.cookies` module.
+
+.. doctest::
+ :options: +NORMALIZE_WHITESPACE
+
+ >>> from http import cookies
+ >>> C = cookies.SimpleCookie()
+ >>> C["fig"] = "newton"
+ >>> C["sugar"] = "wafer"
+ >>> print(C) # generate HTTP headers
+ Set-Cookie: fig=newton
+ Set-Cookie: sugar=wafer
+ >>> print(C.output()) # same thing
+ Set-Cookie: fig=newton
+ Set-Cookie: sugar=wafer
+ >>> C = cookies.SimpleCookie()
+ >>> C["rocky"] = "road"
+ >>> C["rocky"]["path"] = "/cookie"
+ >>> print(C.output(header="Cookie:"))
+ Cookie: rocky=road; Path=/cookie
+ >>> print(C.output(attrs=[], header="Cookie:"))
+ Cookie: rocky=road
+ >>> C = cookies.SimpleCookie()
+ >>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header)
+ >>> print(C)
+ Set-Cookie: chips=ahoy
+ Set-Cookie: vienna=finger
+ >>> C = cookies.SimpleCookie()
+ >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
+ >>> print(C)
+ Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
+ >>> C = cookies.SimpleCookie()
+ >>> C["oreo"] = "doublestuff"
+ >>> C["oreo"]["path"] = "/"
+ >>> print(C)
+ Set-Cookie: oreo=doublestuff; Path=/
+ >>> C = cookies.SimpleCookie()
+ >>> C["twix"] = "none for you"
+ >>> C["twix"].value
+ 'none for you'
+ >>> C = cookies.SimpleCookie()
+ >>> C["number"] = 7 # equivalent to C["number"] = str(7)
+ >>> C["string"] = "seven"
+ >>> C["number"].value
+ '7'
+ >>> C["string"].value
+ 'seven'
+ >>> print(C)
+ Set-Cookie: number=7
+ Set-Cookie: string=seven
diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst
new file mode 100644
index 0000000..300e332
--- /dev/null
+++ b/Doc/library/http.server.rst
@@ -0,0 +1,380 @@
+:mod:`http.server` --- HTTP servers
+===================================
+
+.. module:: http.server
+ :synopsis: HTTP server and request handlers.
+
+
+.. index::
+ pair: WWW; server
+ pair: HTTP; protocol
+ single: URL
+ single: httpd
+
+**Source code:** :source:`Lib/http/server.py`
+
+--------------
+
+This module defines classes for implementing HTTP servers (Web servers).
+
+One class, :class:`HTTPServer`, is a :class:`socketserver.TCPServer` subclass.
+It creates and listens at the HTTP socket, dispatching the requests to a
+handler. Code to create and run the server looks like this::
+
+ def run(server_class=HTTPServer, handler_class=BaseHTTPRequestHandler):
+ server_address = ('', 8000)
+ httpd = server_class(server_address, handler_class)
+ httpd.serve_forever()
+
+
+.. class:: HTTPServer(server_address, RequestHandlerClass)
+
+ This class builds on the :class:`TCPServer` class by storing the server
+ address as instance variables named :attr:`server_name` and
+ :attr:`server_port`. The server is accessible by the handler, typically
+ through the handler's :attr:`server` instance variable.
+
+
+The :class:`HTTPServer` must be given a *RequestHandlerClass* on instantiation,
+of which this module provides three different variants:
+
+.. class:: BaseHTTPRequestHandler(request, client_address, server)
+
+ This class is used to handle the HTTP requests that arrive at the server. By
+ itself, it cannot respond to any actual HTTP requests; it must be subclassed
+ to handle each request method (e.g. GET or POST).
+ :class:`BaseHTTPRequestHandler` provides a number of class and instance
+ variables, and methods for use by subclasses.
+
+ The handler will parse the request and the headers, then call a method
+ specific to the request type. The method name is constructed from the
+ request. For example, for the request method ``SPAM``, the :meth:`do_SPAM`
+ method will be called with no arguments. All of the relevant information is
+ stored in instance variables of the handler. Subclasses should not need to
+ override or extend the :meth:`__init__` method.
+
+ :class:`BaseHTTPRequestHandler` has the following instance variables:
+
+ .. attribute:: client_address
+
+ Contains a tuple of the form ``(host, port)`` referring to the client's
+ address.
+
+ .. attribute:: server
+
+ Contains the server instance.
+
+
+ .. attribute:: command
+
+ Contains the command (request type). For example, ``'GET'``.
+
+ .. attribute:: path
+
+ Contains the request path.
+
+ .. attribute:: request_version
+
+ Contains the version string from the request. For example, ``'HTTP/1.0'``.
+
+ .. attribute:: headers
+
+ Holds an instance of the class specified by the :attr:`MessageClass` class
+ variable. This instance parses and manages the headers in the HTTP
+ request.
+
+ .. attribute:: rfile
+
+ Contains an input stream, positioned at the start of the optional input
+ data.
+
+ .. attribute:: wfile
+
+ Contains the output stream for writing a response back to the
+ client. Proper adherence to the HTTP protocol must be used when writing to
+ this stream.
+
+ :class:`BaseHTTPRequestHandler` has the following class variables:
+
+ .. attribute:: server_version
+
+ Specifies the server software version. You may want to override this. The
+ format is multiple whitespace-separated strings, where each string is of
+ the form name[/version]. For example, ``'BaseHTTP/0.2'``.
+
+ .. attribute:: sys_version
+
+ Contains the Python system version, in a form usable by the
+ :attr:`version_string` method and the :attr:`server_version` class
+ variable. For example, ``'Python/1.4'``.
+
+ .. attribute:: error_message_format
+
+ Specifies a format string for building an error response to the client. It
+ uses parenthesized, keyed format specifiers, so the format operand must be
+ a dictionary. The *code* key should be an integer, specifying the numeric
+ HTTP error code value. *message* should be a string containing a
+ (detailed) error message of what occurred, and *explain* should be an
+ explanation of the error code number. Default *message* and *explain*
+ values can found in the *responses* class variable.
+
+ .. attribute:: error_content_type
+
+ Specifies the Content-Type HTTP header of error responses sent to the
+ client. The default value is ``'text/html'``.
+
+ .. attribute:: protocol_version
+
+ This specifies the HTTP protocol version used in responses. If set to
+ ``'HTTP/1.1'``, the server will permit HTTP persistent connections;
+ however, your server *must* then include an accurate ``Content-Length``
+ header (using :meth:`send_header`) in all of its responses to clients.
+ For backwards compatibility, the setting defaults to ``'HTTP/1.0'``.
+
+ .. attribute:: MessageClass
+
+ Specifies an :class:`email.message.Message`\ -like class to parse HTTP
+ headers. Typically, this is not overridden, and it defaults to
+ :class:`http.client.HTTPMessage`.
+
+ .. attribute:: responses
+
+ This variable contains a mapping of error code integers to two-element tuples
+ containing a short and long message. For example, ``{code: (shortmessage,
+ longmessage)}``. The *shortmessage* is usually used as the *message* key in an
+ error response, and *longmessage* as the *explain* key (see the
+ :attr:`error_message_format` class variable).
+
+ A :class:`BaseHTTPRequestHandler` instance has the following methods:
+
+ .. method:: handle()
+
+ Calls :meth:`handle_one_request` once (or, if persistent connections are
+ enabled, multiple times) to handle incoming HTTP requests. You should
+ never need to override it; instead, implement appropriate :meth:`do_\*`
+ methods.
+
+ .. method:: handle_one_request()
+
+ This method will parse and dispatch the request to the appropriate
+ :meth:`do_\*` method. You should never need to override it.
+
+ .. method:: handle_expect_100()
+
+ When a HTTP/1.1 compliant server receives a ``Expect: 100-continue``
+ request header it responds back with a ``100 Continue`` followed by ``200
+ OK`` headers.
+ This method can be overridden to raise an error if the server does not
+ want the client to continue. For e.g. server can chose to send ``417
+ Expectation Failed`` as a response header and ``return False``.
+
+ .. versionadded:: 3.2
+
+ .. method:: send_error(code, message=None)
+
+ Sends and logs a complete error reply to the client. The numeric *code*
+ specifies the HTTP error code, with *message* as optional, more specific text. A
+ complete set of headers is sent, followed by text composed using the
+ :attr:`error_message_format` class variable.
+
+ .. method:: send_response(code, message=None)
+
+ Sends a response header and logs the accepted request. The HTTP response
+ line is sent, followed by *Server* and *Date* headers. The values for
+ these two headers are picked up from the :meth:`version_string` and
+ :meth:`date_time_string` methods, respectively.
+
+ .. method:: send_header(keyword, value)
+
+ Stores the HTTP header to an internal buffer which will be written to the
+ output stream when :meth:`end_headers` method is invoked.
+ *keyword* should specify the header keyword, with *value*
+ specifying its value.
+
+ .. versionchanged:: 3.2 Storing the headers in an internal buffer
+
+
+ .. method:: send_response_only(code, message=None)
+
+ Sends the reponse header only, used for the purposes when ``100
+ Continue`` response is sent by the server to the client. The headers not
+ buffered and sent directly the output stream.If the *message* is not
+ specified, the HTTP message corresponding the response *code* is sent.
+
+ .. versionadded:: 3.2
+
+ .. method:: end_headers()
+
+ Write the buffered HTTP headers to the output stream and send a blank
+ line, indicating the end of the HTTP headers in the response.
+
+ .. versionchanged:: 3.2 Writing the buffered headers to the output stream.
+
+ .. method:: log_request(code='-', size='-')
+
+ Logs an accepted (successful) request. *code* should specify the numeric
+ HTTP code associated with the response. If a size of the response is
+ available, then it should be passed as the *size* parameter.
+
+ .. method:: log_error(...)
+
+ Logs an error when a request cannot be fulfilled. By default, it passes
+ the message to :meth:`log_message`, so it takes the same arguments
+ (*format* and additional values).
+
+
+ .. method:: log_message(format, ...)
+
+ Logs an arbitrary message to ``sys.stderr``. This is typically overridden
+ to create custom error logging mechanisms. The *format* argument is a
+ standard printf-style format string, where the additional arguments to
+ :meth:`log_message` are applied as inputs to the formatting. The client
+ ip address and current date and time are prefixed to every message logged.
+
+ .. method:: version_string()
+
+ Returns the server software's version string. This is a combination of the
+ :attr:`server_version` and :attr:`sys_version` class variables.
+
+ .. method:: date_time_string(timestamp=None)
+
+ Returns the date and time given by *timestamp* (which must be None or in
+ the format returned by :func:`time.time`), formatted for a message
+ header. If *timestamp* is omitted, it uses the current date and time.
+
+ The result looks like ``'Sun, 06 Nov 1994 08:49:37 GMT'``.
+
+ .. method:: log_date_time_string()
+
+ Returns the current date and time, formatted for logging.
+
+ .. method:: address_string()
+
+ Returns the client address, formatted for logging. A name lookup is
+ performed on the client's IP address.
+
+
+.. class:: SimpleHTTPRequestHandler(request, client_address, server)
+
+ This class serves files from the current directory and below, directly
+ mapping the directory structure to HTTP requests.
+
+ A lot of the work, such as parsing the request, is done by the base class
+ :class:`BaseHTTPRequestHandler`. This class implements the :func:`do_GET`
+ and :func:`do_HEAD` functions.
+
+ The following are defined as class-level attributes of
+ :class:`SimpleHTTPRequestHandler`:
+
+ .. attribute:: server_version
+
+ This will be ``"SimpleHTTP/" + __version__``, where ``__version__`` is
+ defined at the module level.
+
+ .. attribute:: extensions_map
+
+ A dictionary mapping suffixes into MIME types. The default is
+ signified by an empty string, and is considered to be
+ ``application/octet-stream``. The mapping is used case-insensitively,
+ and so should contain only lower-cased keys.
+
+ The :class:`SimpleHTTPRequestHandler` class defines the following methods:
+
+ .. method:: do_HEAD()
+
+ This method serves the ``'HEAD'`` request type: it sends the headers it
+ would send for the equivalent ``GET`` request. See the :meth:`do_GET`
+ method for a more complete explanation of the possible headers.
+
+ .. method:: do_GET()
+
+ The request is mapped to a local file by interpreting the request as a
+ path relative to the current working directory.
+
+ If the request was mapped to a directory, the directory is checked for a
+ file named ``index.html`` or ``index.htm`` (in that order). If found, the
+ file's contents are returned; otherwise a directory listing is generated
+ by calling the :meth:`list_directory` method. This method uses
+ :func:`os.listdir` to scan the directory, and returns a ``404`` error
+ response if the :func:`listdir` fails.
+
+ If the request was mapped to a file, it is opened and the contents are
+ returned. Any :exc:`IOError` exception in opening the requested file is
+ mapped to a ``404``, ``'File not found'`` error. Otherwise, the content
+ type is guessed by calling the :meth:`guess_type` method, which in turn
+ uses the *extensions_map* variable.
+
+ A ``'Content-type:'`` header with the guessed content type is output,
+ followed by a ``'Content-Length:'`` header with the file's size and a
+ ``'Last-Modified:'`` header with the file's modification time.
+
+ Then follows a blank line signifying the end of the headers, and then the
+ contents of the file are output. If the file's MIME type starts with
+ ``text/`` the file is opened in text mode; otherwise binary mode is used.
+
+ For example usage, see the implementation of the :func:`test` function
+ invocation in the :mod:`http.server` module.
+
+
+The :class:`SimpleHTTPRequestHandler` class can be used in the following
+manner in order to create a very basic webserver serving files relative to
+the current directory. ::
+
+ import http.server
+ import socketserver
+
+ PORT = 8000
+
+ Handler = http.server.SimpleHTTPRequestHandler
+
+ httpd = socketserver.TCPServer(("", PORT), Handler)
+
+ print("serving at port", PORT)
+ httpd.serve_forever()
+
+:mod:`http.server` can also be invoked directly using the :option:`-m`
+switch of the interpreter with a ``port number`` argument. Similar to
+the previous example, this serves files relative to the current directory. ::
+
+ python -m http.server 8000
+
+
+.. class:: CGIHTTPRequestHandler(request, client_address, server)
+
+ This class is used to serve either files or output of CGI scripts from the
+ current directory and below. Note that mapping HTTP hierarchic structure to
+ local directory structure is exactly as in :class:`SimpleHTTPRequestHandler`.
+
+ .. note::
+
+ CGI scripts run by the :class:`CGIHTTPRequestHandler` class cannot execute
+ redirects (HTTP code 302), because code 200 (script output follows) is
+ sent prior to execution of the CGI script. This pre-empts the status
+ code.
+
+ The class will however, run the CGI script, instead of serving it as a file,
+ if it guesses it to be a CGI script. Only directory-based CGI are used ---
+ the other common server configuration is to treat special extensions as
+ denoting CGI scripts.
+
+ The :func:`do_GET` and :func:`do_HEAD` functions are modified to run CGI scripts
+ and serve the output, instead of serving files, if the request leads to
+ somewhere below the ``cgi_directories`` path.
+
+ The :class:`CGIHTTPRequestHandler` defines the following data member:
+
+ .. attribute:: cgi_directories
+
+ This defaults to ``['/cgi-bin', '/htbin']`` and describes directories to
+ treat as containing CGI scripts.
+
+ The :class:`CGIHTTPRequestHandler` defines the following method:
+
+ .. method:: do_POST()
+
+ This method serves the ``'POST'`` request type, only allowed for CGI
+ scripts. Error 501, "Can only POST to CGI scripts", is output when trying
+ to POST to a non-CGI url.
+
+ Note that CGI scripts will be run with UID of user nobody, for security
+ reasons. Problems with the CGI script will be translated to error 403.
diff --git a/Doc/library/httplib.rst b/Doc/library/httplib.rst
deleted file mode 100644
index 1e37cdf..0000000
--- a/Doc/library/httplib.rst
+++ /dev/null
@@ -1,614 +0,0 @@
-:mod:`httplib` --- HTTP protocol client
-=======================================
-
-.. module:: httplib
- :synopsis: HTTP and HTTPS protocol client (requires sockets).
-
-.. note::
- The :mod:`httplib` module has been renamed to :mod:`http.client` in Python
- 3. The :term:`2to3` tool will automatically adapt imports when converting
- your sources to Python 3.
-
-
-.. index::
- pair: HTTP; protocol
- single: HTTP; httplib (standard module)
-
-.. index:: module: urllib
-
-**Source code:** :source:`Lib/httplib.py`
-
---------------
-
-This module defines classes which implement the client side of the HTTP and
-HTTPS protocols. It is normally not used directly --- the module :mod:`urllib`
-uses it to handle URLs that use HTTP and HTTPS.
-
-.. note::
-
- HTTPS support is only available if the :mod:`socket` module was compiled with
- SSL support.
-
-.. note::
-
- The public interface for this module changed substantially in Python 2.0. The
- :class:`HTTP` class is retained only for backward compatibility with 1.5.2. It
- should not be used in new code. Refer to the online docstrings for usage.
-
-The module provides the following classes:
-
-
-.. class:: HTTPConnection(host[, port[, strict[, timeout[, source_address]]]])
-
- An :class:`HTTPConnection` instance represents one transaction with an HTTP
- server. It should be instantiated passing it a host and optional port
- number. If no port number is passed, the port is extracted from the host
- string if it has the form ``host:port``, else the default HTTP port (80) is
- used. When True, the optional parameter *strict* (which defaults to a false
- value) causes ``BadStatusLine`` to
- be raised if the status line can't be parsed as a valid HTTP/1.0 or 1.1
- status line. If the optional *timeout* parameter is given, blocking
- operations (like connection attempts) will timeout after that many seconds
- (if it is not given, the global default timeout setting is used).
- The optional *source_address* parameter may be a tuple of a (host, port)
- to use as the source address the HTTP connection is made from.
-
- For example, the following calls all create instances that connect to the server
- at the same host and port::
-
- >>> h1 = httplib.HTTPConnection('www.cwi.nl')
- >>> h2 = httplib.HTTPConnection('www.cwi.nl:80')
- >>> h3 = httplib.HTTPConnection('www.cwi.nl', 80)
- >>> h3 = httplib.HTTPConnection('www.cwi.nl', 80, timeout=10)
-
- .. versionadded:: 2.0
-
- .. versionchanged:: 2.6
- *timeout* was added.
-
- .. versionchanged:: 2.7
- *source_address* was added.
-
-
-.. class:: HTTPSConnection(host[, port[, key_file[, cert_file[, strict[, timeout[, source_address]]]]]])
-
- A subclass of :class:`HTTPConnection` that uses SSL for communication with
- secure servers. Default port is ``443``. *key_file* is the name of a PEM
- formatted file that contains your private key. *cert_file* is a PEM formatted
- certificate chain file.
-
- .. warning::
- This does not do any verification of the server's certificate.
-
- .. versionadded:: 2.0
-
- .. versionchanged:: 2.6
- *timeout* was added.
-
- .. versionchanged:: 2.7
- *source_address* was added.
-
-
-.. class:: HTTPResponse(sock, debuglevel=0, strict=0)
-
- Class whose instances are returned upon successful connection. Not instantiated
- directly by user.
-
- .. versionadded:: 2.0
-
-.. class:: HTTPMessage
-
- An :class:`HTTPMessage` instance is used to hold the headers from an HTTP
- response. It is implemented using the :class:`mimetools.Message` class and
- provides utility functions to deal with HTTP Headers. It is not directly
- instantiated by the users.
-
-
-The following exceptions are raised as appropriate:
-
-
-.. exception:: HTTPException
-
- The base class of the other exceptions in this module. It is a subclass of
- :exc:`Exception`.
-
- .. versionadded:: 2.0
-
-
-.. exception:: NotConnected
-
- A subclass of :exc:`HTTPException`.
-
- .. versionadded:: 2.0
-
-
-.. exception:: InvalidURL
-
- A subclass of :exc:`HTTPException`, raised if a port is given and is either
- non-numeric or empty.
-
- .. versionadded:: 2.3
-
-
-.. exception:: UnknownProtocol
-
- A subclass of :exc:`HTTPException`.
-
- .. versionadded:: 2.0
-
-
-.. exception:: UnknownTransferEncoding
-
- A subclass of :exc:`HTTPException`.
-
- .. versionadded:: 2.0
-
-
-.. exception:: UnimplementedFileMode
-
- A subclass of :exc:`HTTPException`.
-
- .. versionadded:: 2.0
-
-
-.. exception:: IncompleteRead
-
- A subclass of :exc:`HTTPException`.
-
- .. versionadded:: 2.0
-
-
-.. exception:: ImproperConnectionState
-
- A subclass of :exc:`HTTPException`.
-
- .. versionadded:: 2.0
-
-
-.. exception:: CannotSendRequest
-
- A subclass of :exc:`ImproperConnectionState`.
-
- .. versionadded:: 2.0
-
-
-.. exception:: CannotSendHeader
-
- A subclass of :exc:`ImproperConnectionState`.
-
- .. versionadded:: 2.0
-
-
-.. exception:: ResponseNotReady
-
- A subclass of :exc:`ImproperConnectionState`.
-
- .. versionadded:: 2.0
-
-
-.. exception:: BadStatusLine
-
- A subclass of :exc:`HTTPException`. Raised if a server responds with a HTTP
- status code that we don't understand.
-
- .. versionadded:: 2.0
-
-The constants defined in this module are:
-
-
-.. data:: HTTP_PORT
-
- The default port for the HTTP protocol (always ``80``).
-
-
-.. data:: HTTPS_PORT
-
- The default port for the HTTPS protocol (always ``443``).
-
-and also the following constants for integer status codes:
-
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| Constant | Value | Definition |
-+==========================================+=========+=======================================================================+
-| :const:`CONTINUE` | ``100`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.1.1 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.1>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`SWITCHING_PROTOCOLS` | ``101`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.1.2 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.2>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`PROCESSING` | ``102`` | WEBDAV, `RFC 2518, Section 10.1 |
-| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_102>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`OK` | ``200`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.2.1 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`CREATED` | ``201`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.2.2 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`ACCEPTED` | ``202`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.2.3 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.3>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`NON_AUTHORITATIVE_INFORMATION` | ``203`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.2.4 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.4>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`NO_CONTENT` | ``204`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.2.5 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`RESET_CONTENT` | ``205`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.2.6 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.6>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`PARTIAL_CONTENT` | ``206`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.2.7 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`MULTI_STATUS` | ``207`` | WEBDAV `RFC 2518, Section 10.2 |
-| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_207>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`IM_USED` | ``226`` | Delta encoding in HTTP, |
-| | | :rfc:`3229`, Section 10.4.1 |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`MULTIPLE_CHOICES` | ``300`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.3.1 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`MOVED_PERMANENTLY` | ``301`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.3.2 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`FOUND` | ``302`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.3.3 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`SEE_OTHER` | ``303`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.3.4 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`NOT_MODIFIED` | ``304`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.3.5 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`USE_PROXY` | ``305`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.3.6 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.6>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`TEMPORARY_REDIRECT` | ``307`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.3.8 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.8>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`BAD_REQUEST` | ``400`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.1 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`UNAUTHORIZED` | ``401`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.2 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`PAYMENT_REQUIRED` | ``402`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.3 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`FORBIDDEN` | ``403`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.4 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`NOT_FOUND` | ``404`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.5 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`METHOD_NOT_ALLOWED` | ``405`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.6 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.6>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`NOT_ACCEPTABLE` | ``406`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.7 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.7>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`PROXY_AUTHENTICATION_REQUIRED` | ``407`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.8 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`REQUEST_TIMEOUT` | ``408`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.9 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.9>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`CONFLICT` | ``409`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.10 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`GONE` | ``410`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.11 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.11>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`LENGTH_REQUIRED` | ``411`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.12 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.12>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`PRECONDITION_FAILED` | ``412`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.13 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.13>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`REQUEST_ENTITY_TOO_LARGE` | ``413`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.14 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.14>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`REQUEST_URI_TOO_LONG` | ``414`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.15 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.15>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`UNSUPPORTED_MEDIA_TYPE` | ``415`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.16 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.16>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`REQUESTED_RANGE_NOT_SATISFIABLE` | ``416`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.17 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.17>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`EXPECTATION_FAILED` | ``417`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.4.18 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.18>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`UNPROCESSABLE_ENTITY` | ``422`` | WEBDAV, `RFC 2518, Section 10.3 |
-| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_422>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`LOCKED` | ``423`` | WEBDAV `RFC 2518, Section 10.4 |
-| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_423>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`FAILED_DEPENDENCY` | ``424`` | WEBDAV, `RFC 2518, Section 10.5 |
-| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_424>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`UPGRADE_REQUIRED` | ``426`` | HTTP Upgrade to TLS, |
-| | | :rfc:`2817`, Section 6 |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`INTERNAL_SERVER_ERROR` | ``500`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.5.1 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`NOT_IMPLEMENTED` | ``501`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.5.2 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.2>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`BAD_GATEWAY` | ``502`` | HTTP/1.1 `RFC 2616, Section |
-| | | 10.5.3 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.3>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`SERVICE_UNAVAILABLE` | ``503`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.5.4 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`GATEWAY_TIMEOUT` | ``504`` | HTTP/1.1 `RFC 2616, Section |
-| | | 10.5.5 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.5>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`HTTP_VERSION_NOT_SUPPORTED` | ``505`` | HTTP/1.1, `RFC 2616, Section |
-| | | 10.5.6 |
-| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.6>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`INSUFFICIENT_STORAGE` | ``507`` | WEBDAV, `RFC 2518, Section 10.6 |
-| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_507>`_ |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-| :const:`NOT_EXTENDED` | ``510`` | An HTTP Extension Framework, |
-| | | :rfc:`2774`, Section 7 |
-+------------------------------------------+---------+-----------------------------------------------------------------------+
-
-
-.. data:: responses
-
- This dictionary maps the HTTP 1.1 status codes to the W3C names.
-
- Example: ``httplib.responses[httplib.NOT_FOUND]`` is ``'Not Found'``.
-
- .. versionadded:: 2.5
-
-
-.. _httpconnection-objects:
-
-HTTPConnection Objects
-----------------------
-
-:class:`HTTPConnection` instances have the following methods:
-
-
-.. method:: HTTPConnection.request(method, url[, body[, headers]])
-
- This will send a request to the server using the HTTP request method *method*
- and the selector *url*. If the *body* argument is present, it should be a
- string of data to send after the headers are finished. Alternatively, it may
- be an open file object, in which case the contents of the file is sent; this
- file object should support ``fileno()`` and ``read()`` methods. The header
- Content-Length is automatically set to the correct value. The *headers*
- argument should be a mapping of extra HTTP headers to send with the request.
-
- .. versionchanged:: 2.6
- *body* can be a file object.
-
-
-.. method:: HTTPConnection.getresponse()
-
- Should be called after a request is sent to get the response from the server.
- Returns an :class:`HTTPResponse` instance.
-
- .. note::
-
- Note that you must have read the whole response before you can send a new
- request to the server.
-
-
-.. method:: HTTPConnection.set_debuglevel(level)
-
- Set the debugging level (the amount of debugging output printed). The default
- debug level is ``0``, meaning no debugging output is printed.
-
-
-.. method:: HTTPConnection.set_tunnel(host,port=None, headers=None)
-
- Set the host and the port for HTTP Connect Tunnelling. Normally used when
- it is required to do HTTPS Conection through a proxy server.
-
- The headers argument should be a mapping of extra HTTP headers to send
- with the CONNECT request.
-
- .. versionadded:: 2.7
-
-
-.. method:: HTTPConnection.connect()
-
- Connect to the server specified when the object was created.
-
-
-.. method:: HTTPConnection.close()
-
- Close the connection to the server.
-
-As an alternative to using the :meth:`request` method described above, you can
-also send your request step by step, by using the four functions below.
-
-
-.. method:: HTTPConnection.putrequest(request, selector[, skip_host[, skip_accept_encoding]])
-
- This should be the first call after the connection to the server has been made.
- It sends a line to the server consisting of the *request* string, the *selector*
- string, and the HTTP version (``HTTP/1.1``). To disable automatic sending of
- ``Host:`` or ``Accept-Encoding:`` headers (for example to accept additional
- content encodings), specify *skip_host* or *skip_accept_encoding* with non-False
- values.
-
- .. versionchanged:: 2.4
- *skip_accept_encoding* argument added.
-
-
-.. method:: HTTPConnection.putheader(header, argument[, ...])
-
- Send an :rfc:`822`\ -style header to the server. It sends a line to the server
- consisting of the header, a colon and a space, and the first argument. If more
- arguments are given, continuation lines are sent, each consisting of a tab and
- an argument.
-
-
-.. method:: HTTPConnection.endheaders(message_body=None)
-
- Send a blank line to the server, signalling the end of the headers. The
- optional *message_body* argument can be used to pass a message body
- associated with the request. The message body will be sent in the same
- packet as the message headers if it is string, otherwise it is sent in a
- separate packet.
-
- .. versionchanged:: 2.7
- *message_body* was added.
-
-
-.. method:: HTTPConnection.send(data)
-
- Send data to the server. This should be used directly only after the
- :meth:`endheaders` method has been called and before :meth:`getresponse` is
- called.
-
-
-.. _httpresponse-objects:
-
-HTTPResponse Objects
---------------------
-
-:class:`HTTPResponse` instances have the following methods and attributes:
-
-
-.. method:: HTTPResponse.read([amt])
-
- Reads and returns the response body, or up to the next *amt* bytes.
-
-
-.. method:: HTTPResponse.getheader(name[, default])
-
- Get the contents of the header *name*, or *default* if there is no matching
- header.
-
-
-.. method:: HTTPResponse.getheaders()
-
- Return a list of (header, value) tuples.
-
- .. versionadded:: 2.4
-
-.. method:: HTTPResponse.fileno()
-
- Returns the ``fileno`` of the underlying socket.
-
-.. attribute:: HTTPResponse.msg
-
- A :class:`mimetools.Message` instance containing the response headers.
-
-
-.. attribute:: HTTPResponse.version
-
- HTTP protocol version used by server. 10 for HTTP/1.0, 11 for HTTP/1.1.
-
-
-.. attribute:: HTTPResponse.status
-
- Status code returned by server.
-
-
-.. attribute:: HTTPResponse.reason
-
- Reason phrase returned by server.
-
-
-.. _httplib-examples:
-
-Examples
---------
-
-Here is an example session that uses the ``GET`` method::
-
- >>> import httplib
- >>> conn = httplib.HTTPConnection("www.python.org")
- >>> conn.request("GET", "/index.html")
- >>> r1 = conn.getresponse()
- >>> print r1.status, r1.reason
- 200 OK
- >>> data1 = r1.read()
- >>> conn.request("GET", "/parrot.spam")
- >>> r2 = conn.getresponse()
- >>> print r2.status, r2.reason
- 404 Not Found
- >>> data2 = r2.read()
- >>> conn.close()
-
-Here is an example session that uses the ``HEAD`` method. Note that the
-``HEAD`` method never returns any data. ::
-
- >>> import httplib
- >>> conn = httplib.HTTPConnection("www.python.org")
- >>> conn.request("HEAD","/index.html")
- >>> res = conn.getresponse()
- >>> print res.status, res.reason
- 200 OK
- >>> data = res.read()
- >>> print len(data)
- 0
- >>> data == ''
- True
-
-Here is an example session that shows how to ``POST`` requests::
-
- >>> import httplib, urllib
- >>> params = urllib.urlencode({'@number': 12524, '@type': 'issue', '@action': 'show'})
- >>> headers = {"Content-type": "application/x-www-form-urlencoded",
- ... "Accept": "text/plain"}
- >>> conn = httplib.HTTPConnection("bugs.python.org")
- >>> conn.request("POST", "", params, headers)
- >>> response = conn.getresponse()
- >>> print response.status, response.reason
- 302 Found
- >>> data = response.read()
- >>> data
- 'Redirecting to <a href="http://bugs.python.org/issue12524">http://bugs.python.org/issue12524</a>'
- >>> conn.close()
-
diff --git a/Doc/library/i18n.rst b/Doc/library/i18n.rst
index 8e57102..818f129 100644
--- a/Doc/library/i18n.rst
+++ b/Doc/library/i18n.rst
@@ -1,4 +1,3 @@
-
.. _i18n:
********************
diff --git a/Doc/library/ic.rst b/Doc/library/ic.rst
deleted file mode 100644
index ab40e7a..0000000
--- a/Doc/library/ic.rst
+++ /dev/null
@@ -1,124 +0,0 @@
-:mod:`ic` --- Access to the Mac OS X Internet Config
-====================================================
-
-.. module:: ic
- :platform: Mac
- :synopsis: Access to the Mac OS X Internet Config.
- :deprecated:
-
-
-This module provides access to various internet-related preferences set through
-:program:`System Preferences` or the :program:`Finder`.
-
-.. note::
-
- This module has been removed in Python 3.x.
-
-
-.. index:: module: icglue
-
-There is a low-level companion module :mod:`icglue` which provides the basic
-Internet Config access functionality. This low-level module is not documented,
-but the docstrings of the routines document the parameters and the routine names
-are the same as for the Pascal or C API to Internet Config, so the standard IC
-programmers' documentation can be used if this module is needed.
-
-The :mod:`ic` module defines the :exc:`error` exception and symbolic names for
-all error codes Internet Config can produce; see the source for details.
-
-
-.. exception:: error
-
- Exception raised on errors in the :mod:`ic` module.
-
-The :mod:`ic` module defines the following class and function:
-
-
-.. class:: IC([signature[, ic]])
-
- Create an Internet Config object. The signature is a 4-character creator code of
- the current application (default ``'Pyth'``) which may influence some of ICs
- settings. The optional *ic* argument is a low-level ``icglue.icinstance``
- created beforehand, this may be useful if you want to get preferences from a
- different config file, etc.
-
-
-.. function:: launchurl(url[, hint])
- parseurl(data[, start[, end[, hint]]])
- mapfile(file)
- maptypecreator(type, creator[, filename])
- settypecreator(file)
-
- These functions are "shortcuts" to the methods of the same name, described
- below.
-
-
-IC Objects
-----------
-
-:class:`IC` objects have a mapping interface, hence to obtain the mail address
-you simply get ``ic['MailAddress']``. Assignment also works, and changes the
-option in the configuration file.
-
-The module knows about various datatypes, and converts the internal IC
-representation to a "logical" Python data structure. Running the :mod:`ic`
-module standalone will run a test program that lists all keys and values in your
-IC database, this will have to serve as documentation.
-
-If the module does not know how to represent the data it returns an instance of
-the ``ICOpaqueData`` type, with the raw data in its :attr:`data` attribute.
-Objects of this type are also acceptable values for assignment.
-
-Besides the dictionary interface, :class:`IC` objects have the following
-methods:
-
-
-.. method:: IC.launchurl(url[, hint])
-
- Parse the given URL, launch the correct application and pass it the URL. The
- optional *hint* can be a scheme name such as ``'mailto:'``, in which case
- incomplete URLs are completed with this scheme. If *hint* is not provided,
- incomplete URLs are invalid.
-
-
-.. method:: IC.parseurl(data[, start[, end[, hint]]])
-
- Find an URL somewhere in *data* and return start position, end position and the
- URL. The optional *start* and *end* can be used to limit the search, so for
- instance if a user clicks in a long text field you can pass the whole text field
- and the click-position in *start* and this routine will return the whole URL in
- which the user clicked. As above, *hint* is an optional scheme used to complete
- incomplete URLs.
-
-
-.. method:: IC.mapfile(file)
-
- Return the mapping entry for the given *file*, which can be passed as either a
- filename or an :func:`FSSpec` result, and which need not exist.
-
- The mapping entry is returned as a tuple ``(version, type, creator, postcreator,
- flags, extension, appname, postappname, mimetype, entryname)``, where *version*
- is the entry version number, *type* is the 4-character filetype, *creator* is
- the 4-character creator type, *postcreator* is the 4-character creator code of
- an optional application to post-process the file after downloading, *flags* are
- various bits specifying whether to transfer in binary or ascii and such,
- *extension* is the filename extension for this file type, *appname* is the
- printable name of the application to which this file belongs, *postappname* is
- the name of the postprocessing application, *mimetype* is the MIME type of this
- file and *entryname* is the name of this entry.
-
-
-.. method:: IC.maptypecreator(type, creator[, filename])
-
- Return the mapping entry for files with given 4-character *type* and *creator*
- codes. The optional *filename* may be specified to further help finding the
- correct entry (if the creator code is ``'????'``, for instance).
-
- The mapping entry is returned in the same format as for *mapfile*.
-
-
-.. method:: IC.settypecreator(file)
-
- Given an existing *file*, specified either as a filename or as an :func:`FSSpec`
- result, set its creator and type correctly based on its extension. The finder
- is told about the change, so the finder icon will be updated quickly.
diff --git a/Doc/library/imageop.rst b/Doc/library/imageop.rst
deleted file mode 100644
index e6cb669..0000000
--- a/Doc/library/imageop.rst
+++ /dev/null
@@ -1,107 +0,0 @@
-
-:mod:`imageop` --- Manipulate raw image data
-============================================
-
-.. module:: imageop
- :synopsis: Manipulate raw image data.
- :deprecated:
-
-.. deprecated:: 2.6
- The :mod:`imageop` module has been removed in Python 3.
-
-The :mod:`imageop` module contains some useful operations on images. It operates
-on images consisting of 8 or 32 bit pixels stored in Python strings. This is
-the same format as used by :func:`gl.lrectwrite` and the :mod:`imgfile` module.
-
-The module defines the following variables and functions:
-
-
-.. exception:: error
-
- This exception is raised on all errors, such as unknown number of bits per
- pixel, etc.
-
-
-.. function:: crop(image, psize, width, height, x0, y0, x1, y1)
-
- Return the selected part of *image*, which should be *width* by *height* in size
- and consist of pixels of *psize* bytes. *x0*, *y0*, *x1* and *y1* are like the
- :func:`gl.lrectread` parameters, i.e. the boundary is included in the new image.
- The new boundaries need not be inside the picture. Pixels that fall outside the
- old image will have their value set to zero. If *x0* is bigger than *x1* the
- new image is mirrored. The same holds for the y coordinates.
-
-
-.. function:: scale(image, psize, width, height, newwidth, newheight)
-
- Return *image* scaled to size *newwidth* by *newheight*. No interpolation is
- done, scaling is done by simple-minded pixel duplication or removal. Therefore,
- computer-generated images or dithered images will not look nice after scaling.
-
-
-.. function:: tovideo(image, psize, width, height)
-
- Run a vertical low-pass filter over an image. It does so by computing each
- destination pixel as the average of two vertically-aligned source pixels. The
- main use of this routine is to forestall excessive flicker if the image is
- displayed on a video device that uses interlacing, hence the name.
-
-
-.. function:: grey2mono(image, width, height, threshold)
-
- Convert a 8-bit deep greyscale image to a 1-bit deep image by thresholding all
- the pixels. The resulting image is tightly packed and is probably only useful
- as an argument to :func:`mono2grey`.
-
-
-.. function:: dither2mono(image, width, height)
-
- Convert an 8-bit greyscale image to a 1-bit monochrome image using a
- (simple-minded) dithering algorithm.
-
-
-.. function:: mono2grey(image, width, height, p0, p1)
-
- Convert a 1-bit monochrome image to an 8 bit greyscale or color image. All
- pixels that are zero-valued on input get value *p0* on output and all one-value
- input pixels get value *p1* on output. To convert a monochrome black-and-white
- image to greyscale pass the values ``0`` and ``255`` respectively.
-
-
-.. function:: grey2grey4(image, width, height)
-
- Convert an 8-bit greyscale image to a 4-bit greyscale image without dithering.
-
-
-.. function:: grey2grey2(image, width, height)
-
- Convert an 8-bit greyscale image to a 2-bit greyscale image without dithering.
-
-
-.. function:: dither2grey2(image, width, height)
-
- Convert an 8-bit greyscale image to a 2-bit greyscale image with dithering. As
- for :func:`dither2mono`, the dithering algorithm is currently very simple.
-
-
-.. function:: grey42grey(image, width, height)
-
- Convert a 4-bit greyscale image to an 8-bit greyscale image.
-
-
-.. function:: grey22grey(image, width, height)
-
- Convert a 2-bit greyscale image to an 8-bit greyscale image.
-
-
-.. data:: backward_compatible
-
- If set to 0, the functions in this module use a non-backward compatible way
- of representing multi-byte pixels on little-endian systems. The SGI for
- which this module was originally written is a big-endian system, so setting
- this variable will have no effect. However, the code wasn't originally
- intended to run on anything else, so it made assumptions about byte order
- which are not universal. Setting this variable to 0 will cause the byte
- order to be reversed on little-endian systems, so that it then is the same as
- on big-endian systems.
-
diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst
index 9fcbaaa..3f45c95 100644
--- a/Doc/library/imaplib.rst
+++ b/Doc/library/imaplib.rst
@@ -30,7 +30,7 @@ Three classes are provided by the :mod:`imaplib` module, :class:`IMAP4` is the
base class:
-.. class:: IMAP4([host[, port]])
+.. class:: IMAP4(host='', port=IMAP4_PORT)
This class implements the actual IMAP4 protocol. The connection is created and
protocol version (IMAP4 or IMAP4rev1) is determined when the instance is
@@ -60,10 +60,11 @@ Three exceptions are defined as attributes of the :class:`IMAP4` class:
write permission, and the mailbox will need to be re-opened to re-obtain write
permission.
+
There's also a subclass for secure connections:
-.. class:: IMAP4_SSL([host[, port[, keyfile[, certfile]]]])
+.. class:: IMAP4_SSL(host='', port=IMAP4_SSL_PORT, keyfile=None, certfile=None)
This is a subclass derived from :class:`IMAP4` that connects over an SSL
encrypted socket (to use this class you need a socket module that was compiled
@@ -72,6 +73,7 @@ There's also a subclass for secure connections:
and *certfile* are also optional - they can contain a PEM formatted private key
and certificate chain file for the SSL connection.
+
The second subclass allows for connections created by a child process:
@@ -79,9 +81,8 @@ The second subclass allows for connections created by a child process:
This is a subclass derived from :class:`IMAP4` that connects to the
``stdin/stdout`` file descriptors created by passing *command* to
- ``os.popen2()``.
+ ``subprocess.Popen()``.
- .. versionadded:: 2.3
The following utility functions are defined:
@@ -89,7 +90,7 @@ The following utility functions are defined:
.. function:: Internaldate2tuple(datestr)
Parse an IMAP4 ``INTERNALDATE`` string and return corresponding local
- time. The return value is a :class:`time.struct_time` instance or
+ time. The return value is a :class:`time.struct_time` tuple or
None if the string has wrong format.
.. function:: Int2AP(num)
@@ -210,8 +211,6 @@ An :class:`IMAP4` instance has the following methods:
Delete the ACLs (remove any rights) set for who on mailbox.
- .. versionadded:: 2.4
-
.. method:: IMAP4.expunge()
@@ -238,24 +237,18 @@ An :class:`IMAP4` instance has the following methods:
Retrieve the specified ``ANNOTATION``\ s for *mailbox*. The method is
non-standard, but is supported by the ``Cyrus`` server.
- .. versionadded:: 2.5
-
.. method:: IMAP4.getquota(root)
Get the ``quota`` *root*'s resource usage and limits. This method is part of the
IMAP4 QUOTA extension defined in rfc2087.
- .. versionadded:: 2.3
-
.. method:: IMAP4.getquotaroot(mailbox)
Get the list of ``quota`` ``roots`` for the named *mailbox*. This method is part
of the IMAP4 QUOTA extension defined in rfc2087.
- .. versionadded:: 2.3
-
.. method:: IMAP4.list([directory[, pattern]])
@@ -275,15 +268,13 @@ An :class:`IMAP4` instance has the following methods:
the password. Will only work if the server ``CAPABILITY`` response includes the
phrase ``AUTH=CRAM-MD5``.
- .. versionadded:: 2.3
-
.. method:: IMAP4.logout()
Shutdown connection to server. Returns server ``BYE`` response.
-.. method:: IMAP4.lsub([directory[, pattern]])
+.. method:: IMAP4.lsub(directory='""', pattern='*')
List subscribed mailbox names in directory matching pattern. *directory*
defaults to the top level directory and *pattern* defaults to match any mailbox.
@@ -294,15 +285,11 @@ An :class:`IMAP4` instance has the following methods:
Show my ACLs for a mailbox (i.e. the rights that I have on mailbox).
- .. versionadded:: 2.4
-
.. method:: IMAP4.namespace()
Returns IMAP namespaces as defined in RFC2342.
- .. versionadded:: 2.3
-
.. method:: IMAP4.noop()
@@ -328,8 +315,6 @@ An :class:`IMAP4` instance has the following methods:
Assume authentication as *user*. Allows an authorised administrator to proxy
into any user's mailbox.
- .. versionadded:: 2.3
-
.. method:: IMAP4.read(size)
@@ -374,7 +359,7 @@ An :class:`IMAP4` instance has the following methods:
typ, msgnums = M.search(None, '(FROM "LDJ")')
-.. method:: IMAP4.select([mailbox[, readonly]])
+.. method:: IMAP4.select(mailbox='INBOX', readonly=False)
Select a mailbox. Returned data is the count of messages in *mailbox*
(``EXISTS`` response). The default *mailbox* is ``'INBOX'``. If the *readonly*
@@ -397,16 +382,12 @@ An :class:`IMAP4` instance has the following methods:
Set ``ANNOTATION``\ s for *mailbox*. The method is non-standard, but is
supported by the ``Cyrus`` server.
- .. versionadded:: 2.5
-
.. method:: IMAP4.setquota(root, limits)
Set the ``quota`` *root*'s resource *limits*. This method is part of the IMAP4
QUOTA extension defined in rfc2087.
- .. versionadded:: 2.3
-
.. method:: IMAP4.shutdown()
@@ -437,6 +418,15 @@ An :class:`IMAP4` instance has the following methods:
This is an ``IMAP4rev1`` extension command.
+.. method:: IMAP4.starttls(ssl_context=None)
+
+ Send a ``STARTTLS`` command. The *ssl_context* argument is optional
+ and should be a :class:`ssl.SSLContext` object. This will enable
+ encryption on the IMAP connection.
+
+ .. versionadded:: 3.2
+
+
.. method:: IMAP4.status(mailbox, names)
Request named status conditions for *mailbox*.
@@ -481,8 +471,6 @@ An :class:`IMAP4` instance has the following methods:
This is an ``IMAP4rev1`` extension command.
- .. versionadded:: 2.4
-
.. method:: IMAP4.uid(command, arg[, ...])
@@ -497,20 +485,13 @@ An :class:`IMAP4` instance has the following methods:
Unsubscribe from old mailbox.
-.. method:: IMAP4.xatom(name[, arg[, ...]])
+.. method:: IMAP4.xatom(name[, ...])
Allow simple extension commands notified by server in ``CAPABILITY`` response.
-Instances of :class:`IMAP4_SSL` have just one additional method:
-
-
-.. method:: IMAP4_SSL.ssl()
-
- Returns SSLObject instance used for the secure connection with the server.
The following attributes are defined on instances of :class:`IMAP4`:
-
.. attribute:: IMAP4.PROTOCOL_VERSION
The most recent supported protocol in the ``CAPABILITY`` response from the
@@ -539,7 +520,7 @@ retrieves and prints all messages::
typ, data = M.search(None, 'ALL')
for num in data[0].split():
typ, data = M.fetch(num, '(RFC822)')
- print 'Message %s\n%s\n' % (num, data[0][1])
+ print('Message %s\n%s\n' % (num, data[0][1]))
M.close()
M.logout()
diff --git a/Doc/library/imgfile.rst b/Doc/library/imgfile.rst
deleted file mode 100644
index f4c670f..0000000
--- a/Doc/library/imgfile.rst
+++ /dev/null
@@ -1,73 +0,0 @@
-
-:mod:`imgfile` --- Support for SGI imglib files
-===============================================
-
-.. module:: imgfile
- :platform: IRIX
- :synopsis: Support for SGI imglib files.
- :deprecated:
-
-.. deprecated:: 2.6
- The :mod:`imgfile` module has been removed in Python 3.
-
-
-
-The :mod:`imgfile` module allows Python programs to access SGI imglib image
-files (also known as :file:`.rgb` files). The module is far from complete, but
-is provided anyway since the functionality that there is enough in some cases.
-Currently, colormap files are not supported.
-
-The module defines the following variables and functions:
-
-
-.. exception:: error
-
- This exception is raised on all errors, such as unsupported file type, etc.
-
-
-.. function:: getsizes(file)
-
- This function returns a tuple ``(x, y, z)`` where *x* and *y* are the size of
- the image in pixels and *z* is the number of bytes per pixel. Only 3 byte RGB
- pixels and 1 byte greyscale pixels are currently supported.
-
-
-.. function:: read(file)
-
- This function reads and decodes the image on the specified file, and returns it
- as a Python string. The string has either 1 byte greyscale pixels or 4 byte RGBA
- pixels. The bottom left pixel is the first in the string. This format is
- suitable to pass to :func:`gl.lrectwrite`, for instance.
-
-
-.. function:: readscaled(file, x, y, filter[, blur])
-
- This function is identical to read but it returns an image that is scaled to the
- given *x* and *y* sizes. If the *filter* and *blur* parameters are omitted
- scaling is done by simply dropping or duplicating pixels, so the result will be
- less than perfect, especially for computer-generated images.
-
- Alternatively, you can specify a filter to use to smooth the image after
- scaling. The filter forms supported are ``'impulse'``, ``'box'``,
- ``'triangle'``, ``'quadratic'`` and ``'gaussian'``. If a filter is specified
- *blur* is an optional parameter specifying the blurriness of the filter. It
- defaults to ``1.0``.
-
- :func:`readscaled` makes no attempt to keep the aspect ratio correct, so that is
- the users' responsibility.
-
-
-.. function:: ttob(flag)
-
- This function sets a global flag which defines whether the scan lines of the
- image are read or written from bottom to top (flag is zero, compatible with SGI
- GL) or from top to bottom(flag is one, compatible with X). The default is zero.
-
-
-.. function:: write(file, data, x, y, z)
-
- This function writes the RGB or greyscale data in *data* to image file *file*.
- *x* and *y* give the size of the image, *z* is 1 for 1 byte greyscale images or
- 3 for RGB images (which are stored as 4 byte values of which only the lower
- three bytes are used). These are the formats returned by :func:`gl.lrectread`.
-
diff --git a/Doc/library/imghdr.rst b/Doc/library/imghdr.rst
index 20f789f..32ec9cf 100644
--- a/Doc/library/imghdr.rst
+++ b/Doc/library/imghdr.rst
@@ -14,7 +14,7 @@ byte stream.
The :mod:`imghdr` module defines the following function:
-.. function:: what(filename[, h])
+.. function:: what(filename, h=None)
Tests the image data contained in the file named by *filename*, and returns a
string describing the image type. If optional *h* is provided, the *filename*
@@ -49,9 +49,6 @@ from :func:`what`:
| ``'png'`` | Portable Network Graphics |
+------------+-----------------------------------+
-.. versionadded:: 2.5
- Exif detection.
-
You can extend the list of file types :mod:`imghdr` can recognize by appending
to this variable:
diff --git a/Doc/library/imp.rst b/Doc/library/imp.rst
index 8f98d65..1345b25 100644
--- a/Doc/library/imp.rst
+++ b/Doc/library/imp.rst
@@ -1,4 +1,3 @@
-
:mod:`imp` --- Access the :keyword:`import` internals
=====================================================
@@ -49,8 +48,8 @@ This module provides an interface to the mechanisms used to implement the
If search is successful, the return value is a 3-element tuple ``(file,
pathname, description)``:
- *file* is an open file object positioned at the beginning, *pathname* is the
- pathname of the file found, and *description* is a 3-element tuple as
+ *file* is an open :term:`file object` positioned at the beginning, *pathname*
+ is the pathname of the file found, and *description* is a 3-element tuple as
contained in the list returned by :func:`get_suffixes` describing the kind of
module found.
@@ -73,12 +72,10 @@ This module provides an interface to the mechanisms used to implement the
.. function:: load_module(name, file, pathname, description)
- .. index:: builtin: reload
-
Load a module that was previously found by :func:`find_module` (or by an
otherwise conducted search yielding compatible results). This function does
- more than importing the module: if the module was already imported, it is
- equivalent to a :func:`reload`! The *name* argument indicates the full
+ more than importing the module: if the module was already imported, it will
+ reload the module! The *name* argument indicates the full
module name (including the package name, if this is a submodule of a
package). The *file* argument is an open file, and *pathname* is the
corresponding file name; these can be ``None`` and ``''``, respectively, when
@@ -124,141 +121,142 @@ This module provides an interface to the mechanisms used to implement the
On platforms without threads, this function does nothing.
- .. versionadded:: 2.3
-
.. function:: release_lock()
Release the interpreter's import lock. On platforms without threads, this
function does nothing.
- .. versionadded:: 2.3
-
-The following constants with integer values, defined in this module, are used to
-indicate the search result of :func:`find_module`.
+.. function:: reload(module)
-.. data:: PY_SOURCE
+ Reload a previously imported *module*. The argument must be a module object, so
+ it must have been successfully imported before. This is useful if you have
+ edited the module source file using an external editor and want to try out the
+ new version without leaving the Python interpreter. The return value is the
+ module object (the same as the *module* argument).
- The module was found as a source file.
+ When ``reload(module)`` is executed:
+ * Python modules' code is recompiled and the module-level code reexecuted,
+ defining a new set of objects which are bound to names in the module's
+ dictionary. The ``init`` function of extension modules is not called a second
+ time.
-.. data:: PY_COMPILED
+ * As with all other objects in Python the old objects are only reclaimed after
+ their reference counts drop to zero.
- The module was found as a compiled code object file.
+ * The names in the module namespace are updated to point to any new or changed
+ objects.
+ * Other references to the old objects (such as names external to the module) are
+ not rebound to refer to the new objects and must be updated in each namespace
+ where they occur if that is desired.
-.. data:: C_EXTENSION
+ There are a number of other caveats:
- The module was found as dynamically loadable shared library.
+ If a module is syntactically correct but its initialization fails, the first
+ :keyword:`import` statement for it does not bind its name locally, but does
+ store a (partially initialized) module object in ``sys.modules``. To reload the
+ module you must first :keyword:`import` it again (this will bind the name to the
+ partially initialized module object) before you can :func:`reload` it.
+ When a module is reloaded, its dictionary (containing the module's global
+ variables) is retained. Redefinitions of names will override the old
+ definitions, so this is generally not a problem. If the new version of a module
+ does not define a name that was defined by the old version, the old definition
+ remains. This feature can be used to the module's advantage if it maintains a
+ global table or cache of objects --- with a :keyword:`try` statement it can test
+ for the table's presence and skip its initialization if desired::
-.. data:: PKG_DIRECTORY
+ try:
+ cache
+ except NameError:
+ cache = {}
- The module was found as a package directory.
+ It is legal though generally not very useful to reload built-in or dynamically
+ loaded modules, except for :mod:`sys`, :mod:`__main__` and :mod:`__builtin__`.
+ In many cases, however, extension modules are not designed to be initialized
+ more than once, and may fail in arbitrary ways when reloaded.
+ If a module imports objects from another module using :keyword:`from` ...
+ :keyword:`import` ..., calling :func:`reload` for the other module does not
+ redefine the objects imported from it --- one way around this is to re-execute
+ the :keyword:`from` statement, another is to use :keyword:`import` and qualified
+ names (*module*.*name*) instead.
-.. data:: C_BUILTIN
+ If a module instantiates instances of a class, reloading the module that defines
+ the class does not affect the method definitions of the instances --- they
+ continue to use the old class definition. The same is true for derived classes.
- The module was found as a built-in module.
+The following functions are conveniences for handling :pep:`3147` byte-compiled
+file paths.
-.. data:: PY_FROZEN
+.. versionadded:: 3.2
- The module was found as a frozen module (see :func:`init_frozen`).
+.. function:: cache_from_source(path, debug_override=None)
-The following constant and functions are obsolete; their functionality is
-available through :func:`find_module` or :func:`load_module`. They are kept
-around for backward compatibility:
+ Return the :pep:`3147` path to the byte-compiled file associated with the
+ source *path*. For example, if *path* is ``/foo/bar/baz.py`` the return
+ value would be ``/foo/bar/__pycache__/baz.cpython-32.pyc`` for Python 3.2.
+ The ``cpython-32`` string comes from the current magic tag (see
+ :func:`get_tag`). The returned path will end in ``.pyc`` when
+ ``__debug__`` is True or ``.pyo`` for an optimized Python
+ (i.e. ``__debug__`` is False). By passing in True or False for
+ *debug_override* you can override the system's value for ``__debug__`` for
+ extension selection.
+ *path* need not exist.
-.. data:: SEARCH_ERROR
- Unused.
+.. function:: source_from_cache(path)
+ Given the *path* to a :pep:`3147` file name, return the associated source code
+ file path. For example, if *path* is
+ ``/foo/bar/__pycache__/baz.cpython-32.pyc`` the returned path would be
+ ``/foo/bar/baz.py``. *path* need not exist, however if it does not conform
+ to :pep:`3147` format, a ``ValueError`` is raised.
-.. function:: init_builtin(name)
- Initialize the built-in module called *name* and return its module object along
- with storing it in ``sys.modules``. If the module was already initialized, it
- will be initialized *again*. Re-initialization involves the copying of the
- built-in module's ``__dict__`` from the cached module over the module's entry in
- ``sys.modules``. If there is no built-in module called *name*, ``None`` is
- returned.
+.. function:: get_tag()
+ Return the :pep:`3147` magic tag string matching this version of Python's
+ magic number, as returned by :func:`get_magic`.
-.. function:: init_frozen(name)
- Initialize the frozen module called *name* and return its module object. If
- the module was already initialized, it will be initialized *again*. If there
- is no frozen module called *name*, ``None`` is returned. (Frozen modules are
- modules written in Python whose compiled byte-code object is incorporated
- into a custom-built Python interpreter by Python's :program:`freeze`
- utility. See :file:`Tools/freeze/` for now.)
+The following constants with integer values, defined in this module, are used
+to indicate the search result of :func:`find_module`.
-.. function:: is_builtin(name)
+.. data:: PY_SOURCE
- Return ``1`` if there is a built-in module called *name* which can be
- initialized again. Return ``-1`` if there is a built-in module called *name*
- which cannot be initialized again (see :func:`init_builtin`). Return ``0`` if
- there is no built-in module called *name*.
+ The module was found as a source file.
-.. function:: is_frozen(name)
+.. data:: PY_COMPILED
- Return ``True`` if there is a frozen module (see :func:`init_frozen`) called
- *name*, or ``False`` if there is no such module.
+ The module was found as a compiled code object file.
-.. function:: load_compiled(name, pathname, [file])
+.. data:: C_EXTENSION
- .. index:: pair: file; byte-code
+ The module was found as dynamically loadable shared library.
- Load and initialize a module implemented as a byte-compiled code file and return
- its module object. If the module was already initialized, it will be
- initialized *again*. The *name* argument is used to create or access a module
- object. The *pathname* argument points to the byte-compiled code file. The
- *file* argument is the byte-compiled code file, open for reading in binary mode,
- from the beginning. It must currently be a real file object, not a user-defined
- class emulating a file.
+.. data:: PKG_DIRECTORY
-.. function:: load_dynamic(name, pathname[, file])
+ The module was found as a package directory.
- Load and initialize a module implemented as a dynamically loadable shared
- library and return its module object. If the module was already initialized, it
- will be initialized *again*. Re-initialization involves copying the ``__dict__``
- attribute of the cached instance of the module over the value used in the module
- cached in ``sys.modules``. The *pathname* argument must point to the shared
- library. The *name* argument is used to construct the name of the
- initialization function: an external C function called ``initname()`` in the
- shared library is called. The optional *file* argument is ignored. (Note:
- using shared libraries is highly system dependent, and not all systems support
- it.)
- .. impl-detail::
+.. data:: C_BUILTIN
- The import internals identify extension modules by filename, so doing
- ``foo = load_dynamic("foo", "mod.so")`` and
- ``bar = load_dynamic("bar", "mod.so")`` will result in both foo and bar
- referring to the same module, regardless of whether or not
- ``mod.so`` exports an ``initbar`` function. On systems which
- support them, symlinks can be used to import multiple modules from
- the same shared library, as each reference to the module will use
- a different file name.
+ The module was found as a built-in module.
-.. function:: load_source(name, pathname[, file])
+.. data:: PY_FROZEN
- Load and initialize a module implemented as a Python source file and return its
- module object. If the module was already initialized, it will be initialized
- *again*. The *name* argument is used to create or access a module object. The
- *pathname* argument points to the source file. The *file* argument is the
- source file, open for reading as text, from the beginning. It must currently be
- a real file object, not a user-defined class emulating a file. Note that if a
- properly matching byte-compiled file (with suffix :file:`.pyc` or :file:`.pyo`)
- exists, it will be used instead of parsing the given source file.
+ The module was found as a frozen module.
.. class:: NullImporter(path_string)
@@ -278,8 +276,6 @@ around for backward compatibility:
This method always returns ``None``, indicating that the requested module could
not be found.
- .. versionadded:: 2.5
-
.. _examples-imp:
@@ -312,12 +308,3 @@ in that version, since :func:`find_module` has been extended and
# Since we may exit via an exception, close fp explicitly.
if fp:
fp.close()
-
-.. index::
- builtin: reload
- module: knee
-
-A more complete example that implements hierarchical module names and includes a
-:func:`reload` function can be found in the module :mod:`knee`. The :mod:`knee`
-module can be found in :file:`Demo/imputil/` in the Python source distribution.
-
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index c4307b5..1649063 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -1,27 +1,522 @@
-:mod:`importlib` -- Convenience wrappers for :func:`__import__`
-===============================================================
+:mod:`importlib` -- An implementation of :keyword:`import`
+==========================================================
.. module:: importlib
- :synopsis: Convenience wrappers for __import__
+ :synopsis: An implementation of the import machinery.
.. moduleauthor:: Brett Cannon <brett@python.org>
.. sectionauthor:: Brett Cannon <brett@python.org>
-.. versionadded:: 2.7
+.. versionadded:: 3.1
-This module is a minor subset of what is available in the more full-featured
-package of the same name from Python 3.1 that provides a complete
-implementation of :keyword:`import`. What is here has been provided to
-help ease in transitioning from 2.7 to 3.1.
+Introduction
+------------
+
+The purpose of the :mod:`importlib` package is two-fold. One is to provide an
+implementation of the :keyword:`import` statement (and thus, by extension, the
+:func:`__import__` function) in Python source code. This provides an
+implementation of :keyword:`import` which is portable to any Python
+interpreter. This also provides a reference implementation which is easier to
+comprehend than one implemented in a programming language other than Python.
+
+Two, the components to implement :keyword:`import` are exposed in this
+package, making it easier for users to create their own custom objects (known
+generically as an :term:`importer`) to participate in the import process.
+Details on custom importers can be found in :pep:`302`.
+
+.. seealso::
+
+ :ref:`import`
+ The language reference for the :keyword:`import` statement.
+
+ `Packages specification <http://www.python.org/doc/essays/packages.html>`__
+ Original specification of packages. Some semantics have changed since
+ the writing of this document (e.g. redirecting based on ``None``
+ in :data:`sys.modules`).
+
+ The :func:`.__import__` function
+ The :keyword:`import` statement is syntactic sugar for this function.
+
+ :pep:`235`
+ Import on Case-Insensitive Platforms
+
+ :pep:`263`
+ Defining Python Source Code Encodings
+
+ :pep:`302`
+ New Import Hooks
+
+ :pep:`328`
+ Imports: Multi-Line and Absolute/Relative
+
+ :pep:`366`
+ Main module explicit relative imports
+
+ :pep:`3120`
+ Using UTF-8 as the Default Source Encoding
+
+ :pep:`3147`
+ PYC Repository Directories
+
+
+Functions
+---------
+
+.. function:: __import__(name, globals={}, locals={}, fromlist=list(), level=0)
+
+ An implementation of the built-in :func:`__import__` function.
.. function:: import_module(name, package=None)
Import a module. The *name* argument specifies what module to
import in absolute or relative terms
(e.g. either ``pkg.mod`` or ``..mod``). If the name is
- specified in relative terms, then the *package* argument must be
- specified to the package which is to act as the anchor for resolving the
+ specified in relative terms, then the *package* argument must be set to
+ the name of the package which is to act as the anchor for resolving the
package name (e.g. ``import_module('..mod', 'pkg.subpkg')`` will import
- ``pkg.mod``). The specified module will be inserted into
- :data:`sys.modules` and returned.
+ ``pkg.mod``).
+
+ The :func:`import_module` function acts as a simplifying wrapper around
+ :func:`importlib.__import__`. This means all semantics of the function are
+ derived from :func:`importlib.__import__`, including requiring the package
+ from which an import is occurring to have been previously imported
+ (i.e., *package* must already be imported). The most important difference
+ is that :func:`import_module` returns the most nested package or module
+ that was imported (e.g. ``pkg.mod``), while :func:`__import__` returns the
+ top-level package or module (e.g. ``pkg``).
+
+
+:mod:`importlib.abc` -- Abstract base classes related to import
+---------------------------------------------------------------
+
+.. module:: importlib.abc
+ :synopsis: Abstract base classes related to import
+
+The :mod:`importlib.abc` module contains all of the core abstract base classes
+used by :keyword:`import`. Some subclasses of the core abstract base classes
+are also provided to help in implementing the core ABCs.
+
+
+.. class:: Finder
+
+ An abstract base class representing a :term:`finder`.
+ See :pep:`302` for the exact definition for a finder.
+
+ .. method:: find_module(fullname, path=None)
+
+ An abstract method for finding a :term:`loader` for the specified
+ module. If the :term:`finder` is found on :data:`sys.meta_path` and the
+ module to be searched for is a subpackage or module then *path* will
+ be the value of :attr:`__path__` from the parent package. If a loader
+ cannot be found, ``None`` is returned.
+
+
+.. class:: Loader
+
+ An abstract base class for a :term:`loader`.
+ See :pep:`302` for the exact definition for a loader.
+
+ .. method:: load_module(fullname)
+
+ An abstract method for loading a module. If the module cannot be
+ loaded, :exc:`ImportError` is raised, otherwise the loaded module is
+ returned.
+
+ If the requested module already exists in :data:`sys.modules`, that
+ module should be used and reloaded.
+ Otherwise the loader should create a new module and insert it into
+ :data:`sys.modules` before any loading begins, to prevent recursion
+ from the import. If the loader inserted a module and the load fails, it
+ must be removed by the loader from :data:`sys.modules`; modules already
+ in :data:`sys.modules` before the loader began execution should be left
+ alone. The :func:`importlib.util.module_for_loader` decorator handles
+ all of these details.
+
+ The loader should set several attributes on the module.
+ (Note that some of these attributes can change when a module is
+ reloaded.)
+
+ - :attr:`__name__`
+ The name of the module.
+
+ - :attr:`__file__`
+ The path to where the module data is stored (not set for built-in
+ modules).
+
+ - :attr:`__path__`
+ A list of strings specifying the search path within a
+ package. This attribute is not set on modules.
+
+ - :attr:`__package__`
+ The parent package for the module/package. If the module is
+ top-level then it has a value of the empty string. The
+ :func:`importlib.util.set_package` decorator can handle the details
+ for :attr:`__package__`.
+
+ - :attr:`__loader__`
+ The loader used to load the module.
+ (This is not set by the built-in import machinery,
+ but it should be set whenever a :term:`loader` is used.)
+
+
+.. class:: ResourceLoader
+
+ An abstract base class for a :term:`loader` which implements the optional
+ :pep:`302` protocol for loading arbitrary resources from the storage
+ back-end.
+
+ .. method:: get_data(path)
+
+ An abstract method to return the bytes for the data located at *path*.
+ Loaders that have a file-like storage back-end
+ that allows storing arbitrary data
+ can implement this abstract method to give direct access
+ to the data stored. :exc:`IOError` is to be raised if the *path* cannot
+ be found. The *path* is expected to be constructed using a module's
+ :attr:`__file__` attribute or an item from a package's :attr:`__path__`.
+
+
+.. class:: InspectLoader
+
+ An abstract base class for a :term:`loader` which implements the optional
+ :pep:`302` protocol for loaders that inspect modules.
+
+ .. method:: get_code(fullname)
+
+ An abstract method to return the :class:`code` object for a module.
+ ``None`` is returned if the module does not have a code object
+ (e.g. built-in module). :exc:`ImportError` is raised if loader cannot
+ find the requested module.
+
+ .. index::
+ single: universal newlines; importlib.abc.InspectLoader.get_source method
+
+ .. method:: get_source(fullname)
+
+ An abstract method to return the source of a module. It is returned as
+ a text string using :term:`universal newlines`, translating all
+ recognized line separators into ``'\n'`` characters. Returns ``None``
+ if no source is available (e.g. a built-in module). Raises
+ :exc:`ImportError` if the loader cannot find the module specified.
+
+ .. method:: is_package(fullname)
+
+ An abstract method to return a true value if the module is a package, a
+ false value otherwise. :exc:`ImportError` is raised if the
+ :term:`loader` cannot find the module.
+
+
+.. class:: ExecutionLoader
+
+ An abstract base class which inherits from :class:`InspectLoader` that,
+ when implemented, helps a module to be executed as a script. The ABC
+ represents an optional :pep:`302` protocol.
+
+ .. method:: get_filename(fullname)
+
+ An abstract method that is to return the value of :attr:`__file__` for
+ the specified module. If no path is available, :exc:`ImportError` is
+ raised.
+
+ If source code is available, then the method should return the path to
+ the source file, regardless of whether a bytecode was used to load the
+ module.
+
+
+.. class:: SourceLoader
+
+ An abstract base class for implementing source (and optionally bytecode)
+ file loading. The class inherits from both :class:`ResourceLoader` and
+ :class:`ExecutionLoader`, requiring the implementation of:
+
+ * :meth:`ResourceLoader.get_data`
+ * :meth:`ExecutionLoader.get_filename`
+ Should only return the path to the source file; sourceless
+ loading is not supported.
+
+ The abstract methods defined by this class are to add optional bytecode
+ file support. Not implementing these optional methods causes the loader to
+ only work with source code. Implementing the methods allows the loader to
+ work with source *and* bytecode files; it does not allow for *sourceless*
+ loading where only bytecode is provided. Bytecode files are an
+ optimization to speed up loading by removing the parsing step of Python's
+ compiler, and so no bytecode-specific API is exposed.
+
+ .. method:: path_mtime(self, path)
+
+ Optional abstract method which returns the modification time for the
+ specified path.
+
+ .. method:: set_data(self, path, data)
+
+ Optional abstract method which writes the specified bytes to a file
+ path. Any intermediate directories which do not exist are to be created
+ automatically.
+
+ When writing to the path fails because the path is read-only
+ (:attr:`errno.EACCES`), do not propagate the exception.
+
+ .. method:: get_code(self, fullname)
+
+ Concrete implementation of :meth:`InspectLoader.get_code`.
+
+ .. method:: load_module(self, fullname)
+
+ Concrete implementation of :meth:`Loader.load_module`.
+
+ .. method:: get_source(self, fullname)
+
+ Concrete implementation of :meth:`InspectLoader.get_source`.
+
+ .. method:: is_package(self, fullname)
+
+ Concrete implementation of :meth:`InspectLoader.is_package`. A module
+ is determined to be a package if its file path is a file named
+ ``__init__`` when the file extension is removed.
+
+
+.. class:: PyLoader
+
+ An abstract base class inheriting from
+ :class:`ExecutionLoader` and
+ :class:`ResourceLoader` designed to ease the loading of
+ Python source modules (bytecode is not handled; see
+ :class:`SourceLoader` for a source/bytecode ABC). A subclass
+ implementing this ABC will only need to worry about exposing how the source
+ code is stored; all other details for loading Python source code will be
+ handled by the concrete implementations of key methods.
+
+ .. deprecated:: 3.2
+ This class has been deprecated in favor of :class:`SourceLoader` and is
+ slated for removal in Python 3.4. See below for how to create a
+ subclass that is compatible with Python 3.1 onwards.
+
+ If compatibility with Python 3.1 is required, then use the following idiom
+ to implement a subclass that will work with Python 3.1 onwards (make sure
+ to implement :meth:`ExecutionLoader.get_filename`)::
+
+ try:
+ from importlib.abc import SourceLoader
+ except ImportError:
+ from importlib.abc import PyLoader as SourceLoader
+
+
+ class CustomLoader(SourceLoader):
+ def get_filename(self, fullname):
+ """Return the path to the source file."""
+ # Implement ...
+
+ def source_path(self, fullname):
+ """Implement source_path in terms of get_filename."""
+ try:
+ return self.get_filename(fullname)
+ except ImportError:
+ return None
+
+ def is_package(self, fullname):
+ """Implement is_package by looking for an __init__ file
+ name as returned by get_filename."""
+ filename = os.path.basename(self.get_filename(fullname))
+ return os.path.splitext(filename)[0] == '__init__'
+
+
+ .. method:: source_path(fullname)
+
+ An abstract method that returns the path to the source code for a
+ module. Should return ``None`` if there is no source code.
+ Raises :exc:`ImportError` if the loader knows it cannot handle the
+ module.
+
+ .. method:: get_filename(fullname)
+
+ A concrete implementation of
+ :meth:`importlib.abc.ExecutionLoader.get_filename` that
+ relies on :meth:`source_path`. If :meth:`source_path` returns
+ ``None``, then :exc:`ImportError` is raised.
+
+ .. method:: load_module(fullname)
+
+ A concrete implementation of :meth:`importlib.abc.Loader.load_module`
+ that loads Python source code. All needed information comes from the
+ abstract methods required by this ABC. The only pertinent assumption
+ made by this method is that when loading a package
+ :attr:`__path__` is set to ``[os.path.dirname(__file__)]``.
+
+ .. method:: get_code(fullname)
+
+ A concrete implementation of
+ :meth:`importlib.abc.InspectLoader.get_code` that creates code objects
+ from Python source code, by requesting the source code (using
+ :meth:`source_path` and :meth:`get_data`) and compiling it with the
+ built-in :func:`compile` function.
+
+ .. method:: get_source(fullname)
+
+ A concrete implementation of
+ :meth:`importlib.abc.InspectLoader.get_source`. Uses
+ :meth:`importlib.abc.ResourceLoader.get_data` and :meth:`source_path`
+ to get the source code. It tries to guess the source encoding using
+ :func:`tokenize.detect_encoding`.
+
+
+.. class:: PyPycLoader
+
+ An abstract base class inheriting from :class:`PyLoader`.
+ This ABC is meant to help in creating loaders that support both Python
+ source and bytecode.
+
+ .. deprecated:: 3.2
+ This class has been deprecated in favor of :class:`SourceLoader` and to
+ properly support :pep:`3147`. If compatibility is required with
+ Python 3.1, implement both :class:`SourceLoader` and :class:`PyLoader`;
+ instructions on how to do so are included in the documentation for
+ :class:`PyLoader`. Do note that this solution will not support
+ sourceless/bytecode-only loading; only source *and* bytecode loading.
+
+ .. method:: source_mtime(fullname)
+
+ An abstract method which returns the modification time for the source
+ code of the specified module. The modification time should be an
+ integer. If there is no source code, return ``None``. If the
+ module cannot be found then :exc:`ImportError` is raised.
+
+ .. method:: bytecode_path(fullname)
+
+ An abstract method which returns the path to the bytecode for the
+ specified module, if it exists. It returns ``None``
+ if no bytecode exists (yet).
+ Raises :exc:`ImportError` if the loader knows it cannot handle the
+ module.
+
+ .. method:: get_filename(fullname)
+
+ A concrete implementation of
+ :meth:`ExecutionLoader.get_filename` that relies on
+ :meth:`PyLoader.source_path` and :meth:`bytecode_path`.
+ If :meth:`source_path` returns a path, then that value is returned.
+ Else if :meth:`bytecode_path` returns a path, that path will be
+ returned. If a path is not available from both methods,
+ :exc:`ImportError` is raised.
+
+ .. method:: write_bytecode(fullname, bytecode)
+
+ An abstract method which has the loader write *bytecode* for future
+ use. If the bytecode is written, return ``True``. Return
+ ``False`` if the bytecode could not be written. This method
+ should not be called if :data:`sys.dont_write_bytecode` is true.
+ The *bytecode* argument should be a bytes string or bytes array.
+
+
+:mod:`importlib.machinery` -- Importers and path hooks
+------------------------------------------------------
+
+.. module:: importlib.machinery
+ :synopsis: Importers and path hooks
+
+This module contains the various objects that help :keyword:`import`
+find and load modules.
+
+.. class:: BuiltinImporter
+
+ An :term:`importer` for built-in modules. All known built-in modules are
+ listed in :data:`sys.builtin_module_names`. This class implements the
+ :class:`importlib.abc.Finder` and :class:`importlib.abc.InspectLoader`
+ ABCs.
+
+ Only class methods are defined by this class to alleviate the need for
+ instantiation.
+
+
+.. class:: FrozenImporter
+
+ An :term:`importer` for frozen modules. This class implements the
+ :class:`importlib.abc.Finder` and :class:`importlib.abc.InspectLoader`
+ ABCs.
+
+ Only class methods are defined by this class to alleviate the need for
+ instantiation.
+
+
+.. class:: PathFinder
+
+ :term:`Finder` for :data:`sys.path`. This class implements the
+ :class:`importlib.abc.Finder` ABC.
+
+ This class does not perfectly mirror the semantics of :keyword:`import` in
+ terms of :data:`sys.path`. No implicit path hooks are assumed for
+ simplification of the class and its semantics.
+
+ Only class methods are defined by this class to alleviate the need for
+ instantiation.
+
+ .. classmethod:: find_module(fullname, path=None)
+
+ Class method that attempts to find a :term:`loader` for the module
+ specified by *fullname* on :data:`sys.path` or, if defined, on
+ *path*. For each path entry that is searched,
+ :data:`sys.path_importer_cache` is checked. If an non-false object is
+ found then it is used as the :term:`finder` to look for the module
+ being searched for. If no entry is found in
+ :data:`sys.path_importer_cache`, then :data:`sys.path_hooks` is
+ searched for a finder for the path entry and, if found, is stored in
+ :data:`sys.path_importer_cache` along with being queried about the
+ module. If no finder is ever found then ``None`` is returned.
+
+
+:mod:`importlib.util` -- Utility code for importers
+---------------------------------------------------
+
+.. module:: importlib.util
+ :synopsis: Importers and path hooks
+
+This module contains the various objects that help in the construction of
+an :term:`importer`.
+
+.. decorator:: module_for_loader
+
+ A :term:`decorator` for a :term:`loader` method,
+ to handle selecting the proper
+ module object to load with. The decorated method is expected to have a call
+ signature taking two positional arguments
+ (e.g. ``load_module(self, module)``) for which the second argument
+ will be the module **object** to be used by the loader.
+ Note that the decorator
+ will not work on static methods because of the assumption of two
+ arguments.
+
+ The decorated method will take in the **name** of the module to be loaded
+ as expected for a :term:`loader`. If the module is not found in
+ :data:`sys.modules` then a new one is constructed with its
+ :attr:`__name__` attribute set. Otherwise the module found in
+ :data:`sys.modules` will be passed into the method. If an
+ exception is raised by the decorated method and a module was added to
+ :data:`sys.modules` it will be removed to prevent a partially initialized
+ module from being in left in :data:`sys.modules`. If the module was already
+ in :data:`sys.modules` then it is left alone.
+
+ Use of this decorator handles all the details of which module object a
+ loader should initialize as specified by :pep:`302`.
+
+.. decorator:: set_loader
+
+ A :term:`decorator` for a :term:`loader` method,
+ to set the :attr:`__loader__`
+ attribute on loaded modules. If the attribute is already set the decorator
+ does nothing. It is assumed that the first positional argument to the
+ wrapped method is what :attr:`__loader__` should be set to.
+
+.. decorator:: set_package
+
+ A :term:`decorator` for a :term:`loader` to set the :attr:`__package__`
+ attribute on the module returned by the loader. If :attr:`__package__` is
+ set and has a value other than ``None`` it will not be changed.
+ Note that the module returned by the loader is what has the attribute
+ set on and not the module found in :data:`sys.modules`.
+
+ Reliance on this decorator is discouraged when it is possible to set
+ :attr:`__package__` before the execution of the code is possible. By
+ setting it before the code for the module is executed it allows the
+ attribute to be used at the global level of the module during
+ initialization.
+
diff --git a/Doc/library/imputil.rst b/Doc/library/imputil.rst
deleted file mode 100644
index 14d7041..0000000
--- a/Doc/library/imputil.rst
+++ /dev/null
@@ -1,238 +0,0 @@
-
-:mod:`imputil` --- Import utilities
-=====================================================
-
-.. module:: imputil
- :synopsis: Manage and augment the import process.
- :deprecated:
-
-.. deprecated:: 2.6
- The :mod:`imputil` module has been removed in Python 3.
-
-
-.. index:: statement: import
-
-This module provides a very handy and useful mechanism for custom
-:keyword:`import` hooks. Compared to the older :mod:`ihooks` module,
-:mod:`imputil` takes a dramatically simpler and more straight-forward
-approach to custom :keyword:`import` functions.
-
-
-.. class:: ImportManager([fs_imp])
-
- Manage the import process.
-
- .. method:: ImportManager.install([namespace])
-
- Install this ImportManager into the specified namespace.
-
- .. method:: ImportManager.uninstall()
-
- Restore the previous import mechanism.
-
- .. method:: ImportManager.add_suffix(suffix, importFunc)
-
- Undocumented.
-
-
-.. class:: Importer()
-
- Base class for replacing standard import functions.
-
- .. method:: Importer.import_top(name)
-
- Import a top-level module.
-
- .. method:: Importer.get_code(parent, modname, fqname)
-
- Find and retrieve the code for the given module.
-
- *parent* specifies a parent module to define a context for importing.
- It may be ``None``, indicating no particular context for the search.
-
- *modname* specifies a single module (not dotted) within the parent.
-
- *fqname* specifies the fully-qualified module name. This is a
- (potentially) dotted name from the "root" of the module namespace
- down to the modname.
-
- If there is no parent, then modname==fqname.
-
- This method should return ``None``, or a 3-tuple.
-
- * If the module was not found, then ``None`` should be returned.
-
- * The first item of the 2- or 3-tuple should be the integer 0 or 1,
- specifying whether the module that was found is a package or not.
-
- * The second item is the code object for the module (it will be
- executed within the new module's namespace). This item can also
- be a fully-loaded module object (e.g. loaded from a shared lib).
-
- * The third item is a dictionary of name/value pairs that will be
- inserted into new module before the code object is executed. This
- is provided in case the module's code expects certain values (such
- as where the module was found). When the second item is a module
- object, then these names/values will be inserted *after* the module
- has been loaded/initialized.
-
-
-.. class:: BuiltinImporter()
-
- Emulate the import mechanism for built-in and frozen modules. This is a
- sub-class of the :class:`Importer` class.
-
- .. method:: BuiltinImporter.get_code(parent, modname, fqname)
-
- Undocumented.
-
-.. function:: py_suffix_importer(filename, finfo, fqname)
-
- Undocumented.
-
-.. class:: DynLoadSuffixImporter([desc])
-
- Undocumented.
-
- .. method:: DynLoadSuffixImporter.import_file(filename, finfo, fqname)
-
- Undocumented.
-
-.. _examples-imputil:
-
-Examples
---------
-
-This is a re-implementation of hierarchical module import.
-
-This code is intended to be read, not executed. However, it does work
--- all you need to do to enable it is "import knee".
-
-(The name is a pun on the clunkier predecessor of this module, "ni".)
-
-::
-
- import sys, imp, __builtin__
-
- # Replacement for __import__()
- def import_hook(name, globals=None, locals=None, fromlist=None):
- parent = determine_parent(globals)
- q, tail = find_head_package(parent, name)
- m = load_tail(q, tail)
- if not fromlist:
- return q
- if hasattr(m, "__path__"):
- ensure_fromlist(m, fromlist)
- return m
-
- def determine_parent(globals):
- if not globals or not globals.has_key("__name__"):
- return None
- pname = globals['__name__']
- if globals.has_key("__path__"):
- parent = sys.modules[pname]
- assert globals is parent.__dict__
- return parent
- if '.' in pname:
- i = pname.rfind('.')
- pname = pname[:i]
- parent = sys.modules[pname]
- assert parent.__name__ == pname
- return parent
- return None
-
- def find_head_package(parent, name):
- if '.' in name:
- i = name.find('.')
- head = name[:i]
- tail = name[i+1:]
- else:
- head = name
- tail = ""
- if parent:
- qname = "%s.%s" % (parent.__name__, head)
- else:
- qname = head
- q = import_module(head, qname, parent)
- if q: return q, tail
- if parent:
- qname = head
- parent = None
- q = import_module(head, qname, parent)
- if q: return q, tail
- raise ImportError("No module named " + qname)
-
- def load_tail(q, tail):
- m = q
- while tail:
- i = tail.find('.')
- if i < 0: i = len(tail)
- head, tail = tail[:i], tail[i+1:]
- mname = "%s.%s" % (m.__name__, head)
- m = import_module(head, mname, m)
- if not m:
- raise ImportError("No module named " + mname)
- return m
-
- def ensure_fromlist(m, fromlist, recursive=0):
- for sub in fromlist:
- if sub == "*":
- if not recursive:
- try:
- all = m.__all__
- except AttributeError:
- pass
- else:
- ensure_fromlist(m, all, 1)
- continue
- if sub != "*" and not hasattr(m, sub):
- subname = "%s.%s" % (m.__name__, sub)
- submod = import_module(sub, subname, m)
- if not submod:
- raise ImportError("No module named " + subname)
-
- def import_module(partname, fqname, parent):
- try:
- return sys.modules[fqname]
- except KeyError:
- pass
- try:
- fp, pathname, stuff = imp.find_module(partname,
- parent and parent.__path__)
- except ImportError:
- return None
- try:
- m = imp.load_module(fqname, fp, pathname, stuff)
- finally:
- if fp: fp.close()
- if parent:
- setattr(parent, partname, m)
- return m
-
-
- # Replacement for reload()
- def reload_hook(module):
- name = module.__name__
- if '.' not in name:
- return import_module(name, name, None)
- i = name.rfind('.')
- pname = name[:i]
- parent = sys.modules[pname]
- return import_module(name[i+1:], name, parent)
-
-
- # Save the original hooks
- original_import = __builtin__.__import__
- original_reload = __builtin__.reload
-
- # Now install our hooks
- __builtin__.__import__ = import_hook
- __builtin__.reload = reload_hook
-
-.. index::
- module: knee
-
-Also see the :mod:`importers` module (which can be found
-in :file:`Demo/imputil/` in the Python source distribution) for additional
-examples.
-
diff --git a/Doc/library/index.rst b/Doc/library/index.rst
index 71ba916..b6a5559 100644
--- a/Doc/library/index.rst
+++ b/Doc/library/index.rst
@@ -46,6 +46,7 @@ the `Python Package Index <http://pypi.python.org/pypi>`_.
strings.rst
datatypes.rst
numeric.rst
+ functional.rst
filesys.rst
persistence.rst
archiving.rst
@@ -65,15 +66,9 @@ the `Python Package Index <http://pypi.python.org/pypi>`_.
debug.rst
python.rst
custominterp.rst
- restricted.rst
modules.rst
language.rst
- compiler.rst
misc.rst
windows.rst
unix.rst
- mac.rst
- macosa.rst
- sgi.rst
- sun.rst
undoc.rst
diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst
index 2b41bec..d127ce8 100644
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -6,9 +6,6 @@
.. moduleauthor:: Ka-Ping Yee <ping@lfw.org>
.. sectionauthor:: Ka-Ping Yee <ping@lfw.org>
-
-.. versionadded:: 2.1
-
**Source code:** :source:`Lib/inspect.py`
--------------
@@ -36,189 +33,136 @@ provided as convenient choices for the second argument to :func:`getmembers`.
They also help you determine when you can expect to find the following special
attributes:
-+-----------+-----------------+---------------------------+-------+
-| Type | Attribute | Description | Notes |
-+===========+=================+===========================+=======+
-| module | __doc__ | documentation string | |
-+-----------+-----------------+---------------------------+-------+
-| | __file__ | filename (missing for | |
-| | | built-in modules) | |
-+-----------+-----------------+---------------------------+-------+
-| class | __doc__ | documentation string | |
-+-----------+-----------------+---------------------------+-------+
-| | __module__ | name of module in which | |
-| | | this class was defined | |
-+-----------+-----------------+---------------------------+-------+
-| method | __doc__ | documentation string | |
-+-----------+-----------------+---------------------------+-------+
-| | __name__ | name with which this | |
-| | | method was defined | |
-+-----------+-----------------+---------------------------+-------+
-| | im_class | class object that asked | \(1) |
-| | | for this method | |
-+-----------+-----------------+---------------------------+-------+
-| | im_func or | function object | |
-| | __func__ | containing implementation | |
-| | | of method | |
-+-----------+-----------------+---------------------------+-------+
-| | im_self or | instance to which this | |
-| | __self__ | method is bound, or | |
-| | | ``None`` | |
-+-----------+-----------------+---------------------------+-------+
-| function | __doc__ | documentation string | |
-+-----------+-----------------+---------------------------+-------+
-| | __name__ | name with which this | |
-| | | function was defined | |
-+-----------+-----------------+---------------------------+-------+
-| | func_code | code object containing | |
-| | | compiled function | |
-| | | :term:`bytecode` | |
-+-----------+-----------------+---------------------------+-------+
-| | func_defaults | tuple of any default | |
-| | | values for arguments | |
-+-----------+-----------------+---------------------------+-------+
-| | func_doc | (same as __doc__) | |
-+-----------+-----------------+---------------------------+-------+
-| | func_globals | global namespace in which | |
-| | | this function was defined | |
-+-----------+-----------------+---------------------------+-------+
-| | func_name | (same as __name__) | |
-+-----------+-----------------+---------------------------+-------+
-| generator | __iter__ | defined to support | |
-| | | iteration over container | |
-+-----------+-----------------+---------------------------+-------+
-| | close | raises new GeneratorExit | |
-| | | exception inside the | |
-| | | generator to terminate | |
-| | | the iteration | |
-+-----------+-----------------+---------------------------+-------+
-| | gi_code | code object | |
-+-----------+-----------------+---------------------------+-------+
-| | gi_frame | frame object or possibly | |
-| | | None once the generator | |
-| | | has been exhausted | |
-+-----------+-----------------+---------------------------+-------+
-| | gi_running | set to 1 when generator | |
-| | | is executing, 0 otherwise | |
-+-----------+-----------------+---------------------------+-------+
-| | next | return the next item from | |
-| | | the container | |
-+-----------+-----------------+---------------------------+-------+
-| | send | resumes the generator and | |
-| | | "sends" a value that | |
-| | | becomes the result of the | |
-| | | current yield-expression | |
-+-----------+-----------------+---------------------------+-------+
-| | throw | used to raise an | |
-| | | exception inside the | |
-| | | generator | |
-+-----------+-----------------+---------------------------+-------+
-| traceback | tb_frame | frame object at this | |
-| | | level | |
-+-----------+-----------------+---------------------------+-------+
-| | tb_lasti | index of last attempted | |
-| | | instruction in bytecode | |
-+-----------+-----------------+---------------------------+-------+
-| | tb_lineno | current line number in | |
-| | | Python source code | |
-+-----------+-----------------+---------------------------+-------+
-| | tb_next | next inner traceback | |
-| | | object (called by this | |
-| | | level) | |
-+-----------+-----------------+---------------------------+-------+
-| frame | f_back | next outer frame object | |
-| | | (this frame's caller) | |
-+-----------+-----------------+---------------------------+-------+
-| | f_builtins | builtins namespace seen | |
-| | | by this frame | |
-+-----------+-----------------+---------------------------+-------+
-| | f_code | code object being | |
-| | | executed in this frame | |
-+-----------+-----------------+---------------------------+-------+
-| | f_exc_traceback | traceback if raised in | |
-| | | this frame, or ``None`` | |
-+-----------+-----------------+---------------------------+-------+
-| | f_exc_type | exception type if raised | |
-| | | in this frame, or | |
-| | | ``None`` | |
-+-----------+-----------------+---------------------------+-------+
-| | f_exc_value | exception value if raised | |
-| | | in this frame, or | |
-| | | ``None`` | |
-+-----------+-----------------+---------------------------+-------+
-| | f_globals | global namespace seen by | |
-| | | this frame | |
-+-----------+-----------------+---------------------------+-------+
-| | f_lasti | index of last attempted | |
-| | | instruction in bytecode | |
-+-----------+-----------------+---------------------------+-------+
-| | f_lineno | current line number in | |
-| | | Python source code | |
-+-----------+-----------------+---------------------------+-------+
-| | f_locals | local namespace seen by | |
-| | | this frame | |
-+-----------+-----------------+---------------------------+-------+
-| | f_restricted | 0 or 1 if frame is in | |
-| | | restricted execution mode | |
-+-----------+-----------------+---------------------------+-------+
-| | f_trace | tracing function for this | |
-| | | frame, or ``None`` | |
-+-----------+-----------------+---------------------------+-------+
-| code | co_argcount | number of arguments (not | |
-| | | including \* or \*\* | |
-| | | args) | |
-+-----------+-----------------+---------------------------+-------+
-| | co_code | string of raw compiled | |
-| | | bytecode | |
-+-----------+-----------------+---------------------------+-------+
-| | co_consts | tuple of constants used | |
-| | | in the bytecode | |
-+-----------+-----------------+---------------------------+-------+
-| | co_filename | name of file in which | |
-| | | this code object was | |
-| | | created | |
-+-----------+-----------------+---------------------------+-------+
-| | co_firstlineno | number of first line in | |
-| | | Python source code | |
-+-----------+-----------------+---------------------------+-------+
-| | co_flags | bitmap: 1=optimized ``|`` | |
-| | | 2=newlocals ``|`` 4=\*arg | |
-| | | ``|`` 8=\*\*arg | |
-+-----------+-----------------+---------------------------+-------+
-| | co_lnotab | encoded mapping of line | |
-| | | numbers to bytecode | |
-| | | indices | |
-+-----------+-----------------+---------------------------+-------+
-| | co_name | name with which this code | |
-| | | object was defined | |
-+-----------+-----------------+---------------------------+-------+
-| | co_names | tuple of names of local | |
-| | | variables | |
-+-----------+-----------------+---------------------------+-------+
-| | co_nlocals | number of local variables | |
-+-----------+-----------------+---------------------------+-------+
-| | co_stacksize | virtual machine stack | |
-| | | space required | |
-+-----------+-----------------+---------------------------+-------+
-| | co_varnames | tuple of names of | |
-| | | arguments and local | |
-| | | variables | |
-+-----------+-----------------+---------------------------+-------+
-| builtin | __doc__ | documentation string | |
-+-----------+-----------------+---------------------------+-------+
-| | __name__ | original name of this | |
-| | | function or method | |
-+-----------+-----------------+---------------------------+-------+
-| | __self__ | instance to which a | |
-| | | method is bound, or | |
-| | | ``None`` | |
-+-----------+-----------------+---------------------------+-------+
-
-Note:
-
-(1)
- .. versionchanged:: 2.2
- :attr:`im_class` used to refer to the class that defined the method.
++-----------+-----------------+---------------------------+
+| Type | Attribute | Description |
++===========+=================+===========================+
+| module | __doc__ | documentation string |
++-----------+-----------------+---------------------------+
+| | __file__ | filename (missing for |
+| | | built-in modules) |
++-----------+-----------------+---------------------------+
+| class | __doc__ | documentation string |
++-----------+-----------------+---------------------------+
+| | __module__ | name of module in which |
+| | | this class was defined |
++-----------+-----------------+---------------------------+
+| method | __doc__ | documentation string |
++-----------+-----------------+---------------------------+
+| | __name__ | name with which this |
+| | | method was defined |
++-----------+-----------------+---------------------------+
+| | __func__ | function object |
+| | | containing implementation |
+| | | of method |
++-----------+-----------------+---------------------------+
+| | __self__ | instance to which this |
+| | | method is bound, or |
+| | | ``None`` |
++-----------+-----------------+---------------------------+
+| function | __doc__ | documentation string |
++-----------+-----------------+---------------------------+
+| | __name__ | name with which this |
+| | | function was defined |
++-----------+-----------------+---------------------------+
+| | __code__ | code object containing |
+| | | compiled function |
+| | | :term:`bytecode` |
++-----------+-----------------+---------------------------+
+| | __defaults__ | tuple of any default |
+| | | values for arguments |
++-----------+-----------------+---------------------------+
+| | __globals__ | global namespace in which |
+| | | this function was defined |
++-----------+-----------------+---------------------------+
+| traceback | tb_frame | frame object at this |
+| | | level |
++-----------+-----------------+---------------------------+
+| | tb_lasti | index of last attempted |
+| | | instruction in bytecode |
++-----------+-----------------+---------------------------+
+| | tb_lineno | current line number in |
+| | | Python source code |
++-----------+-----------------+---------------------------+
+| | tb_next | next inner traceback |
+| | | object (called by this |
+| | | level) |
++-----------+-----------------+---------------------------+
+| frame | f_back | next outer frame object |
+| | | (this frame's caller) |
++-----------+-----------------+---------------------------+
+| | f_builtins | builtins namespace seen |
+| | | by this frame |
++-----------+-----------------+---------------------------+
+| | f_code | code object being |
+| | | executed in this frame |
++-----------+-----------------+---------------------------+
+| | f_globals | global namespace seen by |
+| | | this frame |
++-----------+-----------------+---------------------------+
+| | f_lasti | index of last attempted |
+| | | instruction in bytecode |
++-----------+-----------------+---------------------------+
+| | f_lineno | current line number in |
+| | | Python source code |
++-----------+-----------------+---------------------------+
+| | f_locals | local namespace seen by |
+| | | this frame |
++-----------+-----------------+---------------------------+
+| | f_restricted | 0 or 1 if frame is in |
+| | | restricted execution mode |
++-----------+-----------------+---------------------------+
+| | f_trace | tracing function for this |
+| | | frame, or ``None`` |
++-----------+-----------------+---------------------------+
+| code | co_argcount | number of arguments (not |
+| | | including \* or \*\* |
+| | | args) |
++-----------+-----------------+---------------------------+
+| | co_code | string of raw compiled |
+| | | bytecode |
++-----------+-----------------+---------------------------+
+| | co_consts | tuple of constants used |
+| | | in the bytecode |
++-----------+-----------------+---------------------------+
+| | co_filename | name of file in which |
+| | | this code object was |
+| | | created |
++-----------+-----------------+---------------------------+
+| | co_firstlineno | number of first line in |
+| | | Python source code |
++-----------+-----------------+---------------------------+
+| | co_flags | bitmap: 1=optimized ``|`` |
+| | | 2=newlocals ``|`` 4=\*arg |
+| | | ``|`` 8=\*\*arg |
++-----------+-----------------+---------------------------+
+| | co_lnotab | encoded mapping of line |
+| | | numbers to bytecode |
+| | | indices |
++-----------+-----------------+---------------------------+
+| | co_name | name with which this code |
+| | | object was defined |
++-----------+-----------------+---------------------------+
+| | co_names | tuple of names of local |
+| | | variables |
++-----------+-----------------+---------------------------+
+| | co_nlocals | number of local variables |
++-----------+-----------------+---------------------------+
+| | co_stacksize | virtual machine stack |
+| | | space required |
++-----------+-----------------+---------------------------+
+| | co_varnames | tuple of names of |
+| | | arguments and local |
+| | | variables |
++-----------+-----------------+---------------------------+
+| builtin | __doc__ | documentation string |
++-----------+-----------------+---------------------------+
+| | __name__ | original name of this |
+| | | function or method |
++-----------+-----------------+---------------------------+
+| | __self__ | instance to which a |
+| | | method is bound, or |
+| | | ``None`` |
++-----------+-----------------+---------------------------+
.. function:: getmembers(object[, predicate])
@@ -235,10 +179,10 @@ Note:
.. function:: getmoduleinfo(path)
- Return a tuple of values that describe how Python will interpret the file
- identified by *path* if it is a module, or ``None`` if it would not be
- identified as a module. The return tuple is ``(name, suffix, mode,
- module_type)``, where *name* is the name of the module without the name of
+ Returns a :term:`named tuple` ``ModuleInfo(name, suffix, mode, module_type)``
+ of values that describe how Python will interpret the file identified by
+ *path* if it is a module, or ``None`` if it would not be identified as a
+ module. In that tuple, *name* is the name of the module without the name of
any enclosing package, *suffix* is the trailing part of the file name (which
may not be a dot-delimited extension), *mode* is the :func:`open` mode that
would be used (``'r'`` or ``'rb'``), and *module_type* is an integer giving
@@ -246,10 +190,6 @@ Note:
compared to the constants defined in the :mod:`imp` module; see the
documentation for that module for more information on module types.
- .. versionchanged:: 2.6
- Returns a :term:`named tuple` ``ModuleInfo(name, suffix, mode,
- module_type)``.
-
.. function:: getmodulename(path)
@@ -285,15 +225,11 @@ Note:
Return true if the object is a Python generator function.
- .. versionadded:: 2.6
-
.. function:: isgenerator(object)
Return true if the object is a generator.
- .. versionadded:: 2.6
-
.. function:: istraceback(object)
@@ -324,8 +260,6 @@ Note:
Return true if the object is an abstract base class.
- .. versionadded:: 2.6
-
.. function:: ismethoddescriptor(object)
@@ -333,15 +267,15 @@ Note:
:func:`ismethod`, :func:`isclass`, :func:`isfunction` or :func:`isbuiltin`
are true.
- This is new as of Python 2.2, and, for example, is true of
- ``int.__add__``. An object passing this test has a :attr:`__get__` attribute
- but not a :attr:`__set__` attribute, but beyond that the set of attributes
- varies. :attr:`__name__` is usually sensible, and :attr:`__doc__` often is.
+ This, for example, is true of ``int.__add__``. An object passing this test
+ has a :attr:`__get__` attribute but not a :attr:`__set__` attribute, but
+ beyond that the set of attributes varies. :attr:`__name__` is usually
+ sensible, and :attr:`__doc__` often is.
Methods implemented via descriptors that also pass one of the other tests
return false from the :func:`ismethoddescriptor` test, simply because the
other tests promise more -- you can, e.g., count on having the
- :attr:`im_func` attribute (etc) when an object passes :func:`ismethod`.
+ :attr:`__func__` attribute (etc) when an object passes :func:`ismethod`.
.. function:: isdatadescriptor(object)
@@ -356,8 +290,6 @@ Note:
(properties, getsets, and members have both of these attributes), but this is
not guaranteed.
- .. versionadded:: 2.3
-
.. function:: isgetsetdescriptor(object)
@@ -369,8 +301,6 @@ Note:
:c:type:`PyGetSetDef` structures. For Python implementations without such
types, this method will always return ``False``.
- .. versionadded:: 2.5
-
.. function:: ismemberdescriptor(object)
@@ -382,8 +312,6 @@ Note:
:c:type:`PyMemberDef` structures. For Python implementations without such
types, this method will always return ``False``.
- .. versionadded:: 2.5
-
.. _inspect-source:
@@ -445,16 +373,13 @@ Retrieving source code
of code. Any whitespace that can be uniformly removed from the second line
onwards is removed. Also, all tabs are expanded to spaces.
- .. versionadded:: 2.6
-
.. _inspect-classes-functions:
Classes and functions
---------------------
-
-.. function:: getclasstree(classes[, unique])
+.. function:: getclasstree(classes, unique=False)
Arrange the given list of classes into a hierarchy of nested lists. Where a
nested list appears, it contains classes derived from the class whose entry
@@ -467,40 +392,54 @@ Classes and functions
.. function:: getargspec(func)
- Get the names and default values of a Python function's arguments. A tuple of
- four things is returned: ``(args, varargs, keywords, defaults)``. *args* is a
- list of the argument names (it may contain nested lists). *varargs* and
- *keywords* are the names of the ``*`` and ``**`` arguments or
- ``None``. *defaults* is a tuple of default argument values or None if there
- are no default arguments; if this tuple has *n* elements, they correspond to
- the last *n* elements listed in *args*.
+ Get the names and default values of a Python function's arguments. A
+ :term:`named tuple` ``ArgSpec(args, varargs, keywords, defaults)`` is
+ returned. *args* is a list of the argument names. *varargs* and *keywords*
+ are the names of the ``*`` and ``**`` arguments or ``None``. *defaults* is a
+ tuple of default argument values or None if there are no default arguments;
+ if this tuple has *n* elements, they correspond to the last *n* elements
+ listed in *args*.
- .. versionchanged:: 2.6
- Returns a :term:`named tuple` ``ArgSpec(args, varargs, keywords,
- defaults)``.
+ .. deprecated:: 3.0
+ Use :func:`getfullargspec` instead, which provides information about
+ keyword-only arguments and annotations.
-.. function:: getargvalues(frame)
+.. function:: getfullargspec(func)
+
+ Get the names and default values of a Python function's arguments. A
+ :term:`named tuple` is returned:
+
+ ``FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults,
+ annotations)``
+
+ *args* is a list of the argument names. *varargs* and *varkw* are the names
+ of the ``*`` and ``**`` arguments or ``None``. *defaults* is an n-tuple of
+ the default values of the last n arguments. *kwonlyargs* is a list of
+ keyword-only argument names. *kwonlydefaults* is a dictionary mapping names
+ from kwonlyargs to defaults. *annotations* is a dictionary mapping argument
+ names to annotations.
- Get information about arguments passed into a particular frame. A tuple of
- four things is returned: ``(args, varargs, keywords, locals)``. *args* is a
- list of the argument names (it may contain nested lists). *varargs* and
- *keywords* are the names of the ``*`` and ``**`` arguments or ``None``.
- *locals* is the locals dictionary of the given frame.
+ The first four items in the tuple correspond to :func:`getargspec`.
- .. versionchanged:: 2.6
- Returns a :term:`named tuple` ``ArgInfo(args, varargs, keywords,
- locals)``.
+
+.. function:: getargvalues(frame)
+
+ Get information about arguments passed into a particular frame. A
+ :term:`named tuple` ``ArgInfo(args, varargs, keywords, locals)`` is
+ returned. *args* is a list of the argument names. *varargs* and *keywords*
+ are the names of the ``*`` and ``**`` arguments or ``None``. *locals* is the
+ locals dictionary of the given frame.
-.. function:: formatargspec(args[, varargs, varkw, defaults, formatarg, formatvarargs, formatvarkw, formatvalue, join])
+.. function:: formatargspec(args[, varargs, varkw, defaults, formatarg, formatvarargs, formatvarkw, formatvalue])
Format a pretty argument spec from the four values returned by
:func:`getargspec`. The format\* arguments are the corresponding optional
formatting functions that are called to turn names and values into strings.
-.. function:: formatargvalues(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue, join])
+.. function:: formatargvalues(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue])
Format a pretty argument spec from the four values returned by
:func:`getargvalues`. The format\* arguments are the corresponding optional
@@ -538,7 +477,7 @@ Classes and functions
...
TypeError: f() takes at least 1 argument (0 given)
- .. versionadded:: 2.7
+ .. versionadded:: 3.2
.. _inspect-stack:
@@ -578,17 +517,13 @@ the number of lines of context to return, which are centered around the current
line.
-.. function:: getframeinfo(frame[, context])
+.. function:: getframeinfo(frame, context=1)
- Get information about a frame or traceback object. A 5-tuple is returned, the
- last five elements of the frame's frame record.
+ Get information about a frame or traceback object. A :term:`named tuple`
+ ``Traceback(filename, lineno, function, code_context, index)`` is returned.
- .. versionchanged:: 2.6
- Returns a :term:`named tuple` ``Traceback(filename, lineno, function,
- code_context, index)``.
-
-.. function:: getouterframes(frame[, context])
+.. function:: getouterframes(frame, context=1)
Get a list of frame records for a frame and all outer frames. These frames
represent the calls that lead to the creation of *frame*. The first entry in the
@@ -596,7 +531,7 @@ line.
on *frame*'s stack.
-.. function:: getinnerframes(traceback[, context])
+.. function:: getinnerframes(traceback, context=1)
Get a list of frame records for a traceback's frame and all inner frames. These
frames represent calls made as a consequence of *frame*. The first entry in the
@@ -616,17 +551,95 @@ line.
function returns ``None``.
-.. function:: stack([context])
+.. function:: stack(context=1)
Return a list of frame records for the caller's stack. The first entry in the
returned list represents the caller; the last entry represents the outermost
call on the stack.
-.. function:: trace([context])
+.. function:: trace(context=1)
Return a list of frame records for the stack between the current frame and the
frame in which an exception currently being handled was raised in. The first
entry in the list represents the caller; the last entry represents where the
exception was raised.
+
+Fetching attributes statically
+------------------------------
+
+Both :func:`getattr` and :func:`hasattr` can trigger code execution when
+fetching or checking for the existence of attributes. Descriptors, like
+properties, will be invoked and :meth:`__getattr__` and :meth:`__getattribute__`
+may be called.
+
+For cases where you want passive introspection, like documentation tools, this
+can be inconvenient. :func:`getattr_static` has the same signature as :func:`getattr`
+but avoids executing code when it fetches attributes.
+
+.. function:: getattr_static(obj, attr, default=None)
+
+ Retrieve attributes without triggering dynamic lookup via the
+ descriptor protocol, :meth:`__getattr__` or :meth:`__getattribute__`.
+
+ Note: this function may not be able to retrieve all attributes
+ that getattr can fetch (like dynamically created attributes)
+ and may find attributes that getattr can't (like descriptors
+ that raise AttributeError). It can also return descriptors objects
+ instead of instance members.
+
+ If the instance :attr:`__dict__` is shadowed by another member (for example a
+ property) then this function will be unable to find instance members.
+
+ .. versionadded:: 3.2
+
+:func:`getattr_static` does not resolve descriptors, for example slot descriptors or
+getset descriptors on objects implemented in C. The descriptor object
+is returned instead of the underlying attribute.
+
+You can handle these with code like the following. Note that
+for arbitrary getset descriptors invoking these may trigger
+code execution::
+
+ # example code for resolving the builtin descriptor types
+ class _foo:
+ __slots__ = ['foo']
+
+ slot_descriptor = type(_foo.foo)
+ getset_descriptor = type(type(open(__file__)).name)
+ wrapper_descriptor = type(str.__dict__['__add__'])
+ descriptor_types = (slot_descriptor, getset_descriptor, wrapper_descriptor)
+
+ result = getattr_static(some_object, 'foo')
+ if type(result) in descriptor_types:
+ try:
+ result = result.__get__()
+ except AttributeError:
+ # descriptors can raise AttributeError to
+ # indicate there is no underlying value
+ # in which case the descriptor itself will
+ # have to do
+ pass
+
+
+Current State of a Generator
+----------------------------
+
+When implementing coroutine schedulers and for other advanced uses of
+generators, it is useful to determine whether a generator is currently
+executing, is waiting to start or resume or execution, or has already
+terminated. :func:`getgeneratorstate` allows the current state of a
+generator to be determined easily.
+
+.. function:: getgeneratorstate(generator)
+
+ Get current state of a generator-iterator.
+
+ Possible states are:
+ * GEN_CREATED: Waiting to start execution.
+ * GEN_RUNNING: Currently being executed by the interpreter.
+ * GEN_SUSPENDED: Currently suspended at a yield expression.
+ * GEN_CLOSED: Execution has completed.
+
+ .. versionadded:: 3.2
diff --git a/Doc/library/internet.rst b/Doc/library/internet.rst
index 16b0a44..6fa7873 100644
--- a/Doc/library/internet.rst
+++ b/Doc/library/internet.rst
@@ -1,4 +1,3 @@
-
.. _internet:
******************************
@@ -24,9 +23,11 @@ is currently supported on most popular platforms. Here is an overview:
cgi.rst
cgitb.rst
wsgiref.rst
- urllib.rst
- urllib2.rst
- httplib.rst
+ urllib.request.rst
+ urllib.parse.rst
+ urllib.error.rst
+ urllib.robotparser.rst
+ http.client.rst
ftplib.rst
poplib.rst
imaplib.rst
@@ -35,13 +36,9 @@ is currently supported on most popular platforms. Here is an overview:
smtpd.rst
telnetlib.rst
uuid.rst
- urlparse.rst
socketserver.rst
- basehttpserver.rst
- simplehttpserver.rst
- cgihttpserver.rst
- cookielib.rst
- cookie.rst
- xmlrpclib.rst
- simplexmlrpcserver.rst
- docxmlrpcserver.rst
+ http.server.rst
+ http.cookies.rst
+ http.cookiejar.rst
+ xmlrpc.client.rst
+ xmlrpc.server.rst
diff --git a/Doc/library/intro.rst b/Doc/library/intro.rst
index 5e5fc80..a0f2d63 100644
--- a/Doc/library/intro.rst
+++ b/Doc/library/intro.rst
@@ -1,4 +1,3 @@
-
.. _library-intro:
************
diff --git a/Doc/library/io.rst b/Doc/library/io.rst
index 8994086..1939352 100644
--- a/Doc/library/io.rst
+++ b/Doc/library/io.rst
@@ -11,178 +11,104 @@
.. moduleauthor:: Benjamin Peterson <benjamin@python.org>
.. sectionauthor:: Benjamin Peterson <benjamin@python.org>
-.. versionadded:: 2.6
+.. _io-overview:
-The :mod:`io` module provides the Python interfaces to stream handling.
-Under Python 2.x, this is proposed as an alternative to the built-in
-:class:`file` object, but in Python 3.x it is the default interface to
-access files and streams.
+Overview
+--------
-.. note::
+.. index::
+ single: file object; io module
- Since this module has been designed primarily for Python 3.x, you have to
- be aware that all uses of "bytes" in this document refer to the
- :class:`str` type (of which :class:`bytes` is an alias), and all uses
- of "text" refer to the :class:`unicode` type. Furthermore, those two
- types are not interchangeable in the :mod:`io` APIs.
+The :mod:`io` module provides Python's main facilities for dealing with various
+types of I/O. There are three main types of I/O: *text I/O*, *binary I/O*
+and *raw I/O*. These are generic categories, and various backing stores can
+be used for each of them. A concrete object belonging to any of these
+categories is called a :term:`file object`. Other common terms are *stream*
+and *file-like object*.
-At the top of the I/O hierarchy is the abstract base class :class:`IOBase`. It
-defines the basic interface to a stream. Note, however, that there is no
-separation between reading and writing to streams; implementations are allowed
-to raise an :exc:`IOError` if they do not support a given operation.
+Independently of its category, each concrete stream object will also have
+various capabilities: it can be read-only, write-only, or read-write. It can
+also allow arbitrary random access (seeking forwards or backwards to any
+location), or only sequential access (for example in the case of a socket or
+pipe).
-Extending :class:`IOBase` is :class:`RawIOBase` which deals simply with the
-reading and writing of raw bytes to a stream. :class:`FileIO` subclasses
-:class:`RawIOBase` to provide an interface to files in the machine's
-file system.
+All streams are careful about the type of data you give to them. For example
+giving a :class:`str` object to the ``write()`` method of a binary stream
+will raise a ``TypeError``. So will giving a :class:`bytes` object to the
+``write()`` method of a text stream.
-:class:`BufferedIOBase` deals with buffering on a raw byte stream
-(:class:`RawIOBase`). Its subclasses, :class:`BufferedWriter`,
-:class:`BufferedReader`, and :class:`BufferedRWPair` buffer streams that are
-readable, writable, and both readable and writable.
-:class:`BufferedRandom` provides a buffered interface to random access
-streams. :class:`BytesIO` is a simple stream of in-memory bytes.
-Another :class:`IOBase` subclass, :class:`TextIOBase`, deals with
-streams whose bytes represent text, and handles encoding and decoding
-from and to :class:`unicode` strings. :class:`TextIOWrapper`, which extends
-it, is a buffered text interface to a buffered raw stream
-(:class:`BufferedIOBase`). Finally, :class:`StringIO` is an in-memory
-stream for unicode text.
+Text I/O
+^^^^^^^^
-Argument names are not part of the specification, and only the arguments of
-:func:`.open` are intended to be used as keyword arguments.
+Text I/O expects and produces :class:`str` objects. This means that whenever
+the backing store is natively made of bytes (such as in the case of a file),
+encoding and decoding of data is made transparently as well as optional
+translation of platform-specific newline characters.
+
+The easiest way to create a text stream is with :meth:`open()`, optionally
+specifying an encoding::
+
+ f = open("myfile.txt", "r", encoding="utf-8")
+
+In-memory text streams are also available as :class:`StringIO` objects::
+
+ f = io.StringIO("some initial text data")
+
+The text stream API is described in detail in the documentation for the
+:class:`TextIOBase`.
+
+
+Binary I/O
+^^^^^^^^^^
+
+Binary I/O (also called *buffered I/O*) expects and produces :class:`bytes`
+objects. No encoding, decoding, or newline translation is performed. This
+category of streams can be used for all kinds of non-text data, and also when
+manual control over the handling of text data is desired.
+The easiest way to create a binary stream is with :meth:`open()` with ``'b'`` in
+the mode string::
-Module Interface
-----------------
+ f = open("myfile.jpg", "rb")
+
+In-memory binary streams are also available as :class:`BytesIO` objects::
+
+ f = io.BytesIO(b"some initial binary data: \x00\x01")
+
+The binary stream API is described in detail in the docs of
+:class:`BufferedIOBase`.
+
+Other library modules may provide additional ways to create text or binary
+streams. See :meth:`socket.socket.makefile` for example.
+
+
+Raw I/O
+^^^^^^^
+
+Raw I/O (also called *unbuffered I/O*) is generally used as a low-level
+building-block for binary and text streams; it is rarely useful to directly
+manipulate a raw stream from user code. Nevertheless, you can create a raw
+stream by opening a file in binary mode with buffering disabled::
+
+ f = open("myfile.jpg", "rb", buffering=0)
+
+The raw stream API is described in detail in the docs of :class:`RawIOBase`.
+
+
+High-level Module Interface
+---------------------------
.. data:: DEFAULT_BUFFER_SIZE
An int containing the default buffer size used by the module's buffered I/O
- classes. :func:`.open` uses the file's blksize (as obtained by
+ classes. :func:`open` uses the file's blksize (as obtained by
:func:`os.stat`) if possible.
-.. function:: open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True)
- Open *file* and return a corresponding stream. If the file cannot be opened,
- an :exc:`IOError` is raised.
-
- *file* is either a string giving the pathname (absolute or
- relative to the current working directory) of the file to be opened or
- an integer file descriptor of the file to be wrapped. (If a file descriptor
- is given, it is closed when the returned I/O object is closed, unless
- *closefd* is set to ``False``.)
-
- *mode* is an optional string that specifies the mode in which the file is
- opened. It defaults to ``'r'`` which means open for reading in text mode.
- Other common values are ``'w'`` for writing (truncating the file if it
- already exists), and ``'a'`` for appending (which on *some* Unix systems,
- means that *all* writes append to the end of the file regardless of the
- current seek position). In text mode, if *encoding* is not specified the
- encoding used is platform dependent. (For reading and writing raw bytes use
- binary mode and leave *encoding* unspecified.) The available modes are:
-
- ========= ===============================================================
- Character Meaning
- --------- ---------------------------------------------------------------
- ``'r'`` open for reading (default)
- ``'w'`` open for writing, truncating the file first
- ``'a'`` open for writing, appending to the end of the file if it exists
- ``'b'`` binary mode
- ``'t'`` text mode (default)
- ``'+'`` open a disk file for updating (reading and writing)
- ``'U'`` universal newlines mode (for backwards compatibility; should
- not be used in new code)
- ========= ===============================================================
-
- The default mode is ``'rt'`` (open for reading text). For binary random
- access, the mode ``'w+b'`` opens and truncates the file to 0 bytes, while
- ``'r+b'`` opens the file without truncation.
-
- Python distinguishes between files opened in binary and text modes, even when
- the underlying operating system doesn't. Files opened in binary mode
- (including ``'b'`` in the *mode* argument) return contents as :class:`bytes`
- objects without any decoding. In text mode (the default, or when ``'t'`` is
- included in the *mode* argument), the contents of the file are returned as
- :class:`unicode` strings, the bytes having been first decoded using a
- platform-dependent encoding or using the specified *encoding* if given.
-
- *buffering* is an optional integer used to set the buffering policy.
- Pass 0 to switch buffering off (only allowed in binary mode), 1 to select
- line buffering (only usable in text mode), and an integer > 1 to indicate
- the size of a fixed-size chunk buffer. When no *buffering* argument is
- given, the default buffering policy works as follows:
-
- * Binary files are buffered in fixed-size chunks; the size of the buffer
- is chosen using a heuristic trying to determine the underlying device's
- "block size" and falling back on :attr:`DEFAULT_BUFFER_SIZE`.
- On many systems, the buffer will typically be 4096 or 8192 bytes long.
-
- * "Interactive" text files (files for which :meth:`isatty` returns True)
- use line buffering. Other text files use the policy described above
- for binary files.
-
- *encoding* is the name of the encoding used to decode or encode the file.
- This should only be used in text mode. The default encoding is platform
- dependent (whatever :func:`locale.getpreferredencoding` returns), but any
- encoding supported by Python can be used. See the :mod:`codecs` module for
- the list of supported encodings.
-
- *errors* is an optional string that specifies how encoding and decoding
- errors are to be handled--this cannot be used in binary mode. Pass
- ``'strict'`` to raise a :exc:`ValueError` exception if there is an encoding
- error (the default of ``None`` has the same effect), or pass ``'ignore'`` to
- ignore errors. (Note that ignoring encoding errors can lead to data loss.)
- ``'replace'`` causes a replacement marker (such as ``'?'``) to be inserted
- where there is malformed data. When writing, ``'xmlcharrefreplace'``
- (replace with the appropriate XML character reference) or
- ``'backslashreplace'`` (replace with backslashed escape sequences) can be
- used. Any other error handling name that has been registered with
- :func:`codecs.register_error` is also valid.
+.. function:: open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True)
- .. index::
- single: universal newlines; open() (in module io)
-
- *newline* controls how :term:`universal newlines` works (it only applies to
- text mode). It can be ``None``, ``''``, ``'\n'``, ``'\r'``, and ``'\r\n'``.
- It works as follows:
-
- * On input, if *newline* is ``None``, universal newlines mode is enabled.
- Lines in the input can end in ``'\n'``, ``'\r'``, or ``'\r\n'``, and these
- are translated into ``'\n'`` before being returned to the caller. If it is
- ``''``, universal newlines mode is enabled, but line endings are returned to
- the caller untranslated. If it has any of the other legal values, input
- lines are only terminated by the given string, and the line ending is
- returned to the caller untranslated.
-
- * On output, if *newline* is ``None``, any ``'\n'`` characters written are
- translated to the system default line separator, :data:`os.linesep`. If
- *newline* is ``''``, no translation takes place. If *newline* is any of
- the other legal values, any ``'\n'`` characters written are translated to
- the given string.
-
- If *closefd* is ``False`` and a file descriptor rather than a filename was
- given, the underlying file descriptor will be kept open when the file is
- closed. If a filename is given *closefd* has no effect and must be ``True``
- (the default).
-
- The type of file object returned by the :func:`.open` function depends on the
- mode. When :func:`.open` is used to open a file in a text mode (``'w'``,
- ``'r'``, ``'wt'``, ``'rt'``, etc.), it returns a subclass of
- :class:`TextIOBase` (specifically :class:`TextIOWrapper`). When used to open
- a file in a binary mode with buffering, the returned class is a subclass of
- :class:`BufferedIOBase`. The exact class varies: in read binary mode, it
- returns a :class:`BufferedReader`; in write binary and append binary modes,
- it returns a :class:`BufferedWriter`, and in read/write mode, it returns a
- :class:`BufferedRandom`. When buffering is disabled, the raw stream, a
- subclass of :class:`RawIOBase`, :class:`FileIO`, is returned.
-
- It is also possible to use an :class:`unicode` or :class:`bytes` string
- as a file for both reading and writing. For :class:`unicode` strings
- :class:`StringIO` can be used like a file opened in text mode,
- and for :class:`bytes` a :class:`BytesIO` can be used like a
- file opened in a binary mode.
+ This is an alias for the builtin :func:`open` function.
.. exception:: BlockingIOError
@@ -205,8 +131,86 @@ Module Interface
when an unsupported operation is called on a stream.
+In-memory streams
+^^^^^^^^^^^^^^^^^
+
+It is also possible to use a :class:`str` or :class:`bytes`-like object as a
+file for both reading and writing. For strings :class:`StringIO` can be used
+like a file opened in text mode. :class:`BytesIO` can be used like a file
+opened in binary mode. Both provide full read-write capabilities with random
+access.
+
+
+.. seealso::
+
+ :mod:`sys`
+ contains the standard IO streams: :data:`sys.stdin`, :data:`sys.stdout`,
+ and :data:`sys.stderr`.
+
+
+Class hierarchy
+---------------
+
+The implementation of I/O streams is organized as a hierarchy of classes. First
+:term:`abstract base classes <abstract base class>` (ABCs), which are used to
+specify the various categories of streams, then concrete classes providing the
+standard stream implementations.
+
+ .. note::
+
+ The abstract base classes also provide default implementations of some
+ methods in order to help implementation of concrete stream classes. For
+ example, :class:`BufferedIOBase` provides unoptimized implementations of
+ ``readinto()`` and ``readline()``.
+
+At the top of the I/O hierarchy is the abstract base class :class:`IOBase`. It
+defines the basic interface to a stream. Note, however, that there is no
+separation between reading and writing to streams; implementations are allowed
+to raise :exc:`UnsupportedOperation` if they do not support a given operation.
+
+The :class:`RawIOBase` ABC extends :class:`IOBase`. It deals with the reading
+and writing of bytes to a stream. :class:`FileIO` subclasses :class:`RawIOBase`
+to provide an interface to files in the machine's file system.
+
+The :class:`BufferedIOBase` ABC deals with buffering on a raw byte stream
+(:class:`RawIOBase`). Its subclasses, :class:`BufferedWriter`,
+:class:`BufferedReader`, and :class:`BufferedRWPair` buffer streams that are
+readable, writable, and both readable and writable. :class:`BufferedRandom`
+provides a buffered interface to random access streams. Another
+:class:`BufferedIOBase` subclass, :class:`BytesIO`, is a stream of in-memory
+bytes.
+
+The :class:`TextIOBase` ABC, another subclass of :class:`IOBase`, deals with
+streams whose bytes represent text, and handles encoding and decoding to and
+from strings. :class:`TextIOWrapper`, which extends it, is a buffered text
+interface to a buffered raw stream (:class:`BufferedIOBase`). Finally,
+:class:`StringIO` is an in-memory stream for text.
+
+Argument names are not part of the specification, and only the arguments of
+:func:`open` are intended to be used as keyword arguments.
+
+The following table summarizes the ABCs provided by the :mod:`io` module:
+
+========================= ================== ======================== ==================================================
+ABC Inherits Stub Methods Mixin Methods and Properties
+========================= ================== ======================== ==================================================
+:class:`IOBase` ``fileno``, ``seek``, ``close``, ``closed``, ``__enter__``,
+ and ``truncate`` ``__exit__``, ``flush``, ``isatty``, ``__iter__``,
+ ``__next__``, ``readable``, ``readline``,
+ ``readlines``, ``seekable``, ``tell``,
+ ``writable``, and ``writelines``
+:class:`RawIOBase` :class:`IOBase` ``readinto`` and Inherited :class:`IOBase` methods, ``read``,
+ ``write`` and ``readall``
+:class:`BufferedIOBase` :class:`IOBase` ``detach``, ``read``, Inherited :class:`IOBase` methods, ``readinto``
+ ``read1``, and ``write``
+:class:`TextIOBase` :class:`IOBase` ``detach``, ``read``, Inherited :class:`IOBase` methods, ``encoding``,
+ ``readline``, and ``errors``, and ``newlines``
+ ``write``
+========================= ================== ======================== ==================================================
+
+
I/O Base Classes
-----------------
+^^^^^^^^^^^^^^^^
.. class:: IOBase
@@ -225,25 +229,25 @@ I/O Base Classes
support are called.
The basic type used for binary data read from or written to a file is
- :class:`bytes` (also known as :class:`str`). :class:`bytearray`\s are
- accepted too, and in some cases (such as :class:`readinto`) required.
- Text I/O classes work with :class:`unicode` data.
+ :class:`bytes`. :class:`bytearray`\s are accepted too, and in some cases
+ (such as :class:`readinto`) required. Text I/O classes work with
+ :class:`str` data.
Note that calling any method (even inquiries) on a closed stream is
undefined. Implementations may raise :exc:`IOError` in this case.
- IOBase (and its subclasses) support the iterator protocol, meaning that an
+ IOBase (and its subclasses) supports the iterator protocol, meaning that an
:class:`IOBase` object can be iterated over yielding the lines in a stream.
Lines are defined slightly differently depending on whether the stream is
- a binary stream (yielding :class:`bytes`), or a text stream (yielding
- :class:`unicode` strings). See :meth:`~IOBase.readline` below.
+ a binary stream (yielding bytes), or a text stream (yielding character
+ strings). See :meth:`~IOBase.readline` below.
IOBase is also a context manager and therefore supports the
:keyword:`with` statement. In this example, *file* is closed after the
:keyword:`with` statement's suite is finished---even if an exception occurs::
- with io.open('spam.txt', 'w') as file:
- file.write(u'Spam and eggs!')
+ with open('spam.txt', 'w') as file:
+ file.write('Spam and eggs!')
:class:`IOBase` provides these data attributes and methods:
@@ -287,7 +291,7 @@ I/O Base Classes
most *limit* bytes will be read.
The line terminator is always ``b'\n'`` for binary files; for text files,
- the *newlines* argument to :func:`.open` can be used to select the line
+ the *newlines* argument to :func:`open` can be used to select the line
terminator(s) recognized.
.. method:: readlines(hint=-1)
@@ -311,8 +315,8 @@ I/O Base Classes
Return the new absolute position.
- .. versionadded:: 2.7
- The ``SEEK_*`` constants
+ .. versionadded:: 3.1
+ The ``SEEK_*`` constants.
.. method:: seekable()
@@ -430,7 +434,7 @@ I/O Base Classes
raw stream to return from this method. They raise
:exc:`UnsupportedOperation`.
- .. versionadded:: 2.7
+ .. versionadded:: 3.1
.. method:: read(n=-1)
@@ -479,7 +483,7 @@ I/O Base Classes
Raw File I/O
-------------
+^^^^^^^^^^^^
.. class:: FileIO(name, mode='r', closefd=True)
@@ -489,7 +493,8 @@ Raw File I/O
The *name* can be one of two things:
- * a string representing the path to the file which will be opened;
+ * a character string or bytes object representing the path to the file
+ which will be opened;
* an integer representing the number of an existing OS-level file descriptor
to which the resulting :class:`FileIO` object will give access.
@@ -516,7 +521,7 @@ Raw File I/O
Buffered Streams
-----------------
+^^^^^^^^^^^^^^^^
Buffered I/O streams provide a higher-level interface to an I/O device
than raw I/O does.
@@ -526,11 +531,29 @@ than raw I/O does.
A stream implementation using an in-memory bytes buffer. It inherits
:class:`BufferedIOBase`.
- The argument *initial_bytes* is an optional initial :class:`bytes`.
+ The argument *initial_bytes* contains optional initial :class:`bytes` data.
:class:`BytesIO` provides or overrides these methods in addition to those
from :class:`BufferedIOBase` and :class:`IOBase`:
+ .. method:: getbuffer()
+
+ Return a readable and writable view over the contents of the buffer
+ without copying them. Also, mutating the view will transparently
+ update the contents of the buffer::
+
+ >>> b = io.BytesIO(b"abcdef")
+ >>> view = b.getbuffer()
+ >>> view[2:4] = b"56"
+ >>> b.getvalue()
+ b'ab56ef'
+
+ .. note::
+ As long as the view exists, the :class:`BytesIO` object cannot be
+ resized.
+
+ .. versionadded:: 3.2
+
.. method:: getvalue()
Return ``bytes`` containing the entire contents of the buffer.
@@ -647,14 +670,14 @@ than raw I/O does.
Text I/O
---------
+^^^^^^^^
.. class:: TextIOBase
- Base class for text streams. This class provides an unicode character
- and line based interface to stream I/O. There is no :meth:`readinto`
- method because Python's :class:`unicode` strings are immutable.
- It inherits :class:`IOBase`. There is no public constructor.
+ Base class for text streams. This class provides a character and line based
+ interface to stream I/O. There is no :meth:`readinto` method because
+ Python's character strings are immutable. It inherits :class:`IOBase`.
+ There is no public constructor.
:class:`TextIOBase` provides or overrides these data attributes and
methods in addition to those from :class:`IOBase`:
@@ -692,17 +715,17 @@ Text I/O
have the concept of an underlying buffer and calling this method will
raise :exc:`UnsupportedOperation`.
- .. versionadded:: 2.7
+ .. versionadded:: 3.1
.. method:: read(n)
Read and return at most *n* characters from the stream as a single
- :class:`unicode`. If *n* is negative or ``None``, reads until EOF.
+ :class:`str`. If *n* is negative or ``None``, reads until EOF.
.. method:: readline(limit=-1)
- Read until newline or EOF and return a single ``unicode``. If the
- stream is already at EOF, an empty string is returned.
+ Read until newline or EOF and return a single ``str``. If the stream is
+ already at EOF, an empty string is returned.
If *limit* is specified, at most *limit* characters will be read.
@@ -723,7 +746,7 @@ Text I/O
Return the new absolute position as an opaque number.
- .. versionadded:: 2.7
+ .. versionadded:: 3.1
The ``SEEK_*`` constants.
.. method:: tell()
@@ -734,8 +757,8 @@ Text I/O
.. method:: write(s)
- Write the :class:`unicode` string *s* to the stream and return the
- number of characters written.
+ Write the string *s* to the stream and return the number of characters
+ written.
.. class:: TextIOWrapper(buffer, encoding=None, errors=None, newline=None, line_buffering=False)
@@ -763,19 +786,20 @@ Text I/O
*newline* controls how line endings are handled. It can be ``None``,
``''``, ``'\n'``, ``'\r'``, and ``'\r\n'``. It works as follows:
- * On input, if *newline* is ``None``, :term:`universal newlines` mode is
- enabled. Lines in the input can end in ``'\n'``, ``'\r'``, or ``'\r\n'``,
- and these are translated into ``'\n'`` before being returned to the
- caller. If it is ``''``, universal newlines mode is enabled, but line
- endings are returned to the caller untranslated. If it has any of the
- other legal values, input lines are only terminated by the given string,
- and the line ending is returned to the caller untranslated.
-
- * On output, if *newline* is ``None``, any ``'\n'`` characters written are
- translated to the system default line separator, :data:`os.linesep`. If
- *newline* is ``''``, no translation takes place. If *newline* is any of
- the other legal values, any ``'\n'`` characters written are translated to
- the given string.
+ * When reading input from the stream, if *newline* is ``None``,
+ :term:`universal newlines` mode is enabled. Lines in the input can end in
+ ``'\n'``, ``'\r'``, or ``'\r\n'``, and these are translated into ``'\n'``
+ before being returned to the caller. If it is ``''``, universal newlines
+ mode is enabled, but line endings are returned to the caller untranslated.
+ If it has any of the other legal values, input lines are only terminated
+ by the given string, and the line ending is returned to the caller
+ untranslated.
+
+ * When writing output to the stream, if *newline* is ``None``, any ``'\n'``
+ characters written are translated to the system default line separator,
+ :data:`os.linesep`. If *newline* is ``''`` or ``'\n'``, no translation
+ takes place. If *newline* is any of the other legal values, any ``'\n'``
+ characters written are translated to the given string.
If *line_buffering* is ``True``, :meth:`flush` is implied when a call to
write contains a newline character.
@@ -788,21 +812,20 @@ Text I/O
Whether line buffering is enabled.
-.. class:: StringIO(initial_value=u'', newline=None)
+.. class:: StringIO(initial_value='', newline=None)
- An in-memory stream for unicode text. It inherits :class:`TextIOWrapper`.
+ An in-memory stream for text I/O.
- The initial value of the buffer (an empty unicode string by default) can
- be set by providing *initial_value*. The *newline* argument works like
- that of :class:`TextIOWrapper`. The default is to do no newline
- translation.
+ The initial value of the buffer (an empty string by default) can be set by
+ providing *initial_value*. The *newline* argument works like that of
+ :class:`TextIOWrapper`. The default is to do no newline translation.
:class:`StringIO` provides this method in addition to those from
- :class:`TextIOWrapper` and its parents:
+ :class:`TextIOBase` and its parents:
.. method:: getvalue()
- Return a ``unicode`` containing the entire contents of the buffer at any
+ Return a ``str`` containing the entire contents of the buffer at any
time before the :class:`StringIO` object's :meth:`close` method is
called.
@@ -811,11 +834,11 @@ Text I/O
import io
output = io.StringIO()
- output.write(u'First line.\n')
- output.write(u'Second line.\n')
+ output.write('First line.\n')
+ print('Second line.', file=output)
# Retrieve file contents -- this will be
- # u'First line.\nSecond line.\n'
+ # 'First line.\nSecond line.\n'
contents = output.getvalue()
# Close object and discard memory buffer --
@@ -832,37 +855,33 @@ Text I/O
It inherits :class:`codecs.IncrementalDecoder`.
-Advanced topics
----------------
-
-Here we will discuss several advanced topics pertaining to the concrete
-I/O implementations described above.
-
Performance
-^^^^^^^^^^^
+-----------
+
+This section discusses the performance of the provided concrete I/O
+implementations.
Binary I/O
-""""""""""
-
-By reading and writing only large chunks of data even when the user asks
-for a single byte, buffered I/O is designed to hide any inefficiency in
-calling and executing the operating system's unbuffered I/O routines. The
-gain will vary very much depending on the OS and the kind of I/O which is
-performed (for example, on some contemporary OSes such as Linux, unbuffered
-disk I/O can be as fast as buffered I/O). The bottom line, however, is
-that buffered I/O will offer you predictable performance regardless of the
-platform and the backing device. Therefore, it is most always preferable to
-use buffered I/O rather than unbuffered I/O.
+^^^^^^^^^^
+
+By reading and writing only large chunks of data even when the user asks for a
+single byte, buffered I/O hides any inefficiency in calling and executing the
+operating system's unbuffered I/O routines. The gain depends on the OS and the
+kind of I/O which is performed. For example, on some modern OSes such as Linux,
+unbuffered disk I/O can be as fast as buffered I/O. The bottom line, however,
+is that buffered I/O offers predictable performance regardless of the platform
+and the backing device. Therefore, it is most always preferable to use buffered
+I/O rather than unbuffered I/O for binary datal
Text I/O
-""""""""
+^^^^^^^^
Text I/O over a binary storage (such as a file) is significantly slower than
-binary I/O over the same storage, because it implies conversions from
-unicode to binary data using a character codec. This can become noticeable
-if you handle huge amounts of text data (for example very large log files).
-Also, :meth:`TextIOWrapper.tell` and :meth:`TextIOWrapper.seek` are both
-quite slow due to the reconstruction algorithm used.
+binary I/O over the same storage, because it requires conversions between
+unicode and binary data using a character codec. This can become noticeable
+handling huge amounts of text data like large log files. Also,
+:meth:`TextIOWrapper.tell` and :meth:`TextIOWrapper.seek` are both quite slow
+due to the reconstruction algorithm used.
:class:`StringIO`, however, is a native in-memory unicode container and will
exhibit similar speed to :class:`BytesIO`.
@@ -870,9 +889,8 @@ exhibit similar speed to :class:`BytesIO`.
Multi-threading
^^^^^^^^^^^^^^^
-:class:`FileIO` objects are thread-safe to the extent that the operating
-system calls (such as ``read(2)`` under Unix) they are wrapping are thread-safe
-too.
+:class:`FileIO` objects are thread-safe to the extent that the operating system
+calls (such as ``read(2)`` under Unix) they wrap are thread-safe too.
Binary buffered objects (instances of :class:`BufferedReader`,
:class:`BufferedWriter`, :class:`BufferedRandom` and :class:`BufferedRWPair`)
@@ -887,12 +905,13 @@ Reentrancy
Binary buffered objects (instances of :class:`BufferedReader`,
:class:`BufferedWriter`, :class:`BufferedRandom` and :class:`BufferedRWPair`)
are not reentrant. While reentrant calls will not happen in normal situations,
-they can arise if you are doing I/O in a :mod:`signal` handler. If it is
-attempted to enter a buffered object again while already being accessed
-*from the same thread*, then a :exc:`RuntimeError` is raised.
-
-The above implicitly extends to text files, since the :func:`open()`
-function will wrap a buffered object inside a :class:`TextIOWrapper`. This
-includes standard streams and therefore affects the built-in function
-:func:`print()` as well.
+they can arise from doing I/O in a :mod:`signal` handler. If a thread tries to
+renter a buffered object which it is already accessing, a :exc:`RuntimeError` is
+raised. Note this doesn't prohibit a different thread from entering the
+buffered object.
+
+The above implicitly extends to text files, since the :func:`open()` function
+will wrap a buffered object inside a :class:`TextIOWrapper`. This includes
+standard streams and therefore affects the built-in function :func:`print()` as
+well.
diff --git a/Doc/library/ipc.rst b/Doc/library/ipc.rst
index 10a6d6a..c873065 100644
--- a/Doc/library/ipc.rst
+++ b/Doc/library/ipc.rst
@@ -1,4 +1,3 @@
-
.. _ipc:
*****************************************
@@ -21,6 +20,5 @@ The list of modules described in this chapter is:
socket.rst
ssl.rst
signal.rst
- popen2.rst
asyncore.rst
asynchat.rst
diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst
index a7f0058..308f925 100644
--- a/Doc/library/itertools.rst
+++ b/Doc/library/itertools.rst
@@ -1,4 +1,3 @@
-
:mod:`itertools` --- Functions creating iterators for efficient looping
=======================================================================
@@ -12,7 +11,6 @@
from itertools import *
-.. versionadded:: 2.3
This module implements a number of :term:`iterator` building blocks inspired
by constructs from APL, Haskell, and SML. Each has been recast in a form
@@ -25,12 +23,12 @@ efficiently in pure Python.
For instance, SML provides a tabulation tool: ``tabulate(f)`` which produces a
sequence ``f(0), f(1), ...``. The same effect can be achieved in Python
-by combining :func:`imap` and :func:`count` to form ``imap(f, count())``.
+by combining :func:`map` and :func:`count` to form ``map(f, count())``.
These tools and their built-in counterparts also work well with the high-speed
functions in the :mod:`operator` module. For example, the multiplication
operator can be mapped across two vectors to form an efficient dot-product:
-``sum(imap(operator.mul, vector1, vector2))``.
+``sum(map(operator.mul, vector1, vector2))``.
**Infinite Iterators:**
@@ -48,19 +46,17 @@ Iterator Arguments Results
==================== ============================ ================================================= =============================================================
Iterator Arguments Results Example
==================== ============================ ================================================= =============================================================
+:func:`accumulate` p p0, p0+p1, p0+p1+p2, ... ``accumulate([1,2,3,4,5]) --> 1 3 6 10 15``
:func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') --> A B C D E F``
:func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... ``compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F``
:func:`dropwhile` pred, seq seq[n], seq[n+1], starting when pred fails ``dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1``
+:func:`filterfalse` pred, seq elements of seq where pred(elem) is False ``filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8``
:func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v)
-:func:`ifilter` pred, seq elements of seq where pred(elem) is True ``ifilter(lambda x: x%2, range(10)) --> 1 3 5 7 9``
-:func:`ifilterfalse` pred, seq elements of seq where pred(elem) is False ``ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8``
:func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] ``islice('ABCDEFG', 2, None) --> C D E F G``
-:func:`imap` func, p, q, ... func(p0, q0), func(p1, q1), ... ``imap(pow, (2,3,10), (5,2,3)) --> 32 9 1000``
:func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... ``starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000``
-:func:`tee` it, n it1, it2 , ... itn splits one iterator into n
:func:`takewhile` pred, seq seq[0], seq[1], until pred fails ``takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4``
-:func:`izip` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``izip('ABCD', 'xy') --> Ax By``
-:func:`izip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-``
+:func:`tee` it, n it1, it2 , ... itn splits one iterator into n
+:func:`zip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-``
==================== ============================ ================================================= =============================================================
**Combinatoric generators:**
@@ -88,6 +84,22 @@ The following module functions all construct and return iterators. Some provide
streams of infinite length, so they should only be accessed by functions or
loops that truncate the stream.
+.. function:: accumulate(iterable)
+
+ Make an iterator that returns accumulated sums. Elements may be any addable
+ type including :class:`Decimal` or :class:`Fraction`. Equivalent to::
+
+ def accumulate(iterable):
+ 'Return running totals'
+ # accumulate([1,2,3,4,5]) --> 1 3 6 10 15
+ it = iter(iterable)
+ total = next(it)
+ yield total
+ for element in it:
+ total = total + element
+ yield total
+
+ .. versionadded:: 3.2
.. function:: chain(*iterables)
@@ -106,16 +118,15 @@ loops that truncate the stream.
.. classmethod:: chain.from_iterable(iterable)
Alternate constructor for :func:`chain`. Gets chained inputs from a
- single iterable argument that is evaluated lazily. Roughly equivalent to::
+ single iterable argument that is evaluated lazily. Equivalent to::
+ @classmethod
def from_iterable(iterables):
# chain.from_iterable(['ABC', 'DEF']) --> A B C D E F
for it in iterables:
for element in it:
yield element
- .. versionadded:: 2.6
-
.. function:: combinations(iterable, r)
@@ -138,7 +149,7 @@ loops that truncate the stream.
n = len(pool)
if r > n:
return
- indices = range(r)
+ indices = list(range(r))
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
@@ -165,8 +176,6 @@ loops that truncate the stream.
The number of items returned is ``n! / r! / (n-r)!`` when ``0 <= r <= n``
or zero when ``r > n``.
- .. versionadded:: 2.6
-
.. function:: combinations_with_replacement(iterable, r)
Return *r* length subsequences of elements from the input *iterable*
@@ -212,7 +221,8 @@ loops that truncate the stream.
The number of items returned is ``(n+r-1)! / r! / (n-1)!`` when ``n > 0``.
- .. versionadded:: 2.7
+ .. versionadded:: 3.1
+
.. function:: compress(data, selectors)
@@ -223,16 +233,16 @@ loops that truncate the stream.
def compress(data, selectors):
# compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
- return (d for d, s in izip(data, selectors) if s)
+ return (d for d, s in zip(data, selectors) if s)
- .. versionadded:: 2.7
+ .. versionadded:: 3.1
.. function:: count(start=0, step=1)
Make an iterator that returns evenly spaced values starting with *n*. Often
- used as an argument to :func:`imap` to generate consecutive data points.
- Also, used with :func:`izip` to add sequence numbers. Equivalent to::
+ used as an argument to :func:`map` to generate consecutive data points.
+ Also, used with :func:`zip` to add sequence numbers. Equivalent to::
def count(start=0, step=1):
# count(10) --> 10 11 12 13 14 ...
@@ -246,8 +256,8 @@ loops that truncate the stream.
achieved by substituting multiplicative code such as: ``(start + step * i
for i in count())``.
- .. versionchanged:: 2.7
- added *step* argument and allowed non-integer arguments.
+ .. versionchanged:: 3.1
+ Added *step* argument and allowed non-integer arguments.
.. function:: cycle(iterable)
@@ -286,8 +296,22 @@ loops that truncate the stream.
for x in iterable:
yield x
+.. function:: filterfalse(predicate, iterable)
+
+ Make an iterator that filters elements from iterable returning only those for
+ which the predicate is ``False``. If *predicate* is ``None``, return the items
+ that are false. Equivalent to::
+
+ def filterfalse(predicate, iterable):
+ # filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
+ if predicate is None:
+ predicate = bool
+ for x in iterable:
+ if not predicate(x):
+ yield x
-.. function:: groupby(iterable[, key])
+
+.. function:: groupby(iterable, key=None)
Make an iterator that returns consecutive keys and groups from the *iterable*.
The *key* is a function computing a key value for each element. If not
@@ -315,7 +339,7 @@ loops that truncate the stream.
:func:`groupby` is equivalent to::
- class groupby(object):
+ class groupby:
# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
def __init__(self, iterable, key=None):
@@ -326,7 +350,7 @@ loops that truncate the stream.
self.tgtkey = self.currkey = self.currvalue = object()
def __iter__(self):
return self
- def next(self):
+ def __next__(self):
while self.currkey == self.tgtkey:
self.currvalue = next(self.it) # Exit on StopIteration
self.currkey = self.keyfunc(self.currvalue)
@@ -338,59 +362,6 @@ loops that truncate the stream.
self.currvalue = next(self.it) # Exit on StopIteration
self.currkey = self.keyfunc(self.currvalue)
- .. versionadded:: 2.4
-
-
-.. function:: ifilter(predicate, iterable)
-
- Make an iterator that filters elements from iterable returning only those for
- which the predicate is ``True``. If *predicate* is ``None``, return the items
- that are true. Equivalent to::
-
- def ifilter(predicate, iterable):
- # ifilter(lambda x: x%2, range(10)) --> 1 3 5 7 9
- if predicate is None:
- predicate = bool
- for x in iterable:
- if predicate(x):
- yield x
-
-
-.. function:: ifilterfalse(predicate, iterable)
-
- Make an iterator that filters elements from iterable returning only those for
- which the predicate is ``False``. If *predicate* is ``None``, return the items
- that are false. Equivalent to::
-
- def ifilterfalse(predicate, iterable):
- # ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
- if predicate is None:
- predicate = bool
- for x in iterable:
- if not predicate(x):
- yield x
-
-
-.. function:: imap(function, *iterables)
-
- Make an iterator that computes the function using arguments from each of the
- iterables. If *function* is set to ``None``, then :func:`imap` returns the
- arguments as a tuple. Like :func:`map` but stops when the shortest iterable is
- exhausted instead of filling in ``None`` for shorter iterables. The reason for
- the difference is that infinite iterator arguments are typically an error for
- :func:`map` (because the output is fully evaluated) but represent a common and
- useful way of supplying arguments to :func:`imap`. Equivalent to::
-
- def imap(function, *iterables):
- # imap(pow, (2,3,10), (5,2,3)) --> 32 9 1000
- iterables = map(iter, iterables)
- while True:
- args = [next(it) for it in iterables]
- if function is None:
- yield tuple(args)
- else:
- yield function(*args)
-
.. function:: islice(iterable, stop)
islice(iterable, start, stop[, step])
@@ -411,7 +382,7 @@ loops that truncate the stream.
# islice('ABCDEFG', 2, None) --> C D E F G
# islice('ABCDEFG', 0, None, 2) --> A C E G
s = slice(*args)
- it = iter(xrange(s.start or 0, s.stop or sys.maxint, s.step or 1))
+ it = iter(range(s.start or 0, s.stop or sys.maxsize, s.step or 1))
nexti = next(it)
for i, element in enumerate(iterable):
if i == nexti:
@@ -421,69 +392,8 @@ loops that truncate the stream.
If *start* is ``None``, then iteration starts at zero. If *step* is ``None``,
then the step defaults to one.
- .. versionchanged:: 2.5
- accept ``None`` values for default *start* and *step*.
-
-
-.. function:: izip(*iterables)
- Make an iterator that aggregates elements from each of the iterables. Like
- :func:`zip` except that it returns an iterator instead of a list. Used for
- lock-step iteration over several iterables at a time. Equivalent to::
-
- def izip(*iterables):
- # izip('ABCD', 'xy') --> Ax By
- iterators = map(iter, iterables)
- while iterators:
- yield tuple(map(next, iterators))
-
- .. versionchanged:: 2.4
- When no iterables are specified, returns a zero length iterator instead of
- raising a :exc:`TypeError` exception.
-
- The left-to-right evaluation order of the iterables is guaranteed. This
- makes possible an idiom for clustering a data series into n-length groups
- using ``izip(*[iter(s)]*n)``.
-
- :func:`izip` should only be used with unequal length inputs when you don't
- care about trailing, unmatched values from the longer iterables. If those
- values are important, use :func:`izip_longest` instead.
-
-
-.. function:: izip_longest(*iterables[, fillvalue])
-
- Make an iterator that aggregates elements from each of the iterables. If the
- iterables are of uneven length, missing values are filled-in with *fillvalue*.
- Iteration continues until the longest iterable is exhausted. Equivalent to::
-
- class ZipExhausted(Exception):
- pass
-
- def izip_longest(*args, **kwds):
- # izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
- fillvalue = kwds.get('fillvalue')
- counter = [len(args) - 1]
- def sentinel():
- if not counter[0]:
- raise ZipExhausted
- counter[0] -= 1
- yield fillvalue
- fillers = repeat(fillvalue)
- iterators = [chain(it, sentinel(), fillers) for it in args]
- try:
- while iterators:
- yield tuple(map(next, iterators))
- except ZipExhausted:
- pass
-
- If one of the iterables is potentially infinite, then the
- :func:`izip_longest` function should be wrapped with something that limits
- the number of calls (for example :func:`islice` or :func:`takewhile`). If
- not specified, *fillvalue* defaults to ``None``.
-
- .. versionadded:: 2.6
-
-.. function:: permutations(iterable[, r])
+.. function:: permutations(iterable, r=None)
Return successive *r* length permutations of elements in the *iterable*.
@@ -509,8 +419,8 @@ loops that truncate the stream.
r = n if r is None else r
if r > n:
return
- indices = range(n)
- cycles = range(n, n-r, -1)
+ indices = list(range(n))
+ cycles = list(range(n, n-r, -1))
yield tuple(pool[i] for i in indices[:r])
while n:
for i in reversed(range(r)):
@@ -541,9 +451,7 @@ loops that truncate the stream.
The number of items returned is ``n! / (n-r)!`` when ``0 <= r <= n``
or zero when ``r > n``.
- .. versionadded:: 2.6
-
-.. function:: product(*iterables[, repeat])
+.. function:: product(*iterables, repeat=1)
Cartesian product of input iterables.
@@ -562,24 +470,23 @@ loops that truncate the stream.
This function is equivalent to the following code, except that the
actual implementation does not build up intermediate results in memory::
- def product(*args, **kwds):
+ def product(*args, repeat=1):
# product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
# product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
- pools = map(tuple, args) * kwds.get('repeat', 1)
+ pools = [tuple(pool) for pool in args] * repeat
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool]
for prod in result:
yield tuple(prod)
- .. versionadded:: 2.6
.. function:: repeat(object[, times])
Make an iterator that returns *object* over and over again. Runs indefinitely
- unless the *times* argument is specified. Used as argument to :func:`imap` for
- invariant function parameters. Also used with :func:`izip` to create constant
- fields in a tuple record. Equivalent to::
+ unless the *times* argument is specified. Used as argument to :func:`map` for
+ invariant parameters to the called function. Also used with :func:`zip` to
+ create an invariant part of a tuple record. Equivalent to::
def repeat(object, times=None):
# repeat(10, 3) --> 10 10 10
@@ -587,21 +494,21 @@ loops that truncate the stream.
while True:
yield object
else:
- for i in xrange(times):
+ for i in range(times):
yield object
- A common use for *repeat* is to supply a stream of constant values to *imap*
+ A common use for *repeat* is to supply a stream of constant values to *map*
or *zip*::
- >>> list(imap(pow, xrange(10), repeat(2)))
+ >>> list(map(pow, range(10), repeat(2)))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
.. function:: starmap(function, iterable)
Make an iterator that computes the function using arguments obtained from
- the iterable. Used instead of :func:`imap` when argument parameters are already
+ the iterable. Used instead of :func:`map` when argument parameters are already
grouped in tuples from a single iterable (the data has been "pre-zipped"). The
- difference between :func:`imap` and :func:`starmap` parallels the distinction
+ difference between :func:`map` and :func:`starmap` parallels the distinction
between ``function(a,b)`` and ``function(*c)``. Equivalent to::
def starmap(function, iterable):
@@ -609,9 +516,6 @@ loops that truncate the stream.
for args in iterable:
yield function(*args)
- .. versionchanged:: 2.6
- Previously, :func:`starmap` required the function arguments to be tuples.
- Now, any iterable is allowed.
.. function:: takewhile(predicate, iterable)
@@ -627,7 +531,7 @@ loops that truncate the stream.
break
-.. function:: tee(iterable[, n=2])
+.. function:: tee(iterable, n=2)
Return *n* independent iterators from a single iterable. Equivalent to::
@@ -652,13 +556,44 @@ loops that truncate the stream.
most or all of the data before another iterator starts, it is faster to use
:func:`list` instead of :func:`tee`.
- .. versionadded:: 2.4
+
+.. function:: zip_longest(*iterables, fillvalue=None)
+
+ Make an iterator that aggregates elements from each of the iterables. If the
+ iterables are of uneven length, missing values are filled-in with *fillvalue*.
+ Iteration continues until the longest iterable is exhausted. Equivalent to::
+
+ class ZipExhausted(Exception):
+ pass
+
+ def zip_longest(*args, **kwds):
+ # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
+ fillvalue = kwds.get('fillvalue')
+ counter = len(args) - 1
+ def sentinel():
+ nonlocal counter
+ if not counter:
+ raise ZipExhausted
+ counter -= 1
+ yield fillvalue
+ fillers = repeat(fillvalue)
+ iterators = [chain(it, sentinel(), fillers) for it in args]
+ try:
+ while iterators:
+ yield tuple(map(next, iterators))
+ except ZipExhausted:
+ pass
+
+ If one of the iterables is potentially infinite, then the :func:`zip_longest`
+ function should be wrapped with something that limits the number of calls
+ (for example :func:`islice` or :func:`takewhile`). If not specified,
+ *fillvalue* defaults to ``None``.
.. _itertools-recipes:
-Recipes
--------
+Itertools Recipes
+-----------------
This section shows recipes for creating an extended toolset using the existing
itertools as building blocks.
@@ -679,7 +614,7 @@ which incur interpreter overhead.
def tabulate(function, start=0):
"Return function(0), function(1), ..."
- return imap(function, count(start))
+ return map(function, count(start))
def consume(iterator, n):
"Advance the iterator n-steps ahead. If n is none, consume entirely."
@@ -697,7 +632,7 @@ which incur interpreter overhead.
def quantify(iterable, pred=bool):
"Count how many times the predicate is true"
- return sum(imap(pred, iterable))
+ return sum(map(pred, iterable))
def padnone(iterable):
"""Returns the sequence elements and then returns None indefinitely.
@@ -711,7 +646,7 @@ which incur interpreter overhead.
return chain.from_iterable(repeat(tuple(iterable), n))
def dotproduct(vec1, vec2):
- return sum(imap(operator.mul, vec1, vec2))
+ return sum(map(operator.mul, vec1, vec2))
def flatten(listOfLists):
"Flatten one level of nesting"
@@ -730,19 +665,18 @@ which incur interpreter overhead.
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
- return izip(a, b)
+ return zip(a, b)
def grouper(n, iterable, fillvalue=None):
- "Collect data into fixed-length chunks or blocks"
- # grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
+ "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
- return izip_longest(fillvalue=fillvalue, *args)
+ return zip_longest(*args, fillvalue=fillvalue)
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
pending = len(iterables)
- nexts = cycle(iter(it).next for it in iterables)
+ nexts = cycle(iter(it).__next__ for it in iterables)
while pending:
try:
for next in nexts:
@@ -751,6 +685,12 @@ which incur interpreter overhead.
pending -= 1
nexts = cycle(islice(nexts, pending))
+ def partition(pred, iterable):
+ 'Use a predicate to partition entries into false entries and true entries'
+ # partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9
+ t1, t2 = tee(iterable)
+ return filterfalse(pred, t1), filter(pred, t2)
+
def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
s = list(iterable)
@@ -763,7 +703,7 @@ which incur interpreter overhead.
seen = set()
seen_add = seen.add
if key is None:
- for element in ifilterfalse(seen.__contains__, iterable):
+ for element in filterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
else:
@@ -777,7 +717,7 @@ which incur interpreter overhead.
"List unique elements, preserving order. Remember only the element just seen."
# unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
# unique_justseen('ABBCcAD', str.lower) --> A B C A D
- return imap(next, imap(itemgetter(1), groupby(iterable, key)))
+ return map(next, map(itemgetter(1), groupby(iterable, key)))
def iter_except(func, exception, first=None):
""" Call a function repeatedly until an exception is raised.
@@ -787,25 +727,24 @@ which incur interpreter overhead.
of a sentinel to end the loop.
Examples:
- bsddbiter = iter_except(db.next, bsddb.error, db.first)
- heapiter = iter_except(functools.partial(heappop, h), IndexError)
- dictiter = iter_except(d.popitem, KeyError)
- dequeiter = iter_except(d.popleft, IndexError)
- queueiter = iter_except(q.get_nowait, Queue.Empty)
- setiter = iter_except(s.pop, KeyError)
+ iter_except(functools.partial(heappop, h), IndexError) # priority queue iterator
+ iter_except(d.popitem, KeyError) # non-blocking dict iterator
+ iter_except(d.popleft, IndexError) # non-blocking deque iterator
+ iter_except(q.get_nowait, Queue.Empty) # loop over a producer Queue
+ iter_except(s.pop, KeyError) # non-blocking set iterator
"""
try:
if first is not None:
- yield first()
+ yield first() # For database APIs needing an initial cast to db.first()
while 1:
yield func()
except exception:
pass
- def random_product(*args, **kwds):
+ def random_product(*args, repeat=1):
"Random selection from itertools.product(*args, **kwds)"
- pools = map(tuple, args) * kwds.get('repeat', 1)
+ pools = [tuple(pool) for pool in args] * repeat
return tuple(random.choice(pool) for pool in pools)
def random_permutation(iterable, r=None):
@@ -818,19 +757,19 @@ which incur interpreter overhead.
"Random selection from itertools.combinations(iterable, r)"
pool = tuple(iterable)
n = len(pool)
- indices = sorted(random.sample(xrange(n), r))
+ indices = sorted(random.sample(range(n), r))
return tuple(pool[i] for i in indices)
def random_combination_with_replacement(iterable, r):
"Random selection from itertools.combinations_with_replacement(iterable, r)"
pool = tuple(iterable)
n = len(pool)
- indices = sorted(random.randrange(n) for i in xrange(r))
+ indices = sorted(random.randrange(n) for i in range(r))
return tuple(pool[i] for i in indices)
Note, many of the above recipes can be optimized by replacing global lookups
with local variables defined as default values. For example, the
*dotproduct* recipe can be written as::
- def dotproduct(vec1, vec2, sum=sum, imap=imap, mul=operator.mul):
- return sum(imap(mul, vec1, vec2))
+ def dotproduct(vec1, vec2, sum=sum, map=map, mul=operator.mul):
+ return sum(map(mul, vec1, vec2))
diff --git a/Doc/library/jpeg.rst b/Doc/library/jpeg.rst
deleted file mode 100644
index 2a8e4e8..0000000
--- a/Doc/library/jpeg.rst
+++ /dev/null
@@ -1,95 +0,0 @@
-
-:mod:`jpeg` --- Read and write JPEG files
-=========================================
-
-.. module:: jpeg
- :platform: IRIX
- :synopsis: Read and write image files in compressed JPEG format.
- :deprecated:
-
-.. deprecated:: 2.6
- The :mod:`jpeg` module has been removed in Python 3.
-
-
-
-.. index:: single: Independent JPEG Group
-
-The module :mod:`jpeg` provides access to the jpeg compressor and decompressor
-written by the Independent JPEG Group (IJG). JPEG is a standard for compressing
-pictures; it is defined in ISO 10918. For details on JPEG or the Independent
-JPEG Group software refer to the JPEG standard or the documentation provided
-with the software.
-
-.. index::
- single: Python Imaging Library
- single: PIL (the Python Imaging Library)
- single: Lundh, Fredrik
-
-A portable interface to JPEG image files is available with the Python Imaging
-Library (PIL) by Fredrik Lundh. Information on PIL is available at
-http://www.pythonware.com/products/pil/.
-
-The :mod:`jpeg` module defines an exception and some functions.
-
-
-.. exception:: error
-
- Exception raised by :func:`compress` and :func:`decompress` in case of errors.
-
-
-.. function:: compress(data, w, h, b)
-
- .. index:: single: JFIF
-
- Treat data as a pixmap of width *w* and height *h*, with *b* bytes per pixel.
- The data is in SGI GL order, so the first pixel is in the lower-left corner.
- This means that :func:`gl.lrectread` return data can immediately be passed to
- :func:`compress`. Currently only 1 byte and 4 byte pixels are allowed, the
- former being treated as greyscale and the latter as RGB color. :func:`compress`
- returns a string that contains the compressed picture, in JFIF format.
-
-
-.. function:: decompress(data)
-
- .. index:: single: JFIF
-
- Data is a string containing a picture in JFIF format. It returns a tuple
- ``(data, width, height, bytesperpixel)``. Again, the data is suitable to pass
- to :func:`gl.lrectwrite`.
-
-
-.. function:: setoption(name, value)
-
- Set various options. Subsequent :func:`compress` and :func:`decompress` calls
- will use these options. The following options are available:
-
- +-----------------+---------------------------------------------+
- | Option | Effect |
- +=================+=============================================+
- | ``'forcegray'`` | Force output to be grayscale, even if input |
- | | is RGB. |
- +-----------------+---------------------------------------------+
- | ``'quality'`` | Set the quality of the compressed image to |
- | | a value between ``0`` and ``100`` (default |
- | | is ``75``). This only affects compression. |
- +-----------------+---------------------------------------------+
- | ``'optimize'`` | Perform Huffman table optimization. Takes |
- | | longer, but results in smaller compressed |
- | | image. This only affects compression. |
- +-----------------+---------------------------------------------+
- | ``'smooth'`` | Perform inter-block smoothing on |
- | | uncompressed image. Only useful for low- |
- | | quality images. This only affects |
- | | decompression. |
- +-----------------+---------------------------------------------+
-
-
-.. seealso::
-
- JPEG Still Image Data Compression Standard
- The canonical reference for the JPEG image format, by Pennebaker and Mitchell.
-
- `Information Technology - Digital Compression and Coding of Continuous-tone Still Images - Requirements and Guidelines <http://www.w3.org/Graphics/JPEG/itu-t81.pdf>`_
- The ISO standard for JPEG is also published as ITU T.81. This is available
- online in PDF form.
-
diff --git a/Doc/library/json.rst b/Doc/library/json.rst
index 71020fd..bdb6436 100644
--- a/Doc/library/json.rst
+++ b/Doc/library/json.rst
@@ -5,7 +5,6 @@
:synopsis: Encode and decode the JSON format.
.. moduleauthor:: Bob Ippolito <bob@redivi.com>
.. sectionauthor:: Bob Ippolito <bob@redivi.com>
-.. versionadded:: 2.6
`JSON (JavaScript Object Notation) <http://json.org>`_, specified by
:rfc:`4627`, is a lightweight data interchange format based on a subset of
@@ -20,15 +19,15 @@ Encoding basic Python object hierarchies::
>>> import json
>>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
'["foo", {"bar": ["baz", null, 1.0, 2]}]'
- >>> print json.dumps("\"foo\bar")
+ >>> print(json.dumps("\"foo\bar"))
"\"foo\bar"
- >>> print json.dumps(u'\u1234')
+ >>> print(json.dumps('\u1234'))
"\u1234"
- >>> print json.dumps('\\')
+ >>> print(json.dumps('\\'))
"\\"
- >>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
+ >>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True))
{"a": 0, "b": 0, "c": 0}
- >>> from StringIO import StringIO
+ >>> from io import StringIO
>>> io = StringIO()
>>> json.dump(['streaming API'], io)
>>> io.getvalue()
@@ -37,14 +36,14 @@ Encoding basic Python object hierarchies::
Compact encoding::
>>> import json
- >>> json.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':'))
+ >>> json.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',', ':'))
'[1,2,3,{"4":5,"6":7}]'
Pretty printing::
>>> import json
- >>> print json.dumps({'4': 5, '6': 7}, sort_keys=True,
- ... indent=4, separators=(',', ': '))
+ >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True,
+ ... indent=4, separators=(',', ': ')))
{
"4": 5,
"6": 7
@@ -54,13 +53,13 @@ Decoding JSON::
>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
- [u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
+ ['foo', {'bar': ['baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
- u'"foo\x08ar'
- >>> from StringIO import StringIO
+ '"foo\x08ar'
+ >>> from io import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
- [u'streaming API']
+ ['streaming API']
Specializing JSON object decoding::
@@ -86,15 +85,15 @@ Extending :class:`JSONEncoder`::
... return [obj.real, obj.imag]
... return json.JSONEncoder.default(self, obj)
...
- >>> dumps(2 + 1j, cls=ComplexEncoder)
+ >>> json.dumps(2 + 1j, cls=ComplexEncoder)
'[2.0, 1.0]'
>>> ComplexEncoder().encode(2 + 1j)
'[2.0, 1.0]'
>>> list(ComplexEncoder().iterencode(2 + 1j))
- ['[', '2.0', ', ', '1.0', ']']
+ ['[2.0', ', 1.0', ']']
-.. highlight:: none
+.. highlight:: bash
Using json.tool from the shell to validate and pretty-print::
@@ -105,7 +104,7 @@ Using json.tool from the shell to validate and pretty-print::
$ echo '{1.2:3.4}' | python -mjson.tool
Expecting property name enclosed in double quotes: line 1 column 1 (char 1)
-.. highlight:: python
+.. highlight:: python3
.. note::
@@ -120,25 +119,23 @@ Basic Usage
.. function:: dump(obj, fp, skipkeys=False, ensure_ascii=True, \
check_circular=True, allow_nan=True, cls=None, \
- indent=None, separators=None, encoding="utf-8", \
- default=None, sort_keys=False, **kw)
+ indent=None, separators=None, default=None, \
+ sort_keys=False, **kw)
Serialize *obj* as a JSON formatted stream to *fp* (a ``.write()``-supporting
:term:`file-like object`).
If *skipkeys* is ``True`` (default: ``False``), then dict keys that are not
- of a basic type (:class:`str`, :class:`unicode`, :class:`int`, :class:`long`,
- :class:`float`, :class:`bool`, ``None``) will be skipped instead of raising a
- :exc:`TypeError`.
-
- If *ensure_ascii* is ``True`` (the default), all non-ASCII characters in the
- output are escaped with ``\uXXXX`` sequences, and the result is a
- :class:`str` instance consisting of ASCII characters only. If
- *ensure_ascii* is ``False``, some chunks written to *fp* may be
- :class:`unicode` instances. This usually happens because the input contains
- unicode strings or the *encoding* parameter is used. Unless ``fp.write()``
- explicitly understands :class:`unicode` (as in :func:`codecs.getwriter`)
- this is likely to cause an error.
+ of a basic type (:class:`str`, :class:`int`, :class:`float`, :class:`bool`,
+ ``None``) will be skipped instead of raising a :exc:`TypeError`.
+
+ The :mod:`json` module always produces :class:`str` objects, not
+ :class:`bytes` objects. Therefore, ``fp.write()`` must support :class:`str`
+ input.
+
+ If *ensure_ascii* is ``True`` (the default), the output is guaranteed to
+ have all incoming non-ASCII characters escaped. If *ensure_ascii* is
+ ``False``, these characters will be output as-is.
If *check_circular* is ``False`` (default: ``True``), then the circular
reference check for container types will be skipped and a circular reference
@@ -149,10 +146,15 @@ Basic Usage
``inf``, ``-inf``) in strict compliance of the JSON specification, instead of
using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
- If *indent* is a non-negative integer, then JSON array elements and object
- members will be pretty-printed with that indent level. An indent level of 0,
- or negative, will only insert newlines. ``None`` (the default) selects the
- most compact representation.
+ If *indent* is a non-negative integer or string, then JSON array elements and
+ object members will be pretty-printed with that indent level. An indent level
+ of 0, negative, or ``""`` will only insert newlines. ``None`` (the default)
+ selects the most compact representation. Using a positive integer indent
+ indents that many spaces per level. If *indent* is a string (such as ``"\t"``),
+ that string is used to indent each level.
+
+ .. versionchanged:: 3.2
+ Allow strings for *indent* in addition to integers.
.. note::
@@ -164,8 +166,6 @@ Basic Usage
will be used instead of the default ``(', ', ': ')`` separators. ``(',',
':')`` is the most compact JSON representation.
- *encoding* is the character encoding for str instances, default is UTF-8.
-
*default(obj)* is a function that should return a serializable version of
*obj* or raise :exc:`TypeError`. The default simply raises :exc:`TypeError`.
@@ -176,22 +176,20 @@ Basic Usage
:meth:`default` method to serialize additional types), specify it with the
*cls* kwarg; otherwise :class:`JSONEncoder` is used.
- .. note::
-
- Unlike :mod:`pickle` and :mod:`marshal`, JSON is not a framed protocol so
- trying to serialize more objects with repeated calls to :func:`dump` and
- the same *fp* will result in an invalid JSON file.
.. function:: dumps(obj, skipkeys=False, ensure_ascii=True, \
check_circular=True, allow_nan=True, cls=None, \
- indent=None, separators=None, encoding="utf-8", \
- default=None, sort_keys=False, **kw)
+ indent=None, separators=None, default=None, \
+ sort_keys=False, **kw)
+
+ Serialize *obj* to a JSON formatted :class:`str`. The arguments have the
+ same meaning as in :func:`dump`.
- Serialize *obj* to a JSON formatted :class:`str`. If *ensure_ascii* is
- ``False``, the result may contain non-ASCII characters and the return value
- may be a :class:`unicode` instance.
+ .. note::
- The arguments have the same meaning as in :func:`dump`.
+ Unlike :mod:`pickle` and :mod:`marshal`, JSON is not a framed protocol,
+ so trying to serialize multiple objects with repeated calls to
+ :func:`dump` using the same *fp* will result in an invalid JSON file.
.. note::
@@ -202,17 +200,11 @@ Basic Usage
the original one. That is, ``loads(dumps(x)) != x`` if x has non-string
keys.
-.. function:: load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])
+.. function:: load(fp, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
Deserialize *fp* (a ``.read()``-supporting :term:`file-like object`
containing a JSON document) to a Python object.
- If the contents of *fp* are encoded with an ASCII based encoding other than
- UTF-8 (e.g. latin-1), then an appropriate *encoding* name must be specified.
- Encodings that are not ASCII based (such as UCS-2) are not allowed, and
- should be wrapped with ``codecs.getreader(encoding)(fp)``, or simply decoded
- to a :class:`unicode` object and passed to :func:`loads`.
-
*object_hook* is an optional function that will be called with the result of
any object literal decoded (a :class:`dict`). The return value of
*object_hook* will be used instead of the :class:`dict`. This feature can be used
@@ -227,7 +219,7 @@ Basic Usage
:func:`collections.OrderedDict` will remember the order of insertion). If
*object_hook* is also defined, the *object_pairs_hook* takes priority.
- .. versionchanged:: 2.7
+ .. versionchanged:: 3.1
Added support for *object_pairs_hook*.
*parse_float*, if specified, will be called with the string of every JSON
@@ -245,7 +237,7 @@ Basic Usage
This can be used to raise an exception if invalid JSON numbers
are encountered.
- .. versionchanged:: 2.7
+ .. versionchanged:: 3.1
*parse_constant* doesn't get called on 'null', 'true', 'false' anymore.
To use a custom :class:`JSONDecoder` subclass, specify it with the ``cls``
@@ -253,23 +245,19 @@ Basic Usage
will be passed to the constructor of the class.
-.. function:: loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])
+.. function:: loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
- Deserialize *s* (a :class:`str` or :class:`unicode` instance containing a JSON
- document) to a Python object.
+ Deserialize *s* (a :class:`str` instance containing a JSON document) to a
+ Python object.
- If *s* is a :class:`str` instance and is encoded with an ASCII based encoding
- other than UTF-8 (e.g. latin-1), then an appropriate *encoding* name must be
- specified. Encodings that are not ASCII based (such as UCS-2) are not
- allowed and should be decoded to :class:`unicode` first.
-
- The other arguments have the same meaning as in :func:`load`.
+ The other arguments have the same meaning as in :func:`load`, except
+ *encoding* which is ignored and deprecated.
Encoders and Decoders
---------------------
-.. class:: JSONDecoder([encoding[, object_hook[, parse_float[, parse_int[, parse_constant[, strict[, object_pairs_hook]]]]]]])
+.. class:: JSONDecoder(object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None)
Simple JSON decoder.
@@ -282,9 +270,9 @@ Encoders and Decoders
+---------------+-------------------+
| array | list |
+---------------+-------------------+
- | string | unicode |
+ | string | str |
+---------------+-------------------+
- | number (int) | int, long |
+ | number (int) | int |
+---------------+-------------------+
| number (real) | float |
+---------------+-------------------+
@@ -298,13 +286,6 @@ Encoders and Decoders
It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as their
corresponding ``float`` values, which is outside the JSON spec.
- *encoding* determines the encoding used to interpret any :class:`str` objects
- decoded by this instance (UTF-8 by default). It has no effect when decoding
- :class:`unicode` objects.
-
- Note that currently only encodings that are a superset of ASCII work, strings
- of other encodings should be passed in as :class:`unicode`.
-
*object_hook*, if specified, will be called with the result of every JSON
object decoded and its return value will be used in place of the given
:class:`dict`. This can be used to provide custom deserializations (e.g. to
@@ -318,7 +299,7 @@ Encoders and Decoders
:func:`collections.OrderedDict` will remember the order of insertion). If
*object_hook* is also defined, the *object_pairs_hook* takes priority.
- .. versionchanged:: 2.7
+ .. versionchanged:: 3.1
Added support for *object_pairs_hook*.
*parse_float*, if specified, will be called with the string of every JSON
@@ -344,20 +325,20 @@ Encoders and Decoders
.. method:: decode(s)
- Return the Python representation of *s* (a :class:`str` or
- :class:`unicode` instance containing a JSON document)
+ Return the Python representation of *s* (a :class:`str` instance
+ containing a JSON document)
.. method:: raw_decode(s)
- Decode a JSON document from *s* (a :class:`str` or :class:`unicode`
- beginning with a JSON document) and return a 2-tuple of the Python
- representation and the index in *s* where the document ended.
+ Decode a JSON document from *s* (a :class:`str` beginning with a
+ JSON document) and return a 2-tuple of the Python representation
+ and the index in *s* where the document ended.
This can be used to decode a JSON document from a string that may have
extraneous data at the end.
-.. class:: JSONEncoder([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, sort_keys[, indent[, separators[, encoding[, default]]]]]]]]])
+.. class:: JSONEncoder(skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)
Extensible JSON encoder for Python data structures.
@@ -370,9 +351,9 @@ Encoders and Decoders
+-------------------+---------------+
| list, tuple | array |
+-------------------+---------------+
- | str, unicode | string |
+ | str | string |
+-------------------+---------------+
- | int, long, float | number |
+ | int, float | number |
+-------------------+---------------+
| True | true |
+-------------------+---------------+
@@ -387,15 +368,12 @@ Encoders and Decoders
(to raise :exc:`TypeError`).
If *skipkeys* is ``False`` (the default), then it is a :exc:`TypeError` to
- attempt encoding of keys that are not str, int, long, float or None. If
+ attempt encoding of keys that are not str, int, float or None. If
*skipkeys* is ``True``, such items are simply skipped.
- If *ensure_ascii* is ``True`` (the default), all non-ASCII characters in the
- output are escaped with ``\uXXXX`` sequences, and the results are
- :class:`str` instances consisting of ASCII characters only. If
- *ensure_ascii* is ``False``, a result may be a :class:`unicode`
- instance. This usually happens if the input contains unicode strings or the
- *encoding* parameter is used.
+ If *ensure_ascii* is ``True`` (the default), the output is guaranteed to
+ have all incoming non-ASCII characters escaped. If *ensure_ascii* is
+ ``False``, these characters will be output as-is.
If *check_circular* is ``True`` (the default), then lists, dicts, and custom
encoded objects will be checked for circular references during encoding to
@@ -412,10 +390,15 @@ Encoders and Decoders
will be sorted by key; this is useful for regression tests to ensure that
JSON serializations can be compared on a day-to-day basis.
- If *indent* is a non-negative integer (it is ``None`` by default), then JSON
- array elements and object members will be pretty-printed with that indent
- level. An indent level of 0 will only insert newlines. ``None`` is the most
- compact representation.
+ If *indent* is a non-negative integer or string, then JSON array elements and
+ object members will be pretty-printed with that indent level. An indent level
+ of 0, negative, or ``""`` will only insert newlines. ``None`` (the default)
+ selects the most compact representation. Using a positive integer indent
+ indents that many spaces per level. If *indent* is a string (such as ``"\t"``),
+ that string is used to indent each level.
+
+ .. versionchanged:: 3.2
+ Allow strings for *indent* in addition to integers.
.. note::
@@ -431,10 +414,6 @@ Encoders and Decoders
otherwise be serialized. It should return a JSON encodable version of the
object or raise a :exc:`TypeError`.
- If *encoding* is not ``None``, then all input strings will be transformed
- into unicode using that encoding prior to JSON-encoding. The default is
- UTF-8.
-
.. method:: default(o)
@@ -452,7 +431,7 @@ Encoders and Decoders
pass
else:
return list(iterable)
- return JSONEncoder.default(self, o)
+ return json.JSONEncoder.default(self, o)
.. method:: encode(o)
@@ -460,7 +439,7 @@ Encoders and Decoders
Return a JSON string representation of a Python data structure, *o*. For
example::
- >>> JSONEncoder().encode({"foo": ["bar", "baz"]})
+ >>> json.JSONEncoder().encode({"foo": ["bar", "baz"]})
'{"foo": ["bar", "baz"]}'
@@ -469,7 +448,7 @@ Encoders and Decoders
Encode the given object, *o*, and yield each string representation as
available. For example::
- for chunk in JSONEncoder().iterencode(bigobject):
+ for chunk in json.JSONEncoder().iterencode(bigobject):
mysocket.write(chunk)
@@ -497,22 +476,17 @@ Character Encodings
^^^^^^^^^^^^^^^^^^^
The RFC recommends that JSON be represented using either UTF-8, UTF-16, or
-UTF-32, with UTF-8 being the default. Accordingly, this module uses UTF-8 as
-the default for its *encoding* parameter.
-
-This module's deserializer only directly works with ASCII-compatible encodings;
-UTF-16, UTF-32, and other ASCII-incompatible encodings require the use of
-workarounds described in the documentation for the deserializer's *encoding*
-parameter.
-
-The RFC also non-normatively describes a limited encoding detection technique
-for JSON texts; this module's deserializer does not implement this or any other
-kind of encoding detection.
+UTF-32, with UTF-8 being the default.
As permitted, though not required, by the RFC, this module's serializer sets
*ensure_ascii=True* by default, thus escaping the output so that the resulting
strings only contain ASCII characters.
+Other than the *ensure_ascii* parameter, this module is defined strictly in
+terms of conversion between Python objects and
+:class:`Unicode strings <str>`, and thus does not otherwise address the issue
+of character encodings.
+
Top-level Non-Object, Non-Array Values
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -524,7 +498,7 @@ JSON null, boolean, number, or string value::
>>> just_a_json_string = '"spam and eggs"' # Not by itself a valid JSON text
>>> json.loads(just_a_json_string)
- u'spam and eggs'
+ 'spam and eggs'
This module itself does not include a way to request that such input texts be
regarded as illegal. Likewise, this module's serializer also accepts single
@@ -532,7 +506,7 @@ Python :data:`None`, :class:`bool`, numeric, and :class:`str`
values as input and will generate output texts consisting solely of a top-level
JSON null, boolean, number, or string value without raising an exception::
- >>> neither_a_list_nor_a_dict = u"spam and eggs"
+ >>> neither_a_list_nor_a_dict = "spam and eggs"
>>> json.dumps(neither_a_list_nor_a_dict) # The result is not a valid JSON text
'"spam and eggs"'
@@ -573,6 +547,6 @@ the last name-value pair for a given name::
>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json)
- {u'x': 3}
+ {'x': 3}
The *object_pairs_hook* parameter can be used to alter this behavior.
diff --git a/Doc/library/language.rst b/Doc/library/language.rst
index eee5ef7..1eac32e 100644
--- a/Doc/library/language.rst
+++ b/Doc/library/language.rst
@@ -1,4 +1,3 @@
-
.. _language:
************************
diff --git a/Doc/library/linecache.rst b/Doc/library/linecache.rst
index 39385f9..dacf8aa 100644
--- a/Doc/library/linecache.rst
+++ b/Doc/library/linecache.rst
@@ -1,4 +1,3 @@
-
:mod:`linecache` --- Random access to text lines
================================================
@@ -18,7 +17,7 @@ to retrieve source lines for inclusion in the formatted traceback.
The :mod:`linecache` module defines the following functions:
-.. function:: getline(filename, lineno[, module_globals])
+.. function:: getline(filename, lineno, module_globals=None)
Get line *lineno* from file named *filename*. This function will never raise an
exception --- it will return ``''`` on errors (the terminating newline character
@@ -31,9 +30,6 @@ The :mod:`linecache` module defines the following functions:
``__loader__`` in *module_globals*, in case the module was imported from a
zipfile or other non-filesystem import source.
- .. versionadded:: 2.5
- The *module_globals* parameter was added.
-
.. function:: clearcache()
@@ -41,12 +37,13 @@ The :mod:`linecache` module defines the following functions:
previously read using :func:`getline`.
-.. function:: checkcache([filename])
+.. function:: checkcache(filename=None)
Check the cache for validity. Use this function if files in the cache may have
changed on disk, and you require the updated version. If *filename* is omitted,
it will check all the entries in the cache.
+
Example::
>>> import linecache
diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst
index d446d72..45aba0a 100644
--- a/Doc/library/locale.rst
+++ b/Doc/library/locale.rst
@@ -1,4 +1,3 @@
-
:mod:`locale` --- Internationalization services
===============================================
@@ -27,7 +26,7 @@ The :mod:`locale` module defines the following exception and functions:
recognized.
-.. function:: setlocale(category[, locale])
+.. function:: setlocale(category, locale=None)
If *locale* is given and not ``None``, :func:`setlocale` modifies the locale
setting for the *category*. The available categories are listed in the data
@@ -50,9 +49,6 @@ The :mod:`locale` module defines the following exception and functions:
specified in the :envvar:`LANG` environment variable). If the locale is not
changed thereafter, using multithreading should not cause problems.
- .. versionchanged:: 2.0
- Added support for iterable values of the *locale* parameter.
-
.. function:: localeconv()
@@ -282,19 +278,17 @@ The :mod:`locale` module defines the following exception and functions:
To maintain compatibility with other platforms, not only the :envvar:`LANG`
variable is tested, but a list of variables given as envvars parameter. The
- first found to be defined will be used. *envvars* defaults to the search path
- used in GNU gettext; it must always contain the variable name ``LANG``. The GNU
- gettext search path contains ``'LANGUAGE'``, ``'LC_ALL'``, ``'LC_CTYPE'``, and
- ``'LANG'``, in that order.
+ first found to be defined will be used. *envvars* defaults to the search
+ path used in GNU gettext; it must always contain the variable name
+ ``'LANG'``. The GNU gettext search path contains ``'LC_ALL'``,
+ ``'LC_CTYPE'``, ``'LANG'`` and ``'LANGUAGE'``, in that order.
Except for the code ``'C'``, the language code corresponds to :rfc:`1766`.
*language code* and *encoding* may be ``None`` if their values cannot be
determined.
- .. versionadded:: 2.0
-
-.. function:: getlocale([category])
+.. function:: getlocale(category=LC_CTYPE)
Returns the current setting for the given locale category as sequence containing
*language code*, *encoding*. *category* may be one of the :const:`LC_\*` values
@@ -304,10 +298,8 @@ The :mod:`locale` module defines the following exception and functions:
*language code* and *encoding* may be ``None`` if their values cannot be
determined.
- .. versionadded:: 2.0
-
-.. function:: getpreferredencoding([do_setlocale])
+.. function:: getpreferredencoding(do_setlocale=True)
Return the encoding used for text data, according to user preferences. User
preferences are expressed differently on different systems, and might not be
@@ -318,8 +310,6 @@ The :mod:`locale` module defines the following exception and functions:
preferences, so this function is not thread-safe. If invoking setlocale is not
necessary or desired, *do_setlocale* should be set to ``False``.
- .. versionadded:: 2.3
-
.. function:: normalize(localename)
@@ -330,18 +320,14 @@ The :mod:`locale` module defines the following exception and functions:
If the given encoding is not known, the function defaults to the default
encoding for the locale code just like :func:`setlocale`.
- .. versionadded:: 2.0
-
-.. function:: resetlocale([category])
+.. function:: resetlocale(category=LC_ALL)
Sets the locale for *category* to the default setting.
The default setting is determined by calling :func:`getdefaultlocale`.
*category* defaults to :const:`LC_ALL`.
- .. versionadded:: 2.0
-
.. function:: strcoll(string1, string2)
@@ -353,15 +339,14 @@ The :mod:`locale` module defines the following exception and functions:
.. function:: strxfrm(string)
- .. index:: builtin: cmp
+ Transforms a string to one that can be used in locale-aware
+ comparisons. For example, ``strxfrm(s1) < strxfrm(s2)`` is
+ equivalent to ``strcoll(s1, s2) < 0``. This function can be used
+ when the same string is compared repeatedly, e.g. when collating a
+ sequence of strings.
- Transforms a string to one that can be used for the built-in function
- :func:`cmp`, and still returns locale-aware results. This function can be used
- when the same string is compared repeatedly, e.g. when collating a sequence of
- strings.
-
-.. function:: format(format, val[, grouping[, monetary]])
+.. function:: format(format, val, grouping=False, monetary=False)
Formats a number *val* according to the current :const:`LC_NUMERIC` setting.
The format follows the conventions of the ``%`` operator. For floating point
@@ -374,19 +359,14 @@ The :mod:`locale` module defines the following exception and functions:
Please note that this function will only work for exactly one %char specifier.
For whole format strings, use :func:`format_string`.
- .. versionchanged:: 2.5
- Added the *monetary* parameter.
-
-.. function:: format_string(format, val[, grouping])
+.. function:: format_string(format, val, grouping=False)
Processes formatting specifiers as in ``format % val``, but takes the current
locale settings into account.
- .. versionadded:: 2.5
-
-.. function:: currency(val[, symbol[, grouping[, international]]])
+.. function:: currency(val, symbol=True, grouping=False, international=False)
Formats a number *val* according to the current :const:`LC_MONETARY` settings.
@@ -398,8 +378,6 @@ The :mod:`locale` module defines the following exception and functions:
Note that this function will not work with the 'C' locale, so you have to set a
locale via :func:`setlocale` first.
- .. versionadded:: 2.5
-
.. function:: str(float)
@@ -506,26 +484,23 @@ is almost as bad: it is expensive and affects other threads that happen to run
before the settings have been restored.
If, when coding a module for general use, you need a locale independent version
-of an operation that is affected by the locale (such as :func:`string.lower`, or
+of an operation that is affected by the locale (such as
certain formats used with :func:`time.strftime`), you will have to find a way to
do it without using the standard library routine. Even better is convincing
yourself that using locale settings is okay. Only as a last resort should you
document that your module is not compatible with non-\ ``C`` locale settings.
-.. index:: module: string
-
-The case conversion functions in the :mod:`string` module are affected by the
-locale settings. When a call to the :func:`setlocale` function changes the
-:const:`LC_CTYPE` settings, the variables ``string.lowercase``,
-``string.uppercase`` and ``string.letters`` are recalculated. Note that code
-that uses these variable through ':keyword:`from` ... :keyword:`import` ...',
-e.g. ``from string import letters``, is not affected by subsequent
-:func:`setlocale` calls.
-
The only way to perform numeric operations according to the locale is to use the
special functions defined by this module: :func:`atof`, :func:`atoi`,
:func:`.format`, :func:`.str`.
+There is no way to perform case conversions and character classifications
+according to the locale. For (Unicode) text strings these are done according
+to the character value only, while for byte strings, the conversions and
+classifications are done according to the ASCII value of the byte, and bytes
+whose high bit is set (i.e., non-ASCII bytes) are never converted or considered
+part of a character class such as letter or whitespace.
+
.. _embedding-locale:
diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst
index 8032612..1391ed2 100644
--- a/Doc/library/logging.config.rst
+++ b/Doc/library/logging.config.rst
@@ -72,7 +72,7 @@ in :mod:`logging` itself) and defining handlers which are declared either in
this new subclass, and then :func:`dictConfig` could be called exactly as
in the default, uncustomized state.
- .. versionadded:: 2.7
+ .. versionadded:: 3.2
.. function:: fileConfig(fname, defaults=None, disable_existing_loggers=True)
@@ -94,9 +94,6 @@ in :mod:`logging` itself) and defining handlers which are declared either in
their ancestors are explicitly named in the
logging configuration.
- .. versionchanged:: 2.6
- The ``disable_existing_loggers`` keyword argument was added. Previously,
- existing loggers were *always* disabled.
.. function:: listen(port=DEFAULT_LOGGING_CONFIG_PORT)
@@ -631,10 +628,6 @@ The ``class`` entry indicates the handler's class (as determined by :func:`eval`
in the ``logging`` package's namespace). The ``level`` is interpreted as for
loggers, and ``NOTSET`` is taken to mean 'log everything'.
-.. versionchanged:: 2.6
- Added support for resolving the handler’s class as a dotted module and
- class name.
-
The ``formatter`` entry indicates the key name of the formatter for this
handler. If blank, a default formatter (``logging._defaultFormatter``) is used.
If a name is specified, it must appear in the ``[formatters]`` section and have
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index 3d05400..ef65cfa 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -45,9 +45,9 @@ and :meth:`flush` methods).
.. method:: emit(record)
If a formatter is specified, it is used to format the record. The record
- is then written to the stream with a newline terminator. If exception
- information is present, it is formatted using
- :func:`traceback.print_exception` and appended to the stream.
+ is then written to the stream with a terminator. If exception information
+ is present, it is formatted using :func:`traceback.print_exception` and
+ appended to the stream.
.. method:: flush()
@@ -56,6 +56,13 @@ and :meth:`flush` methods).
:meth:`close` method is inherited from :class:`Handler` and so does
no output, so an explicit :meth:`flush` call may be needed at times.
+.. versionchanged:: 3.2
+ The ``StreamHandler`` class now has a ``terminator`` attribute, default
+ value ``'\n'``, which is used as the terminator when writing a formatted
+ record to a stream. If you don't want this newline termination, you can
+ set the handler instance's ``terminator`` attribute to the empty string.
+ In earlier versions, the terminator was hardcoded as ``'\n'``.
+
.. _file-handler:
FileHandler
@@ -74,8 +81,6 @@ sends logging output to a disk file. It inherits the output functionality from
with that encoding. If *delay* is true, then file opening is deferred until the
first call to :meth:`emit`. By default, the file grows indefinitely.
- .. versionchanged:: 2.6
- *delay* was added.
.. method:: close()
@@ -92,7 +97,7 @@ sends logging output to a disk file. It inherits the output functionality from
NullHandler
^^^^^^^^^^^
-.. versionadded:: 2.7
+.. versionadded:: 3.1
The :class:`NullHandler` class, located in the core :mod:`logging` package,
does not do any formatting or output. It is essentially a 'no-op' handler
@@ -126,8 +131,6 @@ WatchedFileHandler
.. currentmodule:: logging.handlers
-.. versionadded:: 2.6
-
The :class:`WatchedFileHandler` class, located in the :mod:`logging.handlers`
module, is a :class:`FileHandler` which watches the file it is logging to. If
the file changes, it is closed and reopened using the file name.
@@ -191,9 +194,6 @@ module, supports rotation of disk log files.
:file:`app.log.1`, :file:`app.log.2`, etc. exist, then they are renamed to
:file:`app.log.2`, :file:`app.log.3` etc. respectively.
- .. versionchanged:: 2.6
- *delay* was added.
-
.. method:: doRollover()
@@ -261,9 +261,6 @@ timed intervals.
If *delay* is true, then file opening is deferred until the first call to
:meth:`emit`.
- .. versionchanged:: 2.6
- *delay* and *utc* were added.
-
.. method:: doRollover()
@@ -425,7 +422,7 @@ supports sending logging messages to a remote or local Unix syslog.
application needs to run on several platforms). On Windows, you pretty
much have to use the UDP option.
- .. versionchanged:: 2.7
+ .. versionchanged:: 3.2
*socktype* was added.
@@ -439,6 +436,21 @@ supports sending logging messages to a remote or local Unix syslog.
The record is formatted, and then sent to the syslog server. If exception
information is present, it is *not* sent to the server.
+ .. versionchanged:: 3.2.1
+ (See: :issue:`12168`.) In earlier versions, the message sent to the
+ syslog daemons was always terminated with a NUL byte, because early
+ versions of these daemons expected a NUL terminated message - even
+ though it's not in the relevant specification (RF 5424). More recent
+ versions of these daemons don't expect the NUL byte but strip it off
+ if it's there, and even more recent daemons (which adhere more closely
+ to RFC 5424) pass the NUL byte on as part of the message.
+
+ To enable easier handling of syslog messages in the face of all these
+ differing daemon behaviours, the appending of the NUL byte has been
+ made configurable, through the use of a class-level attribute,
+ ``append_nul``. This defaults to ``True`` (preserving the existing
+ behaviour) but can be set to ``False`` on a ``SysLogHandler`` instance
+ in order for that instance to *not* append the NUL terminator.
.. method:: encodePriority(facility, priority)
@@ -605,12 +617,11 @@ supports sending logging messages to an email address via SMTP.
.. class:: SMTPHandler(mailhost, fromaddr, toaddrs, subject, credentials=None, secure=None)
Returns a new instance of the :class:`SMTPHandler` class. The instance is
- initialized with the from and to addresses and subject line of the email.
- The *toaddrs* should be a list of strings. To specify a non-standard SMTP
- port, use the (host, port) tuple format for the *mailhost* argument. If you
- use a string, the standard SMTP port is used. If your SMTP server requires
- authentication, you can specify a (username, password) tuple for the
- *credentials* argument.
+ initialized with the from and to addresses and subject line of the email. The
+ *toaddrs* should be a list of strings. To specify a non-standard SMTP port, use
+ the (host, port) tuple format for the *mailhost* argument. If you use a string,
+ the standard SMTP port is used. If your SMTP server requires authentication, you
+ can specify a (username, password) tuple for the *credentials* argument.
To specify the use of a secure protocol (TLS), pass in a tuple to the
*secure* argument. This will only be used when authentication credentials are
@@ -619,13 +630,6 @@ supports sending logging messages to an email address via SMTP.
and certificate file. (This tuple is passed to the
:meth:`smtplib.SMTP.starttls` method.)
- .. versionchanged:: 2.6
- *credentials* was added.
-
- .. versionchanged:: 2.7
- *secure* was added.
-
-
.. method:: emit(record)
Formats the record and sends it to the specified addressees.
@@ -717,11 +721,16 @@ supports sending logging messages to a Web server, using either ``GET`` or
``POST`` semantics.
-.. class:: HTTPHandler(host, url, method='GET')
+.. class:: HTTPHandler(host, url, method='GET', secure=False, credentials=None)
Returns a new instance of the :class:`HTTPHandler` class. The *host* can be
of the form ``host:port``, should you need to use a specific port number.
- If no *method* is specified, ``GET`` is used.
+ If no *method* is specified, ``GET`` is used. If *secure* is True, an HTTPS
+ connection will be used. If *credentials* is specified, it should be a
+ 2-tuple consisting of userid and password, which will be placed in an HTTP
+ 'Authorization' header using Basic authentication. If you specify
+ credentials, you should also specify secure=True so that your userid and
+ password are not passed in cleartext across the wire.
.. method:: emit(record)
@@ -729,6 +738,128 @@ supports sending logging messages to a Web server, using either ``GET`` or
Sends the record to the Web server as a percent-encoded dictionary.
+.. _queue-handler:
+
+
+QueueHandler
+^^^^^^^^^^^^
+
+.. versionadded:: 3.2
+
+The :class:`QueueHandler` class, located in the :mod:`logging.handlers` module,
+supports sending logging messages to a queue, such as those implemented in the
+:mod:`queue` or :mod:`multiprocessing` modules.
+
+Along with the :class:`QueueListener` class, :class:`QueueHandler` can be used
+to let handlers do their work on a separate thread from the one which does the
+logging. This is important in Web applications and also other service
+applications where threads servicing clients need to respond as quickly as
+possible, while any potentially slow operations (such as sending an email via
+:class:`SMTPHandler`) are done on a separate thread.
+
+.. class:: QueueHandler(queue)
+
+ Returns a new instance of the :class:`QueueHandler` class. The instance is
+ initialized with the queue to send messages to. The queue can be any queue-
+ like object; it's used as-is by the :meth:`enqueue` method, which needs
+ to know how to send messages to it.
+
+
+ .. method:: emit(record)
+
+ Enqueues the result of preparing the LogRecord.
+
+ .. method:: prepare(record)
+
+ Prepares a record for queuing. The object returned by this
+ method is enqueued.
+
+ The base implementation formats the record to merge the message
+ and arguments, and removes unpickleable items from the record
+ in-place.
+
+ You might want to override this method if you want to convert
+ the record to a dict or JSON string, or send a modified copy
+ of the record while leaving the original intact.
+
+ .. method:: enqueue(record)
+
+ Enqueues the record on the queue using ``put_nowait()``; you may
+ want to override this if you want to use blocking behaviour, or a
+ timeout, or a customised queue implementation.
+
+
+
+.. _queue-listener:
+
+QueueListener
+^^^^^^^^^^^^^
+
+.. versionadded:: 3.2
+
+The :class:`QueueListener` class, located in the :mod:`logging.handlers`
+module, supports receiving logging messages from a queue, such as those
+implemented in the :mod:`queue` or :mod:`multiprocessing` modules. The
+messages are received from a queue in an internal thread and passed, on
+the same thread, to one or more handlers for processing. While
+:class:`QueueListener` is not itself a handler, it is documented here
+because it works hand-in-hand with :class:`QueueHandler`.
+
+Along with the :class:`QueueHandler` class, :class:`QueueListener` can be used
+to let handlers do their work on a separate thread from the one which does the
+logging. This is important in Web applications and also other service
+applications where threads servicing clients need to respond as quickly as
+possible, while any potentially slow operations (such as sending an email via
+:class:`SMTPHandler`) are done on a separate thread.
+
+.. class:: QueueListener(queue, *handlers)
+
+ Returns a new instance of the :class:`QueueListener` class. The instance is
+ initialized with the queue to send messages to and a list of handlers which
+ will handle entries placed on the queue. The queue can be any queue-
+ like object; it's passed as-is to the :meth:`dequeue` method, which needs
+ to know how to get messages from it.
+
+ .. method:: dequeue(block)
+
+ Dequeues a record and return it, optionally blocking.
+
+ The base implementation uses ``get()``. You may want to override this
+ method if you want to use timeouts or work with custom queue
+ implementations.
+
+ .. method:: prepare(record)
+
+ Prepare a record for handling.
+
+ This implementation just returns the passed-in record. You may want to
+ override this method if you need to do any custom marshalling or
+ manipulation of the record before passing it to the handlers.
+
+ .. method:: handle(record)
+
+ Handle a record.
+
+ This just loops through the handlers offering them the record
+ to handle. The actual object passed to the handlers is that which
+ is returned from :meth:`prepare`.
+
+ .. method:: start()
+
+ Starts the listener.
+
+ This starts up a background thread to monitor the queue for
+ LogRecords to process.
+
+ .. method:: stop()
+
+ Stops the listener.
+
+ This asks the thread to terminate, and then waits for it to do so.
+ Note that if you don't call this before your application exits, there
+ may be some records still left on the queue, which won't be processed.
+
+
.. seealso::
Module :mod:`logging`
diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst
index 7ed1f1a..b6622e3 100644
--- a/Doc/library/logging.rst
+++ b/Doc/library/logging.rst
@@ -21,8 +21,6 @@
* :ref:`Logging Cookbook <logging-cookbook>`
-.. versionadded:: 2.3
-
This module defines functions and classes which implement a flexible event
logging system for applications and libraries.
@@ -67,6 +65,7 @@ per-module basis using the recommended construction
``logging.getLogger(__name__)``. That's because in a module, ``__name__``
is the module's name in the Python package namespace.
+
.. class:: Logger
.. attribute:: Logger.propagate
@@ -101,6 +100,11 @@ is the module's name in the Python package namespace.
If the root is reached, and it has a level of NOTSET, then all messages will be
processed. Otherwise, the root's level will be used as the effective level.
+ .. versionchanged:: 3.2
+ The *lvl* parameter now accepts a string representation of the
+ level such as 'INFO' as an alternative to the integer constants
+ such as :const:`INFO`.
+
.. method:: Logger.isEnabledFor(lvl)
@@ -126,7 +130,7 @@ is the module's name in the Python package namespace.
convenience method, useful when the parent logger is named using e.g. ``__name__``
rather than a literal string.
- .. versionadded:: 2.7
+ .. versionadded:: 3.2
.. method:: Logger.debug(msg, *args, **kwargs)
@@ -136,13 +140,31 @@ is the module's name in the Python package namespace.
*msg* using the string formatting operator. (Note that this means that you can
use keywords in the format string, together with a single dictionary argument.)
- There are two keyword arguments in *kwargs* which are inspected: *exc_info*
+ There are three keyword arguments in *kwargs* which are inspected: *exc_info*
which, if it does not evaluate as false, causes exception information to be
added to the logging message. If an exception tuple (in the format returned by
:func:`sys.exc_info`) is provided, it is used; otherwise, :func:`sys.exc_info`
is called to get the exception information.
- The second keyword argument is *extra* which can be used to pass a
+ The second optional keyword argument is *stack_info*, which defaults to
+ False. If specified as True, stack information is added to the logging
+ message, including the actual logging call. Note that this is not the same
+ stack information as that displayed through specifying *exc_info*: The
+ former is stack frames from the bottom of the stack up to the logging call
+ in the current thread, whereas the latter is information about stack frames
+ which have been unwound, following an exception, while searching for
+ exception handlers.
+
+ You can specify *stack_info* independently of *exc_info*, e.g. to just show
+ how you got to a certain point in your code, even when no exceptions were
+ raised. The stack frames are printed following a header line which says::
+
+ Stack (most recent call last):
+
+ This mimics the ``Traceback (most recent call last):`` which is used when
+ displaying exception frames.
+
+ The third keyword argument is *extra* which can be used to pass a
dictionary which is used to populate the __dict__ of the LogRecord created for
the logging event with user-defined attributes. These custom attributes can then
be used as you like. For example, they could be incorporated into logged
@@ -176,6 +198,9 @@ is the module's name in the Python package namespace.
above example). In such circumstances, it is likely that specialized
:class:`Formatter`\ s would be used with particular :class:`Handler`\ s.
+ .. versionadded:: 3.2
+ The *stack_info* parameter was added.
+
.. method:: Logger.info(msg, *args, **kwargs)
@@ -240,14 +265,12 @@ is the module's name in the Python package namespace.
Removes the specified handler *hdlr* from this logger.
-.. method:: Logger.findCaller()
+.. method:: Logger.findCaller(stack_info=False)
Finds the caller's source filename and line number. Returns the filename, line
- number and function name as a 3-element tuple.
+ number, function name and stack information as a 4-element tuple. The stack
+ information is returned as *None* unless *stack_info* is *True*.
- .. versionchanged:: 2.4
- The function name was added. In earlier versions, the filename and line
- number were returned as a 2-element tuple.
.. method:: Logger.handle(record)
@@ -257,13 +280,22 @@ is the module's name in the Python package namespace.
Logger-level filtering is applied using :meth:`~Logger.filter`.
-.. method:: Logger.makeRecord(name, lvl, fn, lno, msg, args, exc_info, func=None, extra=None)
+.. method:: Logger.makeRecord(name, lvl, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None)
This is a factory method which can be overridden in subclasses to create
specialized :class:`LogRecord` instances.
- .. versionchanged:: 2.5
- *func* and *extra* were added.
+.. method:: Logger.hasHandlers()
+
+ Checks to see if this logger has any handlers configured. This is done by
+ looking for handlers in this logger and its parents in the logger hierarchy.
+ Returns True if a handler was found, else False. The method stops searching
+ up the hierarchy whenever a logger with the 'propagate' attribute set to
+ False is found - that will be the last logger which is checked for the
+ existence of handlers.
+
+ .. versionadded:: 3.2
+
.. _handler:
@@ -305,6 +337,11 @@ subclasses. However, the :meth:`__init__` method in subclasses needs to call
severe than *lvl* will be ignored. When a handler is created, the level is set
to :const:`NOTSET` (which causes all messages to be processed).
+ .. versionchanged:: 3.2
+ The *lvl* parameter now accepts a string representation of the
+ level such as 'INFO' as an alternative to the integer constants
+ such as :const:`INFO`.
+
.. method:: Handler.setFormatter(form)
@@ -392,14 +429,14 @@ A Formatter can be initialized with a format string which makes use of knowledge
of the :class:`LogRecord` attributes - such as the default value mentioned above
making use of the fact that the user's message and arguments are pre-formatted
into a :class:`LogRecord`'s *message* attribute. This format string contains
-standard Python %-style mapping keys. See section :ref:`string-formatting`
+standard Python %-style mapping keys. See section :ref:`old-string-formatting`
for more information on string formatting.
The useful mapping keys in a :class:`LogRecord` are given in the section on
:ref:`logrecord-attributes`.
-.. class:: Formatter(fmt=None, datefmt=None)
+.. class:: Formatter(fmt=None, datefmt=None, style='%')
Returns a new instance of the :class:`Formatter` class. The instance is
initialized with a format string for the message as a whole, as well as a
@@ -407,6 +444,14 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on
specified, ``'%(message)s'`` is used. If no *datefmt* is specified, the
ISO8601 date format is used.
+ The *style* parameter can be one of '%', '{' or '$' and determines how
+ the format string will be merged with its data: using one of %-formatting,
+ :meth:`str.format` or :class:`string.Template`.
+
+ .. versionchanged:: 3.2
+ The *style* parameter was added.
+
+
.. method:: format(record)
The record's attribute dictionary is used as the operand to a string
@@ -425,6 +470,9 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on
formatter to handle the event doesn't use the cached value but
recalculates it afresh.
+ If stack information is available, it's appended after the exception
+ information, using :meth:`formatStack` to transform it if necessary.
+
.. method:: formatTime(record, datefmt=None)
@@ -451,6 +499,12 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on
just uses :func:`traceback.print_exception`. The resulting string is
returned.
+ .. method:: formatStack(stack_info)
+
+ Formats the specified stack information (a string as returned by
+ :func:`traceback.print_stack`, but with the last newline removed) as a
+ string. This default implementation just returns the input value.
+
.. _filter:
Filter Objects
@@ -487,6 +541,16 @@ been applied to those descendant loggers.
You don't actually need to subclass ``Filter``: you can pass any instance
which has a ``filter`` method with the same semantics.
+.. versionchanged:: 3.2
+ You don't need to create specialized ``Filter`` classes, or use other
+ classes with a ``filter`` method: you can use a function (or other
+ callable) as a filter. The filtering logic will check to see if the filter
+ object has a ``filter`` attribute: if it does, it's assumed to be a
+ ``Filter`` and its :meth:`~Filter.filter` method is called. Otherwise, it's
+ assumed to be a callable and called with the record as the single
+ parameter. The returned value should conform to that returned by
+ :meth:`~Filter.filter`.
+
Although filters are used primarily to filter records based on more
sophisticated criteria than levels, they get to see every record which is
processed by the handler or logger they're attached to: this can be useful if
@@ -507,7 +571,7 @@ every time something is logged, and can be created manually via
wire).
-.. class:: LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None)
+.. class:: LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None)
Contains all the information pertinent to the event being logged.
@@ -533,9 +597,8 @@ wire).
or *None* if no exception information is available.
:param func: The name of the function or method from which the logging call
was invoked.
-
- .. versionchanged:: 2.5
- *func* was added.
+ :param sinfo: A text string representing stack information from the base of
+ the stack in the current thread, up to the logging call.
.. method:: getMessage()
@@ -546,6 +609,29 @@ wire).
messages, whose ``__str__`` method can return the actual format string to
be used.
+ .. versionchanged:: 3.2
+ The creation of a ``LogRecord`` has been made more configurable by
+ providing a factory which is used to create the record. The factory can be
+ set using :func:`getLogRecordFactory` and :func:`setLogRecordFactory`
+ (see this for the factory's signature).
+
+ This functionality can be used to inject your own values into a
+ LogRecord at creation time. You can use the following pattern::
+
+ old_factory = logging.getLogRecordFactory()
+
+ def record_factory(*args, **kwargs):
+ record = old_factory(*args, **kwargs)
+ record.custom_attribute = 0xdecafbad
+ return record
+
+ logging.setLogRecordFactory(record_factory)
+
+ With this pattern, multiple factories could be chained, and as long
+ as they don't overwrite each other's attributes or unintentionally
+ overwrite the standard attributes listed above, there should be no
+ surprises.
+
.. _logrecord-attributes:
@@ -560,6 +646,18 @@ the format string. The following table lists (in alphabetical order) the
attribute names, their meanings and the corresponding placeholder in a %-style
format string.
+If you are using {}-formatting (:func:`str.format`), you can use
+``{attrname}`` as the placeholder in the format string. If you are using
+$-formatting (:class:`string.Template`), use the form ``${attrname}``. In
+both cases, of course, replace ``attrname`` with the actual attribute name
+you want to use.
+
+In the case of {}-formatting, you can specify formatting flags by placing them
+after the attribute name, separated from it with a colon. For example: a
+placeholder of ``{msecs:03d}`` would format a millisecond value of ``4`` as
+``004``. Refer to the :meth:`str.format` documentation for full details on
+the options available to you.
+
+----------------+-------------------------+-----------------------------------------------+
| Attribute name | Format | Description |
+================+=========================+===============================================+
@@ -621,17 +719,21 @@ format string.
| | | created, relative to the time the logging |
| | | module was loaded. |
+----------------+-------------------------+-----------------------------------------------+
+| stack_info | You shouldn't need to | Stack frame information (where available) |
+| | format this yourself. | from the bottom of the stack in the current |
+| | | thread, up to and including the stack frame |
+| | | of the logging call which resulted in the |
+| | | creation of this record. |
++----------------+-------------------------+-----------------------------------------------+
| thread | ``%(thread)d`` | Thread ID (if available). |
+----------------+-------------------------+-----------------------------------------------+
| threadName | ``%(threadName)s`` | Thread name (if available). |
+----------------+-------------------------+-----------------------------------------------+
-.. versionchanged:: 2.5
- *funcName* was added.
-
-.. versionchanged:: 2.6
+.. versionchanged:: 3.1
*processName* was added.
+
.. _logger-adapter:
LoggerAdapter Objects
@@ -641,9 +743,6 @@ LoggerAdapter Objects
information into logging calls. For a usage example , see the section on
:ref:`adding contextual information to your logging output <context-info>`.
-.. versionadded:: 2.6
-
-
.. class:: LoggerAdapter(logger, extra)
Returns an instance of :class:`LoggerAdapter` initialized with an
@@ -665,9 +764,10 @@ methods of :class:`Logger`, i.e. :meth:`debug`, :meth:`info`, :meth:`warning`,
counterparts in :class:`Logger`, so you can use the two types of instances
interchangeably.
-.. versionchanged:: 2.7
- The :meth:`isEnabledFor` method was added to :class:`LoggerAdapter`. This
- method delegates to the underlying logger.
+.. versionchanged:: 3.2
+ The :meth:`isEnabledFor`, :meth:`getEffectiveLevel`, :meth:`setLevel` and
+ :meth:`hasHandlers` methods were added to :class:`LoggerAdapter`. These
+ methods delegate to the underlying logger.
Thread Safety
@@ -691,11 +791,11 @@ In addition to the classes described above, there are a number of module- level
functions.
-.. function:: getLogger([name])
+.. function:: getLogger(name=None)
- Return a logger with the specified name or, if no name is specified, return a
+ Return a logger with the specified name or, if name is ``None``, return a
logger which is the root logger of the hierarchy. If specified, the name is
- typically a dot-separated hierarchical name like *"a"*, *"a.b"* or *"a.b.c.d"*.
+ typically a dot-separated hierarchical name like *'a'*, *'a.b'* or *'a.b.c.d'*.
Choice of these names is entirely up to the developer who is using logging.
All calls to this function with a given name return the same logger instance.
@@ -714,29 +814,59 @@ functions.
# ... override behaviour here
-.. function:: debug(msg[, *args[, **kwargs]])
+.. function:: getLogRecordFactory()
+
+ Return a callable which is used to create a :class:`LogRecord`.
+
+ .. versionadded:: 3.2
+ This function has been provided, along with :func:`setLogRecordFactory`,
+ to allow developers more control over how the :class:`LogRecord`
+ representing a logging event is constructed.
+
+ See :func:`setLogRecordFactory` for more information about the how the
+ factory is called.
+
+.. function:: debug(msg, *args, **kwargs)
Logs a message with level :const:`DEBUG` on the root logger. The *msg* is the
message format string, and the *args* are the arguments which are merged into
*msg* using the string formatting operator. (Note that this means that you can
use keywords in the format string, together with a single dictionary argument.)
- There are two keyword arguments in *kwargs* which are inspected: *exc_info*
+ There are three keyword arguments in *kwargs* which are inspected: *exc_info*
which, if it does not evaluate as false, causes exception information to be
added to the logging message. If an exception tuple (in the format returned by
:func:`sys.exc_info`) is provided, it is used; otherwise, :func:`sys.exc_info`
is called to get the exception information.
- The other optional keyword argument is *extra* which can be used to pass a
+ The second optional keyword argument is *stack_info*, which defaults to
+ False. If specified as True, stack information is added to the logging
+ message, including the actual logging call. Note that this is not the same
+ stack information as that displayed through specifying *exc_info*: The
+ former is stack frames from the bottom of the stack up to the logging call
+ in the current thread, whereas the latter is information about stack frames
+ which have been unwound, following an exception, while searching for
+ exception handlers.
+
+ You can specify *stack_info* independently of *exc_info*, e.g. to just show
+ how you got to a certain point in your code, even when no exceptions were
+ raised. The stack frames are printed following a header line which says::
+
+ Stack (most recent call last):
+
+ This mimics the ``Traceback (most recent call last):`` which is used when
+ displaying exception frames.
+
+ The third optional keyword argument is *extra* which can be used to pass a
dictionary which is used to populate the __dict__ of the LogRecord created for
the logging event with user-defined attributes. These custom attributes can then
be used as you like. For example, they could be incorporated into logged
messages. For example::
- FORMAT = "%(asctime)-15s %(clientip)s %(user)-8s %(message)s"
+ FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'
logging.basicConfig(format=FORMAT)
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
- logging.warning("Protocol problem: %s", "connection reset", extra=d)
+ logging.warning('Protocol problem: %s', 'connection reset', extra=d)
would print something like::
@@ -760,42 +890,40 @@ functions.
above example). In such circumstances, it is likely that specialized
:class:`Formatter`\ s would be used with particular :class:`Handler`\ s.
- .. versionchanged:: 2.5
- *extra* was added.
+ .. versionadded:: 3.2
+ The *stack_info* parameter was added.
-
-.. function:: info(msg[, *args[, **kwargs]])
+.. function:: info(msg, *args, **kwargs)
Logs a message with level :const:`INFO` on the root logger. The arguments are
interpreted as for :func:`debug`.
-.. function:: warning(msg[, *args[, **kwargs]])
+.. function:: warning(msg, *args, **kwargs)
Logs a message with level :const:`WARNING` on the root logger. The arguments are
interpreted as for :func:`debug`.
-.. function:: error(msg[, *args[, **kwargs]])
+.. function:: error(msg, *args, **kwargs)
Logs a message with level :const:`ERROR` on the root logger. The arguments are
interpreted as for :func:`debug`.
-.. function:: critical(msg[, *args[, **kwargs]])
+.. function:: critical(msg, *args, **kwargs)
Logs a message with level :const:`CRITICAL` on the root logger. The arguments
are interpreted as for :func:`debug`.
-.. function:: exception(msg[, *args])
+.. function:: exception(msg, *args)
Logs a message with level :const:`ERROR` on the root logger. The arguments are
interpreted as for :func:`debug`. Exception info is added to the logging
message. This function should only be called from an exception handler.
-
-.. function:: log(level, msg[, *args[, **kwargs]])
+.. function:: log(level, msg, *args, **kwargs)
Logs a message with level *level* on the root logger. The other arguments are
interpreted as for :func:`debug`.
@@ -841,7 +969,7 @@ functions.
have associated levels with names using :func:`addLevelName` then the name you
have associated with *lvl* is returned. If a numeric value corresponding to one
of the defined levels is passed in, the corresponding string representation is
- returned. Otherwise, the string "Level %s" % lvl is returned.
+ returned. Otherwise, the string 'Level %s' % lvl is returned.
.. function:: makeLogRecord(attrdict)
@@ -852,7 +980,7 @@ functions.
it as a :class:`LogRecord` instance at the receiving end.
-.. function:: basicConfig([**kwargs])
+.. function:: basicConfig(**kwargs)
Does basic configuration for the logging system by creating a
:class:`StreamHandler` with a default :class:`Formatter` and adding it to the
@@ -863,9 +991,6 @@ functions.
This function does nothing if the root logger already has handlers
configured for it.
- .. versionchanged:: 2.4
- Formerly, :func:`basicConfig` did not take any keyword arguments.
-
PLEASE NOTE: This function should be called from the main thread
before other threads are started. In versions of Python prior to
2.7.1 and 3.2, if this function is called from multiple threads,
@@ -891,6 +1016,12 @@ functions.
+--------------+---------------------------------------------+
| ``datefmt`` | Use the specified date/time format. |
+--------------+---------------------------------------------+
+ | ``style`` | If ``format`` is specified, use this style |
+ | | for the format string. One of '%', '{' or |
+ | | '$' for %-formatting, :meth:`str.format` or |
+ | | :class:`string.Template` respectively, and |
+ | | defaulting to '%' if not specified. |
+ +--------------+---------------------------------------------+
| ``level`` | Set the root logger level to the specified |
| | level. |
+--------------+---------------------------------------------+
@@ -900,6 +1031,9 @@ functions.
| | present, 'stream' is ignored. |
+--------------+---------------------------------------------+
+ .. versionchanged:: 3.2
+ The ``style`` argument was added.
+
.. function:: shutdown()
@@ -917,6 +1051,35 @@ functions.
which need to use custom logger behavior.
+.. function:: setLogRecordFactory(factory)
+
+ Set a callable which is used to create a :class:`LogRecord`.
+
+ :param factory: The factory callable to be used to instantiate a log record.
+
+ .. versionadded:: 3.2
+ This function has been provided, along with :func:`getLogRecordFactory`, to
+ allow developers more control over how the :class:`LogRecord` representing
+ a logging event is constructed.
+
+ The factory has the following signature:
+
+ ``factory(name, level, fn, lno, msg, args, exc_info, func=None, sinfo=None, **kwargs)``
+
+ :name: The logger name.
+ :level: The logging level (numeric).
+ :fn: The full pathname of the file where the logging call was made.
+ :lno: The line number in the file where the logging call was made.
+ :msg: The logging message.
+ :args: The arguments for the logging message.
+ :exc_info: An exception tuple, or None.
+ :func: The name of the function or method which invoked the logging
+ call.
+ :sinfo: A stack traceback such as is provided by
+ :func:`traceback.print_stack`, showing the call hierarchy.
+ :kwargs: Additional keyword arguments.
+
+
Integration with the warnings module
------------------------------------
diff --git a/Doc/library/mac.rst b/Doc/library/mac.rst
deleted file mode 100644
index 7ac1ca2..0000000
--- a/Doc/library/mac.rst
+++ /dev/null
@@ -1,27 +0,0 @@
-.. _mac-specific-services:
-
-**************************
-Mac OS X specific services
-**************************
-
-This chapter describes modules that are only available on the Mac OS X platform.
-
-See the chapters :ref:`mac-scripting` and :ref:`undoc-mac-modules` for more
-modules, and the HOWTO :ref:`using-on-mac` for a general introduction to
-Mac-specific Python programming.
-
-.. note::
-
- These modules are deprecated and have been removed in Python 3.x.
-
-
-.. toctree::
-
- ic.rst
- macos.rst
- macostools.rst
- easydialogs.rst
- framework.rst
- autogil.rst
- carbon.rst
- colorpicker.rst
diff --git a/Doc/library/macos.rst b/Doc/library/macos.rst
deleted file mode 100644
index 119c2da..0000000
--- a/Doc/library/macos.rst
+++ /dev/null
@@ -1,123 +0,0 @@
-:mod:`MacOS` --- Access to Mac OS interpreter features
-======================================================
-
-.. module:: MacOS
- :platform: Mac
- :synopsis: Access to Mac OS-specific interpreter features.
- :deprecated:
-
-
-This module provides access to MacOS specific functionality in the Python
-interpreter, such as how the interpreter eventloop functions and the like. Use
-with care.
-
-.. note::
-
- This module has been removed in Python 3.x.
-
-Note the capitalization of the module name; this is a historical artifact.
-
-
-.. data:: runtimemodel
-
- Always ``'macho'``, from Python 2.4 on. In earlier versions of Python the value
- could also be ``'ppc'`` for the classic Mac OS 8 runtime model or ``'carbon'``
- for the Mac OS 9 runtime model.
-
-
-.. data:: linkmodel
-
- The way the interpreter has been linked. As extension modules may be
- incompatible between linking models, packages could use this information to give
- more decent error messages. The value is one of ``'static'`` for a statically
- linked Python, ``'framework'`` for Python in a Mac OS X framework, ``'shared'``
- for Python in a standard Unix shared library. Older Pythons could also have the
- value ``'cfm'`` for Mac OS 9-compatible Python.
-
-
-.. exception:: Error
-
- .. index:: module: macerrors
-
- This exception is raised on MacOS generated errors, either from functions in
- this module or from other mac-specific modules like the toolbox interfaces. The
- arguments are the integer error code (the :c:data:`OSErr` value) and a textual
- description of the error code. Symbolic names for all known error codes are
- defined in the standard module :mod:`macerrors`.
-
-
-.. function:: GetErrorString(errno)
-
- Return the textual description of MacOS error code *errno*.
-
-
-.. function:: DebugStr(message [, object])
-
- On Mac OS X the string is simply printed to stderr (on older Mac OS systems more
- elaborate functionality was available), but it provides a convenient location to
- attach a breakpoint in a low-level debugger like :program:`gdb`.
-
- .. note::
-
- Not available in 64-bit mode.
-
-
-.. function:: SysBeep()
-
- Ring the bell.
-
- .. note::
-
- Not available in 64-bit mode.
-
-
-.. function:: GetTicks()
-
- Get the number of clock ticks (1/60th of a second) since system boot.
-
-
-.. function:: GetCreatorAndType(file)
-
- Return the file creator and file type as two four-character strings. The *file*
- parameter can be a pathname or an ``FSSpec`` or ``FSRef`` object.
-
- .. note::
-
- It is not possible to use an ``FSSpec`` in 64-bit mode.
-
-
-.. function:: SetCreatorAndType(file, creator, type)
-
- Set the file creator and file type. The *file* parameter can be a pathname or an
- ``FSSpec`` or ``FSRef`` object. *creator* and *type* must be four character
- strings.
-
- .. note::
-
- It is not possible to use an ``FSSpec`` in 64-bit mode.
-
-.. function:: openrf(name [, mode])
-
- Open the resource fork of a file. Arguments are the same as for the built-in
- function :func:`open`. The object returned has file-like semantics, but it is
- not a Python file object, so there may be subtle differences.
-
-
-.. function:: WMAvailable()
-
- Checks whether the current process has access to the window manager. The method
- will return ``False`` if the window manager is not available, for instance when
- running on Mac OS X Server or when logged in via ssh, or when the current
- interpreter is not running from a fullblown application bundle. A script runs
- from an application bundle either when it has been started with
- :program:`pythonw` instead of :program:`python` or when running as an applet.
-
-.. function:: splash([resourceid])
-
- Opens a splash screen by resource id. Use resourceid ``0`` to close
- the splash screen.
-
- .. note::
-
- Not available in 64-bit mode.
-
diff --git a/Doc/library/macosa.rst b/Doc/library/macosa.rst
deleted file mode 100644
index 54e62f2..0000000
--- a/Doc/library/macosa.rst
+++ /dev/null
@@ -1,93 +0,0 @@
-
-.. _mac-scripting:
-
-*********************
-MacPython OSA Modules
-*********************
-
-This chapter describes the current implementation of the Open Scripting
-Architecture (OSA, also commonly referred to as AppleScript) for Python,
-allowing you to control scriptable applications from your Python program,
-and with a fairly pythonic interface. Development on this set of modules has
-stopped. For more up-to-date implementation of AppleScript support for Python,
-see the third-party py-appscript project: <http://pypi.python.org/pypi/appscript/>.
-
-For a description of the various components of AppleScript and OSA, and to get
-an understanding of the architecture and terminology, you should read Apple's
-documentation. The "Applescript Language Guide" explains the conceptual model
-and the terminology, and documents the standard suite. The "Open Scripting
-Architecture" document explains how to use OSA from an application programmers
-point of view. In the Apple Help Viewer these books are located in the Developer
-Documentation, Core Technologies section.
-
-As an example of scripting an application, the following piece of AppleScript
-will get the name of the frontmost :program:`Finder` window and print it::
-
- tell application "Finder"
- get name of window 1
- end tell
-
-In Python, the following code fragment will do the same::
-
- import Finder
-
- f = Finder.Finder()
- print f.get(f.window(1).name)
-
-As distributed the Python library includes packages that implement the standard
-suites, plus packages that interface to a small number of common applications.
-
-To send AppleEvents to an application you must first create the Python package
-interfacing to the terminology of the application (what :program:`Script Editor`
-calls the "Dictionary"). This can be done from within the :program:`PythonIDE`
-or by running the :file:`gensuitemodule.py` module as a standalone program from
-the command line.
-
-The generated output is a package with a number of modules, one for every suite
-used in the program plus an :mod:`__init__` module to glue it all together. The
-Python inheritance graph follows the AppleScript inheritance graph, so if a
-program's dictionary specifies that it includes support for the Standard Suite,
-but extends one or two verbs with extra arguments then the output suite will
-contain a module :mod:`Standard_Suite` that imports and re-exports everything
-from :mod:`StdSuites.Standard_Suite` but overrides the methods that have extra
-functionality. The output of :mod:`gensuitemodule` is pretty readable, and
-contains the documentation that was in the original AppleScript dictionary in
-Python docstrings, so reading it is a good source of documentation.
-
-The output package implements a main class with the same name as the package
-which contains all the AppleScript verbs as methods, with the direct object as
-the first argument and all optional parameters as keyword arguments. AppleScript
-classes are also implemented as Python classes, as are comparisons and all the
-other thingies.
-
-The main Python class implementing the verbs also allows access to the
-properties and elements declared in the AppleScript class "application". In the
-current release that is as far as the object orientation goes, so in the example
-above we need to use ``f.get(f.window(1).name)`` instead of the more Pythonic
-``f.window(1).name.get()``.
-
-If an AppleScript identifier is not a Python identifier the name is mangled
-according to a small number of rules:
-
-* spaces are replaced with underscores
-
-* other non-alphanumeric characters are replaced with ``_xx_`` where ``xx`` is
- the hexadecimal character value
-
-* any Python reserved word gets an underscore appended
-
-Python also has support for creating scriptable applications in Python, but The
-following modules are relevant to MacPython AppleScript support:
-
-.. toctree::
-
- gensuitemodule.rst
- aetools.rst
- aepack.rst
- aetypes.rst
- miniaeframe.rst
-
-
-In addition, support modules have been pre-generated for :mod:`Finder`,
-:mod:`Terminal`, :mod:`Explorer`, :mod:`Netscape`, :mod:`CodeWarrior`,
-:mod:`SystemEvents` and :mod:`StdSuites`.
diff --git a/Doc/library/macostools.rst b/Doc/library/macostools.rst
deleted file mode 100644
index 7924669..0000000
--- a/Doc/library/macostools.rst
+++ /dev/null
@@ -1,135 +0,0 @@
-
-:mod:`macostools` --- Convenience routines for file manipulation
-================================================================
-
-.. module:: macostools
- :platform: Mac
- :synopsis: Convenience routines for file manipulation.
- :deprecated:
-
-
-This module contains some convenience routines for file-manipulation on the
-Macintosh. All file parameters can be specified as pathnames, :class:`FSRef` or
-:class:`FSSpec` objects. This module expects a filesystem which supports forked
-files, so it should not be used on UFS partitions.
-
-.. note::
-
- This module has been removed in Python 3.
-
-
-
-The :mod:`macostools` module defines the following functions:
-
-
-.. function:: copy(src, dst[, createpath[, copytimes]])
-
- Copy file *src* to *dst*. If *createpath* is non-zero the folders leading to
- *dst* are created if necessary. The method copies data and resource fork and
- some finder information (creator, type, flags) and optionally the creation,
- modification and backup times (default is to copy them). Custom icons, comments
- and icon position are not copied.
-
- .. note::
-
- This function does not work in 64-bit code because it uses APIs that
- are not available in 64-bit mode.
-
-.. function:: copytree(src, dst)
-
- Recursively copy a file tree from *src* to *dst*, creating folders as needed.
- *src* and *dst* should be specified as pathnames.
-
- .. note::
-
- This function does not work in 64-bit code because it uses APIs that
- are not available in 64-bit mode.
-
-.. function:: mkalias(src, dst)
-
- Create a finder alias *dst* pointing to *src*.
-
- .. note::
-
- This function does not work in 64-bit code because it uses APIs that
- are not available in 64-bit mode.
-
-
-.. function:: touched(dst)
-
- Tell the finder that some bits of finder-information such as creator or type for
- file *dst* has changed. The file can be specified by pathname or fsspec. This
- call should tell the finder to redraw the files icon.
-
- .. deprecated:: 2.6
- The function is a no-op on OS X.
-
-
-.. data:: BUFSIZ
-
- The buffer size for ``copy``, default 1 megabyte.
-
-Note that the process of creating finder aliases is not specified in the Apple
-documentation. Hence, aliases created with :func:`mkalias` could conceivably
-have incompatible behaviour in some cases.
-
-
-:mod:`findertools` --- The :program:`finder`'s Apple Events interface
-======================================================================
-
-.. module:: findertools
- :platform: Mac
- :synopsis: Wrappers around the finder's Apple Events interface.
-
-
-.. index:: single: AppleEvents
-
-This module contains routines that give Python programs access to some
-functionality provided by the finder. They are implemented as wrappers around
-the AppleEvent interface to the finder.
-
-All file and folder parameters can be specified either as full pathnames, or as
-:class:`FSRef` or :class:`FSSpec` objects.
-
-The :mod:`findertools` module defines the following functions:
-
-
-.. function:: launch(file)
-
- Tell the finder to launch *file*. What launching means depends on the file:
- applications are started, folders are opened and documents are opened in the
- correct application.
-
-
-.. function:: Print(file)
-
- Tell the finder to print a file. The behaviour is identical to selecting the
- file and using the print command in the finder's file menu.
-
-
-.. function:: copy(file, destdir)
-
- Tell the finder to copy a file or folder *file* to folder *destdir*. The
- function returns an :class:`Alias` object pointing to the new file.
-
-
-.. function:: move(file, destdir)
-
- Tell the finder to move a file or folder *file* to folder *destdir*. The
- function returns an :class:`Alias` object pointing to the new file.
-
-
-.. function:: sleep()
-
- Tell the finder to put the Macintosh to sleep, if your machine supports it.
-
-
-.. function:: restart()
-
- Tell the finder to perform an orderly restart of the machine.
-
-
-.. function:: shutdown()
-
- Tell the finder to perform an orderly shutdown of the machine.
-
diff --git a/Doc/library/macpath.rst b/Doc/library/macpath.rst
index a7d82d0..b7a5d89 100644
--- a/Doc/library/macpath.rst
+++ b/Doc/library/macpath.rst
@@ -1,4 +1,3 @@
-
:mod:`macpath` --- Mac OS 9 path manipulation functions
=======================================================
diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst
index 3a87c13..0f6aba1 100644
--- a/Doc/library/mailbox.rst
+++ b/Doc/library/mailbox.rst
@@ -1,4 +1,3 @@
-
:mod:`mailbox` --- Manipulate mailboxes in various formats
==========================================================
@@ -13,8 +12,7 @@ accessing and manipulating on-disk mailboxes and the messages they contain.
:class:`Mailbox` offers a dictionary-like mapping from keys to messages.
:class:`Message` extends the :mod:`email.message` module's
:class:`~email.message.Message` class with format-specific state and behavior.
-Supported mailbox formats are
-Maildir, mbox, MH, Babyl, and MMDF.
+Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF.
.. seealso::
@@ -28,7 +26,6 @@ Maildir, mbox, MH, Babyl, and MMDF.
:class:`Mailbox` objects
------------------------
-
.. class:: Mailbox
A mailbox, which may be inspected and modified.
@@ -84,13 +81,17 @@ Maildir, mbox, MH, Babyl, and MMDF.
it.
Parameter *message* may be a :class:`Message` instance, an
- :class:`email.message.Message` instance, a string, or a file-like object
- (which should be open in text mode). If *message* is an instance of the
+ :class:`email.message.Message` instance, a string, a byte string, or a
+ file-like object (which should be open in binary mode). If *message* is
+ an instance of the
appropriate format-specific :class:`Message` subclass (e.g., if it's an
:class:`mboxMessage` instance and this is an :class:`mbox` instance), its
format-specific information is used. Otherwise, reasonable defaults for
format-specific information are used.
+ .. versionchanged:: 3.2
+ Support for binary input was added.
+
.. method:: remove(key)
__delitem__(key)
@@ -111,8 +112,9 @@ Maildir, mbox, MH, Babyl, and MMDF.
:exc:`KeyError` exception if no message already corresponds to *key*.
As with :meth:`add`, parameter *message* may be a :class:`Message`
- instance, an :class:`email.message.Message` instance, a string, or a
- file-like object (which should be open in text mode). If *message* is an
+ instance, an :class:`email.message.Message` instance, a string, a byte
+ string, or a file-like object (which should be open in binary mode). If
+ *message* is an
instance of the appropriate format-specific :class:`Message` subclass
(e.g., if it's an :class:`mboxMessage` instance and this is an
:class:`mbox` instance), its format-specific information is
@@ -174,29 +176,44 @@ Maildir, mbox, MH, Babyl, and MMDF.
raise a :exc:`KeyError` exception if no such message exists.
+ .. method:: get_bytes(key)
+
+ Return a byte representation of the message corresponding to *key*, or
+ raise a :exc:`KeyError` exception if no such message exists.
+
+ .. versionadded:: 3.2
+
+
.. method:: get_string(key)
Return a string representation of the message corresponding to *key*, or
- raise a :exc:`KeyError` exception if no such message exists.
+ raise a :exc:`KeyError` exception if no such message exists. The
+ message is processed through :class:`email.message.Message` to
+ convert it to a 7bit clean representation.
.. method:: get_file(key)
Return a file-like representation of the message corresponding to *key*,
- or raise a :exc:`KeyError` exception if no such message exists. The
- file-like object behaves as if open in binary mode. This file should be
+ or raise a :exc:`KeyError` exception if no such message exists. The
+ file-like object behaves as if open in binary mode. This file should be
closed once it is no longer needed.
+ .. versionchanged:: 3.2
+ The file object really is a binary file; previously it was incorrectly
+ returned in text mode. Also, the file-like object now supports the
+ context manager protocol: you can use a :keyword:`with` statement to
+ automatically close it.
+
.. note::
Unlike other representations of messages, file-like representations are
not necessarily independent of the :class:`Mailbox` instance that
- created them or of the underlying mailbox. More specific documentation
+ created them or of the underlying mailbox. More specific documentation
is provided by each subclass.
- .. method:: has_key(key)
- __contains__(key)
+ .. method:: __contains__(key)
Return ``True`` if *key* corresponds to a message, ``False`` otherwise.
@@ -211,11 +228,10 @@ Maildir, mbox, MH, Babyl, and MMDF.
Delete all messages from the mailbox.
- .. method:: pop(key[, default])
+ .. method:: pop(key, default=None)
Return a representation of the message corresponding to *key* and delete
- the message. If no such message exists, return *default* if it was
- supplied or else raise a :exc:`KeyError` exception. The message is
+ the message. If no such message exists, return *default*. The message is
represented as an instance of the appropriate format-specific
:class:`Message` subclass unless a custom message factory was specified
when the :class:`Mailbox` instance was initialized.
@@ -279,7 +295,7 @@ Maildir, mbox, MH, Babyl, and MMDF.
^^^^^^^^^^^^^^^^
-.. class:: Maildir(dirname, factory=rfc822.Message, create=True)
+.. class:: Maildir(dirname, factory=None, create=True)
A subclass of :class:`Mailbox` for mailboxes in Maildir format. Parameter
*factory* is a callable object that accepts a file-like message representation
@@ -288,10 +304,7 @@ Maildir, mbox, MH, Babyl, and MMDF.
representation. If *create* is ``True``, the mailbox is created if it does not
exist.
- It is for historical reasons that *factory* defaults to :class:`rfc822.Message`
- and that *dirname* is named as such rather than *path*. For a :class:`Maildir`
- instance that behaves like instances of other :class:`Mailbox` subclasses, set
- *factory* to ``None``.
+ It is for historical reasons that *dirname* is named as such rather than *path*.
Maildir is a directory-based mailbox format invented for the qmail mail
transfer agent and now widely supported by other programs. Messages in a
@@ -742,7 +755,7 @@ Maildir, mbox, MH, Babyl, and MMDF.
------------------------
-.. class:: Message([message])
+.. class:: Message(message=None)
A subclass of the :mod:`email.message` module's
:class:`~email.message.Message`. Subclasses of :class:`mailbox.Message` add
@@ -751,9 +764,11 @@ Maildir, mbox, MH, Babyl, and MMDF.
If *message* is omitted, the new instance is created in a default, empty state.
If *message* is an :class:`email.message.Message` instance, its contents are
copied; furthermore, any format-specific information is converted insofar as
- possible if *message* is a :class:`Message` instance. If *message* is a string
+ possible if *message* is a :class:`Message` instance. If *message* is a string,
+ a byte string,
or a file, it should contain an :rfc:`2822`\ -compliant message, which is read
- and parsed.
+ and parsed. Files should be open in binary mode, but text mode files
+ are accepted for backward compatibility.
The format-specific state and behaviors offered by subclasses vary, but in
general it is only the properties that are not specific to a particular
@@ -778,7 +793,7 @@ Maildir, mbox, MH, Babyl, and MMDF.
^^^^^^^^^^^^^^^^^^^^^^^
-.. class:: MaildirMessage([message])
+.. class:: MaildirMessage(message=None)
A message with Maildir-specific behaviors. Parameter *message* has the same
meaning as with the :class:`Message` constructor.
@@ -946,7 +961,7 @@ When a :class:`MaildirMessage` instance is created based upon a
^^^^^^^^^^^^^^^^^^^^
-.. class:: mboxMessage([message])
+.. class:: mboxMessage(message=None)
A message with mbox-specific behaviors. Parameter *message* has the same meaning
as with the :class:`Message` constructor.
@@ -1100,7 +1115,7 @@ instance, the "From " line is copied and all flags directly correspond:
^^^^^^^^^^^^^^^^^^
-.. class:: MHMessage([message])
+.. class:: MHMessage(message=None)
A message with MH-specific behaviors. Parameter *message* has the same meaning
as with the :class:`Message` constructor.
@@ -1190,7 +1205,7 @@ When an :class:`MHMessage` instance is created based upon a
^^^^^^^^^^^^^^^^^^^^^
-.. class:: BabylMessage([message])
+.. class:: BabylMessage(message=None)
A message with Babyl-specific behaviors. Parameter *message* has the same
meaning as with the :class:`Message` constructor.
@@ -1318,7 +1333,7 @@ When a :class:`BabylMessage` instance is created based upon an
^^^^^^^^^^^^^^^^^^^^
-.. class:: MMDFMessage([message])
+.. class:: MMDFMessage(message=None)
A message with MMDF-specific behaviors. Parameter *message* has the same meaning
as with the :class:`Message` constructor.
@@ -1504,135 +1519,6 @@ The following exception classes are defined in the :mod:`mailbox` module:
instance attempts to read a corrupted :file:`.mh_sequences` file.
-.. _mailbox-deprecated:
-
-Deprecated classes and methods
-------------------------------
-
-.. deprecated:: 2.6
-
-Older versions of the :mod:`mailbox` module do not support modification of
-mailboxes, such as adding or removing message, and do not provide classes to
-represent format-specific message properties. For backward compatibility, the
-older mailbox classes are still available, but the newer classes should be used
-in preference to them. The old classes have been removed in Python 3.
-
-Older mailbox objects support only iteration and provide a single public method:
-
-
-.. method:: oldmailbox.next()
-
- Return the next message in the mailbox, created with the optional *factory*
- argument passed into the mailbox object's constructor. By default this is an
- :class:`rfc822.Message` object (see the :mod:`rfc822` module). Depending on the
- mailbox implementation the *fp* attribute of this object may be a true file
- object or a class instance simulating a file object, taking care of things like
- message boundaries if multiple mail messages are contained in a single file,
- etc. If no more messages are available, this method returns ``None``.
-
-Most of the older mailbox classes have names that differ from the current
-mailbox class names, except for :class:`Maildir`. For this reason, the new
-:class:`Maildir` class defines a :meth:`!next` method and its constructor differs
-slightly from those of the other new mailbox classes.
-
-The older mailbox classes whose names are not the same as their newer
-counterparts are as follows:
-
-
-.. class:: UnixMailbox(fp[, factory])
-
- Access to a classic Unix-style mailbox, where all messages are contained in a
- single file and separated by ``From`` (a.k.a. ``From_``) lines. The file object
- *fp* points to the mailbox file. The optional *factory* parameter is a callable
- that should create new message objects. *factory* is called with one argument,
- *fp* by the :meth:`!next` method of the mailbox object. The default is the
- :class:`rfc822.Message` class (see the :mod:`rfc822` module -- and the note
- below).
-
- .. note::
-
- For reasons of this module's internal implementation, you will probably want to
- open the *fp* object in binary mode. This is especially important on Windows.
-
- For maximum portability, messages in a Unix-style mailbox are separated by any
- line that begins exactly with the string ``'From '`` (note the trailing space)
- if preceded by exactly two newlines. Because of the wide-range of variations in
- practice, nothing else on the ``From_`` line should be considered. However, the
- current implementation doesn't check for the leading two newlines. This is
- usually fine for most applications.
-
- The :class:`UnixMailbox` class implements a more strict version of ``From_``
- line checking, using a regular expression that usually correctly matched
- ``From_`` delimiters. It considers delimiter line to be separated by ``From
- name time`` lines. For maximum portability, use the
- :class:`PortableUnixMailbox` class instead. This class is identical to
- :class:`UnixMailbox` except that individual messages are separated by only
- ``From`` lines.
-
-
-.. class:: PortableUnixMailbox(fp[, factory])
-
- A less-strict version of :class:`UnixMailbox`, which considers only the ``From``
- at the beginning of the line separating messages. The "*name* *time*" portion
- of the From line is ignored, to protect against some variations that are
- observed in practice. This works since lines in the message which begin with
- ``'From '`` are quoted by mail handling software at delivery-time.
-
-
-.. class:: MmdfMailbox(fp[, factory])
-
- Access an MMDF-style mailbox, where all messages are contained in a single file
- and separated by lines consisting of 4 control-A characters. The file object
- *fp* points to the mailbox file. Optional *factory* is as with the
- :class:`UnixMailbox` class.
-
-
-.. class:: MHMailbox(dirname[, factory])
-
- Access an MH mailbox, a directory with each message in a separate file with a
- numeric name. The name of the mailbox directory is passed in *dirname*.
- *factory* is as with the :class:`UnixMailbox` class.
-
-
-.. class:: BabylMailbox(fp[, factory])
-
- Access a Babyl mailbox, which is similar to an MMDF mailbox. In Babyl format,
- each message has two sets of headers, the *original* headers and the *visible*
- headers. The original headers appear before a line containing only ``'*** EOOH
- ***'`` (End-Of-Original-Headers) and the visible headers appear after the
- ``EOOH`` line. Babyl-compliant mail readers will show you only the visible
- headers, and :class:`BabylMailbox` objects will return messages containing only
- the visible headers. You'll have to do your own parsing of the mailbox file to
- get at the original headers. Mail messages start with the EOOH line and end
- with a line containing only ``'\037\014'``. *factory* is as with the
- :class:`UnixMailbox` class.
-
-If you wish to use the older mailbox classes with the :mod:`email` module rather
-than the deprecated :mod:`rfc822` module, you can do so as follows::
-
- import email
- import email.Errors
- import mailbox
-
- def msgfactory(fp):
- try:
- return email.message_from_file(fp)
- except email.Errors.MessageParseError:
- # Don't return None since that will
- # stop the mailbox iterator
- return ''
-
- mbox = mailbox.UnixMailbox(fp, msgfactory)
-
-Alternatively, if you know your mailbox contains only well-formed MIME messages,
-you can simplify this to::
-
- import email
- import mailbox
-
- mbox = mailbox.UnixMailbox(fp, email.message_from_file)
-
-
.. _mailbox-examples:
Examples
@@ -1645,7 +1531,7 @@ interesting::
for message in mailbox.mbox('~/mbox'):
subject = message['subject'] # Could possibly be None.
if subject and 'python' in subject.lower():
- print subject
+ print(subject)
To copy all mail from a Babyl mailbox to an MH mailbox, converting all of the
format-specific information that can be converted::
@@ -1668,7 +1554,7 @@ due to malformed messages in the mailbox::
list_names = ('python-list', 'python-dev', 'python-bugs')
- boxes = dict((name, mailbox.mbox('~/email/%s' % name)) for name in list_names)
+ boxes = {name: mailbox.mbox('~/email/%s' % name) for name in list_names}
inbox = mailbox.Maildir('~/Maildir', factory=None)
for key in inbox.iterkeys():
diff --git a/Doc/library/mailcap.rst b/Doc/library/mailcap.rst
index 5507211..4bb31bf 100644
--- a/Doc/library/mailcap.rst
+++ b/Doc/library/mailcap.rst
@@ -22,7 +22,7 @@ Mechanism For Multimedia Mail Format Information," but is not an Internet
standard. However, mailcap files are supported on most Unix systems.
-.. function:: findmatch(caps, MIMEtype[, key[, filename[, plist]]])
+.. function:: findmatch(caps, MIMEtype, key='view', filename='/dev/null', plist=[])
Return a 2-tuple; the first element is a string containing the command line to
be executed (which can be passed to :func:`os.system`), and the second element
diff --git a/Doc/library/markup.rst b/Doc/library/markup.rst
index 6782e39..1b4cca5 100644
--- a/Doc/library/markup.rst
+++ b/Doc/library/markup.rst
@@ -10,11 +10,9 @@ Language (SGML) and the Hypertext Markup Language (HTML), and several interfaces
for working with the Extensible Markup Language (XML).
It is important to note that modules in the :mod:`xml` package require that
-there be at least one SAX-compliant XML parser available. Starting with Python
-2.3, the Expat parser is included with Python, so the :mod:`xml.parsers.expat`
-module will always be available. You may still want to be aware of the `PyXML
-add-on package <http://pyxml.sourceforge.net/>`_; that package provides an
-extended set of XML libraries for Python.
+there be at least one SAX-compliant XML parser available. The Expat parser is
+included with Python, so the :mod:`xml.parsers.expat` module will always be
+available.
The documentation for the :mod:`xml.dom` and :mod:`xml.sax` packages are the
definition of the Python bindings for the DOM and SAX interfaces.
@@ -22,9 +20,9 @@ definition of the Python bindings for the DOM and SAX interfaces.
.. toctree::
- htmlparser.rst
- sgmllib.rst
- htmllib.rst
+ html.rst
+ html.parser.rst
+ html.entities.rst
xml.etree.elementtree.rst
xml.dom.rst
xml.dom.minidom.rst
diff --git a/Doc/library/marshal.rst b/Doc/library/marshal.rst
index f463a7a..3b9e3d2 100644
--- a/Doc/library/marshal.rst
+++ b/Doc/library/marshal.rst
@@ -1,4 +1,3 @@
-
:mod:`marshal` --- Internal Python object serialization
=======================================================
@@ -37,25 +36,14 @@ supports a substantially wider range of objects than marshal.
Not all Python object types are supported; in general, only objects whose value
is independent from a particular invocation of Python can be written and read by
-this module. The following types are supported: booleans, integers, long
-integers, floating point numbers, complex numbers, strings, Unicode objects,
-tuples, lists, sets, frozensets, dictionaries, and code objects, where it should
-be understood that tuples, lists, sets, frozensets and dictionaries are only
-supported as long as the values contained therein are themselves supported; and
-recursive lists, sets and dictionaries should not be written (they will cause
-infinite loops). The singletons :const:`None`, :const:`Ellipsis` and
-:exc:`StopIteration` can also be marshalled and unmarshalled.
-
-.. warning::
-
- On machines where C's ``long int`` type has more than 32 bits (such as the
- DEC Alpha), it is possible to create plain Python integers that are longer
- than 32 bits. If such an integer is marshaled and read back in on a machine
- where C's ``long int`` type has only 32 bits, a Python long integer object
- is returned instead. While of a different type, the numeric value is the
- same. (This behavior is new in Python 2.2. In earlier versions, all but the
- least-significant 32 bits of the value were lost, and a warning message was
- printed.)
+this module. The following types are supported: booleans, integers, floating
+point numbers, complex numbers, strings, bytes, bytearrays, tuples, lists, sets,
+frozensets, dictionaries, and code objects, where it should be understood that
+tuples, lists, sets, frozensets and dictionaries are only supported as long as
+the values contained therein are themselves supported; and recursive lists, sets
+and dictionaries should not be written (they will cause infinite loops). The
+singletons :const:`None`, :const:`Ellipsis` and :exc:`StopIteration` can also be
+marshalled and unmarshalled.
There are functions that read/write files as well as functions operating on
strings.
@@ -74,9 +62,8 @@ The module defines these functions:
:exc:`ValueError` exception is raised --- but garbage data will also be written
to the file. The object will not be properly read back by :func:`load`.
- .. versionadded:: 2.4
- The *version* argument indicates the data format that ``dump`` should use
- (see below).
+ The *version* argument indicates the data format that ``dump`` should use
+ (see below).
.. function:: load(file)
@@ -99,9 +86,8 @@ The module defines these functions:
value must be a supported type. Raise a :exc:`ValueError` exception if value
has (or contains an object that has) an unsupported type.
- .. versionadded:: 2.4
- The *version* argument indicates the data format that ``dumps`` should use
- (see below).
+ The *version* argument indicates the data format that ``dumps`` should use
+ (see below).
.. function:: loads(string)
@@ -115,12 +101,9 @@ In addition, the following constants are defined:
.. data:: version
- Indicates the format that the module uses. Version 0 is the historical format,
- version 1 (added in Python 2.4) shares interned strings and version 2 (added in
- Python 2.5) uses a binary format for floating point numbers. The current version
- is 2.
-
- .. versionadded:: 2.4
+ Indicates the format that the module uses. Version 0 is the historical
+ format, version 1 shares interned strings and version 2 uses a binary format
+ for floating point numbers. The current version is 2.
.. rubric:: Footnotes
diff --git a/Doc/library/math.rst b/Doc/library/math.rst
index e5ffba0..98c5b33 100644
--- a/Doc/library/math.rst
+++ b/Doc/library/math.rst