summaryrefslogtreecommitdiffstats
path: root/doc/src/snippets/xml/simpleparse/handler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/snippets/xml/simpleparse/handler.cpp')
0 files changed, 0 insertions, 0 deletions
/td>.hgtags10
-rw-r--r--Demo/README61
-rw-r--r--Demo/cgi/README10
-rwxr-xr-xDemo/cgi/cgi0.sh8
-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
-rwxr-xr-xDemo/classes/Complex.py314
-rwxr-xr-xDemo/classes/Dates.py227
-rwxr-xr-xDemo/classes/Dbm.py66
-rw-r--r--Demo/classes/README12
-rwxr-xr-xDemo/classes/Range.py93
-rwxr-xr-xDemo/classes/Rev.py95
-rwxr-xr-xDemo/classes/bitvec.py322
-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
-rw-r--r--Demo/curses/ncurses.py273
-rw-r--r--Demo/curses/rain.py94
-rwxr-xr-xDemo/curses/repeat.py80
-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.c89
-rw-r--r--Demo/embed/importexc.c23
-rw-r--r--Demo/embed/loop.c33
-rw-r--r--Demo/md5test/README10
-rwxr-xr-xDemo/md5test/foo1
-rwxr-xr-xDemo/md5test/md5driver.py122
-rw-r--r--Demo/newmetaclasses/Enum.py177
-rw-r--r--Demo/parser/FILES6
-rw-r--r--Demo/parser/README31
-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/texipre.dat100
-rwxr-xr-xDemo/pdist/FSProxy.py322
-rwxr-xr-xDemo/pdist/RCSProxy.py198
-rw-r--r--Demo/pdist/README121
-rwxr-xr-xDemo/pdist/client.py156
-rwxr-xr-xDemo/pdist/cmdfw.py142
-rwxr-xr-xDemo/pdist/cmptree.py213
-rwxr-xr-xDemo/pdist/cvslib.py359
-rwxr-xr-xDemo/pdist/cvslock.py279
-rwxr-xr-xDemo/pdist/mac.py24
-rwxr-xr-xDemo/pdist/makechangelog.py109
-rwxr-xr-xDemo/pdist/rcsbump33
-rwxr-xr-xDemo/pdist/rcsclient.py71
-rwxr-xr-xDemo/pdist/rcslib.py334
-rwxr-xr-xDemo/pdist/rcvs8
-rwxr-xr-xDemo/pdist/rcvs.py476
-rwxr-xr-xDemo/pdist/rrcs8
-rwxr-xr-xDemo/pdist/rrcs.py158
-rwxr-xr-xDemo/pdist/security.py33
-rwxr-xr-xDemo/pdist/server.py143
-rwxr-xr-xDemo/pdist/sumtree.py27
-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.py890
-rwxr-xr-xDemo/rpc/test24
-rw-r--r--Demo/rpc/xdr.py200
-rw-r--r--Demo/scripts/README22
-rwxr-xr-xDemo/scripts/eqfix.py198
-rwxr-xr-xDemo/scripts/fact.py49
-rwxr-xr-xDemo/scripts/from.py35
-rwxr-xr-xDemo/scripts/lpwatch.py102
-rwxr-xr-xDemo/scripts/makedir.py21
-rwxr-xr-xDemo/scripts/mboxconvert.py124
-rwxr-xr-xDemo/scripts/morse.py128
-rwxr-xr-xDemo/scripts/newslist.doc59
-rwxr-xr-xDemo/scripts/newslist.py361
-rwxr-xr-xDemo/scripts/pi.py33
-rwxr-xr-xDemo/scripts/pp.py125
-rwxr-xr-xDemo/scripts/primes.py27
-rwxr-xr-xDemo/scripts/script.py42
-rw-r--r--Demo/scripts/toaiff.py107
-rwxr-xr-xDemo/scripts/unbirthday.py106
-rwxr-xr-xDemo/scripts/update.py92
-rwxr-xr-xDemo/scripts/wh.py2
-rw-r--r--Demo/sockets/README14
-rwxr-xr-xDemo/sockets/broadcast.py15
-rwxr-xr-xDemo/sockets/echosvr.py31
-rwxr-xr-xDemo/sockets/finger.py58
-rwxr-xr-xDemo/sockets/ftp.py152
-rwxr-xr-xDemo/sockets/gopher.py352
-rwxr-xr-xDemo/sockets/radio.py14
-rwxr-xr-xDemo/sockets/rpython.py35
-rwxr-xr-xDemo/sockets/telnet.py109
-rwxr-xr-xDemo/sockets/throughput.py93
-rwxr-xr-xDemo/sockets/udpecho.py64
-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.py154
-rw-r--r--Demo/threads/squasher.py105
-rw-r--r--Demo/threads/sync.py599
-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
-rwxr-xr-xDemo/tix/samples/Balloon.py68
-rwxr-xr-xDemo/tix/samples/BtnBox.py44
-rwxr-xr-xDemo/tix/samples/CmpImg.py196
-rwxr-xr-xDemo/tix/samples/ComboBox.py102
-rwxr-xr-xDemo/tix/samples/Control.py122
-rwxr-xr-xDemo/tix/samples/DirList.py131
-rwxr-xr-xDemo/tix/samples/DirTree.py117
-rwxr-xr-xDemo/tix/samples/NoteBook.py119
-rwxr-xr-xDemo/tix/samples/OptMenu.py68
-rwxr-xr-xDemo/tix/samples/PanedWin.py98
-rwxr-xr-xDemo/tix/samples/PopMenu.py57
-rwxr-xr-xDemo/tix/samples/SHList1.py131
-rwxr-xr-xDemo/tix/samples/SHList2.py168
-rwxr-xr-xDemo/tix/samples/Tree.py80
-rw-r--r--Demo/tix/tixwidgets.py1002
-rw-r--r--Demo/tkinter/README11
-rw-r--r--Demo/tkinter/guido/attr_dialog.py460
-rw-r--r--Demo/tkinter/guido/brownian.py50
-rw-r--r--Demo/tkinter/guido/brownian2.py55
-rw-r--r--Demo/tkinter/guido/canvasevents.py264
-rwxr-xr-xDemo/tkinter/guido/dialog.py108
-rwxr-xr-xDemo/tkinter/guido/electrons.py91
-rwxr-xr-xDemo/tkinter/guido/hello.py17
-rwxr-xr-xDemo/tkinter/guido/imagedraw.py23
-rwxr-xr-xDemo/tkinter/guido/imageview.py12
-rwxr-xr-xDemo/tkinter/guido/kill.py98
-rwxr-xr-xDemo/tkinter/guido/listtree.py34
-rw-r--r--Demo/tkinter/guido/manpage.py215
-rwxr-xr-xDemo/tkinter/guido/mbox.py286
-rwxr-xr-xDemo/tkinter/guido/mimeviewer.py159
-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
-rw-r--r--Demo/tkinter/guido/shell_window.py146
-rwxr-xr-xDemo/tkinter/guido/solitaire.py626
-rwxr-xr-xDemo/tkinter/guido/svkill.py124
-rw-r--r--Demo/tkinter/guido/switch.py55
-rwxr-xr-xDemo/tkinter/guido/tkman.py267
-rwxr-xr-xDemo/tkinter/guido/wish.py34
-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.py43
-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.py45
-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.py52
-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.py268
-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/tdemo_I_dontlike_tiltdemo.py58
-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/ACKS.txt2
-rw-r--r--Doc/Makefile22
-rw-r--r--Doc/README.txt7
-rw-r--r--Doc/c-api/abstract.rst2
-rw-r--r--Doc/c-api/allocation.rst26
-rw-r--r--Doc/c-api/arg.rst232
-rw-r--r--Doc/c-api/bool.rst14
-rw-r--r--Doc/c-api/buffer.rst116
-rw-r--r--Doc/c-api/bytearray.rst32
-rw-r--r--Doc/c-api/bytes.rst50
-rw-r--r--Doc/c-api/capsule.rst68
-rw-r--r--Doc/c-api/cell.rst16
-rw-r--r--Doc/c-api/cobject.rst59
-rw-r--r--Doc/c-api/code.rst50
-rw-r--r--Doc/c-api/codec.rst34
-rw-r--r--Doc/c-api/complex.rst66
-rw-r--r--Doc/c-api/concrete.rst4
-rw-r--r--Doc/c-api/conversion.rst69
-rw-r--r--Doc/c-api/datetime.rst96
-rw-r--r--Doc/c-api/descriptor.rst16
-rw-r--r--Doc/c-api/dict.rst74
-rw-r--r--Doc/c-api/exceptions.rst414
-rw-r--r--Doc/c-api/file.rst22
-rw-r--r--Doc/c-api/float.rst48
-rw-r--r--Doc/c-api/function.rst30
-rw-r--r--Doc/c-api/gcsupport.rst56
-rw-r--r--Doc/c-api/gen.rst12
-rw-r--r--Doc/c-api/import.rst101
-rw-r--r--Doc/c-api/init.rst336
-rw-r--r--Doc/c-api/intro.rst110
-rw-r--r--Doc/c-api/iter.rst4
-rw-r--r--Doc/c-api/iterator.rst20
-rw-r--r--Doc/c-api/list.rst52
-rw-r--r--Doc/c-api/long.rst142
-rw-r--r--Doc/c-api/mapping.rst22
-rw-r--r--Doc/c-api/marshal.rst34
-rw-r--r--Doc/c-api/memory.rst48
-rw-r--r--Doc/c-api/memoryview.rst12
-rw-r--r--Doc/c-api/method.rst44
-rw-r--r--Doc/c-api/module.rst95
-rw-r--r--Doc/c-api/none.rst10
-rw-r--r--Doc/c-api/number.rst92
-rw-r--r--Doc/c-api/objbuffer.rst14
-rw-r--r--Doc/c-api/object.rst119
-rw-r--r--Doc/c-api/refcounting.rst32
-rw-r--r--Doc/c-api/reflection.rst19
-rw-r--r--Doc/c-api/sequence.rst60
-rw-r--r--Doc/c-api/set.rst62
-rw-r--r--Doc/c-api/slice.rst20
-rw-r--r--Doc/c-api/structures.rst92
-rw-r--r--Doc/c-api/sys.rst93
-rw-r--r--Doc/c-api/tuple.rst38
-rw-r--r--Doc/c-api/type.rst32
-rw-r--r--Doc/c-api/typeobj.rst322
-rw-r--r--Doc/c-api/unicode.rst412
-rw-r--r--Doc/c-api/veryhigh.rst181
-rw-r--r--Doc/c-api/weakref.rst18
-rw-r--r--Doc/conf.py8
-rw-r--r--Doc/copyright.rst2
-rw-r--r--Doc/data/refcounts.dat26
-rw-r--r--Doc/distutils/apiref.rst172
-rw-r--r--Doc/distutils/builtdist.rst10
-rw-r--r--Doc/distutils/commandref.rst4
-rw-r--r--Doc/distutils/examples.rst6
-rw-r--r--Doc/distutils/extending.rst4
-rw-r--r--Doc/distutils/sourcedist.rst6
-rw-r--r--Doc/distutils/uploading.rst7
-rw-r--r--Doc/documenting/building.rst10
-rw-r--r--Doc/documenting/markup.rst73
-rw-r--r--Doc/documenting/style.rst73
-rw-r--r--Doc/extending/embedding.rst25
-rw-r--r--Doc/extending/extending.rst288
-rw-r--r--Doc/extending/newtypes.rst108
-rw-r--r--Doc/extending/windows.rst6
-rw-r--r--Doc/faq/design.rst15
-rw-r--r--Doc/faq/extending.rst76
-rw-r--r--Doc/faq/gui.rst63
-rw-r--r--Doc/faq/installed.rst10
-rw-r--r--Doc/faq/library.rst73
-rw-r--r--Doc/faq/programming.rst23
-rw-r--r--Doc/faq/windows.rst9
-rw-r--r--Doc/glossary.rst43
-rw-r--r--Doc/howto/cporting.rst16
-rw-r--r--Doc/howto/descriptor.rst6
-rw-r--r--Doc/howto/doanddont.rst290
-rw-r--r--Doc/howto/index.rst4
-rw-r--r--Doc/howto/logging-cookbook.rst1039
-rw-r--r--Doc/howto/logging.rst1026
-rw-r--r--Doc/howto/pyporting.rst703
-rw-r--r--Doc/howto/sorting.rst12
-rw-r--r--Doc/howto/unicode.rst102
-rw-r--r--Doc/howto/webservers.rst2
-rw-r--r--Doc/includes/dbpickle.py3
-rw-r--r--Doc/includes/email-alternative.py2
-rw-r--r--Doc/includes/email-dir.py2
-rw-r--r--Doc/includes/email-headers.py17
-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.py6
-rw-r--r--Doc/includes/mp_benchmarks.py13
-rw-r--r--Doc/includes/mp_pool.py8
-rw-r--r--Doc/includes/mp_synchronize.py10
-rw-r--r--Doc/includes/mp_webserver.py4
-rw-r--r--Doc/includes/sqlite3/adapter_datetime.py3
-rw-r--r--Doc/includes/sqlite3/load_extension.py26
-rw-r--r--Doc/includes/turtle-star.py10
-rw-r--r--Doc/includes/tzinfo-examples.py2
-rw-r--r--Doc/install/index.rst3
-rw-r--r--Doc/library/2to3.rst23
-rw-r--r--Doc/library/__future__.rst3
-rw-r--r--Doc/library/_dummy_thread.rst3
-rw-r--r--Doc/library/_thread.rst48
-rw-r--r--Doc/library/abc.rst36
-rw-r--r--Doc/library/aifc.rst4
-rw-r--r--Doc/library/allos.rst3
-rw-r--r--Doc/library/argparse.rst1816
-rw-r--r--Doc/library/array.rst36
-rw-r--r--Doc/library/ast.rst10
-rw-r--r--Doc/library/asynchat.rst5
-rw-r--r--Doc/library/asyncore.rst57
-rw-r--r--Doc/library/atexit.rst1
-rw-r--r--Doc/library/base64.rst12
-rw-r--r--Doc/library/bdb.rst25
-rw-r--r--Doc/library/binascii.rst15
-rw-r--r--Doc/library/bisect.rst4
-rw-r--r--Doc/library/builtins.rst2
-rw-r--r--Doc/library/calendar.rst6
-rw-r--r--Doc/library/cgi.rst26
-rw-r--r--Doc/library/cmath.rst15
-rw-r--r--Doc/library/cmd.rst162
-rw-r--r--Doc/library/codecs.rst69
-rw-r--r--Doc/library/collections.rst105
-rw-r--r--Doc/library/colorsys.rst3
-rw-r--r--Doc/library/compileall.rst69
-rw-r--r--Doc/library/concurrent.futures.rst371
-rw-r--r--Doc/library/configparser.rst1359
-rw-r--r--Doc/library/contextlib.rst136
-rw-r--r--Doc/library/csv.rst19
-rw-r--r--Doc/library/ctypes.rst207
-rw-r--r--Doc/library/curses.rst2
-rw-r--r--Doc/library/datetime.rst209
-rw-r--r--Doc/library/dbm.rst9
-rw-r--r--Doc/library/decimal.rst110
-rw-r--r--Doc/library/difflib.rst61
-rw-r--r--Doc/library/dis.rst61
-rw-r--r--Doc/library/doctest.rst54
-rw-r--r--Doc/library/dummy_threading.rst3
-rw-r--r--Doc/library/email-examples.rst6
-rw-r--r--Doc/library/email.generator.rst99
-rw-r--r--Doc/library/email.header.rst35
-rw-r--r--Doc/library/email.message.rst24
-rw-r--r--Doc/library/email.parser.rst69
-rw-r--r--Doc/library/email.rst40
-rw-r--r--Doc/library/email.util.rst10
-rw-r--r--Doc/library/exceptions.rst26
-rw-r--r--Doc/library/fcntl.rst10
-rw-r--r--Doc/library/filecmp.rst3
-rw-r--r--Doc/library/fileformats.rst2
-rw-r--r--Doc/library/fileinput.rst38
-rw-r--r--Doc/library/fnmatch.rst7
-rw-r--r--Doc/library/fractions.rst52
-rw-r--r--Doc/library/ftplib.rst92
-rw-r--r--Doc/library/functional.rst15
-rw-r--r--Doc/library/functions.rst175
-rw-r--r--Doc/library/functools.rst142
-rw-r--r--Doc/library/gc.rst20
-rw-r--r--Doc/library/getopt.rst36
-rw-r--r--Doc/library/gettext.rst3
-rw-r--r--Doc/library/glob.rst4
-rw-r--r--Doc/library/gzip.rst57
-rw-r--r--Doc/library/hashlib.rst34
-rw-r--r--Doc/library/heapq.rst4
-rw-r--r--Doc/library/hmac.rst3
-rw-r--r--Doc/library/html.entities.rst3
-rw-r--r--Doc/library/html.parser.rst19
-rw-r--r--Doc/library/html.rst21
-rw-r--r--Doc/library/http.client.rst95
-rw-r--r--Doc/library/http.cookiejar.rst3
-rw-r--r--Doc/library/http.cookies.rst3
-rw-r--r--Doc/library/http.server.rst39
-rw-r--r--Doc/library/imaplib.rst31
-rw-r--r--Doc/library/imghdr.rst3
-rw-r--r--Doc/library/imp.rst46
-rw-r--r--Doc/library/importlib.rst295
-rw-r--r--Doc/library/index.rst2
-rw-r--r--Doc/library/inspect.rst113
-rw-r--r--Doc/library/io.rst84
-rw-r--r--Doc/library/itertools.rst27
-rw-r--r--Doc/library/json.rst12
-rw-r--r--Doc/library/keyword.rst4
-rw-r--r--Doc/library/language.rst1
-rw-r--r--Doc/library/linecache.rst3
-rw-r--r--Doc/library/locale.rst4
-rw-r--r--Doc/library/logging.config.rst680
-rw-r--r--Doc/library/logging.handlers.rst850
-rw-r--r--Doc/library/logging.rst3158
-rw-r--r--Doc/library/mailbox.rst50
-rw-r--r--Doc/library/mailcap.rst3
-rw-r--r--Doc/library/markup.rst1
-rw-r--r--Doc/library/math.rst79
-rw-r--r--Doc/library/mimetypes.rst20
-rw-r--r--Doc/library/mmap.rst20
-rw-r--r--Doc/library/modulefinder.rst3
-rw-r--r--Doc/library/msilib.rst38
-rw-r--r--Doc/library/msvcrt.rst20
-rw-r--r--Doc/library/multiprocessing.rst62
-rw-r--r--Doc/library/netrc.rst3
-rw-r--r--Doc/library/nntplib.rst556
-rw-r--r--Doc/library/numeric.rst3
-rw-r--r--Doc/library/objects.rst27
-rw-r--r--Doc/library/operator.rst198
-rw-r--r--Doc/library/optparse.rst14
-rw-r--r--Doc/library/os.path.rst22
-rw-r--r--Doc/library/os.rst304
-rw-r--r--Doc/library/ossaudiodev.rst12
-rw-r--r--Doc/library/parser.rst17
-rw-r--r--Doc/library/pdb.rst391
-rw-r--r--Doc/library/persistence.rst1
-rw-r--r--Doc/library/pickle.rst12
-rw-r--r--Doc/library/pickletools.rst88
-rw-r--r--Doc/library/pipes.rst4
-rw-r--r--Doc/library/pkgutil.rst15
-rw-r--r--Doc/library/platform.rst9
-rw-r--r--Doc/library/plistlib.rst4
-rw-r--r--Doc/library/poplib.rst18
-rw-r--r--Doc/library/posix.rst25
-rw-r--r--Doc/library/pprint.rst18
-rw-r--r--Doc/library/profile.rst33
-rw-r--r--Doc/library/pty.rst48
-rw-r--r--Doc/library/pwd.rst1
-rw-r--r--Doc/library/py_compile.rst44
-rw-r--r--Doc/library/pyclbr.rst8
-rw-r--r--Doc/library/pydoc.rst24
-rw-r--r--Doc/library/pyexpat.rst94
-rw-r--r--Doc/library/python.rst3
-rw-r--r--Doc/library/queue.rst33
-rw-r--r--Doc/library/quopri.rst22
-rw-r--r--Doc/library/random.rst124
-rw-r--r--Doc/library/re.rst507
-rw-r--r--Doc/library/readline.rst3
-rw-r--r--Doc/library/reprlib.rst27
-rw-r--r--Doc/library/resource.rst16
-rw-r--r--Doc/library/rlcompleter.rst4
-rw-r--r--Doc/library/runpy.rst146
-rw-r--r--Doc/library/sched.rst5
-rw-r--r--Doc/library/select.rst50
-rw-r--r--Doc/library/shelve.rst23
-rw-r--r--Doc/library/shlex.rst17
-rw-r--r--Doc/library/shutil.rst218
-rw-r--r--Doc/library/signal.rst28
-rw-r--r--Doc/library/site.rst30
-rw-r--r--Doc/library/smtpd.rst101
-rw-r--r--Doc/library/smtplib.rst59
-rw-r--r--Doc/library/sndhdr.rst5
-rw-r--r--Doc/library/socket.rst146
-rw-r--r--Doc/library/socketserver.rst5
-rw-r--r--Doc/library/someos.rst1
-rw-r--r--Doc/library/sqlite3.rst41
-rw-r--r--Doc/library/ssl.rst606
-rw-r--r--Doc/library/stat.rst9
-rw-r--r--Doc/library/stdtypes.rst348
-rw-r--r--Doc/library/string.rst38
-rw-r--r--Doc/library/struct.rst109
-rw-r--r--Doc/library/subprocess.rst109
-rw-r--r--Doc/library/sunau.rst3
-rw-r--r--Doc/library/symbol.rst3
-rw-r--r--Doc/library/sys.rst210
-rw-r--r--Doc/library/sysconfig.rst259
-rw-r--r--Doc/library/syslog.rst82
-rw-r--r--Doc/library/tabnanny.rst4
-rw-r--r--Doc/library/tarfile.rst99
-rw-r--r--Doc/library/telnetlib.rst4
-rw-r--r--Doc/library/tempfile.rst57
-rw-r--r--Doc/library/test.rst184
-rw-r--r--Doc/library/textwrap.rst4
-rw-r--r--Doc/library/threading.rst209
-rw-r--r--Doc/library/time.rst81
-rw-r--r--Doc/library/timeit.rst4
-rw-r--r--Doc/library/tkinter.rst8
-rw-r--r--Doc/library/tkinter.tix.rst6
-rw-r--r--Doc/library/token.rst3
-rw-r--r--Doc/library/tokenize.rst23
-rw-r--r--Doc/library/trace.rst4
-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.rst41
-rw-r--r--Doc/library/types.rst3
-rw-r--r--Doc/library/unicodedata.rst17
-rw-r--r--Doc/library/unittest.rst791
-rw-r--r--Doc/library/urllib.parse.rst267
-rw-r--r--Doc/library/urllib.request.rst383
-rw-r--r--Doc/library/uu.rst4
-rw-r--r--Doc/library/warnings.rst80
-rw-r--r--Doc/library/wave.rst8
-rw-r--r--Doc/library/weakref.rst8
-rw-r--r--Doc/library/webbrowser.rst3
-rw-r--r--Doc/library/winreg.rst68
-rw-r--r--Doc/library/winsound.rst4
-rw-r--r--Doc/library/wsgiref.rst84
-rw-r--r--Doc/library/xdrlib.rst4
-rw-r--r--Doc/library/xml.dom.minidom.rst65
-rw-r--r--Doc/library/xml.dom.pulldom.rst3
-rw-r--r--Doc/library/xml.dom.rst38
-rw-r--r--Doc/library/xml.etree.elementtree.rst520
-rw-r--r--Doc/library/xml.etree.rst23
-rw-r--r--Doc/library/xml.sax.utils.rst8
-rw-r--r--Doc/library/xmlrpc.client.rst4
-rw-r--r--Doc/library/xmlrpc.server.rst3
-rw-r--r--Doc/library/zipfile.rst135
-rw-r--r--Doc/library/zipimport.rst6
-rw-r--r--Doc/library/zlib.rst10
-rw-r--r--Doc/license.rst9
-rw-r--r--Doc/make.bat2
-rw-r--r--Doc/reference/compound_stmts.rst8
-rw-r--r--Doc/reference/datamodel.rst5
-rw-r--r--Doc/reference/executionmodel.rst4
-rw-r--r--Doc/reference/expressions.rst16
-rw-r--r--Doc/reference/simple_stmts.rst26
-rwxr-xr-xDoc/tools/rstlint.py2
-rw-r--r--Doc/tools/sphinxext/download.html4
-rw-r--r--Doc/tools/sphinxext/indexcontent.html2
-rw-r--r--Doc/tools/sphinxext/indexsidebar.html2
-rw-r--r--Doc/tools/sphinxext/patchlevel.py2
-rw-r--r--Doc/tools/sphinxext/pyspecific.py108
-rw-r--r--Doc/tools/sphinxext/static/basic.css10
-rw-r--r--Doc/tools/sphinxext/susp-ignored.csv252
-rw-r--r--Doc/tools/sphinxext/suspicious.py52
-rw-r--r--Doc/tutorial/classes.rst9
-rw-r--r--Doc/tutorial/floatingpoint.rst11
-rw-r--r--Doc/tutorial/inputoutput.rst12
-rw-r--r--Doc/tutorial/interpreter.rst14
-rw-r--r--Doc/tutorial/introduction.rst6
-rw-r--r--Doc/tutorial/stdlib.rst2
-rw-r--r--Doc/using/cmdline.rst49
-rw-r--r--Doc/whatsnew/2.0.rst10
-rw-r--r--Doc/whatsnew/2.1.rst10
-rw-r--r--Doc/whatsnew/2.2.rst58
-rw-r--r--Doc/whatsnew/2.3.rst36
-rw-r--r--Doc/whatsnew/2.4.rst42
-rw-r--r--Doc/whatsnew/2.5.rst106
-rw-r--r--Doc/whatsnew/2.6.rst77
-rw-r--r--Doc/whatsnew/2.7.rst2481
-rw-r--r--Doc/whatsnew/3.0.rst45
-rw-r--r--Doc/whatsnew/3.1.rst34
-rw-r--r--Doc/whatsnew/3.2.rst2704
-rw-r--r--Doc/whatsnew/index.rst2
-rw-r--r--Grammar/Grammar39
-rw-r--r--Include/Python.h20
-rw-r--r--Include/abstract.h13
-rw-r--r--Include/ast.h7
-rw-r--r--Include/bytearrayobject.h4
-rw-r--r--Include/bytes_methods.h37
-rw-r--r--Include/bytesobject.h13
-rw-r--r--Include/cellobject.h3
-rw-r--r--Include/ceval.h21
-rw-r--r--Include/classobject.h2
-rw-r--r--Include/cobject.h61
-rw-r--r--Include/code.h30
-rw-r--r--Include/codecs.h2
-rw-r--r--Include/compile.h12
-rw-r--r--Include/complexobject.h14
-rw-r--r--Include/datetime.h9
-rw-r--r--Include/descrobject.h19
-rw-r--r--Include/dictobject.h20
-rw-r--r--Include/dtoa.h2
-rw-r--r--Include/dynamic_annotations.h499
-rw-r--r--Include/eval.h6
-rw-r--r--Include/fileobject.h5
-rw-r--r--Include/fileutils.h58
-rw-r--r--Include/floatobject.h12
-rw-r--r--Include/frameobject.h12
-rw-r--r--Include/funcobject.h3
-rw-r--r--Include/genobject.h2
-rw-r--r--Include/graminit.h126
-rw-r--r--Include/import.h73
-rw-r--r--Include/listobject.h6
-rw-r--r--Include/longintrepr.h6
-rw-r--r--Include/longobject.h50
-rw-r--r--Include/marshal.h2
-rw-r--r--Include/memoryobject.h8
-rw-r--r--Include/methodobject.h4
-rw-r--r--Include/modsupport.h16
-rw-r--r--Include/moduleobject.h14
-rw-r--r--Include/object.h67
-rw-r--r--Include/objimpl.h22
-rw-r--r--Include/opcode.h9
-rw-r--r--Include/parsetok.h34
-rw-r--r--Include/patchlevel.h6
-rw-r--r--Include/pyarena.h2
-rw-r--r--Include/pyatomic.h181
-rw-r--r--Include/pycapsule.h4
-rw-r--r--Include/pyctype.h2
-rw-r--r--Include/pydebug.h4
-rw-r--r--Include/pyerrors.h97
-rw-r--r--Include/pygetopt.h2
-rw-r--r--Include/pymacconfig.h6
-rw-r--r--Include/pymath.h26
-rw-r--r--Include/pymem.h10
-rw-r--r--Include/pyport.h68
-rw-r--r--Include/pystate.h31
-rw-r--r--Include/pystrtod.h5
-rw-r--r--Include/pythonrun.h116
-rw-r--r--Include/pythread.h59
-rw-r--r--Include/pytime.h48
-rw-r--r--Include/setobject.h22
-rw-r--r--Include/sliceobject.h9
-rw-r--r--Include/structseq.h20
-rw-r--r--Include/symtable.h23
-rw-r--r--Include/sysmodule.h13
-rw-r--r--Include/timefuncs.h2
-rw-r--r--Include/token.h3
-rw-r--r--Include/traceback.h5
-rw-r--r--Include/tupleobject.h8
-rw-r--r--Include/typeslots.h76
-rw-r--r--Include/ucnhash.h3
-rw-r--r--Include/unicodeobject.h319
-rw-r--r--Include/warnings.h23
-rw-r--r--Include/weakrefobject.h6
-rw-r--r--LICENSE8
-rw-r--r--Lib/_dummy_thread.py16
-rw-r--r--Lib/_markupbase.py8
-rw-r--r--Lib/_pyio.py217
-rw-r--r--Lib/_strptime.py50
-rw-r--r--Lib/_threading_local.py158
-rw-r--r--Lib/abc.py40
-rw-r--r--Lib/argparse.py2366
-rw-r--r--Lib/ast.py29
-rw-r--r--Lib/asyncore.py27
-rwxr-xr-xLib/base64.py17
-rw-r--r--Lib/bdb.py181
-rw-r--r--Lib/binhex.py42
-rwxr-xr-xLib/cProfile.py9
-rwxr-xr-xLib/cgi.py263
-rw-r--r--Lib/cmd.py20
-rw-r--r--Lib/code.py5
-rw-r--r--Lib/codecs.py23
-rw-r--r--Lib/collections.py437
-rw-r--r--Lib/compileall.py278
-rw-r--r--Lib/concurrent/__init__.py1
-rw-r--r--Lib/concurrent/futures/__init__.py18
-rw-r--r--Lib/concurrent/futures/_base.py567
-rw-r--r--Lib/concurrent/futures/process.py360
-rw-r--r--Lib/concurrent/futures/thread.py130
-rw-r--r--Lib/configparser.py1289
-rw-r--r--Lib/contextlib.py86
-rw-r--r--Lib/copy.py4
-rw-r--r--Lib/csv.py16
-rw-r--r--Lib/ctypes/__init__.py57
-rw-r--r--Lib/ctypes/test/test_arrays.py4
-rw-r--r--Lib/ctypes/test/test_bitfields.py4
-rw-r--r--Lib/ctypes/test/test_buffers.py14
-rw-r--r--Lib/ctypes/test/test_bytes.py19
-rw-r--r--Lib/ctypes/test/test_callbacks.py34
-rw-r--r--Lib/ctypes/test/test_cast.py8
-rw-r--r--Lib/ctypes/test/test_cfuncs.py2
-rw-r--r--Lib/ctypes/test/test_errno.py75
-rw-r--r--Lib/ctypes/test/test_internals.py18
-rw-r--r--Lib/ctypes/test/test_keeprefs.py8
-rw-r--r--Lib/ctypes/test/test_libc.py2
-rw-r--r--Lib/ctypes/test/test_loading.py2
-rw-r--r--Lib/ctypes/test/test_objects.py4
-rw-r--r--Lib/ctypes/test/test_parameters.py10
-rw-r--r--Lib/ctypes/test/test_prototypes.py2
-rw-r--r--Lib/ctypes/test/test_python_api.py4
-rw-r--r--Lib/ctypes/test/test_random_things.py4
-rw-r--r--Lib/ctypes/test/test_repr.py4
-rw-r--r--Lib/ctypes/test/test_returnfuncptrs.py8
-rw-r--r--Lib/ctypes/test/test_sizes.py9
-rw-r--r--Lib/ctypes/test/test_stringptr.py6
-rw-r--r--Lib/ctypes/test/test_strings.py17
-rw-r--r--Lib/ctypes/test/test_structures.py24
-rw-r--r--Lib/ctypes/test/test_unicode.py103
-rw-r--r--Lib/ctypes/util.py31
-rw-r--r--Lib/ctypes/wintypes.py169
-rw-r--r--Lib/datetime.py2112
-rw-r--r--Lib/dbm/__init__.py23
-rw-r--r--Lib/dbm/dumb.py4
-rw-r--r--Lib/decimal.py620
-rw-r--r--Lib/difflib.py96
-rw-r--r--Lib/dis.py108
-rw-r--r--Lib/distutils/__init__.py2
-rw-r--r--Lib/distutils/command/bdist_msi.py1
-rw-r--r--Lib/distutils/command/build_ext.py6
-rw-r--r--Lib/distutils/command/install.py27
-rw-r--r--Lib/distutils/file_util.py9
-rw-r--r--Lib/distutils/sysconfig.py103
-rw-r--r--Lib/distutils/tests/test_bdist_msi.py25
-rw-r--r--Lib/distutils/tests/test_build.py55
-rw-r--r--Lib/distutils/tests/test_build_ext.py19
-rw-r--r--[-rwxr-xr-x]Lib/distutils/tests/test_clean.py0
-rw-r--r--Lib/distutils/tests/test_dep_util.py81
-rw-r--r--Lib/distutils/tests/test_dist.py1
-rw-r--r--Lib/distutils/tests/test_sysconfig.py11
-rw-r--r--Lib/distutils/text_file.py5
-rw-r--r--Lib/distutils/util.py9
-rw-r--r--Lib/doctest.py39
-rw-r--r--Lib/email/__init__.py19
-rw-r--r--Lib/email/_parseaddr.py20
-rw-r--r--Lib/email/base64mime.py8
-rw-r--r--Lib/email/charset.py33
-rw-r--r--Lib/email/encoders.py9
-rw-r--r--Lib/email/feedparser.py11
-rw-r--r--Lib/email/generator.py215
-rw-r--r--Lib/email/header.py324
-rw-r--r--Lib/email/message.py115
-rw-r--r--Lib/email/parser.py47
-rw-r--r--Lib/email/quoprimime.py6
-rw-r--r--Lib/email/test/data/msg_10.txt7
-rw-r--r--Lib/email/test/data/msg_26.txt3
-rw-r--r--Lib/email/test/test_email.py786
-rw-r--r--Lib/email/test/test_email_codecs.py46
-rw-r--r--Lib/email/test/test_email_torture.py6
-rw-r--r--Lib/email/utils.py11
-rw-r--r--Lib/encodings/__init__.py2
-rw-r--r--Lib/encodings/aliases.py8
-rw-r--r--Lib/encodings/base64_codec.py55
-rw-r--r--Lib/encodings/bz2_codec.py77
-rw-r--r--Lib/encodings/cp720.py309
-rw-r--r--Lib/encodings/cp858.py698
-rw-r--r--Lib/encodings/hex_codec.py55
-rw-r--r--Lib/encodings/punycode.py1
-rw-r--r--Lib/encodings/quopri_codec.py56
-rwxr-xr-xLib/encodings/rot_13.py113
-rw-r--r--Lib/encodings/uu_codec.py99
-rw-r--r--Lib/encodings/zlib_codec.py77
-rw-r--r--Lib/fileinput.py6
-rw-r--r--Lib/fnmatch.py47
-rw-r--r--Lib/fractions.py102
-rw-r--r--Lib/ftplib.py314
-rw-r--r--Lib/functools.py158
-rw-r--r--Lib/genericpath.py2
-rw-r--r--Lib/getopt.py1
-rw-r--r--Lib/gettext.py50
-rw-r--r--Lib/gzip.py245
-rw-r--r--Lib/hashlib.py81
-rw-r--r--Lib/heapq.py13
-rw-r--r--Lib/hmac.py15
-rw-r--r--Lib/html/__init__.py21
-rw-r--r--Lib/html/parser.py101
-rw-r--r--Lib/http/client.py217
-rw-r--r--Lib/http/cookiejar.py20
-rw-r--r--Lib/http/cookies.py244
-rw-r--r--Lib/http/server.py92
-rw-r--r--Lib/idlelib/Bindings.py8
-rw-r--r--Lib/idlelib/EditorWindow.py25
-rw-r--r--Lib/idlelib/NEWS.txt2
-rw-r--r--Lib/idlelib/PyShell.py33
-rw-r--r--Lib/idlelib/idlever.py2
-rw-r--r--Lib/idlelib/macosxSupport.py96
-rw-r--r--Lib/idlelib/run.py7
-rw-r--r--Lib/imaplib.py80
-rw-r--r--Lib/importlib/__init__.py2
-rw-r--r--Lib/importlib/_bootstrap.py594
-rw-r--r--Lib/importlib/abc.py246
-rw-r--r--Lib/importlib/test/__init__.py31
-rw-r--r--Lib/importlib/test/__main__.py29
-rw-r--r--Lib/importlib/test/benchmark.py184
-rw-r--r--Lib/importlib/test/builtin/test_loader.py9
-rw-r--r--Lib/importlib/test/extension/test_case_sensitivity.py3
-rw-r--r--Lib/importlib/test/extension/test_finder.py3
-rw-r--r--Lib/importlib/test/extension/test_loader.py5
-rw-r--r--Lib/importlib/test/extension/test_path_hook.py2
-rw-r--r--Lib/importlib/test/frozen/test_loader.py7
-rw-r--r--Lib/importlib/test/import_/test___package__.py29
-rw-r--r--Lib/importlib/test/import_/test_api.py22
-rw-r--r--Lib/importlib/test/import_/test_fromlist.py11
-rw-r--r--Lib/importlib/test/import_/test_packages.py10
-rw-r--r--Lib/importlib/test/import_/test_path.py35
-rw-r--r--Lib/importlib/test/import_/test_relative_imports.py13
-rw-r--r--Lib/importlib/test/import_/util.py15
-rw-r--r--Lib/importlib/test/regrtest.py35
-rw-r--r--Lib/importlib/test/source/test_abc_loader.py556
-rw-r--r--Lib/importlib/test/source/test_case_sensitivity.py12
-rw-r--r--Lib/importlib/test/source/test_file_loader.py300
-rw-r--r--Lib/importlib/test/source/test_finder.py39
-rw-r--r--Lib/importlib/test/source/test_path_hook.py7
-rw-r--r--Lib/importlib/test/source/test_source_encoding.py13
-rw-r--r--Lib/importlib/test/source/util.py19
-rw-r--r--Lib/importlib/test/test_abc.py13
-rw-r--r--Lib/importlib/test/test_api.py5
-rw-r--r--Lib/importlib/test/test_util.py4
-rw-r--r--Lib/importlib/test/util.py27
-rw-r--r--Lib/importlib/util.py1
-rw-r--r--Lib/inspect.py227
-rw-r--r--Lib/json/decoder.py8
-rw-r--r--Lib/json/encoder.py11
-rw-r--r--Lib/json/scanner.py9
-rwxr-xr-xLib/keyword.py24
-rwxr-xr-xLib/lib2to3/pgen2/token.py2
-rwxr-xr-xLib/lib2to3/tests/pytree_idempotency.py2
-rw-r--r--Lib/linecache.py4
-rw-r--r--Lib/locale.py105
-rw-r--r--Lib/logging/__init__.py613
-rw-r--r--Lib/logging/config.py704
-rw-r--r--Lib/logging/handlers.py293
-rw-r--r--Lib/macpath.py5
-rw-r--r--Lib/mailbox.py394
-rw-r--r--Lib/mimetypes.py54
-rw-r--r--Lib/modulefinder.py22
-rw-r--r--Lib/msilib/__init__.py1
-rw-r--r--Lib/multiprocessing/__init__.py4
-rw-r--r--Lib/multiprocessing/connection.py29
-rw-r--r--Lib/multiprocessing/forking.py10
-rw-r--r--Lib/multiprocessing/managers.py2
-rw-r--r--Lib/multiprocessing/pool.py153
-rw-r--r--Lib/multiprocessing/synchronize.py3
-rw-r--r--Lib/nntplib.py1149
-rw-r--r--Lib/ntpath.py68
-rw-r--r--Lib/numbers.py2
-rw-r--r--Lib/opcode.py11
-rw-r--r--Lib/os.py236
-rw-r--r--Lib/os2emxpath.py3
-rw-r--r--Lib/pdb.doc202
-rwxr-xr-xLib/pdb.py1319
-rw-r--r--Lib/pickle.py98
-rw-r--r--Lib/pickletools.py79
-rw-r--r--Lib/pkgutil.py3
-rw-r--r--Lib/plat-atheos/IN.py944
-rw-r--r--Lib/plat-atheos/TYPES.py142
-rw-r--r--Lib/plat-atheos/regen3
-rwxr-xr-x[-rw-r--r--]Lib/plat-freebsd4/regen0
-rwxr-xr-x[-rw-r--r--]Lib/plat-freebsd5/regen0
-rwxr-xr-x[-rw-r--r--]Lib/plat-freebsd6/regen0
-rwxr-xr-x[-rw-r--r--]Lib/plat-freebsd7/regen0
-rwxr-xr-x[-rw-r--r--]Lib/plat-freebsd8/regen0
-rwxr-xr-x[-rw-r--r--]Lib/plat-os2emx/regen0
-rw-r--r--[-rwxr-xr-x]Lib/plat-sunos5/IN.py0
-rwxr-xr-xLib/platform.py77
-rw-r--r--Lib/plistlib.py2
-rw-r--r--Lib/poplib.py18
-rw-r--r--Lib/posixpath.py9
-rw-r--r--Lib/pprint.py9
-rwxr-xr-xLib/profile.py20
-rw-r--r--Lib/pstats.py111
-rw-r--r--Lib/py_compile.py150
-rwxr-xr-xLib/pydoc.py672
-rw-r--r--Lib/pydoc_data/_pydoc.css6
-rw-r--r--Lib/pydoc_data/topics.py42
-rw-r--r--Lib/queue.py10
-rwxr-xr-xLib/quopri.py20
-rw-r--r--Lib/random.py145
-rw-r--r--Lib/re.py40
-rw-r--r--Lib/reprlib.py32
-rw-r--r--Lib/runpy.py193
-rw-r--r--Lib/shelve.py3
-rw-r--r--Lib/shutil.py491
-rw-r--r--Lib/site.py176
-rwxr-xr-xLib/smtpd.py244
-rwxr-xr-xLib/smtplib.py250
-rw-r--r--Lib/socket.py100
-rw-r--r--Lib/socketserver.py48
-rw-r--r--Lib/sqlite3/__init__.py3
-rw-r--r--Lib/sqlite3/dbapi2.py3
-rw-r--r--Lib/sqlite3/test/dbapi.py75
-rw-r--r--Lib/sqlite3/test/regression.py113
-rw-r--r--Lib/sqlite3/test/transactions.py20
-rw-r--r--Lib/sqlite3/test/types.py8
-rw-r--r--Lib/sre_compile.py2
-rw-r--r--Lib/ssl.py193
-rw-r--r--Lib/string.py51
-rw-r--r--Lib/struct.py2
-rw-r--r--Lib/subprocess.py477
-rw-r--r--Lib/sunau.py11
-rwxr-xr-xLib/symbol.py128
-rw-r--r--Lib/symtable.py9
-rw-r--r--Lib/sysconfig.py778
-rwxr-xr-xLib/tabnanny.py9
-rw-r--r--Lib/tarfile.py680
-rw-r--r--Lib/tempfile.py103
-rw-r--r--Lib/test/__main__.py13
-rw-r--r--Lib/test/badsyntax_nocaret.py2
-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/recursive_call.py2
-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/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/doctest_aliases.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.txt1
-rw-r--r--Lib/test/fork_wait.py6
-rw-r--r--Lib/test/formatfloat_testcases.txt69
-rw-r--r--Lib/test/gdb_sample.py12
-rw-r--r--Lib/test/ieee754.txt6
-rw-r--r--Lib/test/json_tests/__init__.py (renamed from Lib/json/tests/__init__.py)2
-rw-r--r--Lib/test/json_tests/test_decode.py (renamed from Lib/json/tests/test_decode.py)28
-rw-r--r--Lib/test/json_tests/test_default.py (renamed from Lib/json/tests/test_default.py)0
-rw-r--r--Lib/test/json_tests/test_dump.py (renamed from Lib/json/tests/test_dump.py)0
-rw-r--r--Lib/test/json_tests/test_encode_basestring_ascii.py (renamed from Lib/json/tests/test_encode_basestring_ascii.py)0
-rw-r--r--Lib/test/json_tests/test_fail.py (renamed from Lib/json/tests/test_fail.py)0
-rw-r--r--Lib/test/json_tests/test_float.py (renamed from Lib/json/tests/test_float.py)0
-rw-r--r--Lib/test/json_tests/test_indent.py (renamed from Lib/json/tests/test_indent.py)40
-rw-r--r--Lib/test/json_tests/test_pass1.py (renamed from Lib/json/tests/test_pass1.py)0
-rw-r--r--Lib/test/json_tests/test_pass2.py (renamed from Lib/json/tests/test_pass2.py)0
-rw-r--r--Lib/test/json_tests/test_pass3.py (renamed from Lib/json/tests/test_pass3.py)0
-rw-r--r--Lib/test/json_tests/test_recursion.py (renamed from Lib/json/tests/test_recursion.py)0
-rw-r--r--Lib/test/json_tests/test_scanstring.py (renamed from Lib/json/tests/test_scanstring.py)0
-rw-r--r--Lib/test/json_tests/test_separators.py (renamed from Lib/json/tests/test_separators.py)0
-rw-r--r--Lib/test/json_tests/test_speedups.py (renamed from Lib/json/tests/test_speedups.py)0
-rw-r--r--Lib/test/json_tests/test_unicode.py (renamed from Lib/json/tests/test_unicode.py)0
-rw-r--r--Lib/test/keycert.pem59
-rw-r--r--Lib/test/keycert2.pem31
-rw-r--r--Lib/test/lock_tests.py330
-rw-r--r--Lib/test/make_ssl_certs.py64
-rw-r--r--Lib/test/mapping_tests.py46
-rw-r--r--Lib/test/math_testcases.txt519
-rw-r--r--Lib/test/mock_socket.py154
-rw-r--r--Lib/test/pickletester.py69
-rw-r--r--Lib/test/pstats.pckbin0 -> 66607 bytes-rwxr-xr-xLib/test/pystone.py4
-rwxr-xr-xLib/test/re_tests.py2
-rwxr-xr-xLib/test/regrtest.py925
-rw-r--r--Lib/test/script_helper.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.py51
-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.py593
-rw-r--r--Lib/test/test_SimpleHTTPServer.py41
-rw-r--r--Lib/test/test___all__.py8
-rw-r--r--Lib/test/test___future__.py2
-rw-r--r--Lib/test/test__locale.py2
-rw-r--r--Lib/test/test_abc.py68
-rw-r--r--Lib/test/test_abstract_numbers.py1
-rw-r--r--Lib/test/test_argparse.py4681
-rwxr-xr-xLib/test/test_array.py267
-rw-r--r--Lib/test/test_ascii_formatd.py64
-rw-r--r--Lib/test/test_ast.py30
-rw-r--r--Lib/test/test_asynchat.py174
-rw-r--r--Lib/test/test_asyncore.py602
-rw-r--r--Lib/test/test_atexit.py11
-rw-r--r--Lib/test/test_augassign.py4
-rw-r--r--Lib/test/test_base64.py18
-rw-r--r--Lib/test/test_bigmem.py44
-rw-r--r--[-rwxr-xr-x]Lib/test/test_binascii.py160
-rwxr-xr-xLib/test/test_binhex.py13
-rw-r--r--Lib/test/test_binop.py89
-rw-r--r--Lib/test/test_bool.py28
-rw-r--r--Lib/test/test_builtin.py396
-rw-r--r--Lib/test/test_bytes.py243
-rw-r--r--Lib/test/test_bz2.py229
-rw-r--r--Lib/test/test_calendar.py12
-rw-r--r--Lib/test/test_capi.py71
-rw-r--r--Lib/test/test_cfgparser.py1468
-rw-r--r--Lib/test/test_cgi.py136
-rw-r--r--[-rwxr-xr-x]Lib/test/test_cmath.py194
-rw-r--r--Lib/test/test_cmd.py25
-rw-r--r--Lib/test/test_cmd_line.py277
-rw-r--r--Lib/test/test_cmd_line_script.py256
-rw-r--r--Lib/test/test_code.py45
-rw-r--r--Lib/test/test_codecencodings_cn.py2
-rw-r--r--Lib/test/test_codecencodings_hk.py2
-rw-r--r--Lib/test/test_codecencodings_jp.py2
-rw-r--r--Lib/test/test_codecencodings_kr.py2
-rw-r--r--Lib/test/test_codecencodings_tw.py2
-rw-r--r--Lib/test/test_codecmaps_cn.py2
-rw-r--r--Lib/test/test_codecmaps_hk.py2
-rw-r--r--Lib/test/test_codecmaps_jp.py2
-rw-r--r--Lib/test/test_codecmaps_kr.py2
-rw-r--r--Lib/test/test_codecmaps_tw.py2
-rw-r--r--Lib/test/test_codecs.py86
-rw-r--r--Lib/test/test_codeop.py4
-rw-r--r--Lib/test/test_coding.py31
-rw-r--r--Lib/test/test_collections.py288
-rw-r--r--Lib/test/test_compile.py51
-rw-r--r--Lib/test/test_compileall.py285
-rw-r--r--Lib/test/test_complex.py170
-rw-r--r--Lib/test/test_concurrent_futures.py613
-rw-r--r--Lib/test/test_contains.py32
-rw-r--r--Lib/test/test_contextlib.py354
-rw-r--r--Lib/test/test_copy.py13
-rw-r--r--Lib/test/test_copyreg.py4
-rw-r--r--Lib/test/test_cprofile.py19
-rw-r--r--[-rwxr-xr-x]Lib/test/test_crypt.py0
-rw-r--r--Lib/test/test_csv.py20
-rw-r--r--Lib/test/test_datetime.py3415
-rw-r--r--Lib/test/test_dbm.py12
-rw-r--r--Lib/test/test_dbm_dumb.py12
-rwxr-xr-xLib/test/test_dbm_gnu.py8
-rwxr-xr-xLib/test/test_dbm_ndbm.py2
-rw-r--r--Lib/test/test_decimal.py690
-rw-r--r--Lib/test/test_defaultdict.py16
-rw-r--r--Lib/test/test_deque.py52
-rw-r--r--Lib/test/test_descr.py152
-rw-r--r--Lib/test/test_dict.py163
-rw-r--r--Lib/test/test_dictviews.py133
-rw-r--r--Lib/test/test_difflib.py62
-rw-r--r--Lib/test/test_dis.py221
-rw-r--r--Lib/test/test_distutils.py1
-rw-r--r--Lib/test/test_doctest.py182
-rw-r--r--Lib/test/test_doctest2.py5
-rw-r--r--Lib/test/test_docxmlrpc.py86
-rw-r--r--Lib/test/test_dummy_thread.py10
-rw-r--r--Lib/test/test_dynamic.py143
-rw-r--r--Lib/test/test_email.py2
-rw-r--r--Lib/test/test_enumerate.py14
-rw-r--r--Lib/test/test_eof.py2
-rw-r--r--Lib/test/test_epoll.py2
-rwxr-xr-xLib/test/test_errno.py9
-rw-r--r--Lib/test/test_exceptions.py66
-rw-r--r--Lib/test/test_extcall.py35
-rw-r--r--[-rwxr-xr-x]Lib/test/test_fcntl.py13
-rw-r--r--Lib/test/test_file.py13
-rw-r--r--Lib/test/test_filecmp.py2
-rw-r--r--Lib/test/test_fileinput.py24
-rw-r--r--Lib/test/test_fileio.py10
-rw-r--r--Lib/test/test_float.py443
-rw-r--r--Lib/test/test_fnmatch.py35
-rw-r--r--Lib/test/test_fork1.py49
-rw-r--r--Lib/test/test_format.py35
-rw-r--r--Lib/test/test_fractions.py55
-rw-r--r--Lib/test/test_frozen.py25
-rw-r--r--Lib/test/test_ftplib.py433
-rw-r--r--Lib/test/test_funcattrs.py6
-rw-r--r--Lib/test/test_functools.py331
-rw-r--r--Lib/test/test_future.py2
-rw-r--r--Lib/test/test_future5.py2
-rw-r--r--Lib/test/test_gc.py49
-rw-r--r--Lib/test/test_gdb.py681
-rw-r--r--Lib/test/test_generators.py52
-rw-r--r--Lib/test/test_genericpath.py320
-rw-r--r--Lib/test/test_getargs2.py213
-rw-r--r--Lib/test/test_getopt.py1
-rw-r--r--Lib/test/test_glob.py16
-rw-r--r--Lib/test/test_global.py18
-rw-r--r--Lib/test/test_grammar.py22
-rw-r--r--[-rwxr-xr-x]Lib/test/test_grp.py8
-rw-r--r--Lib/test/test_gzip.py312
-rw-r--r--Lib/test/test_hash.py4
-rw-r--r--Lib/test/test_hashlib.py110
-rw-r--r--Lib/test/test_heapq.py18
-rw-r--r--Lib/test/test_hmac.py10
-rw-r--r--Lib/test/test_html.py24
-rw-r--r--[-rwxr-xr-x]Lib/test/test_htmlparser.py66
-rw-r--r--Lib/test/test_http_cookiejar.py117
-rw-r--r--Lib/test/test_http_cookies.py110
-rw-r--r--Lib/test/test_httplib.py221
-rw-r--r--Lib/test/test_httpservers.py355
-rw-r--r--Lib/test/test_imaplib.py50
-rw-r--r--Lib/test/test_imp.py240
-rw-r--r--Lib/test/test_import.py247
-rw-r--r--Lib/test/test_importhooks.py10
-rw-r--r--Lib/test/test_importlib.py7
-rw-r--r--Lib/test/test_index.py92
-rw-r--r--Lib/test/test_inspect.py586
-rw-r--r--Lib/test/test_int.py29
-rw-r--r--Lib/test/test_io.py340
-rw-r--r--Lib/test/test_ioctl.py10
-rw-r--r--Lib/test/test_isinstance.py14
-rw-r--r--Lib/test/test_iter.py25
-rw-r--r--Lib/test/test_itertools.py38
-rw-r--r--Lib/test/test_json.py4
-rw-r--r--Lib/test/test_keywordonlyarg.py10
-rw-r--r--Lib/test/test_kqueue.py11
-rw-r--r--Lib/test/test_linecache.py14
-rw-r--r--Lib/test/test_logging.py1333
-rw-r--r--Lib/test/test_long.py765
-rw-r--r--Lib/test/test_macpath.py46
-rw-r--r--Lib/test/test_mailbox.py263
-rw-r--r--Lib/test/test_marshal.py12
-rw-r--r--Lib/test/test_math.py326
-rw-r--r--Lib/test/test_memoryio.py167
-rw-r--r--Lib/test/test_memoryview.py52
-rw-r--r--Lib/test/test_mimetypes.py27
-rw-r--r--Lib/test/test_minidom.py41
-rw-r--r--Lib/test/test_mmap.py258
-rw-r--r--Lib/test/test_multibytecodec.py5
-rw-r--r--Lib/test/test_multibytecodec_support.py5
-rw-r--r--Lib/test/test_multiprocessing.py139
-rw-r--r--Lib/test/test_nis.py1
-rw-r--r--Lib/test/test_nntplib.py1243
-rw-r--r--Lib/test/test_normalization.py19
-rw-r--r--Lib/test/test_ntpath.py26
-rw-r--r--Lib/test/test_numeric_tower.py206
-rw-r--r--Lib/test/test_opcodes.py2
-rw-r--r--Lib/test/test_operator.py9
-rw-r--r--Lib/test/test_optparse.py13
-rw-r--r--Lib/test/test_os.py558
-rw-r--r--Lib/test/test_ossaudiodev.py10
-rw-r--r--Lib/test/test_parser.py22
-rw-r--r--Lib/test/test_pdb.py383
-rw-r--r--Lib/test/test_peepholer.py126
-rw-r--r--Lib/test/test_pep263.py2
-rw-r--r--Lib/test/test_pep277.py178
-rw-r--r--Lib/test/test_pep292.py60
-rw-r--r--Lib/test/test_pep3120.py3
-rw-r--r--Lib/test/test_pep3131.py1
-rw-r--r--Lib/test/test_pep352.py6
-rw-r--r--Lib/test/test_pickle.py23
-rw-r--r--Lib/test/test_pickletools.py4
-rw-r--r--Lib/test/test_pipes.py15
-rw-r--r--Lib/test/test_pkg.py37
-rw-r--r--Lib/test/test_pkgimport.py34
-rw-r--r--Lib/test/test_platform.py61
-rw-r--r--Lib/test/test_plistlib.py2
-rw-r--r--Lib/test/test_popen.py5
-rw-r--r--Lib/test/test_poplib.py28
-rw-r--r--Lib/test/test_posix.py117
-rw-r--r--Lib/test/test_posixpath.py631
-rw-r--r--Lib/test/test_pprint.py38
-rw-r--r--Lib/test/test_print.py1
-rw-r--r--[-rwxr-xr-x]Lib/test/test_profile.py3
-rw-r--r--Lib/test/test_property.py41
-rw-r--r--Lib/test/test_pstats.py19
-rw-r--r--Lib/test/test_pwd.py31
-rw-r--r--Lib/test/test_pyclbr.py9
-rw-r--r--Lib/test/test_pydoc.py190
-rw-r--r--Lib/test/test_pyexpat.py218
-rw-r--r--Lib/test/test_queue.py38
-rw-r--r--Lib/test/test_quopri.py2
-rw-r--r--Lib/test/test_raise.py24
-rw-r--r--Lib/test/test_random.py38
-rw-r--r--Lib/test/test_range.py389
-rw-r--r--Lib/test/test_re.py25
-rw-r--r--Lib/test/test_readline.py47
-rw-r--r--Lib/test/test_reprlib.py34
-rw-r--r--Lib/test/test_resource.py4
-rw-r--r--Lib/test/test_richcmp.py15
-rw-r--r--Lib/test/test_runpy.py233
-rw-r--r--Lib/test/test_sax.py130
-rw-r--r--Lib/test/test_sched.py80
-rw-r--r--Lib/test/test_scope.py360
-rw-r--r--Lib/test/test_select.py2
-rw-r--r--Lib/test/test_set.py70
-rw-r--r--Lib/test/test_shelve.py13
-rw-r--r--Lib/test/test_shutil.py619
-rw-r--r--Lib/test/test_site.py183
-rw-r--r--Lib/test/test_smtpd.py289
-rw-r--r--Lib/test/test_smtplib.py211
-rw-r--r--Lib/test/test_smtpnet.py2
-rw-r--r--Lib/test/test_socket.py651
-rw-r--r--Lib/test/test_socketserver.py15
-rw-r--r--Lib/test/test_sort.py6
-rw-r--r--Lib/test/test_sqlite.py18
-rw-r--r--Lib/test/test_ssl.py930
-rw-r--r--[-rwxr-xr-x]Lib/test/test_strftime.py1
-rw-r--r--Lib/test/test_string.py24
-rw-r--r--Lib/test/test_strptime.py21
-rw-r--r--Lib/test/test_strtod.py20
-rw-r--r--Lib/test/test_struct.py491
-rw-r--r--Lib/test/test_structmembers.py23
-rw-r--r--Lib/test/test_structseq.py15
-rw-r--r--Lib/test/test_subprocess.py1454
-rw-r--r--Lib/test/test_sundry.py15
-rw-r--r--Lib/test/test_symtable.py2
-rw-r--r--Lib/test/test_syntax.py53
-rw-r--r--Lib/test/test_sys.py264
-rw-r--r--Lib/test/test_sysconfig.py298
-rw-r--r--Lib/test/test_syslog.py2
-rw-r--r--Lib/test/test_tarfile.py1146
-rw-r--r--Lib/test/test_tcl.py12
-rw-r--r--Lib/test/test_telnetlib.py13
-rw-r--r--Lib/test/test_tempfile.py189
-rw-r--r--Lib/test/test_thread.py74
-rw-r--r--Lib/test/test_threaded_import.py4
-rw-r--r--Lib/test/test_threadedtempfile.py5
-rw-r--r--Lib/test/test_threading.py209
-rw-r--r--Lib/test/test_threading_local.py22
-rw-r--r--Lib/test/test_threadsignals.py145
-rw-r--r--Lib/test/test_time.py240
-rw-r--r--Lib/test/test_timeit.py305
-rw-r--r--Lib/test/test_timeout.py142
-rw-r--r--Lib/test/test_tokenize.py41
-rw-r--r--Lib/test/test_trace.py43
-rw-r--r--Lib/test/test_traceback.py37
-rw-r--r--Lib/test/test_ttk_guionly.py1
-rw-r--r--Lib/test/test_ttk_textonly.py1
-rw-r--r--Lib/test/test_tuple.py4
-rw-r--r--Lib/test/test_types.py184
-rw-r--r--Lib/test/test_ucn.py6
-rw-r--r--Lib/test/test_unicode.py358
-rw-r--r--Lib/test/test_unicode_file.py61
-rw-r--r--Lib/test/test_unicodedata.py36
-rw-r--r--Lib/test/test_unittest.py3396
-rw-r--r--Lib/test/test_unpack.py6
-rw-r--r--Lib/test/test_urllib.py64
-rw-r--r--Lib/test/test_urllib2.py90
-rw-r--r--Lib/test/test_urllib2_localnet.py64
-rw-r--r--Lib/test/test_urllib2net.py45
-rw-r--r--Lib/test/test_urllibnet.py37
-rw-r--r--Lib/test/test_urlparse.py293
-rw-r--r--Lib/test/test_userdict.py12
-rwxr-xr-xLib/test/test_userstring.py2
-rw-r--r--Lib/test/test_warnings.py127
-rw-r--r--Lib/test/test_wave.py14
-rw-r--r--Lib/test/test_weakref.py53
-rw-r--r--Lib/test/test_weakset.py52
-rw-r--r--Lib/test/test_winreg.py227
-rw-r--r--Lib/test/test_winsound.py1
-rw-r--r--Lib/test/test_with.py50
-rw-r--r--[-rwxr-xr-x]Lib/test/test_wsgiref.py67
-rw-r--r--Lib/test/test_xml_etree.py1734
-rw-r--r--Lib/test/test_xml_etree_c.py235
-rw-r--r--Lib/test/test_xmlrpc.py373
-rw-r--r--Lib/test/test_xmlrpc_net.py4
-rw-r--r--Lib/test/test_zipfile.py1720
-rw-r--r--Lib/test/test_zipimport.py72
-rw-r--r--Lib/test/test_zipimport_support.py173
-rw-r--r--Lib/test/test_zlib.py30
-rw-r--r--Lib/test/testtar.tarbin272384 -> 427008 bytes-rw-r--r--Lib/test/threaded_import_hangers.py2
-rw-r--r--Lib/test/win_console_handler.py49
-rw-r--r--Lib/test/xmltestdata/simple-ns.xml7
-rw-r--r--Lib/test/xmltestdata/simple.xml6
-rw-r--r--Lib/test/xmltestdata/test.xml (renamed from Lib/test/test.xml)0
-rw-r--r--Lib/test/xmltestdata/test.xml.out (renamed from Lib/test/test.xml.out)0
-rw-r--r--Lib/test/zip_cp437_header.zipbin0 -> 270 bytes-rw-r--r--Lib/threading.py349
-rw-r--r--Lib/timeit.py12
-rw-r--r--Lib/tkinter/__init__.py139
-rw-r--r--Lib/tkinter/__main__.py7
-rw-r--r--Lib/tkinter/font.py2
-rw-r--r--Lib/tkinter/scrolledtext.py7
-rw-r--r--Lib/tkinter/test/test_tkinter/test_font.py33
-rw-r--r--Lib/tkinter/test/test_tkinter/test_loadtk.py3
-rw-r--r--Lib/tkinter/test/test_ttk/test_widgets.py4
-rw-r--r--Lib/tkinter/tix.py175
-rw-r--r--Lib/tkinter/ttk.py12
-rwxr-xr-xLib/token.py18
-rw-r--r--Lib/tokenize.py159
-rw-r--r--Lib/trace.py189
-rw-r--r--Lib/turtle.py52
-rw-r--r--Lib/turtledemo/__init__.py (renamed from Tools/modulator/Templates/copyright)0
-rwxr-xr-x[-rw-r--r--]Lib/turtledemo/__main__.py (renamed from Demo/turtle/turtleDemo.py)95
-rw-r--r--Lib/turtledemo/about_turtle.txt (renamed from Demo/turtle/about_turtle.txt)0
-rw-r--r--Lib/turtledemo/about_turtledemo.txt (renamed from Demo/turtle/about_turtledemo.txt)4
-rw-r--r--Lib/turtledemo/bytedesign.py (renamed from Demo/turtle/tdemo_bytedesign.py)2
-rw-r--r--Lib/turtledemo/chaos.py (renamed from Demo/turtle/tdemo_chaos.py)0
-rw-r--r--Lib/turtledemo/clock.py (renamed from Demo/turtle/tdemo_clock.py)2
-rw-r--r--Lib/turtledemo/colormixer.py (renamed from Demo/turtle/tdemo_colormixer.py)0
-rw-r--r--Lib/turtledemo/demohelp.txt (renamed from Demo/turtle/demohelp.txt)7
-rw-r--r--Lib/turtledemo/forest.py (renamed from Demo/turtle/tdemo_forest.py)2
-rw-r--r--Lib/turtledemo/fractalcurves.py (renamed from Demo/turtle/tdemo_fractalcurves.py)2
-rw-r--r--Lib/turtledemo/lindenmayer.py (renamed from Demo/turtle/tdemo_lindenmayer_indian.py)2
-rw-r--r--Lib/turtledemo/minimal_hanoi.py (renamed from Demo/turtle/tdemo_minimal_hanoi.py)2
-rw-r--r--Lib/turtledemo/nim.py (renamed from Demo/turtle/tdemo_nim.py)21
-rw-r--r--Lib/turtledemo/paint.py (renamed from Demo/turtle/tdemo_paint.py)2
-rw-r--r--Lib/turtledemo/peace.py (renamed from Demo/turtle/tdemo_peace.py)2
-rw-r--r--Lib/turtledemo/penrose.py (renamed from Demo/turtle/tdemo_penrose.py)2
-rw-r--r--Lib/turtledemo/planet_and_moon.py (renamed from Demo/turtle/tdemo_planet_and_moon.py)2
-rw-r--r--Lib/turtledemo/round_dance.py (renamed from Demo/turtle/tdemo_round_dance.py)6
-rw-r--r--Lib/turtledemo/tree.py (renamed from Demo/turtle/tdemo_tree.py)2
-rw-r--r--Lib/turtledemo/turtle.cfg (renamed from Demo/turtle/turtle.cfg)0
-rw-r--r--Lib/turtledemo/two_canvases.py (renamed from Demo/turtle/turtledemo_two_canvases.py)10
-rw-r--r--Lib/turtledemo/wikipedia.py (renamed from Demo/turtle/tdemo_wikipedia.py)2
-rw-r--r--Lib/turtledemo/yinyang.py (renamed from Demo/turtle/tdemo_yinyang.py)2
-rw-r--r--Lib/unittest.py1630
-rw-r--r--Lib/unittest/__init__.py69
-rw-r--r--Lib/unittest/__main__.py12
-rw-r--r--Lib/unittest/case.py1263
-rw-r--r--Lib/unittest/loader.py321
-rw-r--r--Lib/unittest/main.py274
-rw-r--r--Lib/unittest/result.py192
-rw-r--r--Lib/unittest/runner.py213
-rw-r--r--Lib/unittest/signals.py57
-rw-r--r--Lib/unittest/suite.py301
-rw-r--r--Lib/unittest/test/__init__.py21
-rw-r--r--Lib/unittest/test/_test_warnings.py74
-rw-r--r--Lib/unittest/test/dummy.py1
-rw-r--r--Lib/unittest/test/support.py118
-rw-r--r--Lib/unittest/test/test_assertions.py286
-rw-r--r--Lib/unittest/test/test_break.py252
-rw-r--r--Lib/unittest/test/test_case.py1270
-rw-r--r--Lib/unittest/test/test_discovery.py395
-rw-r--r--Lib/unittest/test/test_functiontestcase.py144
-rw-r--r--Lib/unittest/test/test_loader.py1292
-rw-r--r--Lib/unittest/test/test_program.py358
-rw-r--r--Lib/unittest/test/test_result.py568
-rw-r--r--Lib/unittest/test/test_runner.py318
-rw-r--r--Lib/unittest/test/test_setups.py507
-rw-r--r--Lib/unittest/test/test_skipping.py134
-rw-r--r--Lib/unittest/test/test_suite.py368
-rw-r--r--Lib/unittest/util.py140
-rw-r--r--Lib/urllib/parse.py290
-rw-r--r--Lib/urllib/request.py87
-rwxr-xr-xLib/uu.py2
-rw-r--r--Lib/warnings.py19
-rw-r--r--Lib/wave.py8
-rw-r--r--Lib/weakref.py6
-rw-r--r--Lib/webbrowser.py50
-rw-r--r--Lib/wsgiref/handlers.py203
-rw-r--r--Lib/wsgiref/headers.py62
-rw-r--r--Lib/wsgiref/simple_server.py59
-rw-r--r--Lib/wsgiref/util.py40
-rw-r--r--Lib/wsgiref/validate.py42
-rw-r--r--Lib/xml/dom/minidom.py12
-rw-r--r--Lib/xml/etree/ElementInclude.py8
-rw-r--r--Lib/xml/etree/ElementPath.py351
-rw-r--r--Lib/xml/etree/ElementTree.py1238
-rw-r--r--Lib/xml/etree/__init__.py6
-rw-r--r--Lib/xml/parsers/expat.py6
-rw-r--r--Lib/xml/sax/expatreader.py3
-rw-r--r--Lib/xml/sax/saxutils.py42
-rw-r--r--Lib/xmlrpc/client.py290
-rw-r--r--Lib/xmlrpc/server.py114
-rw-r--r--Lib/zipfile.py514
-rw-r--r--Mac/BuildScript/README.txt157
-rwxr-xr-xMac/BuildScript/build-installer.py126
-rw-r--r--Mac/BuildScript/resources/ReadMe.txt47
-rw-r--r--Mac/BuildScript/resources/Welcome.rtf28
-rwxr-xr-xMac/BuildScript/scripts/postflight.documentation31
-rw-r--r--Mac/Extras.ReadMe.txt5
-rw-r--r--Mac/Makefile.in108
-rw-r--r--Mac/PythonLauncher/Makefile.in2
-rw-r--r--Mac/README93
-rw-r--r--Mac/Tools/pythonw.c173
-rw-r--r--Makefile.pre.in234
-rw-r--r--Misc/ACKS79
-rw-r--r--Misc/NEWS4532
-rw-r--r--Misc/Porting2
-rw-r--r--Misc/README15
-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-3.2.spec (renamed from Misc/RPM/python-3.1.spec)63
-rw-r--r--Misc/Vim/vimrc39
-rwxr-xr-xMisc/build.sh10
-rw-r--r--Misc/cheatsheet2181
-rw-r--r--Misc/developers.txt346
-rw-r--r--Misc/gdbinit15
-rw-r--r--Misc/maintainers.rst314
-rw-r--r--Misc/pymemcompat.h85
-rw-r--r--Misc/python-config.in71
-rw-r--r--Misc/python-wing3.wpr (renamed from Misc/python-wing.wpr)2
-rw-r--r--Misc/python-wing4.wpr18
-rw-r--r--Misc/python.man10
-rw-r--r--Misc/python.pc.in6
-rw-r--r--Misc/setuid-prog.c176
-rw-r--r--Modules/Setup.dist13
-rw-r--r--Modules/_bisectmodule.c6
-rw-r--r--Modules/_codecsmodule.c16
-rw-r--r--Modules/_collectionsmodule.c192
-rw-r--r--Modules/_csv.c2
-rw-r--r--Modules/_ctypes/_ctypes.c38
-rw-r--r--Modules/_ctypes/callbacks.c54
-rw-r--r--Modules/_ctypes/callproc.c75
-rw-r--r--Modules/_ctypes/cfield.c93
-rw-r--r--Modules/_ctypes/ctypes.h3
-rw-r--r--Modules/_ctypes/libffi.diff218
-rw-r--r--Modules/_ctypes/libffi/ChangeLog4145
-rw-r--r--Modules/_ctypes/libffi/ChangeLog.libffi613
-rw-r--r--Modules/_ctypes/libffi/ChangeLog.libgcj40
-rw-r--r--Modules/_ctypes/libffi/ChangeLog.v1764
-rw-r--r--Modules/_ctypes/libffi/LICENSE2
-rw-r--r--Modules/_ctypes/libffi/Makefile.am19
-rw-r--r--Modules/_ctypes/libffi/Makefile.in573
-rw-r--r--Modules/_ctypes/libffi/README179
-rw-r--r--Modules/_ctypes/libffi/aclocal.m46926
-rwxr-xr-xModules/_ctypes/libffi/compile142
-rwxr-xr-xModules/_ctypes/libffi/config.guess268
-rwxr-xr-xModules/_ctypes/libffi/config.sub130
-rwxr-xr-xModules/_ctypes/libffi/configure24291
-rw-r--r--Modules/_ctypes/libffi/configure.ac55
-rwxr-xr-xModules/_ctypes/libffi/depcomp584
-rw-r--r--Modules/_ctypes/libffi/doc/libffi.info591
-rw-r--r--Modules/_ctypes/libffi/doc/libffi.texi598
-rw-r--r--Modules/_ctypes/libffi/doc/stamp-vti4
-rw-r--r--Modules/_ctypes/libffi/doc/version.texi4
-rw-r--r--Modules/_ctypes/libffi/fficonfig.h.in30
-rw-r--r--Modules/_ctypes/libffi/fficonfig.py.in6
-rw-r--r--Modules/_ctypes/libffi/include/Makefile.am2
-rw-r--r--Modules/_ctypes/libffi/include/Makefile.in147
-rw-r--r--Modules/_ctypes/libffi/include/ffi.h.in13
-rw-r--r--Modules/_ctypes/libffi/include/ffi_common.h24
-rw-r--r--Modules/_ctypes/libffi/libffi.pc.in10
-rw-r--r--Modules/_ctypes/libffi/libtool-version29
-rwxr-xr-xModules/_ctypes/libffi/ltmain.sh8406
-rw-r--r--Modules/_ctypes/libffi/m4/libtool.m47360
-rw-r--r--Modules/_ctypes/libffi/m4/ltoptions.m4368
-rw-r--r--Modules/_ctypes/libffi/m4/ltsugar.m4123
-rw-r--r--Modules/_ctypes/libffi/m4/ltversion.m423
-rw-r--r--Modules/_ctypes/libffi/m4/lt~obsolete.m492
-rw-r--r--Modules/_ctypes/libffi/man/Makefile.am8
-rw-r--r--Modules/_ctypes/libffi/man/Makefile.in448
-rw-r--r--Modules/_ctypes/libffi/man/ffi.331
-rw-r--r--Modules/_ctypes/libffi/man/ffi_call.3103
-rw-r--r--Modules/_ctypes/libffi/man/ffi_prep_cif.366
-rwxr-xr-xModules/_ctypes/libffi/mdate-sh201
-rwxr-xr-xModules/_ctypes/libffi/missing23
-rw-r--r--Modules/_ctypes/libffi/msvcc.sh185
-rw-r--r--Modules/_ctypes/libffi/src/arm/sysv.S24
-rw-r--r--Modules/_ctypes/libffi/src/avr32/ffi.c421
-rw-r--r--Modules/_ctypes/libffi/src/avr32/ffitarget.h50
-rw-r--r--Modules/_ctypes/libffi/src/avr32/sysv.S208
-rw-r--r--Modules/_ctypes/libffi/src/closures.c610
-rw-r--r--Modules/_ctypes/libffi/src/darwin/ffitarget.h25
-rw-r--r--Modules/_ctypes/libffi/src/debug.c59
-rw-r--r--Modules/_ctypes/libffi/src/dlmalloc.c5099
-rw-r--r--Modules/_ctypes/libffi/src/frv/ffi.c2
-rw-r--r--Modules/_ctypes/libffi/src/java_raw_api.c356
-rw-r--r--Modules/_ctypes/libffi/src/mips/ffi.c167
-rw-r--r--Modules/_ctypes/libffi/src/mips/ffitarget.h41
-rw-r--r--Modules/_ctypes/libffi/src/mips/n32.S79
-rw-r--r--Modules/_ctypes/libffi/src/mips/o32.S16
-rw-r--r--Modules/_ctypes/libffi/src/moxie/eabi.S128
-rw-r--r--Modules/_ctypes/libffi/src/moxie/ffi.c276
-rw-r--r--Modules/_ctypes/libffi/src/moxie/ffitarget.h56
-rw-r--r--Modules/_ctypes/libffi/src/pa/ffi.c7
-rw-r--r--Modules/_ctypes/libffi/src/powerpc/aix.S227
-rw-r--r--Modules/_ctypes/libffi/src/powerpc/aix_closure.S420
-rw-r--r--Modules/_ctypes/libffi/src/powerpc/ffi.c27
-rw-r--r--Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c288
-rw-r--r--Modules/_ctypes/libffi/src/powerpc/ffitarget.h14
-rw-r--r--Modules/_ctypes/libffi/src/powerpc/sysv.S35
-rw-r--r--Modules/_ctypes/libffi/src/prep_cif.c9
-rw-r--r--Modules/_ctypes/libffi/src/raw_api.c254
-rw-r--r--Modules/_ctypes/libffi/src/s390/sysv.S2
-rw-r--r--Modules/_ctypes/libffi/src/sh/ffi.c4
-rw-r--r--Modules/_ctypes/libffi/src/sh/sysv.S22
-rw-r--r--Modules/_ctypes/libffi/src/sh64/ffi.c59
-rw-r--r--Modules/_ctypes/libffi/src/sh64/sysv.S39
-rw-r--r--Modules/_ctypes/libffi/src/sparc/ffi.c27
-rw-r--r--Modules/_ctypes/libffi/src/sparc/v8.S73
-rw-r--r--Modules/_ctypes/libffi/src/types.c77
-rw-r--r--Modules/_ctypes/libffi/src/x86/darwin.S19
-rw-r--r--Modules/_ctypes/libffi/src/x86/ffi.c444
-rw-r--r--Modules/_ctypes/libffi/src/x86/ffi64.c99
-rw-r--r--Modules/_ctypes/libffi/src/x86/ffitarget.h36
-rw-r--r--Modules/_ctypes/libffi/src/x86/sysv.S25
-rw-r--r--Modules/_ctypes/libffi/src/x86/unix64.S12
-rw-r--r--Modules/_ctypes/libffi/src/x86/win32.S1106
-rw-r--r--Modules/_ctypes/libffi/src/x86/win64.S460
-rw-r--r--Modules/_ctypes/libffi/testsuite/Makefile.am80
-rw-r--r--Modules/_ctypes/libffi/testsuite/Makefile.in482
-rw-r--r--Modules/_ctypes/libffi/testsuite/config/default.exp1
-rw-r--r--Modules/_ctypes/libffi/testsuite/lib/libffi-dg.exp300
-rw-r--r--Modules/_ctypes/libffi/testsuite/lib/target-libpath.exp263
-rw-r--r--Modules/_ctypes/libffi/testsuite/lib/wrapper.exp45
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/call.exp36
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/closure_fn0.c89
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/closure_fn1.c81
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/closure_fn2.c81
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/closure_fn3.c82
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/closure_fn4.c89
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/closure_fn5.c92
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/closure_fn6.c90
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/closure_loc_fn0.c95
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/closure_stdcall.c64
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_12byte.c94
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_16byte.c95
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_18byte.c96
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_19byte.c102
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_1_1byte.c89
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_20byte.c91
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_20byte1.c93
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_24byte.c113
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_2byte.c90
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_3_1byte.c95
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_3byte1.c90
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_3byte2.c90
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_4_1byte.c98
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_4byte.c90
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_5_1_byte.c109
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_5byte.c98
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_64byte.c124
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_6_1_byte.c113
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_6byte.c99
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_7_1_byte.c117
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_7byte.c97
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_8byte.c88
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_9byte1.c90
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_9byte2.c91
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_double.c93
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_float.c91
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_longdouble.c92
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_longdouble_split.c134
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c117
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_pointer.c95
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_sint16.c91
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_sint32.c91
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_sint64.c92
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_uint16.c91
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_uint32.c91
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_uint64.c93
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_dbls_struct.c66
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_double.c43
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_double_va.c57
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_float.c42
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_longdouble.c105
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_longdouble_va.c57
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_multi_schar.c74
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_multi_sshort.c74
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_multi_sshortchar.c86
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_multi_uchar.c91
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_multi_ushort.c74
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_multi_ushortchar.c86
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_pointer.c74
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_pointer_stack.c140
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_schar.c44
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_sint.c42
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_sshort.c42
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_uchar.c42
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_uint.c43
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_ulonglong.c47
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/cls_ushort.c43
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/err_bad_abi.c37
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/err_bad_typedef.c25
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/ffitest.h129
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/float.c59
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/float1.c58
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/float2.c58
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/float3.c72
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/float4.c62
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/huge_struct.c342
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/many.c69
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/many_win32.c63
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/negint.c53
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct.c152
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct1.c161
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct10.c133
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct2.c110
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct3.c111
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct4.c111
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct5.c112
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct6.c131
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct7.c111
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct8.c131
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct9.c131
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/problem1.c90
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/promotion.c59
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/pyobjc-tc.c114
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/return_dbl.c35
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/return_dbl1.c43
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/return_dbl2.c42
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/return_fl.c35
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/return_fl1.c36
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/return_fl2.c49
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/return_fl3.c42
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/return_ldl.c34
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/return_ll.c41
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/return_ll1.c43
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/return_sc.c36
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/return_sl.c38
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/return_uc.c38
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/return_ul.c38
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/stret_large.c145
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/stret_large2.c148
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/stret_medium.c124
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/stret_medium2.c125
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/strlen.c44
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/strlen_win32.c44
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/struct1.c65
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/struct2.c67
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/struct3.c59
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/struct4.c63
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/struct5.c65
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/struct6.c64
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/struct7.c74
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/struct8.c80
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/struct9.c67
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.call/testclosure.c70
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.special/ffitestcxx.h96
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.special/special.exp37
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.special/unwindtest.cc124
-rw-r--r--Modules/_ctypes/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc53
-rw-r--r--Modules/_ctypes/libffi/texinfo.tex7210
-rw-r--r--Modules/_ctypes/libffi_msvc/ffi.c12
-rw-r--r--Modules/_ctypes/libffi_msvc/ffi.h8
-rw-r--r--Modules/_ctypes/libffi_msvc/prep_cif.c2
-rw-r--r--Modules/_ctypes/libffi_osx/include/ffi.h5
-rw-r--r--Modules/_ctypes/malloc_closure.c7
-rw-r--r--Modules/_cursesmodule.c2807
-rw-r--r--Modules/_datetimemodule.c (renamed from Modules/datetimemodule.c)1682
-rw-r--r--Modules/_elementtree.c890
-rw-r--r--Modules/_functoolsmodule.c44
-rw-r--r--Modules/_gdbmmodule.c47
-rw-r--r--Modules/_hashopenssl.c84
-rw-r--r--Modules/_heapqmodule.c26
-rw-r--r--Modules/_io/_iomodule.c2
-rw-r--r--Modules/_io/_iomodule.h20
-rw-r--r--Modules/_io/bufferedio.c116
-rw-r--r--Modules/_io/bytesio.c263
-rw-r--r--Modules/_io/fileio.c97
-rw-r--r--Modules/_io/iobase.c15
-rw-r--r--Modules/_io/stringio.c140
-rw-r--r--Modules/_io/textio.c94
-rw-r--r--Modules/_json.c172
-rw-r--r--Modules/_localemodule.c51
-rw-r--r--Modules/_lsprof.c11
-rw-r--r--Modules/_math.c232
-rw-r--r--Modules/_math.h45
-rw-r--r--Modules/_multiprocessing/multiprocessing.h6
-rw-r--r--Modules/_pickle.c2410
-rw-r--r--Modules/_posixsubprocess.c501
-rw-r--r--Modules/_randommodule.c2
-rw-r--r--Modules/_sqlite/cache.c3
-rw-r--r--Modules/_sqlite/cache.h2
-rw-r--r--Modules/_sqlite/connection.c196
-rw-r--r--Modules/_sqlite/connection.h13
-rw-r--r--Modules/_sqlite/cursor.c132
-rw-r--r--Modules/_sqlite/cursor.h9
-rw-r--r--Modules/_sqlite/module.c2
-rw-r--r--Modules/_sqlite/module.h4
-rw-r--r--Modules/_sqlite/prepare_protocol.c3
-rw-r--r--Modules/_sqlite/prepare_protocol.h2
-rw-r--r--Modules/_sqlite/row.c24
-rw-r--r--Modules/_sqlite/row.h2
-rw-r--r--Modules/_sqlite/sqlitecompat.h31
-rw-r--r--Modules/_sqlite/statement.c7
-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.c14
-rw-r--r--Modules/_ssl.c866
-rw-r--r--Modules/_struct.c110
-rw-r--r--Modules/_testcapimodule.c725
-rw-r--r--Modules/_testembed.c52
-rw-r--r--Modules/_threadmodule.c461
-rw-r--r--Modules/_time.c28
-rw-r--r--Modules/_time.h3
-rw-r--r--Modules/_tkinter.c4
-rw-r--r--Modules/arraymodule.c726
-rw-r--r--Modules/atexitmodule.c1
-rw-r--r--Modules/audioop.c136
-rw-r--r--Modules/binascii.c26
-rw-r--r--Modules/bz2module.c5
-rw-r--r--Modules/cmathmodule.c25
-rw-r--r--Modules/config.c.in4
-rw-r--r--Modules/errnomodule.c53
-rw-r--r--Modules/gcmodule.c57
-rw-r--r--Modules/getpath.c223
-rw-r--r--Modules/grpmodule.c13
-rw-r--r--Modules/itertoolsmodule.c134
-rw-r--r--Modules/ld_so_aix.in2
-rw-r--r--Modules/main.c300
-rwxr-xr-xModules/makesetup2
-rw-r--r--Modules/mathmodule.c986
-rw-r--r--Modules/md5module.c4
-rw-r--r--Modules/mmapmodule.c41
-rw-r--r--Modules/nismodule.c26
-rw-r--r--Modules/operator.c133
-rw-r--r--Modules/ossaudiodev.c25
-rw-r--r--Modules/parsermodule.c87
-rw-r--r--Modules/posixmodule.c2229
-rw-r--r--Modules/pwdmodule.c9
-rw-r--r--Modules/pyexpat.c288
-rw-r--r--Modules/python.c109
-rw-r--r--Modules/readline.c138
-rw-r--r--Modules/resource.c5
-rw-r--r--Modules/selectmodule.c100
-rw-r--r--Modules/sha1module.c60
-rw-r--r--Modules/sha256module.c4
-rw-r--r--Modules/sha512module.c4
-rw-r--r--Modules/signalmodule.c21
-rw-r--r--Modules/socketmodule.c299
-rw-r--r--Modules/socketmodule.h1
-rw-r--r--Modules/spwdmodule.c9
-rw-r--r--Modules/symtablemodule.c5
-rw-r--r--Modules/syslogmodule.c123
-rw-r--r--Modules/termios.c40
-rw-r--r--Modules/timemodule.c486
-rw-r--r--Modules/unicodedata.c35
-rw-r--r--Modules/unicodedata_db.h6595
-rw-r--r--Modules/unicodename_db.h33783
-rw-r--r--Modules/xxlimited.c287
-rw-r--r--Modules/xxmodule.c2
-rw-r--r--Modules/zipimport.c366
-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.c6
-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.c139
-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.h65
-rw-r--r--Modules/zlibmodule.c22
-rw-r--r--Objects/abstract.c129
-rw-r--r--Objects/bytearrayobject.c623
-rw-r--r--Objects/bytesobject.c760
-rw-r--r--Objects/capsule.c36
-rw-r--r--Objects/classobject.c4
-rw-r--r--Objects/cobject.c169
-rw-r--r--Objects/codeobject.c221
-rw-r--r--Objects/complexobject.c203
-rw-r--r--Objects/descrobject.c74
-rw-r--r--Objects/dictobject.c148
-rw-r--r--Objects/enumobject.c7
-rw-r--r--Objects/exceptions.c68
-rw-r--r--Objects/fileobject.c24
-rw-r--r--Objects/floatobject.c228
-rw-r--r--Objects/frameobject.c28
-rw-r--r--Objects/funcobject.c3
-rw-r--r--Objects/genobject.c2
-rw-r--r--Objects/iterobject.c4
-rw-r--r--Objects/listobject.c500
-rw-r--r--Objects/lnotab_notes.txt124
-rw-r--r--Objects/longobject.c2027
-rw-r--r--Objects/memoryobject.c138
-rw-r--r--Objects/methodobject.c4
-rw-r--r--Objects/moduleobject.c75
-rw-r--r--Objects/object.c202
-rw-r--r--Objects/obmalloc.c143
-rw-r--r--Objects/rangeobject.c626
-rw-r--r--Objects/setobject.c109
-rw-r--r--Objects/sliceobject.c27
-rw-r--r--Objects/stringlib/README.txt4
-rw-r--r--Objects/stringlib/count.h16
-rw-r--r--Objects/stringlib/ctype.h1
-rw-r--r--Objects/stringlib/fastsearch.h148
-rw-r--r--Objects/stringlib/find.h86
-rw-r--r--Objects/stringlib/formatter.h92
-rw-r--r--Objects/stringlib/partition.h47
-rw-r--r--Objects/stringlib/split.h394
-rw-r--r--Objects/stringlib/string_format.h26
-rw-r--r--Objects/stringlib/stringdefs.h4
-rw-r--r--Objects/stringlib/transmogrify.h113
-rw-r--r--Objects/stringlib/unicodedefs.h22
-rw-r--r--Objects/structseq.c238
-rw-r--r--Objects/tupleobject.c10
-rw-r--r--Objects/typeobject.c181
-rw-r--r--Objects/typeslots.inc75
-rw-r--r--Objects/typeslots.py30
-rw-r--r--Objects/unicodectype.c657
-rw-r--r--Objects/unicodeobject.c1585
-rw-r--r--Objects/unicodetype_db.h4305
-rw-r--r--Objects/weakrefobject.c4
-rw-r--r--PC/VC6/_ctypes.dsp8
-rw-r--r--PC/VC6/_msi.dsp8
-rw-r--r--PC/VC6/build_ssl.py11
-rw-r--r--PC/VC6/bz2.dsp2
-rw-r--r--PC/VC6/pythoncore.dsp30
-rw-r--r--PC/VC6/readme.txt7
-rw-r--r--PC/VC6/tcl852.patch11
-rw-r--r--PC/VS7.1/pythoncore.vcproj64
-rwxr-xr-xPC/VS7.1/rt.bat2
-rw-r--r--PC/VS8.0/_hashlib.vcproj8
-rw-r--r--PC/VS8.0/_sqlite3.vcproj16
-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.py39
-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.sln23
-rw-r--r--PC/VS8.0/pyproject.vsprops6
-rw-r--r--PC/VS8.0/pythoncore.vcproj154
-rw-r--r--PC/VS8.0/rt.bat2
-rw-r--r--PC/VS8.0/sqlite3.vcproj8
-rw-r--r--PC/VS8.0/sqlite3.vsprops2
-rw-r--r--PC/VS8.0/ssl.vcproj189
-rw-r--r--PC/_msi.c2
-rw-r--r--PC/_subprocess.c9
-rw-r--r--PC/config.c6
-rw-r--r--PC/getpathp.c59
-rwxr-xr-xPC/msvcrtmodule.c19
-rw-r--r--PC/os2emx/Makefile1
-rw-r--r--PC/os2emx/python27.def6
-rw-r--r--PC/os2vacpp/python.def1
-rw-r--r--PC/pyconfig.h19
-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/winreg.c169
-rw-r--r--PC/winsound.c28
-rw-r--r--PCbuild/_hashlib.vcproj8
-rw-r--r--PCbuild/_ssl.vcproj8
-rw-r--r--PCbuild/build_ssl.py55
-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.sln58
-rw-r--r--PCbuild/pyproject.vsprops6
-rw-r--r--PCbuild/python3dll.vcproj246
-rw-r--r--PCbuild/pythoncore.vcproj154
-rw-r--r--PCbuild/readme.txt6
-rw-r--r--PCbuild/rt.bat6
-rw-r--r--PCbuild/ssl.vcproj189
-rw-r--r--PCbuild/vs9to8.py2
-rw-r--r--PCbuild/xxlimited.vcproj417
-rw-r--r--Parser/Python.asdl4
-rwxr-xr-xParser/asdl_c.py8
-rw-r--r--Parser/grammar.mak45
-rw-r--r--Parser/myreadline.c2
-rw-r--r--Parser/parsetok.c19
-rw-r--r--Parser/pgenmain.c2
-rw-r--r--Parser/printgrammar.c2
-rw-r--r--Parser/tokenizer.c143
-rw-r--r--Parser/tokenizer.h7
-rw-r--r--Python/Python-ast.c24
-rw-r--r--Python/_warnings.c125
-rw-r--r--Python/ast.c205
-rw-r--r--Python/bltinmodule.c163
-rw-r--r--Python/ceval.c616
-rw-r--r--Python/ceval_gil.h433
-rw-r--r--Python/compile.c335
-rw-r--r--Python/dtoa.c5
-rw-r--r--Python/dynamic_annotations.c154
-rw-r--r--Python/dynload_atheos.c47
-rw-r--r--Python/dynload_shlib.c21
-rw-r--r--Python/dynload_win.c14
-rw-r--r--Python/errors.c89
-rw-r--r--Python/fileutils.c431
-rw-r--r--Python/formatter_unicode.c2
-rw-r--r--Python/future.c8
-rw-r--r--Python/getargs.c502
-rw-r--r--Python/getcopyright.c2
-rw-r--r--Python/getopt.c6
-rw-r--r--Python/graminit.c1768
-rw-r--r--Python/import.c816
-rw-r--r--Python/importdl.c34
-rw-r--r--Python/marshal.c24
-rw-r--r--Python/modsupport.c46
-rw-r--r--Python/opcode_targets.h8
-rw-r--r--Python/peephole.c44
-rw-r--r--Python/pyarena.c1
-rw-r--r--Python/pymath.c199
-rw-r--r--Python/pystate.c58
-rw-r--r--Python/pystrtod.c88
-rw-r--r--Python/pythonrun.c315
-rw-r--r--Python/pytime.c60
-rw-r--r--Python/symtable.c73
-rw-r--r--Python/sysmodule.c691
-rw-r--r--Python/thread.c14
-rw-r--r--Python/thread_atheos.h300
-rw-r--r--Python/thread_cthread.h50
-rw-r--r--Python/thread_foobar.h44
-rw-r--r--Python/thread_lwp.h40
-rw-r--r--Python/thread_nt.h124
-rw-r--r--Python/thread_os2.h46
-rw-r--r--Python/thread_pth.h39
-rw-r--r--Python/thread_pthread.h239
-rw-r--r--Python/thread_sgi.h122
-rw-r--r--Python/thread_solaris.h50
-rw-r--r--Python/thread_wince.h41
-rw-r--r--Python/traceback.c11
-rw-r--r--README170
-rw-r--r--Tools/README45
-rw-r--r--Tools/buildbot/clean-amd64.bat5
-rw-r--r--Tools/buildbot/clean.bat3
-rw-r--r--Tools/buildbot/external-amd64.bat10
-rw-r--r--Tools/buildbot/external-common.bat18
-rw-r--r--Tools/buildbot/external.bat10
-rw-r--r--Tools/buildbot/test.bat2
-rw-r--r--Tools/ccbench/ccbench.py612
-rw-r--r--Tools/demo/README16
-rwxr-xr-x[-rw-r--r--]Tools/demo/beer.py (renamed from Demo/scripts/beer.py)9
-rwxr-xr-x[-rw-r--r--]Tools/demo/eiffel.py (renamed from Demo/newmetaclasses/Eiffel.py)125
-rwxr-xr-xTools/demo/hanoi.py (renamed from Demo/tkinter/guido/hanoi.py)26
-rwxr-xr-xTools/demo/life.py (renamed from Demo/curses/life.py)119
-rwxr-xr-xTools/demo/markov.py (renamed from Demo/scripts/markov.py)6
-rwxr-xr-xTools/demo/mcast.py (renamed from Demo/sockets/mcast.py)22
-rwxr-xr-xTools/demo/queens.py (renamed from Demo/scripts/queens.py)6
-rw-r--r--Tools/demo/redemo.py (renamed from Tools/scripts/redemo.py)0
-rwxr-xr-xTools/demo/rpython.py38
-rwxr-xr-xTools/demo/rpythond.py (renamed from Demo/sockets/rpythond.py)34
-rwxr-xr-x[-rw-r--r--]Tools/demo/sortvisu.py (renamed from Demo/tkinter/guido/sortvisu.py)7
-rwxr-xr-x[-rw-r--r--]Tools/demo/ss1.py (renamed from Demo/tkinter/guido/ss1.py)8
-rwxr-xr-xTools/demo/vector.py (renamed from Demo/classes/Vec.py)10
-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.py840
-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.py215
-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
-rwxr-xr-xTools/freeze/freeze.py4
-rw-r--r--Tools/freeze/makeconfig.py13
-rw-r--r--Tools/gdb/libpython.py1633
-rw-r--r--Tools/i18n/makelocalealias.py4
-rwxr-xr-xTools/i18n/msgfmt.py58
-rwxr-xr-xTools/i18n/pygettext.py2
-rw-r--r--Tools/iobench/iobench.py545
-rw-r--r--Tools/modulator/EXAMPLE.py53
-rw-r--r--Tools/modulator/README25
-rw-r--r--Tools/modulator/ScrolledListbox.py37
-rw-r--r--Tools/modulator/Templates/module_head6
-rw-r--r--Tools/modulator/Templates/module_method14
-rw-r--r--Tools/modulator/Templates/module_tail37
-rw-r--r--Tools/modulator/Templates/object_head13
-rw-r--r--Tools/modulator/Templates/object_method14
-rw-r--r--Tools/modulator/Templates/object_mlist8
-rw-r--r--Tools/modulator/Templates/object_new13
-rw-r--r--Tools/modulator/Templates/object_structure37
-rw-r--r--Tools/modulator/Templates/object_tail33
-rw-r--r--Tools/modulator/Templates/object_tp_as_mapping29
-rw-r--r--Tools/modulator/Templates/object_tp_as_number162
-rw-r--r--Tools/modulator/Templates/object_tp_as_sequence58
-rw-r--r--Tools/modulator/Templates/object_tp_call7
-rw-r--r--Tools/modulator/Templates/object_tp_compare6
-rw-r--r--Tools/modulator/Templates/object_tp_dealloc7
-rw-r--r--Tools/modulator/Templates/object_tp_getattr7
-rw-r--r--Tools/modulator/Templates/object_tp_hash6
-rw-r--r--Tools/modulator/Templates/object_tp_print7
-rw-r--r--Tools/modulator/Templates/object_tp_repr9
-rw-r--r--Tools/modulator/Templates/object_tp_setattr9
-rw-r--r--Tools/modulator/Templates/object_tp_str10
-rwxr-xr-xTools/modulator/Tkextra.py234
-rwxr-xr-xTools/modulator/genmodule.py160
-rwxr-xr-xTools/modulator/modulator.py383
-rw-r--r--Tools/modulator/varsubst.py56
-rw-r--r--Tools/msi/merge.py84
-rw-r--r--Tools/msi/msi.py137
-rw-r--r--Tools/msi/msilib.py65
-rw-r--r--Tools/msi/uuids.py47
-rw-r--r--Tools/parser/test_unparse.py240
-rw-r--r--Tools/parser/unparse.py (renamed from Demo/parser/unparse.py)227
-rwxr-xr-xTools/pybench/pybench.py2
-rw-r--r--Tools/pynche/ChipViewer.py2
-rw-r--r--Tools/pynche/DetailsViewer.py2
-rw-r--r--Tools/pynche/ListViewer.py2
-rw-r--r--Tools/pynche/PyncheWidget.py22
-rw-r--r--Tools/pynche/StripViewer.py18
-rw-r--r--Tools/pynche/Switchboard.py10
-rw-r--r--Tools/pynche/TextViewer.py2
-rw-r--r--Tools/pynche/TypeinViewer.py2
-rw-r--r--Tools/scripts/README126
-rw-r--r--Tools/scripts/abitype.py199
-rwxr-xr-xTools/scripts/byext.py25
-rwxr-xr-xTools/scripts/byteyears.py2
-rwxr-xr-xTools/scripts/checkappend.py169
-rwxr-xr-xTools/scripts/checkpyc.py39
-rwxr-xr-xTools/scripts/classfix.py190
-rw-r--r--Tools/scripts/cleanfuture.py2
-rw-r--r--Tools/scripts/combinerefs.py2
-rwxr-xr-xTools/scripts/copytime.py2
-rwxr-xr-xTools/scripts/crlf.py2
-rwxr-xr-xTools/scripts/cvsfiles.py72
-rw-r--r--Tools/scripts/db2pickle.py2
-rwxr-xr-xTools/scripts/dutree.py2
-rwxr-xr-xTools/scripts/eptags.py2
-rwxr-xr-x[-rw-r--r--]Tools/scripts/find-uname.py (renamed from Demo/scripts/find-uname.py)2
-rw-r--r--Tools/scripts/find_recursionlimit.py2
-rwxr-xr-xTools/scripts/finddiv.py2
-rwxr-xr-xTools/scripts/findlinksto.py2
-rwxr-xr-xTools/scripts/findnocoding.py2
-rwxr-xr-xTools/scripts/fixcid.py2
-rwxr-xr-xTools/scripts/fixdiv.py2
-rwxr-xr-xTools/scripts/fixheader.py2
-rwxr-xr-xTools/scripts/fixnotice.py2
-rwxr-xr-xTools/scripts/fixps.py2
-rwxr-xr-xTools/scripts/ftpmirror.py2
-rw-r--r--Tools/scripts/get-remote-certificate.py (renamed from Tools/ssl/get-remote-certificate.py)9
-rwxr-xr-xTools/scripts/google.py2
-rwxr-xr-xTools/scripts/gprof2html.py2
-rwxr-xr-xTools/scripts/h2py.py10
-rwxr-xr-xTools/scripts/ifdef.py2
-rwxr-xr-xTools/scripts/lfcr.py2
-rwxr-xr-xTools/scripts/linktree.py2
-rwxr-xr-xTools/scripts/lll.py2
-rwxr-xr-xTools/scripts/logmerge.py185
-rw-r--r--[-rwxr-xr-x]Tools/scripts/mailerdaemon.py0
-rw-r--r--Tools/scripts/md5sum.py2
-rwxr-xr-xTools/scripts/methfix.py171
-rwxr-xr-xTools/scripts/mkreal.py2
-rwxr-xr-xTools/scripts/ndiff.py2
-rwxr-xr-xTools/scripts/nm2def.py2
-rwxr-xr-xTools/scripts/objgraph.py2
-rwxr-xr-xTools/scripts/parseentities.py2
-rwxr-xr-xTools/scripts/pathfix.py21
-rwxr-xr-xTools/scripts/pdeps.py2
-rw-r--r--Tools/scripts/pickle2db.py2
-rwxr-xr-xTools/scripts/pindent.py6
-rwxr-xr-xTools/scripts/ptags.py2
-rw-r--r--Tools/scripts/pysource.py2
-rwxr-xr-xTools/scripts/reindent.py62
-rwxr-xr-xTools/scripts/rgrep.py14
-rwxr-xr-xTools/scripts/serve.py35
-rw-r--r--Tools/scripts/setup.py20
-rwxr-xr-xTools/scripts/suff.py21
-rw-r--r--Tools/scripts/svneol.py51
-rwxr-xr-xTools/scripts/texi2html.py2
-rwxr-xr-xTools/scripts/treesync.py2
-rwxr-xr-xTools/scripts/untabify.py16
-rwxr-xr-xTools/scripts/which.py2
-rwxr-xr-xTools/scripts/xxci.py121
-rw-r--r--Tools/test2to3/README (renamed from Demo/distutils/test2to3/README)0
-rw-r--r--Tools/test2to3/maintest.py (renamed from Demo/distutils/test2to3/maintest.py)2
-rw-r--r--Tools/test2to3/setup.py (renamed from Demo/distutils/test2to3/setup.py)0
-rw-r--r--Tools/test2to3/test/runtests.py (renamed from Demo/distutils/test2to3/test/runtests.py)0
-rw-r--r--Tools/test2to3/test/test_foo.py (renamed from Demo/distutils/test2to3/test/test_foo.py)0
-rw-r--r--Tools/test2to3/test2to3/__init__.py (renamed from Demo/distutils/test2to3/test2to3/__init__.py)0
-rw-r--r--Tools/test2to3/test2to3/hello.py (renamed from Demo/distutils/test2to3/test2to3/hello.py)0
-rw-r--r--Tools/unicode/comparecodecs.py2
-rw-r--r--Tools/unicode/gencodec.py24
-rw-r--r--Tools/unicode/genwincodec.py61
-rw-r--r--Tools/unicode/genwincodecs.bat7
-rw-r--r--Tools/unicode/makeunicodedata.py231
-rw-r--r--Tools/unittestgui/README.txt16
-rw-r--r--Tools/unittestgui/unittestgui.py479
-rw-r--r--Tools/webchecker/README23
-rw-r--r--Tools/webchecker/tktools.py366
-rwxr-xr-xTools/webchecker/wcgui.py462
-rw-r--r--Tools/webchecker/wcmac.py9
-rwxr-xr-xTools/webchecker/webchecker.py890
-rwxr-xr-xTools/webchecker/websucker.py125
-rwxr-xr-xTools/webchecker/wsgui.py240
-rw-r--r--Tools/world/README85
-rwxr-xr-xTools/world/world568
-rwxr-xr-xconfigure1570
-rw-r--r--configure.in1674
-rw-r--r--pyconfig.h.in87
-rwxr-xr-xruntests.sh93
-rw-r--r--setup.py446
2208 files changed, 291930 insertions, 188798 deletions
diff --git a/.bzrignore b/.bzrignore
index 463e983..376f00f 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -11,27 +11,12 @@ python
build
Makefile.pre
platform
+pybuilddir.txt
pyconfig.h
libpython*.a
python.exe
-CP936.TXT
-SHIFT_JISX0213.TXT
-JOHAB.TXT
-EUC-JP.TXT
-NormalizationTest-3.2.0.txt
-NormalizationTest.txt
-BIG5.TXT
-BIG5HKSCS-2004.TXT
-CP949.TXT
-EUC-CN.TXT
-BIG5HKSCS.TXT
-SHIFTJIS.TXT
-EUC-KR.TXT
-EUC-JISX0213.TXT
-CP932.TXT
-CP950.TXT
+python-gdb.py
reflog.txt
-gb-18030-2000.xml
tags
TAGS
.gdb_history
@@ -47,5 +32,8 @@ 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__
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ad3d0e7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,44 @@
+*.cover
+*.o
+*.orig
+*.pyc
+*.pyd
+*.pyo
+*.rej
+*~
+Doc/build/
+Doc/tools/docutils/
+Doc/tools/jinja2/
+Doc/tools/pygments/
+Doc/tools/sphinx/
+Lib/lib2to3/*.pickle
+Makefile
+Makefile.pre
+Misc/python.pc
+Modules/Setup
+Modules/Setup.config
+Modules/Setup.local
+Modules/config.c
+Modules/ld_so_aix
+PCbuild/*.bsc
+PCbuild/*.dll
+PCbuild/*.exe
+PCbuild/*.exp
+PCbuild/*.lib
+PCbuild/*.ncb
+PCbuild/*.o
+PCbuild/*.pdb
+PCbuild/Win32-temp-*
+Parser/pgen
+Parser/pgen.stamp
+__pycache__
+autom4te.cache
+build/
+config.log
+config.status
+libpython*.a
+pybuilddir.txt
+pyconfig.h
+python
+python-gdb.py
+tags
diff --git a/.hgignore b/.hgignore
index 33e6caa..e5e149f 100644
--- a/.hgignore
+++ b/.hgignore
@@ -1,40 +1,23 @@
.gdb_history
.purify
-.svn
-BIG5.TXT
-BIG5HKSCS-2004.TXT
-BIG5HKSCS.TXT
-CP932.TXT
-CP936.TXT
-CP949.TXT
-CP950.TXT
-EUC-CN.TXT
-EUC-JISX0213.TXT
-EUC-JP.TXT
-EUC-KR.TXT
-JOHAB.TXT
+.svn/
Makefile$
Makefile.pre$
-NormalizationTest-3.2.0.txt
-NormalizationTest.txt
-SHIFTJIS.TXT
-SHIFT_JISX0213.TXT
-TAGS
-autom4te.cache
-build
-buildno
+TAGS$
+autom4te.cache$
+build/
+buildno$
config.cache
config.log
config.status
config.status.lineno
db_home
-gb-18030-2000.xml
-platform
-pyconfig.h
-python
-python.exe
-reflog.txt
-tags
+platform$
+pyconfig.h$
+python$
+python.exe$
+reflog.txt$
+tags$
Lib/plat-mac/errors.rsrc.df.rsrc
Doc/tools/sphinx/
Doc/tools/docutils/
@@ -42,15 +25,21 @@ Doc/tools/jinja/
Doc/tools/jinja2/
Doc/tools/pygments/
Misc/python.pc
-Modules/Setup
+Modules/Setup$
Modules/Setup.config
Modules/Setup.local
Modules/config.c
-Parser/pgen
-core
Modules/ld_so_aix$
+Parser/pgen$
+Parser/pgen.stamp$
+^core
+^python-gdb.py
+^python.exe-gdb.py
+^pybuilddir.txt
+
syntax: glob
libpython*.a
+*.swp
*.o
*.pyc
*.pyo
@@ -60,6 +49,8 @@ libpython*.a
*.rej
*~
Lib/lib2to3/*.pickle
+Lib/test/data/*
+Misc/*.wpu
PC/python_nt*.h
PC/pythonnt_rc*.h
PC/*.obj
@@ -72,3 +63,5 @@ PCbuild/*.o
PCbuild/*.ncb
PCbuild/*.bsc
PCbuild/Win32-temp-*
+__pycache__
+Modules/_testembed
diff --git a/.hgtags b/.hgtags
index 720a533..6427e41 100644
--- a/.hgtags
+++ b/.hgtags
@@ -75,3 +75,13 @@ a69a031ac1402dede8b1ef80096436bca6d371f3 v3.1
960efa327c5d9c18df995437b0ac550cb89c9f85 v3.1.2
d18e9d71f369d8211f6ac87252c6d3211f9bd09f v3.1.3rc1
a4f75773c0060cee38b0bb651a7aba6f56b0e996 v3.1.3
+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
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 c0631b6..0000000
--- a/Demo/cgi/README
+++ /dev/null
@@ -1,10 +0,0 @@
-CGI Examples
-------------
-
-Here are some example CGI programs.
-
-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 842fef2..0000000
--- a/Demo/cgi/cgi1.py
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/local/bin/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 1d5822c..0000000
--- a/Demo/cgi/cgi2.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/local/bin/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 a3421b5..0000000
--- a/Demo/cgi/cgi3.py
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/local/bin/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 6b97113..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:", end=' ')
- 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 as err:
- return "IOError: %s" % str(err)
diff --git a/Demo/classes/Complex.py b/Demo/classes/Complex.py
deleted file mode 100755
index 64c56d4..0000000
--- a/Demo/classes/Complex.py
+++ /dev/null
@@ -1,314 +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)
-# 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 __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 __bool__(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, end=' ')
- try:
- result = eval(expr)
- except:
- result = sys.exc_info()[0]
- 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 100755
index e1b054f..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(1)
-
-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*365 + (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 name in self.__dict__:
- 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 100755
index f931e93..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.ndbm
- self.db = dbm.ndbm.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 repr(key) in self.db
-
-
-def test():
- d = Dbm('@dbm', 'rw', 0o600)
- print(d)
- while 1:
- try:
- key = eval(input('key: '))
- if key in d:
- value = d[key]
- print('currently:', value)
- value = eval(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 100755
index a0cef74..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, builtins
- #Just a quick sanity check
- correct_result = builtins.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 builtins.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 100755
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/bitvec.py b/Demo/classes/bitvec.py
deleted file mode 100755
index 62b26cc..0000000
--- a/Demo/classes/bitvec.py
+++ /dev/null
@@ -1,322 +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 = 1 << l
- if bitmask <= param:
- raise ValueError('(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 = 0
- self._len = 0
- if not len(params):
- pass
- elif len(params) == 1:
- param, = params
- if type(param) == type([]):
- value = 0
- bit_mask = 1
- 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(0):
- 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(0):
- 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 & \
- ((1 << 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(int(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(int(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, 0
- 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 = ((1 << 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 = 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 & (1 << 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 | (1 << key)
- else:
- self._data = self._data & ~(1 << 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(0, 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 & ((1 << 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 = 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 = 0, 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(0, 0)
- elif multiplier == 1:
- return self.copy()
- #handle special cases all 0 or all 1...
- if self._data == 0:
- return BitVec(0, self._len * multiplier)
- elif (~self)._data == 0:
- return ~BitVec(0, self._len * multiplier)
- #otherwise el cheapo again...
- retval = BitVec(0, 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 = 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 = 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 = 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 & ((1 << self._len) - 1), \
- self._len)
-
- def __int__(self):
- return int(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 d2c534d..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 = list(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 as 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), end=' ')
-
-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 f9ed854..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), end=' ')
- print()
-
-main()
diff --git a/Demo/comparisons/systemtest.py b/Demo/comparisons/systemtest.py
deleted file mode 100755
index e3d840e..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 as 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 as 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/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 93372c5..0000000
--- a/Demo/curses/repeat.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#! /usr/bin/env python
-
-"""repeat [-i SECONDS] <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.
-
-The -i option lets you override the sleep time between executions.
-
-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
-import getopt
-
-def main():
- interval = 1.0
- try:
- opts, args = getopt.getopt(sys.argv[1:], "hi:")
- except getopt.error as err:
- print(err, file=sys.stderr)
- sys.exit(2)
- if not args:
- print(__doc__)
- sys.exit(0)
- for opt, arg in opts:
- if opt == "-i":
- interval = float(arg)
- if opt == "-h":
- print(__doc__)
- sys.exit(0)
- cmd = " ".join(args)
- cmd_really = cmd + " 2>&1"
- p = os.popen(cmd_really, "r")
- text = p.read()
- sts = p.close()
- text = addsts(interval, cmd, text, sts)
- w = curses.initscr()
- try:
- while True:
- w.erase()
- try:
- w.addstr(text)
- except curses.error:
- pass
- w.refresh()
- time.sleep(interval)
- p = os.popen(cmd_really, "r")
- text = p.read()
- sts = p.close()
- text = addsts(interval, cmd, text, sts)
- finally:
- curses.endwin()
-
-def addsts(interval, cmd, text, sts):
- now = time.strftime("%H:%M:%S")
- text = "%s, every %g sec: %s\n%s" % (now, interval, cmd, text)
- if sts:
- msg = "Exit status: %d; signal: %d" % (sts>>8, sts&0xFF)
- if text and not text.endswith("\n"):
- msg = "\n" + msg
- text += msg
- return text
-
-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 711b95b..0000000
--- a/Demo/embed/Makefile
+++ /dev/null
@@ -1,57 +0,0 @@
-# Makefile for embedded Python use demo.
-# (This version tailored for my Red Hat Linux 6.1 setup;
-# 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= 3.0
-
-# 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)/Modules/Makefile
-LIBS= -lnsl -ldl -lreadline -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 99d39ca..0000000
--- a/Demo/embed/demo.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Example of embedding Python in another program */
-
-#include "Python.h"
-
-PyObject* PyInit_xyzzy(void); /* Forward */
-
-main(int argc, char **argv)
-{
- /* Ignore passed-in argc/argv. If desired, conversion
- should use mbstowcs to convert them. */
- wchar_t *args[] = {L"embed", L"hello", 0};
-
- /* Pass argv[0] to the Python interpreter */
- Py_SetProgramName(args[0]);
-
- /* Add a static module */
- PyImport_AppendInittab("xyzzy", PyInit_xyzzy);
-
- /* Initialize the Python interpreter. Required. */
- Py_Initialize();
-
- /* Define sys.argv. It is up to the application if you
- want this; you can also let 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(2, args, 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 PyLong_FromLong(42L);
-}
-
-static PyMethodDef xyzzy_methods[] = {
- {"foo", xyzzy_foo, METH_NOARGS,
- "Return the meaning of everything."},
- {NULL, NULL} /* sentinel */
-};
-
-static struct PyModuleDef xyzzymodule = {
- {}, /* m_base */
- "xyzzy", /* m_name */
- 0, /* m_doc */
- 0, /* m_size */
- xyzzy_methods, /* m_methods */
- 0, /* m_reload */
- 0, /* m_traverse */
- 0, /* m_clear */
- 0, /* m_free */
-};
-
-PyObject*
-PyInit_xyzzy(void)
-{
- return PyModule_Create(&xyzzymodule);
-}
diff --git a/Demo/embed/importexc.c b/Demo/embed/importexc.c
deleted file mode 100644
index 59b1d01..0000000
--- a/Demo/embed/importexc.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <Python.h>
-
-#if 0
-char* cmd = "import codecs, encodings.utf_8, types; print(types)";
-#else
-char* cmd = "import types; print(types)";
-#endif
-
-int main()
-{
- printf("Initialize interpreter\n");
- Py_Initialize();
- PyEval_InitThreads();
- PyRun_SimpleString(cmd);
- Py_EndInterpreter(PyThreadState_Get());
-
- printf("\nInitialize subinterpreter\n");
- 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 4a341fd..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(L"loop");
-
- /* 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 100755
index 7f561ab..0000000
--- a/Demo/md5test/md5driver.py
+++ /dev/null
@@ -1,122 +0,0 @@
-from hashlib import md5
-import string
-from sys import argv
-
-def MDPrint(str):
- outstr = ''
- for o in str:
- outstr = (outstr
- + string.hexdigits[(o >> 4) & 0xF]
- + string.hexdigits[o & 0xF])
- print(outstr, end=' ')
-
-
-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()
-
- 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(str.encode("utf-8")).digest())
- print('"' + str + '"')
-
-
-def MDFile(filename):
- f = open(filename, 'rb')
- mdContext = md5()
-
- while 1:
- data = f.read(1024)
- if not data:
- break
- mdContext.update(data)
-
- MDPrint(mdContext.digest())
- print(filename)
-
-
-import sys
-
-def MDFilter():
- mdContext = md5()
-
- while 1:
- data = sys.stdin.read(16).encode()
- 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/newmetaclasses/Enum.py b/Demo/newmetaclasses/Enum.py
deleted file mode 100644
index 3ff8ddd..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):
- pass
-
-class FullEnum(metaclass=FullEnumMetaclass):
- pass
-
-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 a576d33..0000000
--- a/Demo/parser/README
+++ /dev/null
@@ -1,31 +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.
-
- example.py -- module that uses the `parser' module to extract
- information from the parse tree of Python source
- code.
-
- docstring.py -- sample source file containing only a module docstring.
-
- 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.
-
- unparse.py AST (2.5) based example to recreate source code
- from an AST. This is incomplete; contributions
- are welcome.
-
-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 c2f0883..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 list(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 list(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 list(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 e4d5571..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, end=' ')
- try:
- ast = parser.suite(t)
- tup = parser.ast2tuple(ast)
- # this discards the first AST; a huge memory savings when running
- # against a large source file like Tkinter.py.
- ast = None
- new = parser.tuple2ast(tup)
- except parser.ParserError as err:
- print()
- print('parser module raised exception on input file', fileName + ':')
- traceback.print_exc()
- _numFailed = _numFailed + 1
- else:
- if tup != parser.ast2tuple(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()
- list(map(testFile, args))
- sys.exit(_numFailed != 0)
-
-if __name__ == '__main__':
- test()
diff --git a/Demo/parser/texipre.dat b/Demo/parser/texipre.dat
deleted file mode 100644
index 8ad03a6..0000000
--- a/Demo/parser/texipre.dat
+++ /dev/null
@@ -1,100 +0,0 @@
-\input texinfo @c -*-texinfo-*-
-@c %**start of header
-@setfilename parser.info
-@settitle Python Parser Module Reference
-@setchapternewpage odd
-@footnotestyle end
-@c %**end of header
-
-@ifinfo
-This file describes the interfaces
-published by the optional @code{parser} module and gives examples of
-how they may be used. It contains the same text as the chapter on the
-@code{parser} module in the @cite{Python Library Reference}, but is
-presented as a separate document.
-
-Copyright 1995-1996 by Fred L. Drake, Jr., Reston, Virginia, USA, and
-Virginia Polytechnic Institute and State University, Blacksburg,
-Virginia, USA. Portions of the software copyright 1991-1995 by
-Stichting Mathematisch Centrum, Amsterdam, The Netherlands. Copying is
-permitted under the terms associated with the main Python distribution,
-with the additional restriction that this additional notice be included
-and maintained on all distributed copies.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the names of Fred L. Drake, Jr. and
-Virginia Polytechnic Institute and State University not be used in
-advertising or publicity pertaining to distribution of the software
-without specific, written prior permission.
-
-FRED L. DRAKE, JR. AND VIRGINIA POLYTECHNIC INSTITUTE AND STATE
-UNIVERSITY DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-EVENT SHALL FRED L. DRAKE, JR. OR VIRGINIA POLYTECHNIC INSTITUTE AND
-STATE UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
-PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-@end ifinfo
-
-@titlepage
-@title Python Parser Module Reference
-@author Fred L. Drake, Jr.
-
-@c The following two commands start the copyright page.
-@page
-@vskip 0pt plus 1filll
-Copyright 1995-1996 by Fred L. Drake, Jr., Reston, Virginia, USA, and
-Virginia Polytechnic Institute and State University, Blacksburg,
-Virginia, USA. Portions of the software copyright 1991-1995 by
-Stichting Mathematisch Centrum, Amsterdam, The Netherlands. Copying is
-permitted under the terms associated with the main Python distribution,
-with the additional restriction that this additional notice be included
-and maintained on all distributed copies.
-
-@center All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the names of Fred L. Drake, Jr. and
-Virginia Polytechnic Institute and State University not be used in
-advertising or publicity pertaining to distribution of the software
-without specific, written prior permission.
-
-FRED L. DRAKE, JR. AND VIRGINIA POLYTECHNIC INSTITUTE AND STATE
-UNIVERSITY DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-EVENT SHALL FRED L. DRAKE, JR. OR VIRGINIA POLYTECHNIC INSTITUTE AND
-STATE UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
-PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-@end titlepage
-
-
-@node Top, Overview, (dir), (dir)
-@top The Python Parser Module
-
-@ifinfo
-This file describes the interfaces
-published by the optional @code{parser} module and gives examples of
-how they may be used. It contains the same text as the chapter on the
-@code{parser} module in the @cite{Python Library Reference}, but is
-presented as a separate document.
-
-This version corresponds to Python version 1.4 (1 Sept. 1996).
-
-@end ifinfo
-
-@c placeholder for the master menu -- patched by texinfo-all-menus-update
-@menu
-@end menu
diff --git a/Demo/pdist/FSProxy.py b/Demo/pdist/FSProxy.py
deleted file mode 100755
index 510ac76..0000000
--- a/Demo/pdist/FSProxy.py
+++ /dev/null
@@ -1,322 +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
-
-if os.name == 'mac':
- import macfs
- maxnamelen = 31
-else:
- macfs = None
- 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):
- if os.name == 'mac':
- return name[0] == '(' and name[-1] == ')'
- else:
- return name[0] == '.'
-
- def _hide(self, name):
- if os.name == 'mac':
- return '(%s)' % name
- else:
- 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 macfs:
- if os.path.exists(name) and not os.path.isdir(name):
- try:
- fs = macfs.FSSpec(name)
- c, t = fs.GetCreatorType()
- if t != 'TEXT': return 0
- except macfs.error as msg:
- print("***", name, msg)
- return 0
- else:
- 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 = list(filter(keep, files))
- files = list(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 = list(filter(os.path.isfile, files))
- return self._filter(files, pat)
-
- def listsubdirs(self, pat = None):
- files = os.listdir(os.curdir)
- files = list(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, 0o777)
-
- 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 7c3b24f..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 = list(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, 0o777)
-
- 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 hasattr(attr, '__call__'):
- print(attr(*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 100755
index c9fe369..0000000
--- a/Demo/pdist/client.py
+++ /dev/null
@@ -1,156 +0,0 @@
-"""RPC Client module."""
-
-import sys
-import socket
-import pickle
-import builtins
-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(builtins, exception):
- x = getattr(builtins, 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 id in self._replies:
- 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):
- self._pre_init(*args)
- Security.__init__(self)
- self._wf.flush()
- line = self._rf.readline()
- challenge = int(line.strip())
- response = self._encode_challenge(challenge)
- line = repr(int(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 100755
index ec854b1..0000000
--- a/Demo/pdist/cmdfw.py
+++ /dev/null
@@ -1,142 +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 as 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 as 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 name in docstrings:
- 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:")
- for name in sorted(docstrings.keys()):
- 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 100755
index c1bbf1a..0000000
--- a/Demo/pdist/cmptree.py
+++ /dev/null
@@ -1,213 +0,0 @@
-"""Compare local and remote dictionaries and transfer differing files -- like rdist."""
-
-import sys
-from reprlib import repr
-import FSProxy
-import time
-import os
-
-def raw_input(prompt):
- sys.stdout.write(prompt)
- sys.stdout.flush()
- return sys.stdin.readline()
-
-def main():
- pwd = os.getcwd()
- s = 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 = 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")
- input("[Return to exit] ")
-
-def ask(prompt, default):
- s = input("%s [%s] " % (prompt, default))
- return s or default
-
-def askint(prompt, default):
- s = 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 name not in lsumdict:
- 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), end=' ')
- rmtime = remote.mtime(name)
- lmtime = local.mtime(name)
- if rmtime > lmtime:
- print("remote newer", end=' ')
- if 'r' in mode:
- recvfile(local, remote, name)
- elif lmtime > rmtime:
- print("local newer", end=' ')
- if 'w' in mode:
- sendfile(local, remote, name)
- else:
- print("same mtime but different sum?!?!", end=' ')
- print()
- for name in lsumdict.keys():
- if not list(rsumdict.keys()):
- print(repr(name), "only locally", end=' ')
- 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) as msg:
- print("cannot create:", msg)
- return
-
- print("sending ...", end=' ')
- 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", end=' ')
- if dt:
- print("i.e.", round(len(data)/dt), "bytes/sec", end=' ')
- 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) as msg:
- print("cannot create:", msg)
- return
-
- print("receiving ...", end=' ')
- 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", end=' ')
- if dt:
- print("i.e.", int(size//dt), "bytes/sec", end=' ')
- 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 100755
index 78e4fbb..0000000
--- a/Demo/pdist/cvslib.py
+++ /dev/null
@@ -1,359 +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 list(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 list(self.values()):
- f.write(e.putentry())
- f.close()
-
- def getlocalfiles(self):
- entries_keys = set(self.entries.keys())
- addlist = os.listdir(os.curdir)
- for name in addlist:
- if not self.ignored(name):
- entries_keys.add(name)
- for file in sorted(entries_keys):
- 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 list(self.values()):
- e.report()
- print('-'*50)
-
- def keys(self):
- return sorted(self.entries.keys())
-
- def values(self):
- def value(key, self=self):
- return self.entries[key]
- return [value(k) for k in self.keys()]
-
- def items(self):
- def item(key, self=self):
- return (key, self.entries[key])
- return [item(k) for k in 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] = list(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 100755
index ffaa15e..0000000
--- a/Demo/pdist/cvslock.py
+++ /dev/null
@@ -1,279 +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, 0o777)
- return
- except os.error as msg:
- self.lockdir = None
- if msg.args[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], end=' ')
- 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 as 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])
- 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 100755
index beb77ec..0000000
--- a/Demo/pdist/mac.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import sys
-import rcvs
-
-def raw_input(prompt):
- sys.stdout.write(prompt)
- sys.stdout.flush()
- return sys.stdin.readline()
-
-def main():
- while 1:
- try:
- line = input('$ ')
- except EOFError:
- break
- words = line.split()
- if not words:
- continue
- if words[0] != 'rcvs':
- words.insert(0, 'rcvs')
- sys.argv = words
- rcvs.main()
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/pdist/makechangelog.py b/Demo/pdist/makechangelog.py
deleted file mode 100755
index db66e8f..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 author in authormap: author = authormap[author]
- tfields = list(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, end=' ')
- col = -1
- else:
- print(word, end=' ')
- 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 100755
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 100755
index 9690f3b..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 = list(filter(self._isrcs, files))
- if os.path.isdir('RCS'):
- files2 = os.listdir('RCS')
- files2 = list(filter(self._isrcs, files2))
- files = files + files2
- files = list(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 = list(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 4e2532a..0000000
--- a/Demo/pdist/rcvs.py
+++ /dev/null
@@ -1,476 +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 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:", end=' ')
- print(self.file, end=' ')
- 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 = 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, ' '.join(files),
- ' '.join(files), message)
- print('-'*70)
- print(mailtext)
- print('-'*70)
- ok = input("OK to mail to %s? " % towhom)
- if ok.lower().strip() 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 file in self.entries:
- e = self.entries[file]
- else:
- e = self.FileClass(file)
- self.entries[file] = e
- list.append(e)
- else:
- list = list(self.entries.values())
- for file in self.proxy.listfiles():
- if file in self.entries:
- continue
- e = self.FileClass(file)
- self.entries[file] = e
- list.append(e)
- if localfilestoo:
- for file in os.listdir(os.curdir):
- if file not in self.entries \
- 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 647ecc5..0000000
--- a/Demo/pdist/rrcs.py
+++ /dev/null
@@ -1,158 +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 cmd not in commands:
- raise getopt.error("unknown command")
- coptset, func = commands[cmd]
- copts, files = getopt.getopt(rest, coptset)
- except getopt.error as 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) as 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):
- info_dict = x.info(fn)
- for key in sorted(info_dict.keys()):
- print(key + ':', info_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,", end=' ')
- else:
- print("enter log message,", end=' ')
- 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 100755
index ffdbe2d..0000000
--- a/Demo/pdist/security.py
+++ /dev/null
@@ -1,33 +0,0 @@
-class Security:
-
- def __init__(self):
- import os
- env = os.environ
- if 'PYTHON_KEYFILE' in env:
- keyfile = env['PYTHON_KEYFILE']
- else:
- keyfile = '.python_keyfile'
- if 'HOME' in env:
- 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(int(challenge), p, m)
diff --git a/Demo/pdist/server.py b/Demo/pdist/server.py
deleted file mode 100755
index b3943ff..0000000
--- a/Demo/pdist/server.py
+++ /dev/null
@@ -1,143 +0,0 @@
-"""RPC Server module."""
-
-import sys
-import socket
-import pickle
-from fnmatch import fnmatch
-from reprlib 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, method(*args), id)
- except:
- reply = (sys.exc_info()[:2], 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 = sorted([x for x in cl.__dict__.keys() if x[0] != '_'])
- for base in cl.__bases__:
- basenames = self._listmethods(base)
- basenames = list(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):
- 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 100755
index 92e7771..0000000
--- a/Demo/pdist/sumtree.py
+++ /dev/null
@@ -1,27 +0,0 @@
-import time
-import sys
-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")
- sys.stdout.write("[Return to exit] ")
- sys.stdout.flush()
- sys.stdin.readline()
-
-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 3e94dbe..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 as msg:
- usage(msg)
- for o, a in opts:
- pass
- if args:
- try:
- port = string.atoi(args[0])
- except ValueError as msg:
- usage(msg)
- else:
- port = PORT
- main_thread(port)
-
-def usage(msg=None):
- sys.stdout = sys.stderr
- if msg:
- print(msg)
- print("\n", __doc__, end=' ')
- 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), end=' ')
- stdin = conn.makefile("r")
- stdout = conn.makefile("w", 0)
- run_interpreter(stdin, stdout)
- print("Thread %s is done.\n" % str(_thread.get_ident()), end=' ')
-
-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 as 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 as 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, globals)
- except SystemExit as how:
- raise SystemExit(how).with_traceback(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 81797df..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 a291ce0..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 eaabefe..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:', end=' ')
- for (line, name, host, time), idle in list:
- print(strip0(name), end=' ')
- 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 30b3017..0000000
--- a/Demo/rpc/rpc.py
+++ /dev/null
@@ -1,890 +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 | 0x80000000
- 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 = int(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 as e:
- (errno, msg) = e
- 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 as 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, end=' ')
- if prot == IPPROTO_TCP: print('tcp', end=' ')
- elif prot == IPPROTO_UDP: print('udp', end=' ')
- else: print(prot, end=' ')
- 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 as 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 2d5f9c3..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(0)
-
-
-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 + 0x80000000) % 0x100000000 \
- - 0x80000000)
- 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 = int(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 < 0x80000000: 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 >= 0x80000000: x = x - 0x100000000
- return int(x)
-
- unpack_enum = unpack_int
-
- unpack_bool = unpack_int
-
- def unpack_uhyper(self):
- hi = self.unpack_uint()
- lo = self.unpack_uint()
- return int(hi)<<32 | lo
-
- def unpack_hyper(self):
- x = self.unpack_uhyper()
- if x >= 0x8000000000000000: x = x - 0x10000000000000000
- 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 097b9b7..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 (as an 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/eqfix.py b/Demo/scripts/eqfix.py
deleted file mode 100755
index 47c00d3..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 as 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 as 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 as 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] & 0o7777)
- except os.error as 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 as 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 as 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, end=' ')
- 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 token in match:
- 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, end=' ')
- return line
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/scripts/fact.py b/Demo/scripts/fact.py
deleted file mode 100755
index 71fcda2..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(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/from.py b/Demo/scripts/from.py
deleted file mode 100755
index 323e684..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], end=' ')
- while 1:
- line = mail.readline()
- if not line or line == '\n':
- break
- if line.startswith('Subject: '):
- print(repr(line[9:-1]), end=' ')
- print()
diff --git a/Demo/scripts/lpwatch.py b/Demo/scripts/lpwatch.py
deleted file mode 100755
index 90b3ecf..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 'PRINTER' in os.environ:
- 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' % next(iter(users))
- 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 7095868..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, 0o777)
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/scripts/mboxconvert.py b/Demo/scripts/mboxconvert.py
deleted file mode 100755
index 2e44f06..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 as 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 as 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 as 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.get('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, end=' ')
- # Invent Message-ID header if none is present
- if 'message-id' not in m:
- 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, end=' ')
- # 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 5aacaa1..0000000
--- a/Demo/scripts/morse.py
+++ /dev/null
@@ -1,128 +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, aifc
-from contextlib import closing
-
-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 = b'\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 = bytearray()
- for i in range(100):
- val = int(math.sin(math.pi * i * octave / 50.0) * 30000)
- sinewave.extend([(val >> 8) & 255, val & 255])
- return bytes(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)
- wave = defaultwave
- outfile = 'morse.aifc'
- for o, a in opts:
- if o == '-o':
- outfile = a
- if o == '-p':
- wave = mkwave(int(a))
- with closing(aifc.open(outfile, 'w')) as fp:
- fp.setframerate(44100)
- fp.setsampwidth(2)
- fp.setnchannels(1)
- if args:
- source = [' '.join(args)]
- else:
- source = iter(sys.stdin.readline, '')
- for line in source:
- mline = morse(line)
- play(mline, fp, wave)
-
-# 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, fp, wave):
- for c in line:
- if c == '.':
- sine(fp, DOT, wave)
- elif c == '-':
- sine(fp, DAH, wave)
- else: # space
- pause(fp, DAH + DOT)
- pause(fp, DOT)
-
-def sine(fp, length, wave):
- for i in range(length):
- fp.writeframesraw(wave)
-
-def pause(fp, length):
- for i in range(length):
- fp.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 9cea1b4..0000000
--- a/Demo/scripts/newslist.py
+++ /dev/null
@@ -1,361 +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)
- exec(open(rcfile).read())
- break
-
-from nntplib import NNTP
-from stat import *
-
-rcsrev = '$Revision$'
-rcsrev = ' '.join([s for s in rcsrev.split() if '$' not in s])
-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 = sorted(tree.keys())
-
- if l > 1:
- 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, 0o777)
- 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.decode() + ' ', end=' ')
- else:
- groups.append(grpname.decode())
- 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, end=' ')
- info = server.newgroups(treedate, '000001')[1]
- print('got %d.' % len(info))
- print('Processing...', end=' ')
- groups = []
- for i in info:
- grpname = i.split()[0]
- groups.append(grpname.decode())
- 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) as 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 2c948f7..0000000
--- a/Demo/scripts/pp.py
+++ /dev/null
@@ -1,125 +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 as 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'
-
-if DFLAG:
- import pdb
- pdb.run(program)
-else:
- exec(program)
diff --git a/Demo/scripts/primes.py b/Demo/scripts/primes.py
deleted file mode 100755
index 0924aab..0000000
--- a/Demo/scripts/primes.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#! /usr/bin/env python
-
-# Print prime numbers in a given range
-
-def main():
- import sys
- min, max = 2, 0x7fffffff
- if sys.argv[1:]:
- min = int(eval(sys.argv[1]))
- if sys.argv[2:]:
- max = int(eval(sys.argv[2]))
- primes(min, max)
-
-def primes(min, max):
- if 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 = i+2
-
-if __name__ == "__main__":
- main()
diff --git a/Demo/scripts/script.py b/Demo/scripts/script.py
deleted file mode 100755
index b490b17..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 = 'wb'
-if 'SHELL' in os.environ:
- shell = os.environ['SHELL']
-
-try:
- opts, args = getopt.getopt(sys.argv[1:], 'ap')
-except getopt.error as msg:
- print('%s: %s' % (sys.argv[0], msg))
- sys.exit(2)
-
-for o, a in opts:
- if o == '-a':
- mode = 'ab'
- 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())).encode())
-pty.spawn(shell, read)
-script.write(('Script done on %s\n' % time.ctime(time.time())).encode())
-sys.stdout.write('Script done, file is %s\n' % filename)
diff --git a/Demo/scripts/toaiff.py b/Demo/scripts/toaiff.py
deleted file mode 100644
index 0e9be23..0000000
--- a/Demo/scripts/toaiff.py
+++ /dev/null
@@ -1,107 +0,0 @@
-"""Convert "arbitrary" sound files to AIFF (Apple and SGI's audio format).
-
-Input may be compressed.
-Uncompressed file type may be AIFF, WAV, VOC, 8SVX, NeXT/Sun, and others.
-An exception is raised if the file is not of a recognized type.
-Returned filename is either the input filename or a temporary filename;
-in the latter case the caller must ensure that it is removed.
-Other temporary files used are removed by the function.
-"""
-
-import os
-import tempfile
-import pipes
-import sndhdr
-
-__all__ = ["error", "toaiff"]
-
-table = {}
-
-t = pipes.Template()
-t.append('sox -t au - -t aiff -r 8000 -', '--')
-table['au'] = t
-
-# XXX The following is actually sub-optimal.
-# XXX The HCOM sampling rate can be 22k, 22k/2, 22k/3 or 22k/4.
-# XXX We must force the output sampling rate else the SGI won't play
-# XXX files sampled at 5.5k or 7.333k; however this means that files
-# XXX sampled at 11k are unnecessarily expanded.
-# XXX Similar comments apply to some other file types.
-t = pipes.Template()
-t.append('sox -t hcom - -t aiff -r 22050 -', '--')
-table['hcom'] = t
-
-t = pipes.Template()
-t.append('sox -t voc - -t aiff -r 11025 -', '--')
-table['voc'] = t
-
-t = pipes.Template()
-t.append('sox -t wav - -t aiff -', '--')
-table['wav'] = t
-
-t = pipes.Template()
-t.append('sox -t 8svx - -t aiff -r 16000 -', '--')
-table['8svx'] = t
-
-t = pipes.Template()
-t.append('sox -t sndt - -t aiff -r 16000 -', '--')
-table['sndt'] = t
-
-t = pipes.Template()
-t.append('sox -t sndr - -t aiff -r 16000 -', '--')
-table['sndr'] = t
-
-uncompress = pipes.Template()
-uncompress.append('uncompress', '--')
-
-
-class error(Exception):
- pass
-
-def toaiff(filename):
- temps = []
- ret = None
- try:
- ret = _toaiff(filename, temps)
- finally:
- for temp in temps[:]:
- if temp != ret:
- try:
- os.unlink(temp)
- except os.error:
- pass
- temps.remove(temp)
- return ret
-
-def _toaiff(filename, temps):
- if filename[-2:] == '.Z':
- (fd, fname) = tempfile.mkstemp()
- os.close(fd)
- temps.append(fname)
- sts = uncompress.copy(filename, fname)
- if sts:
- raise error(filename + ': uncompress failed')
- else:
- fname = filename
- try:
- ftype = sndhdr.whathdr(fname)
- if ftype:
- ftype = ftype[0] # All we're interested in
- except IOError as msg:
- if type(msg) == type(()) and len(msg) == 2 and \
- type(msg.args[0]) == type(0) and type(msg.args[1]) == type(''):
- msg = msg.args[1]
- if type(msg) != type(''):
- msg = repr(msg)
- raise error(filename + ': ' + msg)
- if ftype == 'aiff':
- return fname
- if ftype is None or not ftype in table:
- raise error('%s: unsupported audio file type %r' % (filename, ftype))
- (fd, temp) = tempfile.mkstemp()
- os.close(fd)
- temps.append(temp)
- sts = table[ftype].copy(fname, temp)
- if sts:
- raise error(filename + ': conversion to aiff failed')
- return temp
diff --git a/Demo/scripts/unbirthday.py b/Demo/scripts/unbirthday.py
deleted file mode 100755
index af58f8f..0000000
--- a/Demo/scripts/unbirthday.py
+++ /dev/null
@@ -1,106 +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(input('In which year were you born? '))
- if 0 <= year < 100:
- print("I'll assume that by", year, end=' ')
- 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(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(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', end=' ')
- else:
- print('Today is your', end=' ')
- print(nth(days - age), 'unbirthday')
-
-def format(date):
- (year, month, day) = date
- 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(date):
- # 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...
- (year, month, day) = date
- 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 d49e4b3..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 as 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) as 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), end=' ')
- 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), end=' ')
- return
- if self.lines[i] == rest:
- print('(no change): %s:%s:%s' % (
- self.filename, lineno, rest), end=' ')
- return
- if not self.changed:
- self.changed = 1
- print('%sc%s' % (lineno, lineno))
- print('<', self.lines[i], end=' ')
- print('---')
- self.lines[i] = rest
- print('>', self.lines[i], end=' ')
-
-def main():
- if sys.argv[1:]:
- try:
- fp = open(sys.argv[1], 'r')
- except IOError as 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, end=' ')
- 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/scripts/wh.py b/Demo/scripts/wh.py
deleted file mode 100755
index b9b09ef..0000000
--- a/Demo/scripts/wh.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# This is here so I can use 'wh' instead of 'which' in '~/bin/generic_python'
-import which
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 100755
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 7de6391..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 100755
index 5ea99c7..0000000
--- a/Demo/sockets/ftp.py
+++ /dev/null
@@ -1,152 +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, end=' ')
- code = line[:3]
- if line[3:4] == '-':
- while 1:
- line = f.readline()
- if not line: break # Really an error
- print(line, end=' ')
- 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)')
-
-def raw_input(prompt):
- sys.stdout.write(prompt)
- sys.stdout.flush()
- return sys.stdin.readline()
-
-# Get a command from the user.
-#
-def getcommand():
- try:
- while 1:
- line = input('ftp.py> ')
- if line: return line
- except EOFError:
- return ''
-
-
-# Call the main program.
-#
-if __name__ == '__main__':
- main()
diff --git a/Demo/sockets/gopher.py b/Demo/sockets/gopher.py
deleted file mode 100755
index c287319..0000000
--- a/Demo/sockets/gopher.py
+++ /dev/null
@@ -1,352 +0,0 @@
-#! /usr/bin/env python
-
-# A simple gopher client.
-#
-# Usage: gopher [ [selector] host [port] ]
-
-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 = int(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 = line[1:].split(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 as 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(repr(i+1).rjust(3) + ':', description, end=' ')
- if typechar in typename:
- print(typename[typechar])
- else:
- print('<TYPE=' + repr(typechar) + '>')
- print()
- while 1:
- try:
- str = input('Choice [CR == up a level]: ')
- except EOFError:
- print()
- return
- if not str:
- return
- try:
- choice = int(str)
- except ValueError:
- 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 typechar in typebrowser:
- browserfunc = typebrowser[typechar]
- try:
- browserfunc(i_selector, i_host, i_port)
- except (IOError, socket.error):
- t, v, tb = sys.exc_info()
- print('***', t, ':', v)
- 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 as 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 as msg:
- print('IOError:', msg)
- x.close()
-
-def raw_input(prompt):
- sys.stdout.write(prompt)
- sys.stdout.flush()
- return sys.stdin.readline()
-
-# 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 = input('Query [CR == up a level]: ')
- except EOFError:
- print()
- break
- query = query.strip()
- 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 = input( \
- 'Save as file [CR == don\'t save; |pipeline or ~user/... OK]: ')
- except EOFError:
- print()
- return None
- savefile = savefile.strip()
- if not savefile:
- return None
- if savefile[0] == '|':
- cmd = savefile[1:].strip()
- try:
- p = os.popen(cmd, 'w')
- except IOError as 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 as 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 = int(sys.argv[2])
- selector = ''
- host = sys.argv[1]
- except ValueError:
- 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/radio.py b/Demo/sockets/radio.py
deleted file mode 100755
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 b654dc2..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, end=' ')
-
-main()
diff --git a/Demo/sockets/telnet.py b/Demo/sockets/telnet.py
deleted file mode 100755
index 038036ff..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 as 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)', end=' ')
- else: print('(DONT)', end=' ')
- opt = IAC + WONT
- elif c in (WILL, WONT):
- if c == WILL: print('(WILL)', end=' ')
- else: print('(WONT)', end=' ')
- opt = IAC + DONT
- else:
- print('(command)', ord(c))
- elif c == IAC:
- iac = 1
- print('(IAC)', end=' ')
- 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 64244aa..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), end=' ')
- print('K/sec.')
-
-
-main()
diff --git a/Demo/sockets/udpecho.py b/Demo/sockets/udpecho.py
deleted file mode 100755
index 9966fd8..0000000
--- a/Demo/sockets/udpecho.py
+++ /dev/null
@@ -1,64 +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
- print('addr = ', addr)
- s.sendto(bytes(line, 'ascii'), 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 5e87eed..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(b'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 c3c9c4f..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 690fadc..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 as 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.__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:
- 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 target not in self.invokedby:
- 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 3a2963f..0000000
--- a/Demo/threads/Generator.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Generator implementation using threads
-
-import _thread as thread
-import sys
-
-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:
- 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 = 2, 4, 1, 12, 4
- while 1:
- # 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:
- g.put(int(d))
- a, a1 = 10*(a%b), 10*(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(), end=' ')
- print()
- h = g.clone()
- g.kill()
- while 1:
- print(h.get(), end=' ')
- 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 bc2e3ed..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), end=' ')
- 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 2b4ef7d..0000000
--- a/Demo/threads/find.py
+++ /dev/null
@@ -1,154 +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 time
-import os
-from stat import *
-import _thread as 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
- 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 = int(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] & 0o002) != 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 as 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 as 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 35b1b1d..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 90fff2e..0000000
--- a/Demo/threads/sync.py
+++ /dev/null
@@ -1,599 +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 are no threads waiting to write. (This is a
-# weakness of the interface!)
-
-import _thread as 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 dfe4905..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 as 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 as 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)', end=' ')
- else: print('(DONT)', end=' ')
- opt = IAC + WONT
- elif c in (WILL, WONT):
- if c == WILL: print('(WILL)', end=' ')
- else: print('(WONT)', end=' ')
- opt = IAC + DONT
- else:
- print('(command)', ord(c))
- elif c == IAC:
- iac = 1
- print('(IAC)', end=' ')
- 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 4268f07..0000000
--- a/Demo/tix/grid.py
+++ /dev/null
@@ -1,28 +0,0 @@
-###
-import tkinter.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 range(5):
- for y in range(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 100755
index bc25a2e..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 tkinter.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 = tkinter.tix.Label(w, width=40, relief=tkinter.tix.SUNKEN, bd=1)
- status.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.Y, padx=2, pady=1)
-
- # Create two mysterious widgets that need balloon help
- button1 = tkinter.tix.Button(w, text='Something Unexpected',
- command=self.quitcmd)
- button2 = tkinter.tix.Button(w, text='Something Else Unexpected')
- button2['command'] = lambda w=button2: w.destroy()
- button1.pack(side=tkinter.tix.TOP, expand=1)
- button2.pack(side=tkinter.tix.TOP, expand=1)
-
- # Create the balloon widget and associate it with the widgets that we want
- # to provide tips for:
- b = tkinter.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 = tkinter.tix.Tk()
- RunSample(root)
diff --git a/Demo/tix/samples/BtnBox.py b/Demo/tix/samples/BtnBox.py
deleted file mode 100755
index 3b9ee4b..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 tkinter.tix
-
-def RunSample(w):
- # Create the label on the top of the dialog box
- #
- top = tkinter.tix.Label(w, padx=20, pady=10, bd=1, relief=tkinter.tix.RAISED,
- anchor=tkinter.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 = tkinter.tix.ButtonBox(w, orientation=tkinter.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=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
- top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1)
-
-if __name__ == '__main__':
- root = tkinter.tix.Tk()
- RunSample(root)
- root.mainloop()
diff --git a/Demo/tix/samples/CmpImg.py b/Demo/tix/samples/CmpImg.py
deleted file mode 100755
index ad49181..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 tkinter.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 = tkinter.tix.Image('pixmap', data=network_pixmap)
- if not w.img0:
- w.img0 = tkinter.tix.Image('bitmap', data=network_bitmap)
- w.img1 = tkinter.tix.Image('pixmap', data=hard_disk_pixmap)
- if not w.img0:
- w.img1 = tkinter.tix.Image('bitmap', data=hard_disk_bitmap)
-
- hdd = tkinter.tix.Button(w, padx=4, pady=1, width=120)
- net = tkinter.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 = tkinter.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 = tkinter.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 = tkinter.tix.Button(w, pady=1, text='Close',
- command=lambda w=w: w.destroy())
-
- hdd.pack(side=tkinter.tix.LEFT, padx=10, pady=10, fill=tkinter.tix.Y, expand=1)
- net.pack(side=tkinter.tix.LEFT, padx=10, pady=10, fill=tkinter.tix.Y, expand=1)
- close.pack(side=tkinter.tix.LEFT, padx=10, pady=10, fill=tkinter.tix.Y, expand=1)
-
-if __name__ == '__main__':
- root = tkinter.tix.Tk()
- RunSample(root)
- root.mainloop()
diff --git a/Demo/tix/samples/ComboBox.py b/Demo/tix/samples/ComboBox.py
deleted file mode 100755
index 80d78f2..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 tkinter.tix
-
-def RunSample(w):
- global demo_month, demo_year
-
- top = tkinter.tix.Frame(w, bd=1, relief=tkinter.tix.RAISED)
-
- demo_month = tkinter.tix.StringVar()
- demo_year = tkinter.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 = tkinter.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 = tkinter.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=tkinter.tix.TOP, anchor=tkinter.tix.W)
- b.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W)
-
- a.insert(tkinter.tix.END, 'January')
- a.insert(tkinter.tix.END, 'February')
- a.insert(tkinter.tix.END, 'March')
- a.insert(tkinter.tix.END, 'April')
- a.insert(tkinter.tix.END, 'May')
- a.insert(tkinter.tix.END, 'June')
- a.insert(tkinter.tix.END, 'July')
- a.insert(tkinter.tix.END, 'August')
- a.insert(tkinter.tix.END, 'September')
- a.insert(tkinter.tix.END, 'October')
- a.insert(tkinter.tix.END, 'November')
- a.insert(tkinter.tix.END, 'December')
-
- b.insert(tkinter.tix.END, '1992')
- b.insert(tkinter.tix.END, '1993')
- b.insert(tkinter.tix.END, '1994')
- b.insert(tkinter.tix.END, '1995')
- b.insert(tkinter.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 = tkinter.tix.ButtonBox(w, orientation=tkinter.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=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
- top.pack(side=tkinter.tix.TOP, fill=tkinter.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 = tkinter.tix.Tk()
- RunSample(root)
- root.mainloop()
diff --git a/Demo/tix/samples/Control.py b/Demo/tix/samples/Control.py
deleted file mode 100755
index fbc5e64..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 tkinter.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 = tkinter.tix.StringVar()
- demo_thrust = tkinter.tix.DoubleVar()
- demo_num_engines = tkinter.tix.IntVar()
- demo_maker.set('P&W')
- demo_thrust.set(20000.0)
- demo_num_engines.set(2)
-
- top = tkinter.tix.Frame(w, bd=1, relief=tkinter.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 = tkinter.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 = tkinter.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 = tkinter.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=tkinter.tix.TOP, anchor=tkinter.tix.W)
- b.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W)
- c.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W)
-
- box = tkinter.tix.ButtonBox(w, orientation=tkinter.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=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
- top.pack(side=tkinter.tix.TOP, fill=tkinter.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 = tkinter.tix.Tk()
- RunSample(root)
diff --git a/Demo/tix/samples/DirList.py b/Demo/tix/samples/DirList.py
deleted file mode 100755
index 6d28ca3..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 tkinter.tix, os, copy
-from tkinter.constants 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 = tkinter.tix.Frame( w, relief=RAISED, bd=1)
-
- # Create the DirList widget. By default it will show the current
- # directory
- #
- #
- top.dir = tkinter.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 = tkinter.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 = tkinter.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 = tkinter.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 tkinter.messagebox, traceback
-
- try:
- root=tkinter.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 = tkinter.messagebox.showerror ( 'Tix Demo Error', text)
diff --git a/Demo/tix/samples/DirTree.py b/Demo/tix/samples/DirTree.py
deleted file mode 100755
index 5411ded..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 tkinter.tix, os, copy
-from tkinter.constants 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 = tkinter.tix.Frame( w, relief=RAISED, bd=1)
-
- # Create the DirTree widget. By default it will show the current
- # directory
- #
- #
- top.dir = tkinter.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 = tkinter.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 = tkinter.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 = tkinter.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=tkinter.tix.Tk()
- RunSample(root)
diff --git a/Demo/tix/samples/NoteBook.py b/Demo/tix/samples/NoteBook.py
deleted file mode 100755
index d8b5fa8..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 tkinter.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 = tkinter.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', tkinter.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 = tkinter.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=tkinter.tix.BOTH, padx=5, pady=5 ,side=tkinter.tix.TOP)
-
- #----------------------------------------
- # Create the first page
- #----------------------------------------
- # Create two frames: one for the common buttons, one for the
- # other widgets
- #
- tab=nb.hard_disk
- f = tkinter.tix.Frame(tab)
- common = tkinter.tix.Frame(tab)
-
- f.pack(side=tkinter.tix.LEFT, padx=2, pady=2, fill=tkinter.tix.BOTH, expand=1)
- common.pack(side=tkinter.tix.RIGHT, padx=2, fill=tkinter.tix.Y)
-
- a = tkinter.tix.Control(f, value=12, label='Access time: ')
- w = tkinter.tix.Control(f, value=400, label='Write Throughput: ')
- r = tkinter.tix.Control(f, value=400, label='Read Throughput: ')
- c = tkinter.tix.Control(f, value=1021, label='Capacity: ')
-
- a.pack(side=tkinter.tix.TOP, padx=20, pady=2)
- w.pack(side=tkinter.tix.TOP, padx=20, pady=2)
- r.pack(side=tkinter.tix.TOP, padx=20, pady=2)
- c.pack(side=tkinter.tix.TOP, padx=20, pady=2)
-
- # Create the common buttons
- createCommonButtons(common)
-
- #----------------------------------------
- # Create the second page
- #----------------------------------------
-
- tab = nb.network
-
- f = tkinter.tix.Frame(tab)
- common = tkinter.tix.Frame(tab)
-
- f.pack(side=tkinter.tix.LEFT, padx=2, pady=2, fill=tkinter.tix.BOTH, expand=1)
- common.pack(side=tkinter.tix.RIGHT, padx=2, fill=tkinter.tix.Y)
-
- a = tkinter.tix.Control(f, value=12, label='Access time: ')
- w = tkinter.tix.Control(f, value=400, label='Write Throughput: ')
- r = tkinter.tix.Control(f, value=400, label='Read Throughput: ')
- c = tkinter.tix.Control(f, value=1021, label='Capacity: ')
- u = tkinter.tix.Control(f, value=10, label='Users: ')
-
- a.pack(side=tkinter.tix.TOP, padx=20, pady=2)
- w.pack(side=tkinter.tix.TOP, padx=20, pady=2)
- r.pack(side=tkinter.tix.TOP, padx=20, pady=2)
- c.pack(side=tkinter.tix.TOP, padx=20, pady=2)
- u.pack(side=tkinter.tix.TOP, padx=20, pady=2)
-
- createCommonButtons(common)
-
-def doDestroy():
- global root
- root.destroy()
-
-def createCommonButtons(master):
- ok = tkinter.tix.Button(master, name='ok', text='OK', width=6,
- command=doDestroy)
- cancel = tkinter.tix.Button(master, name='cancel',
- text='Cancel', width=6,
- command=doDestroy)
-
- ok.pack(side=tkinter.tix.TOP, padx=2, pady=2)
- cancel.pack(side=tkinter.tix.TOP, padx=2, pady=2)
-
-if __name__ == '__main__':
- root = tkinter.tix.Tk()
- RunSample(root)
- root.mainloop()
diff --git a/Demo/tix/samples/OptMenu.py b/Demo/tix/samples/OptMenu.py
deleted file mode 100755
index d1dd46d..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 tkinter.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 = tkinter.tix.StringVar()
- demo_opt_to = tkinter.tix.StringVar()
-
- top = tkinter.tix.Frame(w, bd=1, relief=tkinter.tix.RAISED)
-
- from_file = tkinter.tix.OptionMenu(top, label="From File Format : ",
- variable=demo_opt_from,
- options = 'label.width 19 label.anchor e menubutton.width 15')
-
- to_file = tkinter.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=tkinter.tix.TOP, anchor=tkinter.tix.W, pady=3, padx=6)
- to_file.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W, pady=3, padx=6)
-
- box = tkinter.tix.ButtonBox(w, orientation=tkinter.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=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
- top.pack(side=tkinter.tix.TOP, fill=tkinter.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 = tkinter.tix.Tk()
- RunSample(root)
- root.mainloop()
diff --git a/Demo/tix/samples/PanedWin.py b/Demo/tix/samples/PanedWin.py
deleted file mode 100755
index 1ffc470..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 tkinter.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 = tkinter.tix.LabelEntry(w, label='Newsgroup:', options='entry.width 25')
- group.entry.insert(0,'comp.lang.python')
- pane = tkinter.tix.PanedWindow(w, orientation='vertical')
-
- p1 = pane.add('list', min=70, size=100)
- p2 = pane.add('text', min=70)
- list = tkinter.tix.ScrolledListBox(p1)
- list.listbox['width'] = 80
- list.listbox['height'] = 5
- text = tkinter.tix.ScrolledText(p2)
- text.text['width'] = 80
- text.text['height'] = 20
-
- list.listbox.insert(tkinter.tix.END, " 12324 Re: Tkinter is good for your health")
- list.listbox.insert(tkinter.tix.END, "+ 12325 Re: Tkinter is good for your health")
- list.listbox.insert(tkinter.tix.END, "+ 12326 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(tkinter.tix.END, " 12327 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(tkinter.tix.END, "+ 12328 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(tkinter.tix.END, " 12329 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(tkinter.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(tkinter.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=tkinter.tix.BOTH, padx=4, pady=6)
- text.pack(expand=1, fill=tkinter.tix.BOTH, padx=4, pady=6)
-
- group.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH)
- pane.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH, expand=1)
-
- box = tkinter.tix.ButtonBox(w, orientation=tkinter.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=tkinter.tix.BOTTOM, fill=tkinter.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 = tkinter.tix.Tk()
- RunSample(root)
diff --git a/Demo/tix/samples/PopMenu.py b/Demo/tix/samples/PopMenu.py
deleted file mode 100755
index cb75d85..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 tkinter.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 = tkinter.tix.Frame(w, relief=tkinter.tix.RAISED, bd=1)
- but = tkinter.tix.Button(top, text='Press the right mouse button over this button or its surrounding area')
- but.pack(expand=1, fill=tkinter.tix.BOTH, padx=50, pady=50)
-
- p = tkinter.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 = tkinter.tix.Menu(p.menu)
- m1.add_command(label='Hello')
- p.menu.add_cascade(label='More', menu=m1)
-
- but.pack(side=tkinter.tix.TOP, padx=40, pady=50)
-
- box = tkinter.tix.ButtonBox(w, orientation=tkinter.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=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
- top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1)
-
-if __name__ == '__main__':
- root = tkinter.tix.Tk()
- RunSample(root)
- root.mainloop()
diff --git a/Demo/tix/samples/SHList1.py b/Demo/tix/samples/SHList1.py
deleted file mode 100755
index bf46020..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 tkinter.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 = tkinter.tix.Frame( w, relief=tkinter.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 = tkinter.tix.ScrolledHList(top)
- top.a.pack( expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10, side=tkinter.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=tkinter.tix.Frame(hlist, name='sep%d' % count, height=2, width=150,
- bd=2, relief=tkinter.tix.SUNKEN )
-
- hlist.add_child( itemtype=tkinter.tix.WINDOW,
- window=f, state=tkinter.tix.DISABLED )
-
- hlist.add(boss, itemtype=tkinter.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= tkinter.tix.ButtonBox(top, orientation=tkinter.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=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
- top.pack( side=tkinter.tix.TOP, fill=tkinter.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=tkinter.tix.Tk()
- RunSample(root)
diff --git a/Demo/tix/samples/SHList2.py b/Demo/tix/samples/SHList2.py
deleted file mode 100755
index 370c765..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 tkinter.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 = tkinter.tix.Frame( w, relief=tkinter.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 = tkinter.tix.ScrolledHList(top, options='hlist.columns 3 hlist.header 1' )
- top.a.pack( expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10, side=tkinter.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'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, refwindow=hlist,
- anchor=tkinter.tix.CENTER, padx=8, pady=2, font = boldfont )
-
- hlist.header_create(0, itemtype=tkinter.tix.TEXT, text='Name',
- style=style['header'])
- hlist.header_create(1, itemtype=tkinter.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'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, refwindow=hlist)
-
- style['mgr_posn'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, padx=8, refwindow=hlist)
-
- style['empl_name'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, refwindow=hlist)
-
- style['empl_posn'] = tkinter.tix.DisplayStyle(tkinter.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=tkinter.tix.TEXT, text=boss[1],
- style=style['mgr_name'])
- hlist.item_create('.', 1, itemtype=tkinter.tix.TEXT, text=boss[2],
- style=style['mgr_posn'])
-
- # Create the managers
- #
-
- for key,name,posn in managers :
- e= '.'+ key
- hlist.add(e, itemtype=tkinter.tix.TEXT, text=name,
- style=style['mgr_name'])
- hlist.item_create(e, 1, itemtype=tkinter.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=tkinter.tix.TEXT,
- text = posn, style = style['empl_posn'] )
-
-
- # Use a ButtonBox to hold the buttons.
- #
- box= tkinter.tix.ButtonBox(top, orientation=tkinter.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=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
- top.pack( side=tkinter.tix.TOP, fill=tkinter.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=tkinter.tix.Tk()
- RunSample(root)
diff --git a/Demo/tix/samples/Tree.py b/Demo/tix/samples/Tree.py
deleted file mode 100755
index e46ff60..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 tkinter.tix, os
-
-def RunSample(w):
- top = tkinter.tix.Frame(w, relief=tkinter.tix.RAISED, bd=1)
- tree = tkinter.tix.Tree(top, options='separator "/"')
- tree.pack(expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10, side=tkinter.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 = tkinter.tix.ButtonBox(w, orientation=tkinter.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=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
- top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1)
-
-def adddir(tree, dir):
- if dir == '/':
- text = '/'
- else:
- text = os.path.basename(dir)
- tree.hlist.add(dir, itemtype=tkinter.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=tkinter.tix.IMAGETEXT, text=file,
- image=tree.tk.call('tix', 'getimage', 'file'))
-
-if __name__ == '__main__':
- root = tkinter.tix.Tk()
- RunSample(root)
- root.mainloop()
diff --git a/Demo/tix/tixwidgets.py b/Demo/tix/tixwidgets.py
deleted file mode 100644
index 42bcedc..0000000
--- a/Demo/tix/tixwidgets.py
+++ /dev/null
@@ -1,1002 +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, tkinter.tix
-from tkinter.constants import *
-import traceback, tkinter.messagebox
-
-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 = tkinter.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 = tkinter.tix.Frame(top, bd=2, relief=RAISED)
- file = tkinter.tix.Menubutton(w, text='File', underline=0, takefocus=0)
- help = tkinter.tix.Menubutton(w, text='Help', underline=0, takefocus=0)
- file.pack(side=LEFT)
- help.pack(side=RIGHT)
- fm = tkinter.tix.Menu(file, tearoff=0)
- file['menu'] = fm
- hm = tkinter.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'
- #w.tk.call('trace', 'variable', self.useBalloons, 'w', ToggleHelp))
-
- return w
-
- def MkMainNotebook(self):
- top = self.root
- w = tkinter.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 = tkinter.tix.Frame(top, relief=tkinter.tix.RAISED, bd=1)
- demo.statusbar = tkinter.tix.Label(w, relief=tkinter.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 = tkinter.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 tkinter.messagebox.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: tkinter.messagebox.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 = tkinter.tix.Frame(top, bd=2, relief=tkinter.tix.GROOVE)
- b1 = tkinter.tix.ComboBox(w, command=lambda w=top: MainTextFont(w))
- b2 = tkinter.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(tkinter.tix.END, 'Courier')
- b1.insert(tkinter.tix.END, 'Helvetica')
- b1.insert(tkinter.tix.END, 'Lucida')
- b1.insert(tkinter.tix.END, 'Times Roman')
-
- b2.insert(tkinter.tix.END, '8')
- b2.insert(tkinter.tix.END, '10')
- b2.insert(tkinter.tix.END, '12')
- b2.insert(tkinter.tix.END, '14')
- b2.insert(tkinter.tix.END, '18')
-
- b1.pick(1)
- b2.pick(3)
-
- b1.pack(side=tkinter.tix.LEFT, padx=4, pady=4)
- b2.pack(side=tkinter.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 = tkinter.tix.ScrolledWindow(top, scrollbar='auto')
- win = w.window
- text = 'Welcome to TIX in Python'
- title = tkinter.tix.Label(win,
- bd=0, width=30, anchor=tkinter.tix.N, text=text)
- msg = tkinter.tix.Message(win,
- bd=0, width=400, anchor=tkinter.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=tkinter.tix.BOTH, padx=10, pady=10)
- msg.pack(expand=1, fill=tkinter.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 = tkinter.tix.LabelFrame(w, label='Chooser Widgets', options=options)
- cbx = tkinter.tix.LabelFrame(w, label='tixComboBox', options=options)
- ctl = tkinter.tix.LabelFrame(w, label='tixControl', options=options)
- sel = tkinter.tix.LabelFrame(w, label='tixSelect', options=options)
- opt = tkinter.tix.LabelFrame(w, label='tixOptionMenu', options=options)
- fil = tkinter.tix.LabelFrame(w, label='tixFileEntry', options=options)
- fbx = tkinter.tix.LabelFrame(w, label='tixFileSelectBox', options=options)
- tbr = tkinter.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, tkinter.tix.E, 14)
-
- static = tkinter.tix.ComboBox(w, label='Static', editable=0, options=options)
- editable = tkinter.tix.ComboBox(w, label='Editable', editable=1, options=options)
- history = tkinter.tix.ComboBox(w, label='History', editable=1, history=1,
- anchor=tkinter.tix.E, options=options)
- static.insert(tkinter.tix.END, 'January')
- static.insert(tkinter.tix.END, 'February')
- static.insert(tkinter.tix.END, 'March')
- static.insert(tkinter.tix.END, 'April')
- static.insert(tkinter.tix.END, 'May')
- static.insert(tkinter.tix.END, 'June')
- static.insert(tkinter.tix.END, 'July')
- static.insert(tkinter.tix.END, 'August')
- static.insert(tkinter.tix.END, 'September')
- static.insert(tkinter.tix.END, 'October')
- static.insert(tkinter.tix.END, 'November')
- static.insert(tkinter.tix.END, 'December')
-
- editable.insert(tkinter.tix.END, 'Angola')
- editable.insert(tkinter.tix.END, 'Bangladesh')
- editable.insert(tkinter.tix.END, 'China')
- editable.insert(tkinter.tix.END, 'Denmark')
- editable.insert(tkinter.tix.END, 'Ecuador')
-
- history.insert(tkinter.tix.END, '/usr/bin/ksh')
- history.insert(tkinter.tix.END, '/usr/local/lib/python')
- history.insert(tkinter.tix.END, '/var/adm')
-
- static.pack(side=tkinter.tix.TOP, padx=5, pady=3)
- editable.pack(side=tkinter.tix.TOP, padx=5, pady=3)
- history.pack(side=tkinter.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, tkinter.tix.E, 13)
-
- demo_spintxt = tkinter.tix.StringVar()
- demo_spintxt.set(states[0])
- simple = tkinter.tix.Control(w, label='Numbers', options=options)
- spintxt = tkinter.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=tkinter.tix.TOP, padx=5, pady=3)
- spintxt.pack(side=tkinter.tix.TOP, padx=5, pady=3)
-
-def MkSelect(w):
- options = "label.anchor %s" % tkinter.tix.CENTER
-
- sel1 = tkinter.tix.Select(w, label='Mere Mortals', allowzero=1, radio=1,
- orientation=tkinter.tix.VERTICAL,
- labelside=tkinter.tix.TOP,
- options=options)
- sel2 = tkinter.tix.Select(w, label='Geeks', allowzero=1, radio=0,
- orientation=tkinter.tix.VERTICAL,
- labelside= tkinter.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=tkinter.tix.LEFT, padx=5, pady=3, fill=tkinter.tix.X)
- sel2.pack(side=tkinter.tix.LEFT, padx=5, pady=3, fill=tkinter.tix.X)
-
-def MkOptMenu(w):
- options='menubutton.width 15 label.anchor %s' % tkinter.tix.E
-
- m = tkinter.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=tkinter.tix.X, padx=5, pady=3)
-
-def MkFileEnt(w):
- msg = tkinter.tix.Message(w,
- relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N,
- text='Press the "open file" icon button and a TixFileSelectDialog will popup.')
- ent = tkinter.tix.FileEntry(w, label='Select a file : ')
- msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3)
- ent.pack(side=tkinter.tix.TOP, fill=tkinter.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 = tkinter.tix.Message(w,
- relief=tkinter.tix.FLAT, width=240, anchor=tkinter.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 = tkinter.tix.FileSelectBox(w)
- msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3)
- box.pack(side=tkinter.tix.TOP, fill=tkinter.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 = tkinter.tix.Message(w,
- relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N,
- text='The Select widget is also good for arranging buttons in a tool bar.')
- bar = tkinter.tix.Frame(w, bd=2, relief=tkinter.tix.RAISED)
- font = tkinter.tix.Select(w, allowzero=1, radio=0, label='', options=options)
- para = tkinter.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=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3)
- bar.pack(side=tkinter.tix.TOP, fill=tkinter.tix.X, padx=3, pady=3)
- font.pack({'in':bar}, side=tkinter.tix.LEFT, padx=3, pady=3)
- para.pack({'in':bar}, side=tkinter.tix.LEFT, padx=3, pady=3)
-
-def MkTitle(w):
- msg = tkinter.tix.Message(w,
- relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N,
- text='There are many types of "chooser" widgets that allow the user to input different types of information')
- msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3)
-
-def MkScroll(nb, name):
- w = nb.page(name)
- options='label.padX 4'
-
- sls = tkinter.tix.LabelFrame(w, label='Tix.ScrolledListBox', options=options)
- swn = tkinter.tix.LabelFrame(w, label='Tix.ScrolledWindow', options=options)
- stx = tkinter.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 = tkinter.tix.Frame(w, width=300, height=330)
- bot = tkinter.tix.Frame(w)
- msg = tkinter.tix.Message(top,
- relief=tkinter.tix.FLAT, width=200, anchor=tkinter.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 = tkinter.tix.ScrolledListBox(top, scrollbar='auto')
- list.place(x=50, y=150, width=120, height=80)
- list.listbox.insert(tkinter.tix.END, 'Alabama')
- list.listbox.insert(tkinter.tix.END, 'California')
- list.listbox.insert(tkinter.tix.END, 'Montana')
- list.listbox.insert(tkinter.tix.END, 'New Jersey')
- list.listbox.insert(tkinter.tix.END, 'New York')
- list.listbox.insert(tkinter.tix.END, 'Pennsylvania')
- list.listbox.insert(tkinter.tix.END, 'Washington')
-
- rh = tkinter.tix.ResizeHandle(top, bg='black',
- relief=tkinter.tix.RAISED,
- handlesize=8, gridded=1, minwidth=50, minheight=30)
- btn = tkinter.tix.Button(bot, text='Reset', command=lambda w=rh, x=list: SList_reset(w,x))
- top.propagate(0)
- msg.pack(fill=tkinter.tix.X)
- btn.pack(anchor=tkinter.tix.CENTER)
- top.pack(expand=1, fill=tkinter.tix.BOTH)
- bot.pack(fill=tkinter.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 = tkinter.tix.Frame(w, width=330, height=330)
- bot = tkinter.tix.Frame(w)
- msg = tkinter.tix.Message(top,
- relief=tkinter.tix.FLAT, width=200, anchor=tkinter.tix.N,
- text=text)
-
- win = tkinter.tix.ScrolledWindow(top, scrollbar='auto')
-
- image1 = win.window.image_create('photo', file=file)
- lbl = tkinter.tix.Label(win.window, image=image1)
- lbl.pack(expand=1, fill=tkinter.tix.BOTH)
-
- win.place(x=30, y=150, width=190, height=120)
-
- rh = tkinter.tix.ResizeHandle(top, bg='black',
- relief=tkinter.tix.RAISED,
- handlesize=8, gridded=1, minwidth=50, minheight=30)
- btn = tkinter.tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SWindow_reset(w,x))
- top.propagate(0)
- msg.pack(fill=tkinter.tix.X)
- btn.pack(anchor=tkinter.tix.CENTER)
- top.pack(expand=1, fill=tkinter.tix.BOTH)
- bot.pack(fill=tkinter.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 = tkinter.tix.Frame(w, width=330, height=330)
- bot = tkinter.tix.Frame(w)
- msg = tkinter.tix.Message(top,
- relief=tkinter.tix.FLAT, width=200, anchor=tkinter.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 = tkinter.tix.ScrolledText(top, scrollbar='auto')
- win.text['wrap'] = 'none'
- win.text.insert(tkinter.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 = tkinter.tix.ResizeHandle(top, bg='black',
- relief=tkinter.tix.RAISED,
- handlesize=8, gridded=1, minwidth=50, minheight=30)
- btn = tkinter.tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SText_reset(w,x))
- top.propagate(0)
- msg.pack(fill=tkinter.tix.X)
- btn.pack(anchor=tkinter.tix.CENTER)
- top.pack(expand=1, fill=tkinter.tix.BOTH)
- bot.pack(fill=tkinter.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 = tkinter.tix.LabelFrame(w, label='Tix.PanedWindow', options=options)
- note = tkinter.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 = tkinter.tix.Message(w,
- relief=tkinter.tix.FLAT, width=240, anchor=tkinter.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 = tkinter.tix.LabelEntry(w, label='Newsgroup:', options='entry.width 25')
- group.entry.insert(0,'comp.lang.python')
- pane = tkinter.tix.PanedWindow(w, orientation='vertical')
-
- p1 = pane.add('list', min=70, size=100)
- p2 = pane.add('text', min=70)
- list = tkinter.tix.ScrolledListBox(p1)
- text = tkinter.tix.ScrolledText(p2)
-
- list.listbox.insert(tkinter.tix.END, " 12324 Re: Tkinter is good for your health")
- list.listbox.insert(tkinter.tix.END, "+ 12325 Re: Tkinter is good for your health")
- list.listbox.insert(tkinter.tix.END, "+ 12326 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(tkinter.tix.END, " 12327 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(tkinter.tix.END, "+ 12328 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(tkinter.tix.END, " 12329 Re: Tix is even better for your health (Was: Tkinter is good...)")
- list.listbox.insert(tkinter.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(tkinter.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.
-""")
- list.pack(expand=1, fill=tkinter.tix.BOTH, padx=4, pady=6)
- text.pack(expand=1, fill=tkinter.tix.BOTH, padx=4, pady=6)
-
- msg.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH)
- group.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH)
- pane.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH, expand=1)
-
-def MkNoteBook(w):
- msg = tkinter.tix.Message(w,
- relief=tkinter.tix.FLAT, width=240, anchor=tkinter.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, tkinter.tix.E)
-
- nb = tkinter.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 = tkinter.tix.Frame(nb.hard_disk)
- common.pack(side=tkinter.tix.RIGHT, padx=2, pady=2, fill=tkinter.tix.Y)
- CreateCommonButtons(common)
-
- # Widgets belonging only to this page
- a = tkinter.tix.Control(nb.hard_disk, value=12, label='Access Time: ')
- w = tkinter.tix.Control(nb.hard_disk, value=400, label='Write Throughput: ')
- r = tkinter.tix.Control(nb.hard_disk, value=400, label='Read Throughput: ')
- c = tkinter.tix.Control(nb.hard_disk, value=1021, label='Capacity: ')
- a.pack(side=tkinter.tix.TOP, padx=20, pady=2)
- w.pack(side=tkinter.tix.TOP, padx=20, pady=2)
- r.pack(side=tkinter.tix.TOP, padx=20, pady=2)
- c.pack(side=tkinter.tix.TOP, padx=20, pady=2)
-
- common = tkinter.tix.Frame(nb.network)
- common.pack(side=tkinter.tix.RIGHT, padx=2, pady=2, fill=tkinter.tix.Y)
- CreateCommonButtons(common)
-
- a = tkinter.tix.Control(nb.network, value=12, label='Access Time: ')
- w = tkinter.tix.Control(nb.network, value=400, label='Write Throughput: ')
- r = tkinter.tix.Control(nb.network, value=400, label='Read Throughput: ')
- c = tkinter.tix.Control(nb.network, value=1021, label='Capacity: ')
- u = tkinter.tix.Control(nb.network, value=10, label='Users: ')
- a.pack(side=tkinter.tix.TOP, padx=20, pady=2)
- w.pack(side=tkinter.tix.TOP, padx=20, pady=2)
- r.pack(side=tkinter.tix.TOP, padx=20, pady=2)
- c.pack(side=tkinter.tix.TOP, padx=20, pady=2)
- u.pack(side=tkinter.tix.TOP, padx=20, pady=2)
-
- msg.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH)
- nb.pack(side=tkinter.tix.TOP, padx=5, pady=5, fill=tkinter.tix.BOTH, expand=1)
-
-def CreateCommonButtons(f):
- ok = tkinter.tix.Button(f, text='OK', width = 6)
- cancel = tkinter.tix.Button(f, text='Cancel', width = 6)
- ok.pack(side=tkinter.tix.TOP, padx=2, pady=2)
- cancel.pack(side=tkinter.tix.TOP, padx=2, pady=2)
-
-def MkDirList(nb, name):
- w = nb.page(name)
- options = "label.padX 4"
-
- dir = tkinter.tix.LabelFrame(w, label='Tix.DirList', options=options)
- fsbox = tkinter.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 = tkinter.tix.Message(w,
- relief=tkinter.tix.FLAT, width=240, anchor=tkinter.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 = tkinter.tix.DirList(w, options='hlist.padY 1 hlist.width 25 hlist.height 16')
- msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3)
- dirlist.pack(side=tkinter.tix.TOP, padx=3, pady=3)
-
-def MkExFileWidget(w):
- """The TixExFileSelectBox widget is more user friendly than the Motif
- style FileSelectBox. """
- msg = tkinter.tix.Message(w,
- relief=tkinter.tix.FLAT, width=240, anchor=tkinter.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 = tkinter.tix.ExFileSelectBox(w, bd=2, relief=tkinter.tix.RAISED)
- msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3)
- box.pack(side=tkinter.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 = tkinter.tix.PanedWindow(w, orientation='horizontal')
- pane.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH)
- f1 = pane.add('list', expand='1')
- f2 = pane.add('text', expand='5')
- f1['relief'] = 'flat'
- f2['relief'] = 'flat'
-
- lab = tkinter.tix.LabelFrame(f1, label='Select a sample program:')
- lab.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=5, pady=5)
- lab1 = tkinter.tix.LabelFrame(f2, label='Source:')
- lab1.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=5, pady=5)
-
- slb = tkinter.tix.Tree(lab.frame, options='hlist.width 20')
- slb.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=5)
-
- stext = tkinter.tix.ScrolledText(lab1.frame, name='stext')
- font = root.tk.eval('tix option get fixed_font')
- stext.text.config(font=font)
-
- frame = tkinter.tix.Frame(lab1.frame, name='frame')
-
- run = tkinter.tix.Button(frame, text='Run ...', name='run')
- view = tkinter.tix.Button(frame, text='View Source ...', name='view')
- run.pack(side=tkinter.tix.LEFT, expand=0, fill=tkinter.tix.NONE)
- view.pack(side=tkinter.tix.LEFT, expand=0, fill=tkinter.tix.NONE)
-
- stext.text['bg'] = slb.hlist['bg']
- stext.text['state'] = 'disabled'
- stext.text['wrap'] = 'none'
- stext.text['width'] = 80
-
- frame.pack(side=tkinter.tix.BOTTOM, expand=0, fill=tkinter.tix.X, padx=7)
- stext.pack(side=tkinter.tix.TOP, expand=0, fill=tkinter.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 = tkinter.tix.Frame(slb.hlist, bd=2, height=2, width=150,
- relief=tkinter.tix.SUNKEN, bg=slb.hlist['bg'])
- slb.hlist.add_child(itemtype=tkinter.tix.WINDOW, window=x, state='disabled')
- x = slb.hlist.add_child(itemtype=tkinter.tix.TEXT, state='disabled',
- text=comments[type])
- for key in stypes[type]:
- slb.hlist.add_child(x, itemtype=tkinter.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 = tkinter.tix.Toplevel()
- w.title(title)
- rtn = eval(prog + '.RunSample')
- rtn(w)
- elif action == 'view':
- w = tkinter.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 = tkinter.tix.Button(w, text='Close', command=w.destroy)
- t = tkinter.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', tkinter.tix.END)
-
- try:
- f = open(fname)
- lines = f.readlines()
- for s in lines:
- w.insert(tkinter.tix.END, s)
- f.close()
- finally:
-# w.see('1.0')
- w['state'] = old_state
-
-if __name__ == '__main__':
- root = tkinter.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/attr_dialog.py b/Demo/tkinter/guido/attr_dialog.py
deleted file mode 100644
index 229a558..0000000
--- a/Demo/tkinter/guido/attr_dialog.py
+++ /dev/null
@@ -1,460 +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) is tuple:
- 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:
- self.dialog.widget.pack(**{self.option: self.current})
- except TclError as 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 as 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 as 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.klass in self.addclasses:
- 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 as 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 as 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 as 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):
- list = e.widget
- sel = list.curselection()
- for i in sel:
- item = list.get(i)
- widget = item.split()[0]
- RemoteWidgetDialog(list, list.app, widget)
- if widget == '.': continue
- try:
- RemotePackDialog(list, list.app, widget)
- except TclError as msg:
- print(msg)
-
-test()
diff --git a/Demo/tkinter/guido/brownian.py b/Demo/tkinter/guido/brownian.py
deleted file mode 100644
index 7ab3e67..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 dc1d43a..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 ffeb0ca..0000000
--- a/Demo/tkinter/guido/canvasevents.py
+++ /dev/null
@@ -1,264 +0,0 @@
-#! /usr/bin/env python
-
-from tkinter import *
-
-
-# Since Canvas.Group is no longer present, the following class reproduces
-# a subset of the old Group class that is used by this app.
-
-class Group:
- def __init__(self, canvas, tag=None):
- if tag is None:
- tag = 'Group%d' % id(self)
-
- self.tag = self.id = tag
- self.canvas = canvas
- self.canvas.dtag(self.tag)
-
- def __str__(self):
- return self.tag
-
- def _do(self, cmd, *args):
- return self.canvas.tk.call(self.canvas._w, cmd, self.tag, *args)
-
- def addtag_withtag(self, tagOrId):
- self._do('addtag', 'withtag', tagOrId)
-
- def bind(self, sequence=None, command=None, add=None):
- return self.canvas.tag_bind(self.id, sequence, command, add)
-
- def move(self, x_amount, y_amount):
- self._do('move', x_amount, y_amount)
-
- def dtag(self, tagToDelete=None):
- self._do('dtag', tagToDelete)
-
- def tkraise(self, aboveThis=None):
- self._do('raise', aboveThis)
-
-
-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 = self.canvas.create_oval(self.x - 20, self.y - 10,
- self.x + 20, self.y + 20, fill=fill, width=3)
- self.group.addtag_withtag(self.__oval)
- self.__text = self.canvas.create_text(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 = self.canvas.create_oval(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 2a4a939..0000000
--- a/Demo/tkinter/guido/dialog.py
+++ /dev/null
@@ -1,108 +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)
- 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 b5c9ec0..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
-
- # First argument is number of electrons, default 30
- if sys.argv[1:]:
- n = int(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/hello.py b/Demo/tkinter/guido/hello.py
deleted file mode 100755
index f10fb7a..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 100755
index a168831..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 100755
index 276858a..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 36caba6..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 subprocess
-import os
-
-class BarButton(Menubutton):
- def __init__(self, master=None, **cnf):
- 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 = subprocess.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 100755
index 8db5b60..0000000
--- a/Demo/tkinter/guido/listtree.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# List a remote app's widget tree (names and classes only)
-
-import sys
-
-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)
- 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/manpage.py b/Demo/tkinter/guido/manpage.py
deleted file mode 100644
index 750c675..0000000
--- a/Demo/tkinter/guido/manpage.py
+++ /dev/null
@@ -1,215 +0,0 @@
-# Widget to display a man page
-
-import os
-import re
-import sys
-
-from tkinter import *
-from tkinter.font import Font
-from tkinter.scrolledtext import ScrolledText
-
-# 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')
-
-
-class EditableManPage(ScrolledText):
- """Basic Man Page class -- does not disable editing."""
-
- def __init__(self, master=None, **cnf):
- ScrolledText.__init__(self, master, **cnf)
-
- bold = Font(font=self['font']).copy()
- bold.config(weight='bold')
- italic = Font(font=self['font']).copy()
- italic.config(slant='italic')
-
- # Define tags for formatting styles
- self.tag_config('X', underline=1)
- self.tag_config('!', font=bold)
- self.tag_config('_', font=italic)
-
- # Set state to idle
- self.fp = None
- self.lineno = 0
-
- def busy(self):
- """Test whether we are busy parsing a file."""
- return self.fp != None
-
- def kill(self):
- """Ensure we're not busy."""
- if self.busy():
- self._endparser()
-
- def asyncparsefile(self, fp):
- """Parse a file, in the background."""
- self._startparser(fp)
- self.tk.createfilehandler(fp, READABLE,
- self._filehandler)
-
- parsefile = asyncparsefile # Alias
-
- def _filehandler(self, fp, mask):
- """I/O handler used by background parsing."""
- nextline = self.fp.readline()
- if not nextline:
- self._endparser()
- return
- self._parseline(nextline)
-
- def syncparsefile(self, fp):
- """Parse a file, now (cannot be aborted)."""
- self._startparser(fp)
- while True:
- nextline = fp.readline()
- if not nextline:
- break
- self._parseline(nextline)
- self._endparser()
-
- def _startparser(self, fp):
- """Initialize parsing from a particular file -- must not be busy."""
- 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
-
- def _endparser(self):
- """End parsing -- must be busy, need not be at EOF."""
- if not self.busy():
- raise RuntimeError('endparser: not busy')
- if self.buffer:
- self._parseline('')
- try:
- self.tk.deletefilehandler(self.fp)
- except TclError:
- pass
- self.fp.close()
- self.fp = None
- del self.ok, self.empty, self.buffer
-
- def _parseline(self, nextline):
- """Parse a single line."""
- if not self.buffer:
- # Save this line -- we need one line read-ahead
- self.buffer = nextline
- return
- if emptyprog.match(self.buffer):
- # Buffered line was empty -- set a flag
- self.empty = 1
- self.buffer = nextline
- return
- textline = self.buffer
- if ulprog.match(nextline):
- # 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):
- # 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
-
- def _insert_prop(self, str, prop = ' '):
- """Insert a string at the end, with at most one property (tag)."""
- 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())
-
-
-class ReadonlyManPage(EditableManPage):
- """Readonly Man Page class -- disables editing, otherwise the same."""
-
- def __init__(self, master=None, **cnf):
- cnf['state'] = DISABLED
- EditableManPage.__init__(self, master, **cnf)
-
-# Alias
-ManPage = ReadonlyManPage
-
-# usage: ManPage [manpage]; or ManPage [-f] file
-# -f means that the file is nroff -man output run through ul -i
-def main():
- # XXX This directory may be different on your system
- MANDIR = ''
- 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 -c %s | ul -i' % name, 'r')
- manpage.parsefile(fp)
- root.mainloop()
-
-if __name__ == '__main__':
- main()
diff --git a/Demo/tkinter/guido/mbox.py b/Demo/tkinter/guido/mbox.py
deleted file mode 100755
index 754a312..0000000
--- a/Demo/tkinter/guido/mbox.py
+++ /dev/null
@@ -1,286 +0,0 @@
-#! /usr/bin/env python
-
-# Scan MH folder, display results in window
-
-import os
-import re
-import sys
-import getopt
-import mailbox
-from tkinter import *
-
-from dialog import dialog
-
-MBOXPATH = 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 as msg:
- print(msg)
- sys.exit(2)
- for arg in args:
- if arg[:1] == '+':
- folder = arg[1:]
- else:
- seq = arg
-
- # Initialize MH
-
- mh = mailbox.MH(MBOXPATH)
- mhf = mh.get_folder(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.get_folder(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)
- m = scanparser.match(line)
- if m:
- num = int(m.group(1))
- m = mhf.get_message(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)
- m = scanparser.match(line)
- if m:
- toremove = int(m.group(1))
- todo.append(toremove)
- mhf.remove(toremove)
- 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)
- m = scanparser.match(line)
- if m:
- todo.append(int(m.group(1)))
- if lastrefile != refileto or not tofolder:
- lastrefile = refileto
- tofolder = None
- tofolder = mh.get_folder(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))
- m = scanparser.match(line)
- if m:
- num = int(m.group(1))
- if num >= near:
- break
- else:
- i = 'end'
- scanbox.yview(itop)
-
-def setfolders():
- folderbox.delete(0, 'end')
- for fn in mh.list_folders():
- 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 [line[:-1] for line in
- os.popen('scan +%s %s' % (folder, sequence), 'r').readlines()]
-
-main()
diff --git a/Demo/tkinter/guido/mimeviewer.py b/Demo/tkinter/guido/mimeviewer.py
deleted file mode 100755
index babed8f..0000000
--- a/Demo/tkinter/guido/mimeviewer.py
+++ /dev/null
@@ -1,159 +0,0 @@
-#! /usr/bin/env python3
-
-# View a single MIME multipart message.
-# Display each part as a box.
-
-import os
-import sys
-import getopt
-import mailbox
-from tkinter import *
-from tkinter.scrolledtext import ScrolledText
-
-MBOXPATH = os.environ['HOME'] + '/Mail'
-
-class Error(Exception):
- pass
-
-def getcurrent(self):
- """Return the current message. Raise Error when there is none."""
- seqs = self.get_sequences()
- try:
- return max(seqs['cur'])
- except (ValueError, KeyError):
- raise Error("no cur message")
-
-
-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 = []
- for item in msg.items():
- headertext.append("%s: %s" % item)
- headertext = '\n'.join(headertext)
- 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.get_payload()
- if type(body) == str:
- 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 = str.find('\n', i)
- if i < 0: break
- n = n+1
- i = i+1
- return n
-
-def main():
- 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 = int(arg)
-
- mh = mailbox.MH(MBOXPATH)
- f = mh.get_folder(folder)
- if message is None:
- message = getcurrent(f)
- m = mailbox.MHMessage(f.get(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/newmenubardemo.py b/Demo/tkinter/guido/newmenubardemo.py
deleted file mode 100644
index 51c4e64..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 1e72aa5..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 = OptionMenu(root, var2, *CHOICES)
-menu2.pack()
-
-root.mainloop()
diff --git a/Demo/tkinter/guido/paint.py b/Demo/tkinter/guido/paint.py
deleted file mode 100644
index 65f2353..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 350d60b..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')
-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) # convert tuple to list
- 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/shell_window.py b/Demo/tkinter/guido/shell_window.py
deleted file mode 100644
index c5a0401..0000000
--- a/Demo/tkinter/guido/shell_window.py
+++ /dev/null
@@ -1,146 +0,0 @@
-import os
-import sys
-from tkinter import *
-from tkinter.scrolledtext import ScrolledText
-from tkinter.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 = shell.split()
- shell = args[0]
-
- 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).decode()
- 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.encode())
- 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 = ' '.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/solitaire.py b/Demo/tkinter/guido/solitaire.py
deleted file mode 100755
index 43106e1..0000000
--- a/Demo/tkinter/guido/solitaire.py
+++ /dev/null
@@ -1,626 +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 random
-
-from tkinter import *
-from canvasevents import Group
-
-
-# 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 = list(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"] + list(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.canvas = canvas
- self.group = Group(canvas)
-
- text = "%s %s" % (VALNAMES[value], suit)
- self.__text = canvas.create_text(CARDWIDTH // 2, 0, anchor=N,
- fill=self.color, text=text)
- self.group.addtag_withtag(self.__text)
-
- self.__rect = canvas.create_rectangle(0, 0, CARDWIDTH, CARDHEIGHT,
- outline='black', fill='white')
- self.group.addtag_withtag(self.__rect)
-
- self.__back = canvas.create_rectangle(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.canvas.tag_raise(self.__rect)
- self.canvas.tag_raise(self.__text)
- self.face_shown = 1
-
- def showback(self):
- """Turn the card's face down."""
- self.tkraise()
- self.canvas.tag_raise(self.__rect)
- self.canvas.tag_raise(self.__back)
- 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 = self.game.canvas.create_rectangle(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 = list(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 = self.game.canvas.create_rectangle(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)
- self.canvas.create_window(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/svkill.py b/Demo/tkinter/guido/svkill.py
deleted file mode 100755
index e63a32b..0000000
--- a/Demo/tkinter/guido/svkill.py
+++ /dev/null
@@ -1,124 +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")
-
-import subprocess
-import os
-
-user = os.environ['LOGNAME']
-
-class BarButton(Menubutton):
- def __init__(self, master=None, **cnf):
- 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 = selected.split()[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 = subprocess.getoutput('ps %s %s' % (view, format))
- list = s.split('\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):
- 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,
- 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,
- 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 3f43925..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 1baed88..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 os
-import re
-import sys
-from tkinter import *
-
-from manpage import ManPage
-
-MANNDIRLIST = ['/usr/local/man/mann', '/usr/share/man/mann']
-MAN3DIRLIST = ['/usr/local/man/man3', '/usr/share/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 = list(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 -c %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 as msg:
- self.frame.bell()
- print('Regex error:', msg)
- return
- here = self.text.index(AtInsert())
- lineno = int(here[:here.find('.')])
- end = self.text.index(AtEnd())
- endlineno = int(end[:end.find('.')])
- 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:
- found = 1
- n = max(1, len(i.group(0)))
- try:
- self.text.tag_remove('sel',
- AtSelFirst(),
- AtSelLast())
- except TclError:
- pass
- self.text.tag_add('sel',
- '%d.%d' % (lineno, i.start()),
- '%d.%d' % (lineno, i.start()+n))
- self.text.mark_set(AtInsert(),
- '%d.%d' % (lineno, i.start()))
- 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 100755
index 332501d..0000000
--- a/Demo/tkinter/guido/wish.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# This is about all it requires to write a wish shell in Python!
-
-import _tkinter
-import os
-import sys
-
-tk = _tkinter.create(os.environ['DISPLAY'], 'wish', 'Tk', 1, 1)
-tk.call('update')
-
-cmd = ''
-
-while True:
- if cmd:
- prompt = ''
- else:
- prompt = '% '
- try:
- sys.stdout.write(prompt)
- sys.stdout.flush()
- line = sys.stdin.readline()
- if not line:
- break
- except EOFError:
- break
- cmd += line
- if tk.getboolean(tk.call('info', 'complete', cmd)):
- tk.record(line)
- try:
- result = tk.call('eval', cmd)
- except _tkinter.TclError as 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 3b4092a..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 4120d66..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 88309ca..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 0da7c37..0000000
--- a/Demo/tkinter/matt/bind-w-mult-calls-p-type.py
+++ /dev/null
@@ -1,43 +0,0 @@
-from tkinter import *
-
-# 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 7f2c17b..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 2f9d23a..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 edd64f7..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 21d724f..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 4875b44..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 265f0a1..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 ca96583..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 1c5681a..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 c0b8825..0000000
--- a/Demo/tkinter/matt/dialog-box.py
+++ /dev/null
@@ -1,64 +0,0 @@
-from tkinter import *
-from tkinter.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 1f55df5..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 7d93da7..0000000
--- a/Demo/tkinter/matt/entry-with-shared-variable.py
+++ /dev/null
@@ -1,45 +0,0 @@
-from tkinter import *
-
-# 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 = self.contents.get().upper()
- 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 b4034d1..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 84f162e..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 5d3303f..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 85c65c8..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 4512063..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 3cf6c45..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 64f61d5..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 6be0de9..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 82a5dc0..0000000
--- a/Demo/tkinter/matt/pong-demo-1.py
+++ /dev/null
@@ -1,52 +0,0 @@
-from tkinter import *
-
-
-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 771a60d..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(list(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 a2719b8..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 48526d8..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 cfc4882..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 687f8a3..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 ce97f35..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 38b61b1..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 32c8b70..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 f5e6230..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 9f82367..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 "text" not in kwargs:
- kwargs["text"] = "QUIT"
- if "command" not in kwargs:
- kwargs["command"] = master.quit
- 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 45eee2d..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.
-"""
-from tkinter 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 bacddb5..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
-from 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 05faf63..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
-from 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 97b1eaf..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
-from 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 6e65f09..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
-from 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 9c68bb5..0000000
--- a/Demo/tkinter/ttk/plastik_theme.py
+++ /dev/null
@@ -1,268 +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
-from tkinter import ttk, 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 ce3685a..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
-from 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 09c5a72..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
-from 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 be72237..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 tkinter.font
-from tkinter 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=tkinter.font.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 = tkinter.font.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 8e35f1f..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 tkinter.font
-from tkinter 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 = tkinter.font.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 = tkinter.font.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 b68f13b..0000000
--- a/Demo/tkinter/ttk/widget_state.py
+++ /dev/null
@@ -1,83 +0,0 @@
-"""Sample demo showing widget states and some font styling."""
-from tkinter 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/tdemo_I_dontlike_tiltdemo.py b/Demo/turtle/tdemo_I_dontlike_tiltdemo.py
deleted file mode 100644
index 1d8652c..0000000
--- a/Demo/turtle/tdemo_I_dontlike_tiltdemo.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/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/xml/elem_count.py b/Demo/xml/elem_count.py
deleted file mode 100644
index 99d6ca9..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 49cd154..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 = 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 28d8b26..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 53463dd..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), end=' ')
- 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), end=' ')
- print('Uncompressed:', len(decomp))
-
-if __name__ == '__main__':
- main()
diff --git a/Doc/ACKS.txt b/Doc/ACKS.txt
index 73d4e13..7f67d36 100644
--- a/Doc/ACKS.txt
+++ b/Doc/ACKS.txt
@@ -120,6 +120,7 @@ docs@python.org), and we'll be glad to correct the problem.
* Robert Lehmann
* Marc-André Lemburg
* Ross Light
+ * Gediminas Liktaras
* Ulf A. Lindgren
* Everett Lipman
* Mirko Liss
@@ -213,6 +214,7 @@ docs@python.org), and we'll be glad to correct the problem.
* Mats Wichmann
* Gerry Wiener
* Timothy Wild
+ * Paul Winkler
* Collin Winter
* Blake Winton
* Dan Wolfe
diff --git a/Doc/Makefile b/Doc/Makefile
index 8fcf538..a1ffe63 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"
@@ -34,12 +35,13 @@ help:
@echo " dist to create a \"dist\" directory with archived docs for download"
@echo " suspicious to check for suspicious markup in output text"
@echo " check to run a check for frequent markup errors"
+ @echo " serve to serve the documentation on the localhost (8000)"
# Note: if you update versions here, do the same in make.bat and README.txt
checkout:
@if [ ! -d tools/sphinx ]; then \
echo "Checking out Sphinx..."; \
- svn checkout $(SVNROOT)/external/Sphinx-0.6.5/sphinx tools/sphinx; \
+ svn checkout $(SVNROOT)/external/Sphinx-1.0.7/sphinx tools/sphinx; \
fi
@if [ ! -d tools/docutils ]; then \
echo "Checking out Docutils..."; \
@@ -80,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."
@@ -157,9 +163,23 @@ 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
+serve:
+ ../Tools/scripts/serve.py build/html
+
# Targets for daily automated doc build
# for development releases: always build
diff --git a/Doc/README.txt b/Doc/README.txt
index 7a561c0..50c199e 100644
--- a/Doc/README.txt
+++ b/Doc/README.txt
@@ -54,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.
@@ -78,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.5/sphinx tools/sphinx
+ svn co http://svn.python.org/projects/external/Sphinx-1.0.7/sphinx tools/sphinx
or by installing it from PyPI.
@@ -132,7 +135,7 @@ The Python source is copyrighted, but you can freely use and copy it
as long as you don't change or remove the copyright notice:
----------------------------------------------------------------------
-Copyright (c) 2000-2008 Python Software Foundation.
+Copyright (c) 2000-2011 Python Software Foundation.
All rights reserved.
Copyright (c) 2000 BeOpen.com.
diff --git a/Doc/c-api/abstract.rst b/Doc/c-api/abstract.rst
index aba804d..ad53881 100644
--- a/Doc/c-api/abstract.rst
+++ b/Doc/c-api/abstract.rst
@@ -12,7 +12,7 @@ sequence types). When used on object types for which they do not apply, they
will raise a Python exception.
It is not possible to use these functions on objects that are not properly
-initialized, such as a list object that has been created by :cfunc:`PyList_New`,
+initialized, such as a list object that has been created by :c:func:`PyList_New`,
but whose items have not been set to some non-\ ``NULL`` value yet.
.. toctree::
diff --git a/Doc/c-api/allocation.rst b/Doc/c-api/allocation.rst
index b64381b..e8f60bf 100644
--- a/Doc/c-api/allocation.rst
+++ b/Doc/c-api/allocation.rst
@@ -6,13 +6,13 @@ Allocating Objects on the Heap
==============================
-.. cfunction:: PyObject* _PyObject_New(PyTypeObject *type)
+.. c:function:: PyObject* _PyObject_New(PyTypeObject *type)
-.. cfunction:: PyVarObject* _PyObject_NewVar(PyTypeObject *type, Py_ssize_t size)
+.. c:function:: PyVarObject* _PyObject_NewVar(PyTypeObject *type, Py_ssize_t size)
-.. cfunction:: PyObject* PyObject_Init(PyObject *op, PyTypeObject *type)
+.. c:function:: PyObject* PyObject_Init(PyObject *op, PyTypeObject *type)
Initialize a newly-allocated object *op* with its type and initial
reference. Returns the initialized object. If *type* indicates that the
@@ -21,13 +21,13 @@ Allocating Objects on the Heap
affected.
-.. cfunction:: PyVarObject* PyObject_InitVar(PyVarObject *op, PyTypeObject *type, Py_ssize_t size)
+.. c:function:: PyVarObject* PyObject_InitVar(PyVarObject *op, PyTypeObject *type, Py_ssize_t size)
- This does everything :cfunc:`PyObject_Init` does, and also initializes the
+ This does everything :c:func:`PyObject_Init` does, and also initializes the
length information for a variable-size object.
-.. cfunction:: TYPE* PyObject_New(TYPE, PyTypeObject *type)
+.. c:function:: TYPE* PyObject_New(TYPE, PyTypeObject *type)
Allocate a new Python object using the C structure type *TYPE* and the
Python type object *type*. Fields not defined by the Python object header
@@ -36,7 +36,7 @@ Allocating Objects on the Heap
the type object.
-.. cfunction:: TYPE* PyObject_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size)
+.. c:function:: TYPE* PyObject_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size)
Allocate a new Python object using the C structure type *TYPE* and the
Python type object *type*. Fields not defined by the Python object header
@@ -48,24 +48,24 @@ Allocating Objects on the Heap
improving the memory management efficiency.
-.. cfunction:: void PyObject_Del(PyObject *op)
+.. c:function:: void PyObject_Del(PyObject *op)
- Releases memory allocated to an object using :cfunc:`PyObject_New` or
- :cfunc:`PyObject_NewVar`. This is normally called from the
+ Releases memory allocated to an object using :c:func:`PyObject_New` or
+ :c:func:`PyObject_NewVar`. This is normally called from the
:attr:`tp_dealloc` handler specified in the object's type. The fields of
the object should not be accessed after this call as the memory is no
longer a valid Python object.
-.. cvar:: PyObject _Py_NoneStruct
+.. c:var:: PyObject _Py_NoneStruct
Object which is visible in Python as ``None``. This should only be accessed
- using the :cmacro:`Py_None` macro, which evaluates to a pointer to this
+ using the :c:macro:`Py_None` macro, which evaluates to a pointer to this
object.
.. seealso::
- :cfunc:`PyModule_Create`
+ :c:func:`PyModule_Create`
To allocate and create extension modules.
diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
index 21cebe9..d4dda7c 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -9,8 +9,8 @@ These functions are useful when creating your own extensions functions and
methods. Additional information and examples are available in
:ref:`extending-index`.
-The first three of these functions described, :cfunc:`PyArg_ParseTuple`,
-:cfunc:`PyArg_ParseTupleAndKeywords`, and :cfunc:`PyArg_Parse`, all use *format
+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.
@@ -35,23 +35,23 @@ 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.
-However, when a :ctype:`Py_buffer` structure gets filled, the underlying
+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 :ctype:`Py_BEGIN_ALLOW_THREADS` block without the risk of mutable data
+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**
-:cfunc:`PyBuffer_Release` after you have finished processing the data (or
+: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 :ctype:`Py_ssize_t`) is controlled by
- defining the macro :cmacro:`PY_SSIZE_T_CLEAN` before including
+ 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
- :ctype:`Py_ssize_t` rather than an :ctype:`int`. This behavior will change
- in a future Python version to only support :ctype:`Py_ssize_t` and
- drop :ctype:`int` support. It is best to always define :cmacro:`PY_SSIZE_T_CLEAN`.
+ :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 \*]
@@ -66,17 +66,17 @@ Unless otherwise stated, buffers are not NUL-terminated.
.. 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 :cfunc:`PyUnicode_FSConverter`
+ 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 :ctype:`Py_buffer` structure provided by the caller.
+ 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 :ctype:`Py_ssize_t`]
+``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.
@@ -89,7 +89,7 @@ Unless otherwise stated, buffers are not NUL-terminated.
``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 :ctype:`Py_buffer` structure is set to *NULL*.
+ ``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
@@ -113,19 +113,21 @@ Unless otherwise stated, buffers are not NUL-terminated.
``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 :ctype:`PyObject\*`.
+ 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 :ctype:`PyObject\*`.
+ 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 :ctype:`Py_UNICODE`
+ 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 :ctype:`Py_UNICODE`
+ 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
@@ -138,55 +140,38 @@ Unless otherwise stated, buffers are not NUL-terminated.
``Z`` (:class:`str` or ``None``) [Py_UNICODE \*]
Like ``u``, but the Python object may also be ``None``, in which case the
- :ctype:`Py_UNICODE` pointer is set to *NULL*.
+ :c:type:`Py_UNICODE` pointer is set to *NULL*.
``Z#`` (:class:`str` or ``None``) [Py_UNICODE \*, int]
Like ``u#``, but the Python object may also be ``None``, in which case the
- :ctype:`Py_UNICODE` pointer is set to *NULL*.
+ :c:type:`Py_UNICODE` pointer is set to *NULL*.
``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 :ctype:`PyObject\*`.
-
-``t#`` (:class:`bytes`, :class:`bytearray` or read-only character buffer) [char \*, int]
- Like ``s#``, but accepts any object which implements the read-only buffer
- interface. The :ctype:`char\*` variable is set to point to the first byte of
- the buffer, and the :ctype:`int` is set to the length of the buffer. Only
- single-segment buffer objects are accepted; :exc:`TypeError` is raised for all
- others.
-
-``w`` (:class:`bytearray` or read-write character buffer) [char \*]
- Similar to ``y``, 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.
+ object. The C variable may also be declared as :c:type:`PyObject\*`.
``w*`` (:class:`bytearray` or read-write byte-oriented buffer) [Py_buffer]
- This is to ``w`` what ``y*`` is to ``y``.
-
-``w#`` (:class:`bytearray` or read-write character buffer) [char \*, int]
- Like ``y#``, but accepts any object which implements the read-write buffer
- interface. The :ctype:`char \*` variable is set to point to the first byte
- of the buffer, and the :ctype:`int` is set to the length of the buffer.
- Only single-segment buffer objects are accepted; :exc:`TypeError` is raised
- for all others.
+ 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`` (: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 :ctype:`const char\*` which points to the name of an encoding as a
+ 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 :ctype:`char\*\*`; the value of the pointer it
+ 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.
- :cfunc:`PyArg_ParseTuple` will allocate a buffer of the needed size, copy the
+ :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 :cfunc:`PyMem_Free` to
+ 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]
@@ -200,10 +185,10 @@ Unless otherwise stated, buffers are not NUL-terminated.
characters.
It requires three arguments. The first is only used as input, and must be a
- :ctype:`const char\*` which points to the name of an encoding as 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 :ctype:`char\*\*`; the value of the pointer it
+ 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
@@ -214,10 +199,10 @@ Unless otherwise stated, buffers are not NUL-terminated.
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
- :cfunc:`PyMem_Free` to free the allocated buffer after usage.
+ :c:func:`PyMem_Free` to free the allocated buffer after usage.
If *\*buffer* points to a non-*NULL* pointer (an already allocated buffer),
- :cfunc:`PyArg_ParseTuple` will use this location as the buffer and interpret the
+ :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.
@@ -235,62 +220,62 @@ Numbers
``b`` (:class:`int`) [unsigned char]
Convert a nonnegative Python integer to an unsigned tiny int, stored in a C
- :ctype:`unsigned char`.
+ :c:type:`unsigned char`.
``B`` (:class:`int`) [unsigned char]
Convert a Python integer to a tiny int without overflow checking, stored in a C
- :ctype:`unsigned char`.
+ :c:type:`unsigned char`.
``h`` (:class:`int`) [short int]
- Convert a Python integer to a C :ctype:`short int`.
+ Convert a Python integer to a C :c:type:`short int`.
``H`` (:class:`int`) [unsigned short int]
- Convert a Python integer to a C :ctype:`unsigned short int`, without overflow
+ Convert a Python integer to a C :c:type:`unsigned short int`, without overflow
checking.
``i`` (:class:`int`) [int]
- Convert a Python integer to a plain C :ctype:`int`.
+ Convert a Python integer to a plain C :c:type:`int`.
``I`` (:class:`int`) [unsigned int]
- Convert a Python integer to a C :ctype:`unsigned int`, without overflow
+ Convert a Python integer to a C :c:type:`unsigned int`, without overflow
checking.
``l`` (:class:`int`) [long int]
- Convert a Python integer to a C :ctype:`long int`.
+ Convert a Python integer to a C :c:type:`long int`.
``k`` (:class:`int`) [unsigned long]
- Convert a Python integer to a C :ctype:`unsigned long` without
+ Convert a Python integer to a C :c:type:`unsigned long` without
overflow checking.
``L`` (:class:`int`) [PY_LONG_LONG]
- Convert a Python integer to a C :ctype:`long long`. This format is only
- available on platforms that support :ctype:`long long` (or :ctype:`_int64` on
+ 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`` (:class:`int`) [unsigned PY_LONG_LONG]
- Convert a Python integer to a C :ctype:`unsigned 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 :ctype:`unsigned long long` (or :ctype:`unsigned _int64` on Windows).
+ support :c:type:`unsigned long long` (or :c:type:`unsigned _int64` on Windows).
``n`` (:class:`int`) [Py_ssize_t]
- Convert a Python integer to a C :ctype:`Py_ssize_t`.
+ Convert a Python integer to a C :c:type:`Py_ssize_t`.
``c`` (:class:`bytes` of length 1) [char]
Convert a Python byte, represented as a :class:`bytes` object of length 1,
- to a C :ctype:`char`.
+ 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 :ctype:`int`.
+ length 1, to a C :c:type:`int`.
``f`` (:class:`float`) [float]
- Convert a Python floating point number to a C :ctype:`float`.
+ Convert a Python floating point number to a C :c:type:`float`.
``d`` (:class:`float`) [double]
- Convert a Python floating point number to a C :ctype:`double`.
+ Convert a Python floating point number to a C :c:type:`double`.
``D`` (:class:`complex`) [Py_complex]
- Convert a Python complex number to a C :ctype:`Py_complex` structure.
+ Convert a Python complex number to a C :c:type:`Py_complex` structure.
Other objects
-------------
@@ -303,20 +288,20 @@ Other objects
``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 :ctype:`PyObject\*`) into which
+ 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 :ctype:`void \*`. The *converter*
+ 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
- :ctype:`void\*` argument that was passed to the :cfunc:`PyArg_Parse\*` function.
+ :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.
@@ -348,13 +333,13 @@ 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,
- :cfunc:`PyArg_ParseTuple` does not touch the contents of the corresponding C
+ :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
- :cfunc:`PyArg_ParseTuple` raises).
+ :c:func:`PyArg_ParseTuple` raises).
``;``
The list of format units ends here; the string after the semicolon is used as
@@ -372,43 +357,52 @@ 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
-:cfunc:`PyArg_Parse\*` functions return true, otherwise they return
+:c:func:`PyArg_Parse\*` functions return true, otherwise they return
false and raise an appropriate exception. When the
-:cfunc:`PyArg_Parse\*` functions fail due to conversion failure in one
+: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
-------------
-.. cfunction:: int PyArg_ParseTuple(PyObject *args, const char *format, ...)
+.. 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.
-.. cfunction:: int PyArg_VaParse(PyObject *args, const char *format, va_list vargs)
+.. c:function:: int PyArg_VaParse(PyObject *args, const char *format, va_list vargs)
- Identical to :cfunc:`PyArg_ParseTuple`, except that it accepts a va_list rather
+ Identical to :c:func:`PyArg_ParseTuple`, except that it accepts a va_list rather
than a variable number of arguments.
-.. cfunction:: int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], ...)
+.. c:function:: int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], ...)
Parse the parameters of a function that takes both positional and keyword
parameters into local variables. Returns true on success; on failure, it
returns false and raises the appropriate exception.
-.. cfunction:: int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], va_list vargs)
+.. c:function:: int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], va_list vargs)
- Identical to :cfunc:`PyArg_ParseTupleAndKeywords`, except that it accepts a
+ Identical to :c:func:`PyArg_ParseTupleAndKeywords`, except that it accepts a
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
-.. cfunction:: int PyArg_Parse(PyObject *args, const char *format, ...)
+.. 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
@@ -418,7 +412,7 @@ API Functions
however, and may continue to be used for that purpose.
-.. cfunction:: int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)
+.. 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
@@ -427,7 +421,7 @@ API Functions
*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
- :ctype:`PyObject\*` variable; these will be filled in with the values from
+ :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
@@ -450,8 +444,8 @@ API Functions
return result;
}
- The call to :cfunc:`PyArg_UnpackTuple` in this example is entirely equivalent to
- this call to :cfunc:`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)
@@ -460,14 +454,14 @@ API Functions
Building values
---------------
-.. cfunction:: PyObject* Py_BuildValue(const char *format, ...)
+.. c:function:: PyObject* Py_BuildValue(const char *format, ...)
Create a new value based on a format string similar to those accepted by the
- :cfunc:`PyArg_Parse\*` family of functions and a sequence of values. Returns
+ :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.
- :cfunc:`Py_BuildValue` does not always build a tuple. It builds a tuple only if
+ :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
@@ -476,10 +470,10 @@ Building values
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
- :cfunc:`Py_BuildValue`. In other words, if your code invokes :cfunc:`malloc`
- and passes the allocated memory to :cfunc:`Py_BuildValue`, your code is
- responsible for calling :cfunc:`free` for that memory once
- :cfunc:`Py_BuildValue` returns.
+ :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;
@@ -522,72 +516,70 @@ Building values
and ``None`` is returned.
``U`` (:class:`str` or ``None``) [char \*]
- Convert a null-terminated C string to a Python unicode object. If the C string
- pointer is *NULL*, ``None`` is used.
+ Same as ``s``.
``U#`` (:class:`str` or ``None``) [char \*, int]
- Convert a C string and its length to a Python unicode object. If the C string
- pointer is *NULL*, the length is ignored and ``None`` is returned.
+ Same as ``s#``.
``i`` (:class:`int`) [int]
- Convert a plain C :ctype:`int` to a Python integer object.
+ Convert a plain C :c:type:`int` to a Python integer object.
``b`` (:class:`int`) [char]
- Convert a plain C :ctype:`char` to a Python integer object.
+ Convert a plain C :c:type:`char` to a Python integer object.
``h`` (:class:`int`) [short int]
- Convert a plain C :ctype:`short int` to a Python integer object.
+ Convert a plain C :c:type:`short int` to a Python integer object.
``l`` (:class:`int`) [long int]
- Convert a C :ctype:`long int` to a Python integer object.
+ Convert a C :c:type:`long int` to a Python integer object.
``B`` (:class:`int`) [unsigned char]
- Convert a C :ctype:`unsigned char` to a Python integer object.
+ Convert a C :c:type:`unsigned char` to a Python integer object.
``H`` (:class:`int`) [unsigned short int]
- Convert a C :ctype:`unsigned short int` to a Python integer object.
+ Convert a C :c:type:`unsigned short int` to a Python integer object.
``I`` (:class:`int`) [unsigned int]
- Convert a C :ctype:`unsigned int` to a Python integer object.
+ Convert a C :c:type:`unsigned int` to a Python integer object.
``k`` (:class:`int`) [unsigned long]
- Convert a C :ctype:`unsigned long` to a Python integer object.
+ Convert a C :c:type:`unsigned long` to a Python integer object.
``L`` (:class:`int`) [PY_LONG_LONG]
- Convert a C :ctype:`long long` to a Python integer object. Only available
- on platforms that support :ctype:`long long` (or :ctype:`_int64` on
+ 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).
``K`` (:class:`int`) [unsigned PY_LONG_LONG]
- Convert a C :ctype:`unsigned long long` to a Python integer object. Only
- available on platforms that support :ctype:`unsigned long long` (or
- :ctype:`unsigned _int64` on Windows).
+ 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).
``n`` (:class:`int`) [Py_ssize_t]
- Convert a C :ctype:`Py_ssize_t` to a Python integer.
+ Convert a C :c:type:`Py_ssize_t` to a Python integer.
``c`` (:class:`bytes` of length 1) [char]
- Convert a C :ctype:`int` representing a byte to a Python :class:`bytes` object of
+ Convert a C :c:type:`int` representing a byte to a Python :class:`bytes` object of
length 1.
``C`` (:class:`str` of length 1) [int]
- Convert a C :ctype:`int` representing a character to Python :class:`str`
+ Convert a C :c:type:`int` representing a character to Python :class:`str`
object of length 1.
``d`` (:class:`float`) [double]
- Convert a C :ctype:`double` to a Python floating point number.
+ Convert a C :c:type:`double` to a Python floating point number.
``f`` (:class:`float`) [float]
- Convert a C :ctype:`float` to a Python floating point number.
+ Convert a C :c:type:`float` to a Python floating point number.
``D`` (:class:`complex`) [Py_complex \*]
- Convert a C :ctype:`Py_complex` structure to a Python complex number.
+ 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, :cfunc:`Py_BuildValue` will return *NULL* but won't
+ 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.
@@ -601,7 +593,7 @@ Building values
``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 :ctype:`void
+ 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.
@@ -619,7 +611,7 @@ Building values
If there is an error in the format string, the :exc:`SystemError` exception is
set and *NULL* returned.
-.. cfunction:: PyObject* Py_VaBuildValue(const char *format, va_list vargs)
+.. c:function:: PyObject* Py_VaBuildValue(const char *format, va_list vargs)
- Identical to :cfunc:`Py_BuildValue`, except that it accepts a va_list
+ Identical to :c:func:`Py_BuildValue`, except that it accepts a va_list
rather than a variable number of arguments.
diff --git a/Doc/c-api/bool.rst b/Doc/c-api/bool.rst
index 4479bc6..a9fb342 100644
--- a/Doc/c-api/bool.rst
+++ b/Doc/c-api/bool.rst
@@ -11,36 +11,36 @@ creation and deletion functions don't apply to booleans. The following macros
are available, however.
-.. cfunction:: int PyBool_Check(PyObject *o)
+.. c:function:: int PyBool_Check(PyObject *o)
- Return true if *o* is of type :cdata:`PyBool_Type`.
+ Return true if *o* is of type :c:data:`PyBool_Type`.
-.. cvar:: PyObject* Py_False
+.. c:var:: PyObject* Py_False
The Python ``False`` object. This object has no methods. It needs to be
treated just like any other object with respect to reference counts.
-.. cvar:: PyObject* Py_True
+.. c:var:: PyObject* Py_True
The Python ``True`` object. This object has no methods. It needs to be treated
just like any other object with respect to reference counts.
-.. cmacro:: Py_RETURN_FALSE
+.. c:macro:: Py_RETURN_FALSE
Return :const:`Py_False` from a function, properly incrementing its reference
count.
-.. cmacro:: Py_RETURN_TRUE
+.. c:macro:: Py_RETURN_TRUE
Return :const:`Py_True` from a function, properly incrementing its reference
count.
-.. cfunction:: PyObject* PyBool_FromLong(long v)
+.. 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*.
diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst
index 094f7f2..5a34bc0 100644
--- a/Doc/c-api/buffer.rst
+++ b/Doc/c-api/buffer.rst
@@ -50,12 +50,12 @@ selectively allow or reject exporting of read-write and read-only buffers.
There are two ways for a consumer of the buffer interface to acquire a buffer
over a target object:
-* call :cfunc:`PyObject_GetBuffer` with the right parameters;
+* call :c:func:`PyObject_GetBuffer` with the right parameters;
-* call :cfunc:`PyArg_ParseTuple` (or one of its siblings) with one of the
+* 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, :cfunc:`PyBuffer_Release` must be called when the buffer
+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.
@@ -73,55 +73,55 @@ 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 :ctype:`PyObject` pointers but rather simple C structures. This
+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.
-.. ctype:: Py_buffer
+.. c:type:: Py_buffer
- .. cmember:: void *buf
+ .. c:member:: void *buf
A pointer to the start of the memory for the object.
- .. cmember:: Py_ssize_t len
+ .. c:member:: Py_ssize_t len
:noindex:
The total length of the memory in bytes.
- .. cmember:: int readonly
+ .. c:member:: int readonly
An indicator of whether the buffer is read only.
- .. cmember:: const char *format
+ .. c:member:: const char *format
:noindex:
A *NULL* terminated string in :mod:`struct` module style syntax giving
the contents of the elements available through the buffer. If this is
*NULL*, ``"B"`` (unsigned bytes) is assumed.
- .. cmember:: int ndim
+ .. c:member:: int ndim
The number of dimensions the memory represents as a multi-dimensional
- array. If it is 0, :cdata:`strides` and :cdata:`suboffsets` must be
+ array. If it is 0, :c:data:`strides` and :c:data:`suboffsets` must be
*NULL*.
- .. cmember:: Py_ssize_t *shape
+ .. c:member:: Py_ssize_t *shape
- An array of :ctype:`Py_ssize_t`\s the length of :cdata:`ndim` giving the
+ An array of :c:type:`Py_ssize_t`\s the length of :c:data:`ndim` giving the
shape of the memory as a multi-dimensional array. Note that
``((*shape)[0] * ... * (*shape)[ndims-1])*itemsize`` should be equal to
- :cdata:`len`.
+ :c:data:`len`.
- .. cmember:: Py_ssize_t *strides
+ .. c:member:: Py_ssize_t *strides
- An array of :ctype:`Py_ssize_t`\s the length of :cdata:`ndim` giving the
+ An array of :c:type:`Py_ssize_t`\s the length of :c:data:`ndim` giving the
number of bytes to skip to get to a new element in each dimension.
- .. cmember:: Py_ssize_t *suboffsets
+ .. c:member:: Py_ssize_t *suboffsets
- An array of :ctype:`Py_ssize_t`\s the length of :cdata:`ndim`. If these
+ An array of :c:type:`Py_ssize_t`\s the length of :c:data:`ndim`. If these
suboffset numbers are greater than or equal to 0, then the value stored
along the indicated dimension is a pointer and the suboffset value
dictates how many bytes to add to the pointer after de-referencing. A
@@ -146,16 +146,16 @@ can be created.
}
- .. cmember:: Py_ssize_t itemsize
+ .. c:member:: Py_ssize_t itemsize
This is a storage for the itemsize (in bytes) of each element of the
shared memory. It is technically un-necessary as it can be obtained
- using :cfunc:`PyBuffer_SizeFromFormat`, however an exporter may know
+ using :c:func:`PyBuffer_SizeFromFormat`, however an exporter may know
this information without parsing the format string and it is necessary
to know the itemsize for proper interpretation of striding. Therefore,
storing it is more convenient and faster.
- .. cmember:: void *internal
+ .. c:member:: void *internal
This is for use internally by the exporting object. For example, this
might be re-cast as an integer by the exporter and used to store flags
@@ -168,32 +168,32 @@ Buffer-related functions
========================
-.. cfunction:: int PyObject_CheckBuffer(PyObject *obj)
+.. c:function:: int PyObject_CheckBuffer(PyObject *obj)
Return 1 if *obj* supports the buffer interface otherwise 0. When 1 is
- returned, it doesn't guarantee that :cfunc:`PyObject_GetBuffer` will
+ returned, it doesn't guarantee that :c:func:`PyObject_GetBuffer` will
succeed.
-.. cfunction:: int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
+.. c:function:: int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
Export a view over some internal data from the target object *obj*.
*obj* must not be NULL, and *view* must point to an existing
- :ctype:`Py_buffer` structure allocated by the caller (most uses of
+ :c:type:`Py_buffer` structure allocated by the caller (most uses of
this function will simply declare a local variable of type
- :ctype:`Py_buffer`). The *flags* argument is a bit field indicating
+ :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 :cmacro:`PyBUF_SIMPLE` for a read-only
- view and :cmacro:`PyBUF_WRITABLE` for a read-write view).
+ 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
just not possible. These errors should be a :exc:`BufferError` unless
there is another error that is actually causing the problem. The
exporter can use flags information to simplify how much of the
- :cdata:`Py_buffer` structure is filled in with non-default values and/or
+ :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.
On success, 0 is returned and the *view* structure is filled with useful
@@ -202,7 +202,7 @@ Buffer-related functions
The following are the possible values to the *flags* arguments.
- .. cmacro:: PyBUF_SIMPLE
+ .. c:macro:: PyBUF_SIMPLE
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,
@@ -210,47 +210,45 @@ Buffer-related functions
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.
- .. cmacro:: PyBUF_WRITABLE
+ .. c:macro:: PyBUF_WRITABLE
- Like :cmacro:`PyBUF_SIMPLE`, but the returned buffer is writable. If
+ Like :c:macro:`PyBUF_SIMPLE`, but the returned buffer is writable. If
the exporter doesn't support writable buffers, an error is raised.
- .. cmacro:: PyBUF_STRIDES
+ .. c:macro:: PyBUF_STRIDES
- This implies :cmacro:`PyBUF_ND`. The returned buffer must provide
+ 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).
- .. cmacro:: PyBUF_ND
+ .. 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*.
- .. cmacro:: PyBUF_C_CONTIGUOUS
-
- .. cmacro:: PyBUF_F_CONTIGUOUS
-
- .. cmacro:: PyBUF_ANY_CONTIGUOUS
+ .. c:macro:: PyBUF_C_CONTIGUOUS
+ PyBUF_F_CONTIGUOUS
+ PyBUF_ANY_CONTIGUOUS
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 :cmacro:`PyBUF_STRIDES` and guarantee that the
+ these flags imply :c:macro:`PyBUF_STRIDES` and guarantee that the
strides buffer info structure will be filled in correctly.
- .. cmacro:: PyBUF_INDIRECT
+ .. 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 :cmacro:`PyBUF_STRIDES`.
+ by these suboffsets. This implies :c:macro:`PyBUF_STRIDES`.
- .. cmacro:: PyBUF_FORMAT
+ .. 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
@@ -259,68 +257,68 @@ Buffer-related functions
explicitly requested then the format must be returned as *NULL* (which
means ``'B'``, or unsigned bytes).
- .. cmacro:: PyBUF_STRIDED
+ .. c:macro:: PyBUF_STRIDED
This is equivalent to ``(PyBUF_STRIDES | PyBUF_WRITABLE)``.
- .. cmacro:: PyBUF_STRIDED_RO
+ .. c:macro:: PyBUF_STRIDED_RO
This is equivalent to ``(PyBUF_STRIDES)``.
- .. cmacro:: PyBUF_RECORDS
+ .. c:macro:: PyBUF_RECORDS
This is equivalent to ``(PyBUF_STRIDES | PyBUF_FORMAT |
PyBUF_WRITABLE)``.
- .. cmacro:: PyBUF_RECORDS_RO
+ .. c:macro:: PyBUF_RECORDS_RO
This is equivalent to ``(PyBUF_STRIDES | PyBUF_FORMAT)``.
- .. cmacro:: PyBUF_FULL
+ .. c:macro:: PyBUF_FULL
This is equivalent to ``(PyBUF_INDIRECT | PyBUF_FORMAT |
PyBUF_WRITABLE)``.
- .. cmacro:: PyBUF_FULL_RO
+ .. c:macro:: PyBUF_FULL_RO
This is equivalent to ``(PyBUF_INDIRECT | PyBUF_FORMAT)``.
- .. cmacro:: PyBUF_CONTIG
+ .. c:macro:: PyBUF_CONTIG
This is equivalent to ``(PyBUF_ND | PyBUF_WRITABLE)``.
- .. cmacro:: PyBUF_CONTIG_RO
+ .. c:macro:: PyBUF_CONTIG_RO
This is equivalent to ``(PyBUF_ND)``.
-.. cfunction:: void PyBuffer_Release(Py_buffer *view)
+.. 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.
-.. cfunction:: Py_ssize_t PyBuffer_SizeFromFormat(const char *)
+.. c:function:: Py_ssize_t PyBuffer_SizeFromFormat(const char *)
- Return the implied :cdata:`~Py_buffer.itemsize` from the struct-stype
- :cdata:`~Py_buffer.format`.
+ Return the implied :c:data:`~Py_buffer.itemsize` from the struct-stype
+ :c:data:`~Py_buffer.format`.
-.. cfunction:: int PyBuffer_IsContiguous(Py_buffer *view, char fortran)
+.. 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.
-.. cfunction:: void PyBuffer_FillContiguousStrides(int ndim, Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t itemsize, char fortran)
+.. 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.
-.. cfunction:: int PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, int readonly, int infoflags)
+.. c:function:: int PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, int readonly, int infoflags)
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
diff --git a/Doc/c-api/bytearray.rst b/Doc/c-api/bytearray.rst
index 5e11d8a..95ded96 100644
--- a/Doc/c-api/bytearray.rst
+++ b/Doc/c-api/bytearray.rst
@@ -8,27 +8,27 @@ Byte Array Objects
.. index:: object: bytearray
-.. ctype:: PyByteArrayObject
+.. c:type:: PyByteArrayObject
- This subtype of :ctype:`PyObject` represents a Python bytearray object.
+ This subtype of :c:type:`PyObject` represents a Python bytearray object.
-.. cvar:: PyTypeObject PyByteArray_Type
+.. c:var:: PyTypeObject PyByteArray_Type
- This instance of :ctype:`PyTypeObject` represents the Python bytearray type;
+ This instance of :c:type:`PyTypeObject` represents the Python bytearray type;
it is the same object as :class:`bytearray` in the Python layer.
Type check macros
^^^^^^^^^^^^^^^^^
-.. cfunction:: int PyByteArray_Check(PyObject *o)
+.. c:function:: int PyByteArray_Check(PyObject *o)
Return true if the object *o* is a bytearray object or an instance of a
subtype of the bytearray type.
-.. cfunction:: int PyByteArray_CheckExact(PyObject *o)
+.. c:function:: int PyByteArray_CheckExact(PyObject *o)
Return true if the object *o* is a bytearray object, but not an instance of a
subtype of the bytearray type.
@@ -37,7 +37,7 @@ Type check macros
Direct API functions
^^^^^^^^^^^^^^^^^^^^
-.. cfunction:: PyObject* PyByteArray_FromObject(PyObject *o)
+.. c:function:: PyObject* PyByteArray_FromObject(PyObject *o)
Return a new bytearray object from any object, *o*, that implements the
buffer protocol.
@@ -45,29 +45,29 @@ Direct API functions
.. XXX expand about the buffer protocol, at least somewhere
-.. cfunction:: PyObject* PyByteArray_FromStringAndSize(const char *string, Py_ssize_t len)
+.. c:function:: PyObject* PyByteArray_FromStringAndSize(const char *string, Py_ssize_t len)
Create a new bytearray object from *string* and its length, *len*. On
failure, *NULL* is returned.
-.. cfunction:: PyObject* PyByteArray_Concat(PyObject *a, PyObject *b)
+.. c:function:: PyObject* PyByteArray_Concat(PyObject *a, PyObject *b)
Concat bytearrays *a* and *b* and return a new bytearray with the result.
-.. cfunction:: Py_ssize_t PyByteArray_Size(PyObject *bytearray)
+.. c:function:: Py_ssize_t PyByteArray_Size(PyObject *bytearray)
Return the size of *bytearray* after checking for a *NULL* pointer.
-.. cfunction:: char* PyByteArray_AsString(PyObject *bytearray)
+.. c:function:: char* PyByteArray_AsString(PyObject *bytearray)
Return the contents of *bytearray* as a char array after checking for a
*NULL* pointer.
-.. cfunction:: int PyByteArray_Resize(PyObject *bytearray, Py_ssize_t len)
+.. c:function:: int PyByteArray_Resize(PyObject *bytearray, Py_ssize_t len)
Resize the internal buffer of *bytearray* to *len*.
@@ -76,11 +76,11 @@ Macros
These macros trade safety for speed and they don't check pointers.
-.. cfunction:: char* PyByteArray_AS_STRING(PyObject *bytearray)
+.. c:function:: char* PyByteArray_AS_STRING(PyObject *bytearray)
- Macro version of :cfunc:`PyByteArray_AsString`.
+ Macro version of :c:func:`PyByteArray_AsString`.
-.. cfunction:: Py_ssize_t PyByteArray_GET_SIZE(PyObject *bytearray)
+.. c:function:: Py_ssize_t PyByteArray_GET_SIZE(PyObject *bytearray)
- Macro version of :cfunc:`PyByteArray_Size`.
+ Macro version of :c:func:`PyByteArray_Size`.
diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst
index abd8744..12ec80c 100644
--- a/Doc/c-api/bytes.rst
+++ b/Doc/c-api/bytes.rst
@@ -11,46 +11,46 @@ called with a non-bytes parameter.
.. index:: object: bytes
-.. ctype:: PyBytesObject
+.. c:type:: PyBytesObject
- This subtype of :ctype:`PyObject` represents a Python bytes object.
+ This subtype of :c:type:`PyObject` represents a Python bytes object.
-.. cvar:: PyTypeObject PyBytes_Type
+.. c:var:: PyTypeObject PyBytes_Type
- This instance of :ctype:`PyTypeObject` represents the Python bytes type; it
+ This instance of :c:type:`PyTypeObject` represents the Python bytes type; it
is the same object as :class:`bytes` in the Python layer.
-.. cfunction:: int PyBytes_Check(PyObject *o)
+.. 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.
-.. cfunction:: int PyBytes_CheckExact(PyObject *o)
+.. 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.
-.. cfunction:: PyObject* PyBytes_FromString(const char *v)
+.. 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.
-.. cfunction:: PyObject* PyBytes_FromStringAndSize(const char *v, Py_ssize_t len)
+.. 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.
-.. cfunction:: PyObject* PyBytes_FromFormat(const char *format, ...)
+.. c:function:: PyObject* PyBytes_FromFormat(const char *format, ...)
- Take a C :cfunc:`printf`\ -style *format* string and a variable number of
+ 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
@@ -110,44 +110,44 @@ called with a non-bytes parameter.
copied as-is to the result string, and any extra arguments discarded.
-.. cfunction:: PyObject* PyBytes_FromFormatV(const char *format, va_list vargs)
+.. c:function:: PyObject* PyBytes_FromFormatV(const char *format, va_list vargs)
- Identical to :func:`PyBytes_FromFormat` except that it takes exactly two
+ Identical to :c:func:`PyBytes_FromFormat` except that it takes exactly two
arguments.
-.. cfunction:: PyObject* PyBytes_FromObject(PyObject *o)
+.. c:function:: PyObject* PyBytes_FromObject(PyObject *o)
Return the bytes representation of object *o* that implements the buffer
protocol.
-.. cfunction:: Py_ssize_t PyBytes_Size(PyObject *o)
+.. c:function:: Py_ssize_t PyBytes_Size(PyObject *o)
Return the length of the bytes in bytes object *o*.
-.. cfunction:: Py_ssize_t PyBytes_GET_SIZE(PyObject *o)
+.. c:function:: Py_ssize_t PyBytes_GET_SIZE(PyObject *o)
- Macro form of :cfunc:`PyBytes_Size` but without error checking.
+ Macro form of :c:func:`PyBytes_Size` but without error checking.
-.. cfunction:: char* PyBytes_AsString(PyObject *o)
+.. 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, :cfunc:`PyBytes_AsString` returns *NULL*
+ *o* is not a string object at all, :c:func:`PyBytes_AsString` returns *NULL*
and raises :exc:`TypeError`.
-.. cfunction:: char* PyBytes_AS_STRING(PyObject *string)
+.. c:function:: char* PyBytes_AS_STRING(PyObject *string)
- Macro form of :cfunc:`PyBytes_AsString` but without error checking.
+ Macro form of :c:func:`PyBytes_AsString` but without error checking.
-.. cfunction:: int PyBytes_AsStringAndSize(PyObject *obj, char **buffer, Py_ssize_t *length)
+.. 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*.
@@ -158,11 +158,11 @@ called with a non-bytes parameter.
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, :cfunc:`PyBytes_AsStringAndSize`
+ *string* is not a string object at all, :c:func:`PyBytes_AsStringAndSize`
returns ``-1`` and raises :exc:`TypeError`.
-.. cfunction:: void PyBytes_Concat(PyObject **bytes, PyObject *newpart)
+.. 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
@@ -171,14 +171,14 @@ called with a non-bytes parameter.
of *\*bytes* will be set to *NULL*; the appropriate exception will be set.
-.. cfunction:: void PyBytes_ConcatAndDel(PyObject **bytes, PyObject *newpart)
+.. 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*.
-.. cfunction:: int _PyBytes_Resize(PyObject **bytes, Py_ssize_t newsize)
+.. 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
diff --git a/Doc/c-api/capsule.rst b/Doc/c-api/capsule.rst
index 2939314..6f6250f 100644
--- a/Doc/c-api/capsule.rst
+++ b/Doc/c-api/capsule.rst
@@ -10,33 +10,33 @@ Capsules
Refer to :ref:`using-capsules` for more information on using these objects.
-.. ctype:: PyCapsule
+.. c:type:: PyCapsule
- This subtype of :ctype:`PyObject` represents an opaque value, useful for C
- extension modules who need to pass an opaque value (as a :ctype:`void\*`
+ 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.
-.. ctype:: PyCapsule_Destructor
+.. c:type:: PyCapsule_Destructor
The type of a destructor callback for a capsule. Defined as::
typedef void (*PyCapsule_Destructor)(PyObject *);
- See :cfunc:`PyCapsule_New` for the semantics of PyCapsule_Destructor
+ See :c:func:`PyCapsule_New` for the semantics of PyCapsule_Destructor
callbacks.
-.. cfunction:: int PyCapsule_CheckExact(PyObject *p)
+.. c:function:: int PyCapsule_CheckExact(PyObject *p)
- Return true if its argument is a :ctype:`PyCapsule`.
+ Return true if its argument is a :c:type:`PyCapsule`.
-.. cfunction:: PyObject* PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
+.. c:function:: PyObject* PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
- Create a :ctype:`PyCapsule` encapsulating the *pointer*. The *pointer*
+ Create a :c:type:`PyCapsule` encapsulating the *pointer*. The *pointer*
argument may not be *NULL*.
On failure, set an exception and return *NULL*.
@@ -50,91 +50,91 @@ Refer to :ref:`using-capsules` for more information on using these objects.
If this capsule will be stored as an attribute of a module, the *name* should
be specified as ``modulename.attributename``. This will enable other modules
- to import the capsule using :cfunc:`PyCapsule_Import`.
+ to import the capsule using :c:func:`PyCapsule_Import`.
-.. cfunction:: void* PyCapsule_GetPointer(PyObject *capsule, const char *name)
+.. c:function:: void* PyCapsule_GetPointer(PyObject *capsule, const char *name)
Retrieve the *pointer* stored in the capsule. On failure, set an exception
and return *NULL*.
The *name* parameter must compare exactly to the name stored in the capsule.
If the name stored in the capsule is *NULL*, the *name* passed in must also
- be *NULL*. Python uses the C function :cfunc:`strcmp` to compare capsule
+ be *NULL*. Python uses the C function :c:func:`strcmp` to compare capsule
names.
-.. cfunction:: PyCapsule_Destructor PyCapsule_GetDestructor(PyObject *capsule)
+.. c:function:: PyCapsule_Destructor PyCapsule_GetDestructor(PyObject *capsule)
Return the current destructor stored in the capsule. On failure, set an
exception and return *NULL*.
It is legal for a capsule to have a *NULL* destructor. This makes a *NULL*
- return code somewhat ambiguous; use :cfunc:`PyCapsule_IsValid` or
- :cfunc:`PyErr_Occurred` to disambiguate.
+ return code somewhat ambiguous; use :c:func:`PyCapsule_IsValid` or
+ :c:func:`PyErr_Occurred` to disambiguate.
-.. cfunction:: void* PyCapsule_GetContext(PyObject *capsule)
+.. c:function:: void* PyCapsule_GetContext(PyObject *capsule)
Return the current context stored in the capsule. On failure, set an
exception and return *NULL*.
It is legal for a capsule to have a *NULL* context. This makes a *NULL*
- return code somewhat ambiguous; use :cfunc:`PyCapsule_IsValid` or
- :cfunc:`PyErr_Occurred` to disambiguate.
+ return code somewhat ambiguous; use :c:func:`PyCapsule_IsValid` or
+ :c:func:`PyErr_Occurred` to disambiguate.
-.. cfunction:: const char* PyCapsule_GetName(PyObject *capsule)
+.. c:function:: const char* PyCapsule_GetName(PyObject *capsule)
Return the current name stored in the capsule. On failure, set an exception
and return *NULL*.
It is legal for a capsule to have a *NULL* name. This makes a *NULL* return
- code somewhat ambiguous; use :cfunc:`PyCapsule_IsValid` or
- :cfunc:`PyErr_Occurred` to disambiguate.
+ code somewhat ambiguous; use :c:func:`PyCapsule_IsValid` or
+ :c:func:`PyErr_Occurred` to disambiguate.
-.. cfunction:: void* PyCapsule_Import(const char *name, int no_block)
+.. c:function:: void* PyCapsule_Import(const char *name, int no_block)
Import a pointer to a C object from a capsule attribute in a module. The
*name* parameter should specify the full name to the attribute, as in
``module.attribute``. The *name* stored in the capsule must match this
string exactly. If *no_block* is true, import the module without blocking
- (using :cfunc:`PyImport_ImportModuleNoBlock`). If *no_block* is false,
- import the module conventionally (using :cfunc:`PyImport_ImportModule`).
+ (using :c:func:`PyImport_ImportModuleNoBlock`). If *no_block* is false,
+ import the module conventionally (using :c:func:`PyImport_ImportModule`).
Return the capsule's internal *pointer* on success. On failure, set an
- exception and return *NULL*. However, if :cfunc:`PyCapsule_Import` failed to
+ exception and return *NULL*. However, if :c:func:`PyCapsule_Import` failed to
import the module, and *no_block* was true, no exception is set.
-.. cfunction:: int PyCapsule_IsValid(PyObject *capsule, const char *name)
+.. c:function:: int PyCapsule_IsValid(PyObject *capsule, const char *name)
Determines whether or not *capsule* is a valid capsule. A valid capsule is
- non-*NULL*, passes :cfunc:`PyCapsule_CheckExact`, has a non-*NULL* pointer
+ non-*NULL*, passes :c:func:`PyCapsule_CheckExact`, has a non-*NULL* pointer
stored in it, and its internal name matches the *name* parameter. (See
- :cfunc:`PyCapsule_GetPointer` for information on how capsule names are
+ :c:func:`PyCapsule_GetPointer` for information on how capsule names are
compared.)
- In other words, if :cfunc:`PyCapsule_IsValid` returns a true value, calls to
- any of the accessors (any function starting with :cfunc:`PyCapsule_Get`) are
+ In other words, if :c:func:`PyCapsule_IsValid` returns a true value, calls to
+ any of the accessors (any function starting with :c:func:`PyCapsule_Get`) are
guaranteed to succeed.
Return a nonzero value if the object is valid and matches the name passed in.
Return 0 otherwise. This function will not fail.
-.. cfunction:: int PyCapsule_SetContext(PyObject *capsule, void *context)
+.. c:function:: int PyCapsule_SetContext(PyObject *capsule, void *context)
Set the context pointer inside *capsule* to *context*.
Return 0 on success. Return nonzero and set an exception on failure.
-.. cfunction:: int PyCapsule_SetDestructor(PyObject *capsule, PyCapsule_Destructor destructor)
+.. c:function:: int PyCapsule_SetDestructor(PyObject *capsule, PyCapsule_Destructor destructor)
Set the destructor inside *capsule* to *destructor*.
Return 0 on success. Return nonzero and set an exception on failure.
-.. cfunction:: int PyCapsule_SetName(PyObject *capsule, const char *name)
+.. c:function:: int PyCapsule_SetName(PyObject *capsule, const char *name)
Set the name inside *capsule* to *name*. If non-*NULL*, the name must
outlive the capsule. If the previous *name* stored in the capsule was not
@@ -142,7 +142,7 @@ Refer to :ref:`using-capsules` for more information on using these objects.
Return 0 on success. Return nonzero and set an exception on failure.
-.. cfunction:: int PyCapsule_SetPointer(PyObject *capsule, void *pointer)
+.. c:function:: int PyCapsule_SetPointer(PyObject *capsule, void *pointer)
Set the void pointer inside *capsule* to *pointer*. The pointer may not be
*NULL*.
diff --git a/Doc/c-api/cell.rst b/Doc/c-api/cell.rst
index 3562ed9..427259c 100644
--- a/Doc/c-api/cell.rst
+++ b/Doc/c-api/cell.rst
@@ -15,39 +15,39 @@ generated byte-code; these are not automatically de-referenced when accessed.
Cell objects are not likely to be useful elsewhere.
-.. ctype:: PyCellObject
+.. c:type:: PyCellObject
The C structure used for cell objects.
-.. cvar:: PyTypeObject PyCell_Type
+.. c:var:: PyTypeObject PyCell_Type
The type object corresponding to cell objects.
-.. cfunction:: int PyCell_Check(ob)
+.. c:function:: int PyCell_Check(ob)
Return true if *ob* is a cell object; *ob* must not be *NULL*.
-.. cfunction:: PyObject* PyCell_New(PyObject *ob)
+.. c:function:: PyObject* PyCell_New(PyObject *ob)
Create and return a new cell object containing the value *ob*. The parameter may
be *NULL*.
-.. cfunction:: PyObject* PyCell_Get(PyObject *cell)
+.. c:function:: PyObject* PyCell_Get(PyObject *cell)
Return the contents of the cell *cell*.
-.. cfunction:: PyObject* PyCell_GET(PyObject *cell)
+.. c:function:: PyObject* PyCell_GET(PyObject *cell)
Return the contents of the cell *cell*, but without checking that *cell* is
non-*NULL* and a cell object.
-.. cfunction:: int PyCell_Set(PyObject *cell, PyObject *value)
+.. c:function:: int PyCell_Set(PyObject *cell, PyObject *value)
Set the contents of the cell object *cell* to *value*. This releases the
reference to any current content of the cell. *value* may be *NULL*. *cell*
@@ -55,7 +55,7 @@ Cell objects are not likely to be useful elsewhere.
success, ``0`` will be returned.
-.. cfunction:: void PyCell_SET(PyObject *cell, PyObject *value)
+.. c:function:: void PyCell_SET(PyObject *cell, PyObject *value)
Sets the value of the cell object *cell* to *value*. No reference counts are
adjusted, and no checks are made for safety; *cell* must be non-*NULL* and must
diff --git a/Doc/c-api/cobject.rst b/Doc/c-api/cobject.rst
deleted file mode 100644
index ee65a98..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 3.1. Please switch to the new
- :ref:`capsules` API.
-
-.. ctype:: PyCObject
-
- This subtype of :ctype:`PyObject` represents an opaque value, useful for C
- extension modules who need to pass an opaque value (as a :ctype:`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.
-
-
-.. cfunction:: int PyCObject_Check(PyObject *p)
-
- Return true if its argument is a :ctype:`PyCObject`.
-
-
-.. cfunction:: PyObject* PyCObject_FromVoidPtr(void* cobj, void (*destr)(void *))
-
- Create a :ctype:`PyCObject` from the ``void *`` *cobj*. The *destr* function
- will be called when the object is reclaimed, unless it is *NULL*.
-
-
-.. cfunction:: PyObject* PyCObject_FromVoidPtrAndDesc(void* cobj, void* desc, void (*destr)(void *, void *))
-
- Create a :ctype:`PyCObject` from the :ctype:`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.
-
-
-.. cfunction:: void* PyCObject_AsVoidPtr(PyObject* self)
-
- Return the object :ctype:`void \*` that the :ctype:`PyCObject` *self* was
- created with.
-
-
-.. cfunction:: void* PyCObject_GetDesc(PyObject* self)
-
- Return the description :ctype:`void \*` that the :ctype:`PyCObject` *self* was
- created with.
-
-
-.. cfunction:: int PyCObject_SetVoidPtr(PyObject* self, void* cobj)
-
- Set the void pointer inside *self* to *cobj*. The :ctype:`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
new file mode 100644
index 0000000..52c4245
--- /dev/null
+++ b/Doc/c-api/code.rst
@@ -0,0 +1,50 @@
+.. highlightlang:: c
+
+.. _codeobjects:
+
+Code Objects
+------------
+
+.. sectionauthor:: Jeffrey Yasskin <jyasskin@gmail.com>
+
+
+.. index::
+ object: code
+
+Code objects are a low-level detail of the CPython implementation.
+Each one represents a chunk of executable code that hasn't yet been
+bound into a function.
+
+.. c:type:: PyCodeObject
+
+ The C structure of the objects used to describe code objects. The
+ fields of this type are subject to change at any time.
+
+
+.. c:var:: PyTypeObject PyCode_Type
+
+ This is an instance of :c:type:`PyTypeObject` representing the Python
+ :class:`code` type.
+
+
+.. c:function:: int PyCode_Check(PyObject *co)
+
+ Return true if *co* is a :class:`code` object
+
+.. c:function:: int PyCode_GetNumFree(PyObject *co)
+
+ 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)
+
+ Return a new code object. If you need a dummy code object to
+ create a frame, use :c:func:`PyCode_NewEmpty` instead. Calling
+ :c:func:`PyCode_New` directly can bind you to a precise Python
+ version since the definition of the bytecode changes often.
+
+
+.. c:function:: int PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
+
+ Return a new empty code object with the specified filename,
+ function name, and first line number. It is illegal to
+ :func:`exec` or :func:`eval` the resulting code object.
diff --git a/Doc/c-api/codec.rst b/Doc/c-api/codec.rst
index 2597d38..8207ae0 100644
--- a/Doc/c-api/codec.rst
+++ b/Doc/c-api/codec.rst
@@ -3,19 +3,19 @@
Codec registry and support functions
====================================
-.. cfunction:: int PyCodec_Register(PyObject *search_function)
+.. c:function:: int PyCodec_Register(PyObject *search_function)
Register a new codec search function.
As side effect, this tries to load the :mod:`encodings` package, if not yet
done, to make sure that it is always first in the list of search functions.
-.. cfunction:: int PyCodec_KnownEncoding(const char *encoding)
+.. c:function:: int PyCodec_KnownEncoding(const char *encoding)
Return ``1`` or ``0`` depending on whether there is a registered codec for
the given *encoding*.
-.. cfunction:: PyObject* PyCodec_Encode(PyObject *object, const char *encoding, const char *errors)
+.. c:function:: PyObject* PyCodec_Encode(PyObject *object, const char *encoding, const char *errors)
Generic codec based encoding API.
@@ -24,7 +24,7 @@ Codec registry and support functions
be *NULL* to use the default method defined for the codec. Raises a
:exc:`LookupError` if no encoder can be found.
-.. cfunction:: PyObject* PyCodec_Decode(PyObject *object, const char *encoding, const char *errors)
+.. c:function:: PyObject* PyCodec_Decode(PyObject *object, const char *encoding, const char *errors)
Generic codec based decoding API.
@@ -42,27 +42,27 @@ lower-case characters, which makes encodings looked up through this mechanism
effectively case-insensitive. If no codec is found, a :exc:`KeyError` is set
and *NULL* returned.
-.. cfunction:: PyObject* PyCodec_Encoder(const char *encoding)
+.. c:function:: PyObject* PyCodec_Encoder(const char *encoding)
Get an encoder function for the given *encoding*.
-.. cfunction:: PyObject* PyCodec_Decoder(const char *encoding)
+.. c:function:: PyObject* PyCodec_Decoder(const char *encoding)
Get a decoder function for the given *encoding*.
-.. cfunction:: PyObject* PyCodec_IncrementalEncoder(const char *encoding, const char *errors)
+.. c:function:: PyObject* PyCodec_IncrementalEncoder(const char *encoding, const char *errors)
Get an :class:`IncrementalEncoder` object for the given *encoding*.
-.. cfunction:: PyObject* PyCodec_IncrementalDecoder(const char *encoding, const char *errors)
+.. c:function:: PyObject* PyCodec_IncrementalDecoder(const char *encoding, const char *errors)
Get an :class:`IncrementalDecoder` object for the given *encoding*.
-.. cfunction:: PyObject* PyCodec_StreamReader(const char *encoding, PyObject *stream, const char *errors)
+.. c:function:: PyObject* PyCodec_StreamReader(const char *encoding, PyObject *stream, const char *errors)
Get a :class:`StreamReader` factory function for the given *encoding*.
-.. cfunction:: PyObject* PyCodec_StreamWriter(const char *encoding, PyObject *stream, const char *errors)
+.. c:function:: PyObject* PyCodec_StreamWriter(const char *encoding, PyObject *stream, const char *errors)
Get a :class:`StreamWriter` factory function for the given *encoding*.
@@ -70,7 +70,7 @@ and *NULL* returned.
Registry API for Unicode encoding error handlers
------------------------------------------------
-.. cfunction:: int PyCodec_RegisterError(const char *name, PyObject *error)
+.. c:function:: int PyCodec_RegisterError(const char *name, PyObject *error)
Register the error handling callback function *error* under the given *name*.
This callback function will be called by a codec when it encounters
@@ -89,29 +89,29 @@ Registry API for Unicode encoding error handlers
Return ``0`` on success, ``-1`` on error.
-.. cfunction:: PyObject* PyCodec_LookupError(const char *name)
+.. c:function:: PyObject* PyCodec_LookupError(const char *name)
Lookup the error handling callback function registered under *name*. As a
special case *NULL* can be passed, in which case the error handling callback
for "strict" will be returned.
-.. cfunction:: PyObject* PyCodec_StrictErrors(PyObject *exc)
+.. c:function:: PyObject* PyCodec_StrictErrors(PyObject *exc)
Raise *exc* as an exception.
-.. cfunction:: PyObject* PyCodec_IgnoreErrors(PyObject *exc)
+.. c:function:: PyObject* PyCodec_IgnoreErrors(PyObject *exc)
Ignore the unicode error, skipping the faulty input.
-.. cfunction:: PyObject* PyCodec_ReplaceErrors(PyObject *exc)
+.. c:function:: PyObject* PyCodec_ReplaceErrors(PyObject *exc)
Replace the unicode encode error with ``?`` or ``U+FFFD``.
-.. cfunction:: PyObject* PyCodec_XMLCharRefReplaceErrors(PyObject *exc)
+.. c:function:: PyObject* PyCodec_XMLCharRefReplaceErrors(PyObject *exc)
Replace the unicode encode error with XML character references.
-.. cfunction:: PyObject* PyCodec_BackslashReplaceErrors(PyObject *exc)
+.. c:function:: PyObject* PyCodec_BackslashReplaceErrors(PyObject *exc)
Replace the unicode encode error with backslash escapes (``\x``, ``\u`` and
``\U``).
diff --git a/Doc/c-api/complex.rst b/Doc/c-api/complex.rst
index 0bcdf4d..43dfe56 100644
--- a/Doc/c-api/complex.rst
+++ b/Doc/c-api/complex.rst
@@ -21,7 +21,7 @@ them as results do so *by value* rather than dereferencing them through
pointers. This is consistent throughout the API.
-.. ctype:: Py_complex
+.. c:type:: Py_complex
The C structure which corresponds to the value portion of a Python complex
number object. Most of the functions for dealing with complex number objects
@@ -34,39 +34,39 @@ pointers. This is consistent throughout the API.
} Py_complex;
-.. cfunction:: Py_complex _Py_c_sum(Py_complex left, Py_complex right)
+.. c:function:: Py_complex _Py_c_sum(Py_complex left, Py_complex right)
- Return the sum of two complex numbers, using the C :ctype:`Py_complex`
+ Return the sum of two complex numbers, using the C :c:type:`Py_complex`
representation.
-.. cfunction:: Py_complex _Py_c_diff(Py_complex left, Py_complex right)
+.. c:function:: Py_complex _Py_c_diff(Py_complex left, Py_complex right)
Return the difference between two complex numbers, using the C
- :ctype:`Py_complex` representation.
+ :c:type:`Py_complex` representation.
-.. cfunction:: Py_complex _Py_c_neg(Py_complex complex)
+.. c:function:: Py_complex _Py_c_neg(Py_complex complex)
Return the negation of the complex number *complex*, using the C
- :ctype:`Py_complex` representation.
+ :c:type:`Py_complex` representation.
-.. cfunction:: Py_complex _Py_c_prod(Py_complex left, Py_complex right)
+.. c:function:: Py_complex _Py_c_prod(Py_complex left, Py_complex right)
- Return the product of two complex numbers, using the C :ctype:`Py_complex`
+ Return the product of two complex numbers, using the C :c:type:`Py_complex`
representation.
-.. cfunction:: Py_complex _Py_c_quot(Py_complex dividend, Py_complex divisor)
+.. c:function:: Py_complex _Py_c_quot(Py_complex dividend, Py_complex divisor)
- Return the quotient of two complex numbers, using the C :ctype:`Py_complex`
+ Return the quotient of two complex numbers, using the C :c:type:`Py_complex`
representation.
-.. cfunction:: Py_complex _Py_c_pow(Py_complex num, Py_complex exp)
+.. c:function:: Py_complex _Py_c_pow(Py_complex num, Py_complex exp)
- Return the exponentiation of *num* by *exp*, using the C :ctype:`Py_complex`
+ Return the exponentiation of *num* by *exp*, using the C :c:type:`Py_complex`
representation.
@@ -74,52 +74,52 @@ Complex Numbers as Python Objects
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. ctype:: PyComplexObject
+.. c:type:: PyComplexObject
- This subtype of :ctype:`PyObject` represents a Python complex number object.
+ This subtype of :c:type:`PyObject` represents a Python complex number object.
-.. cvar:: PyTypeObject PyComplex_Type
+.. c:var:: PyTypeObject PyComplex_Type
- This instance of :ctype:`PyTypeObject` represents the Python complex number
+ This instance of :c:type:`PyTypeObject` represents the Python complex number
type. It is the same object as :class:`complex` in the Python layer.
-.. cfunction:: int PyComplex_Check(PyObject *p)
+.. c:function:: int PyComplex_Check(PyObject *p)
- Return true if its argument is a :ctype:`PyComplexObject` or a subtype of
- :ctype:`PyComplexObject`.
+ Return true if its argument is a :c:type:`PyComplexObject` or a subtype of
+ :c:type:`PyComplexObject`.
-.. cfunction:: int PyComplex_CheckExact(PyObject *p)
+.. c:function:: int PyComplex_CheckExact(PyObject *p)
- Return true if its argument is a :ctype:`PyComplexObject`, but not a subtype of
- :ctype:`PyComplexObject`.
+ Return true if its argument is a :c:type:`PyComplexObject`, but not a subtype of
+ :c:type:`PyComplexObject`.
-.. cfunction:: PyObject* PyComplex_FromCComplex(Py_complex v)
+.. c:function:: PyObject* PyComplex_FromCComplex(Py_complex v)
- Create a new Python complex number object from a C :ctype:`Py_complex` value.
+ Create a new Python complex number object from a C :c:type:`Py_complex` value.
-.. cfunction:: PyObject* PyComplex_FromDoubles(double real, double imag)
+.. c:function:: PyObject* PyComplex_FromDoubles(double real, double imag)
- Return a new :ctype:`PyComplexObject` object from *real* and *imag*.
+ Return a new :c:type:`PyComplexObject` object from *real* and *imag*.
-.. cfunction:: double PyComplex_RealAsDouble(PyObject *op)
+.. c:function:: double PyComplex_RealAsDouble(PyObject *op)
- Return the real part of *op* as a C :ctype:`double`.
+ Return the real part of *op* as a C :c:type:`double`.
-.. cfunction:: double PyComplex_ImagAsDouble(PyObject *op)
+.. c:function:: double PyComplex_ImagAsDouble(PyObject *op)
- Return the imaginary part of *op* as a C :ctype:`double`.
+ Return the imaginary part of *op* as a C :c:type:`double`.
-.. cfunction:: Py_complex PyComplex_AsCComplex(PyObject *op)
+.. c:function:: Py_complex PyComplex_AsCComplex(PyObject *op)
- Return the :ctype:`Py_complex` value of the complex number *op*.
+ Return the :c:type:`Py_complex` value of the complex number *op*.
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
diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst
index d728599..65904ee 100644
--- a/Doc/c-api/concrete.rst
+++ b/Doc/c-api/concrete.rst
@@ -11,7 +11,7 @@ The functions in this chapter are specific to certain Python object types.
Passing them an object of the wrong type is not a good idea; if you receive an
object from a Python program and you are not sure that it has the right type,
you must perform a type check first; for example, to check that an object is a
-dictionary, use :cfunc:`PyDict_Check`. The chapter is structured like the
+dictionary, use :c:func:`PyDict_Check`. The chapter is structured like the
"family tree" of Python object types.
.. warning::
@@ -102,7 +102,7 @@ Other Objects
memoryview.rst
weakref.rst
capsule.rst
- cobject.rst
cell.rst
gen.rst
datetime.rst
+ code.rst
diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst
index ad3f2fa..dfc0a3a 100644
--- a/Doc/c-api/conversion.rst
+++ b/Doc/c-api/conversion.rst
@@ -8,20 +8,20 @@ String conversion and formatting
Functions for number conversion and formatted string output.
-.. cfunction:: int PyOS_snprintf(char *str, size_t size, const char *format, ...)
+.. c:function:: int PyOS_snprintf(char *str, size_t size, const char *format, ...)
Output not more than *size* bytes to *str* according to the format string
*format* and the extra arguments. See the Unix man page :manpage:`snprintf(2)`.
-.. cfunction:: int PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
+.. c:function:: int PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
Output not more than *size* bytes to *str* according to the format string
*format* and the variable argument list *va*. Unix man page
:manpage:`vsnprintf(2)`.
-:cfunc:`PyOS_snprintf` and :cfunc:`PyOS_vsnprintf` wrap the Standard C library
-functions :cfunc:`snprintf` and :cfunc:`vsnprintf`. Their purpose is to
+:c:func:`PyOS_snprintf` and :c:func:`PyOS_vsnprintf` wrap the Standard C library
+functions :c:func:`snprintf` and :c:func:`vsnprintf`. Their purpose is to
guarantee consistent behavior in corner cases, which the Standard C functions do
not.
@@ -30,7 +30,7 @@ never write more than *size* bytes (including the trailing ``'\0'``) into str.
Both functions require that ``str != NULL``, ``size > 0`` and ``format !=
NULL``.
-If the platform doesn't have :cfunc:`vsnprintf` and the buffer size needed to
+If the platform doesn't have :c:func:`vsnprintf` and the buffer size needed to
avoid truncation exceeds *size* by more than 512 bytes, Python aborts with a
*Py_FatalError*.
@@ -51,24 +51,9 @@ The return value (*rv*) for these functions should be interpreted as follows:
The following functions provide locale-independent string to number conversions.
-.. cfunction:: double PyOS_ascii_strtod(const char *nptr, char **endptr)
+.. c:function:: double PyOS_string_to_double(const char *s, char **endptr, PyObject *overflow_exception)
- Convert a string to a :ctype:`double`. This function behaves like the Standard C
- function :cfunc:`strtod` does in the C locale. It does this without changing the
- current locale, since that would not be thread-safe.
-
- :cfunc:`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.
-
- .. deprecated:: 3.1
- Use :cfunc:`PyOS_string_to_double` instead.
-
-
-.. cfunction:: double PyOS_string_to_double(const char *s, char **endptr, PyObject *overflow_exception)
-
- Convert a string ``s`` to a :ctype:`double`, raising a Python
+ Convert a string ``s`` to a :c:type:`double`, raising a Python
exception on failure. The set of accepted strings corresponds to
the set of strings accepted by Python's :func:`float` constructor,
except that ``s`` must not have leading or trailing whitespace.
@@ -100,23 +85,9 @@ The following functions provide locale-independent string to number conversions.
.. versionadded:: 3.1
-.. cfunction:: char* PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d)
-
- Convert a :ctype:`double` to a string using the ``'.'`` as the decimal
- separator. *format* is a :cfunc:`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.
+.. c:function:: char* PyOS_double_to_string(double val, char format_code, int precision, int flags, int *ptype)
- .. deprecated:: 3.1
- Use :cfunc:`PyOS_double_to_string` instead.
-
-
-.. cfunction:: char* PyOS_double_to_string(double val, char format_code, int precision, int flags, int *ptype)
-
- Convert a :ctype:`double` *val* to a string using supplied
+ Convert a :c:type:`double` *val* to a string using supplied
*format_code*, *precision*, and *flags*.
*format_code* must be one of ``'e'``, ``'E'``, ``'f'``, ``'F'``,
@@ -134,7 +105,7 @@ The following functions provide locale-independent string to number conversions.
like an integer.
* *Py_DTSF_ALT* means to apply "alternate" formatting rules. See the
- documentation for the :cfunc:`PyOS_snprintf` ``'#'`` specifier for
+ documentation for the :c:func:`PyOS_snprintf` ``'#'`` specifier for
details.
If *ptype* is non-NULL, then the value it points to will be set to one of
@@ -143,28 +114,18 @@ The following functions provide locale-independent string to number conversions.
The return value is a pointer to *buffer* with the converted string or
*NULL* if the conversion failed. The caller is responsible for freeing the
- returned string by calling :cfunc:`PyMem_Free`.
+ returned string by calling :c:func:`PyMem_Free`.
.. versionadded:: 3.1
-.. cfunction:: double PyOS_ascii_atof(const char *nptr)
-
- Convert a string to a :ctype:`double` in a locale-independent way.
-
- See the Unix man page :manpage:`atof(2)` for details.
-
- .. deprecated:: 3.1
- Use :cfunc:`PyOS_string_to_double` instead.
-
-
-.. cfunction:: char* PyOS_stricmp(char *s1, char *s2)
+.. c:function:: char* PyOS_stricmp(char *s1, char *s2)
Case insensitive comparison of strings. The function works almost
- identically to :cfunc:`strcmp` except that it ignores the case.
+ identically to :c:func:`strcmp` except that it ignores the case.
-.. cfunction:: char* PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size)
+.. c:function:: char* PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size)
Case insensitive comparison of strings. The function works almost
- identically to :cfunc:`strncmp` except that it ignores the case.
+ identically to :c:func:`strncmp` except that it ignores the case.
diff --git a/Doc/c-api/datetime.rst b/Doc/c-api/datetime.rst
index 6515bab..fcd1395 100644
--- a/Doc/c-api/datetime.rst
+++ b/Doc/c-api/datetime.rst
@@ -8,93 +8,93 @@ DateTime Objects
Various date and time objects are supplied by the :mod:`datetime` module.
Before using any of these functions, the header file :file:`datetime.h` must be
included in your source (note that this is not included by :file:`Python.h`),
-and the macro :cmacro:`PyDateTime_IMPORT` must be invoked, usually as part of
+and the macro :c:macro:`PyDateTime_IMPORT` must be invoked, usually as part of
the module initialisation function. The macro puts a pointer to a C structure
-into a static variable, :cdata:`PyDateTimeAPI`, that is used by the following
+into a static variable, :c:data:`PyDateTimeAPI`, that is used by the following
macros.
Type-check macros:
-.. cfunction:: int PyDate_Check(PyObject *ob)
+.. c:function:: int PyDate_Check(PyObject *ob)
- Return true if *ob* is of type :cdata:`PyDateTime_DateType` or a subtype of
- :cdata:`PyDateTime_DateType`. *ob* must not be *NULL*.
+ Return true if *ob* is of type :c:data:`PyDateTime_DateType` or a subtype of
+ :c:data:`PyDateTime_DateType`. *ob* must not be *NULL*.
-.. cfunction:: int PyDate_CheckExact(PyObject *ob)
+.. c:function:: int PyDate_CheckExact(PyObject *ob)
- Return true if *ob* is of type :cdata:`PyDateTime_DateType`. *ob* must not be
+ Return true if *ob* is of type :c:data:`PyDateTime_DateType`. *ob* must not be
*NULL*.
-.. cfunction:: int PyDateTime_Check(PyObject *ob)
+.. c:function:: int PyDateTime_Check(PyObject *ob)
- Return true if *ob* is of type :cdata:`PyDateTime_DateTimeType` or a subtype of
- :cdata:`PyDateTime_DateTimeType`. *ob* must not be *NULL*.
+ Return true if *ob* is of type :c:data:`PyDateTime_DateTimeType` or a subtype of
+ :c:data:`PyDateTime_DateTimeType`. *ob* must not be *NULL*.
-.. cfunction:: int PyDateTime_CheckExact(PyObject *ob)
+.. c:function:: int PyDateTime_CheckExact(PyObject *ob)
- Return true if *ob* is of type :cdata:`PyDateTime_DateTimeType`. *ob* must not
+ Return true if *ob* is of type :c:data:`PyDateTime_DateTimeType`. *ob* must not
be *NULL*.
-.. cfunction:: int PyTime_Check(PyObject *ob)
+.. c:function:: int PyTime_Check(PyObject *ob)
- Return true if *ob* is of type :cdata:`PyDateTime_TimeType` or a subtype of
- :cdata:`PyDateTime_TimeType`. *ob* must not be *NULL*.
+ Return true if *ob* is of type :c:data:`PyDateTime_TimeType` or a subtype of
+ :c:data:`PyDateTime_TimeType`. *ob* must not be *NULL*.
-.. cfunction:: int PyTime_CheckExact(PyObject *ob)
+.. c:function:: int PyTime_CheckExact(PyObject *ob)
- Return true if *ob* is of type :cdata:`PyDateTime_TimeType`. *ob* must not be
+ Return true if *ob* is of type :c:data:`PyDateTime_TimeType`. *ob* must not be
*NULL*.
-.. cfunction:: int PyDelta_Check(PyObject *ob)
+.. c:function:: int PyDelta_Check(PyObject *ob)
- Return true if *ob* is of type :cdata:`PyDateTime_DeltaType` or a subtype of
- :cdata:`PyDateTime_DeltaType`. *ob* must not be *NULL*.
+ Return true if *ob* is of type :c:data:`PyDateTime_DeltaType` or a subtype of
+ :c:data:`PyDateTime_DeltaType`. *ob* must not be *NULL*.
-.. cfunction:: int PyDelta_CheckExact(PyObject *ob)
+.. c:function:: int PyDelta_CheckExact(PyObject *ob)
- Return true if *ob* is of type :cdata:`PyDateTime_DeltaType`. *ob* must not be
+ Return true if *ob* is of type :c:data:`PyDateTime_DeltaType`. *ob* must not be
*NULL*.
-.. cfunction:: int PyTZInfo_Check(PyObject *ob)
+.. c:function:: int PyTZInfo_Check(PyObject *ob)
- Return true if *ob* is of type :cdata:`PyDateTime_TZInfoType` or a subtype of
- :cdata:`PyDateTime_TZInfoType`. *ob* must not be *NULL*.
+ Return true if *ob* is of type :c:data:`PyDateTime_TZInfoType` or a subtype of
+ :c:data:`PyDateTime_TZInfoType`. *ob* must not be *NULL*.
-.. cfunction:: int PyTZInfo_CheckExact(PyObject *ob)
+.. c:function:: int PyTZInfo_CheckExact(PyObject *ob)
- Return true if *ob* is of type :cdata:`PyDateTime_TZInfoType`. *ob* must not be
+ Return true if *ob* is of type :c:data:`PyDateTime_TZInfoType`. *ob* must not be
*NULL*.
Macros to create objects:
-.. cfunction:: PyObject* PyDate_FromDate(int year, int month, int day)
+.. c:function:: PyObject* PyDate_FromDate(int year, int month, int day)
Return a ``datetime.date`` object with the specified year, month and day.
-.. cfunction:: PyObject* PyDateTime_FromDateAndTime(int year, int month, int day, int hour, int minute, int second, int usecond)
+.. 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.
-.. cfunction:: PyObject* PyTime_FromTime(int hour, int minute, int second, int usecond)
+.. 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.
-.. cfunction:: PyObject* PyDelta_FromDSU(int days, int seconds, int useconds)
+.. c:function:: PyObject* PyDelta_FromDSU(int days, int seconds, int useconds)
Return a ``datetime.timedelta`` object representing the given number of days,
seconds and microseconds. Normalization is performed so that the resulting
@@ -103,82 +103,82 @@ Macros to create objects:
Macros to extract fields from date objects. The argument must be an instance of
-:cdata:`PyDateTime_Date`, including subclasses (such as
-:cdata:`PyDateTime_DateTime`). The argument must not be *NULL*, and the type is
+:c:data:`PyDateTime_Date`, including subclasses (such as
+:c:data:`PyDateTime_DateTime`). The argument must not be *NULL*, and the type is
not checked:
-.. cfunction:: int PyDateTime_GET_YEAR(PyDateTime_Date *o)
+.. c:function:: int PyDateTime_GET_YEAR(PyDateTime_Date *o)
Return the year, as a positive int.
-.. cfunction:: int PyDateTime_GET_MONTH(PyDateTime_Date *o)
+.. c:function:: int PyDateTime_GET_MONTH(PyDateTime_Date *o)
Return the month, as an int from 1 through 12.
-.. cfunction:: int PyDateTime_GET_DAY(PyDateTime_Date *o)
+.. c:function:: int PyDateTime_GET_DAY(PyDateTime_Date *o)
Return the day, as an int from 1 through 31.
Macros to extract fields from datetime objects. The argument must be an
-instance of :cdata:`PyDateTime_DateTime`, including subclasses. The argument
+instance of :c:data:`PyDateTime_DateTime`, including subclasses. The argument
must not be *NULL*, and the type is not checked:
-.. cfunction:: int PyDateTime_DATE_GET_HOUR(PyDateTime_DateTime *o)
+.. c:function:: int PyDateTime_DATE_GET_HOUR(PyDateTime_DateTime *o)
Return the hour, as an int from 0 through 23.
-.. cfunction:: int PyDateTime_DATE_GET_MINUTE(PyDateTime_DateTime *o)
+.. c:function:: int PyDateTime_DATE_GET_MINUTE(PyDateTime_DateTime *o)
Return the minute, as an int from 0 through 59.
-.. cfunction:: int PyDateTime_DATE_GET_SECOND(PyDateTime_DateTime *o)
+.. c:function:: int PyDateTime_DATE_GET_SECOND(PyDateTime_DateTime *o)
Return the second, as an int from 0 through 59.
-.. cfunction:: int PyDateTime_DATE_GET_MICROSECOND(PyDateTime_DateTime *o)
+.. c:function:: int PyDateTime_DATE_GET_MICROSECOND(PyDateTime_DateTime *o)
Return the microsecond, as an int from 0 through 999999.
Macros to extract fields from time objects. The argument must be an instance of
-:cdata:`PyDateTime_Time`, including subclasses. The argument must not be *NULL*,
+:c:data:`PyDateTime_Time`, including subclasses. The argument must not be *NULL*,
and the type is not checked:
-.. cfunction:: int PyDateTime_TIME_GET_HOUR(PyDateTime_Time *o)
+.. c:function:: int PyDateTime_TIME_GET_HOUR(PyDateTime_Time *o)
Return the hour, as an int from 0 through 23.
-.. cfunction:: int PyDateTime_TIME_GET_MINUTE(PyDateTime_Time *o)
+.. c:function:: int PyDateTime_TIME_GET_MINUTE(PyDateTime_Time *o)
Return the minute, as an int from 0 through 59.
-.. cfunction:: int PyDateTime_TIME_GET_SECOND(PyDateTime_Time *o)
+.. c:function:: int PyDateTime_TIME_GET_SECOND(PyDateTime_Time *o)
Return the second, as an int from 0 through 59.
-.. cfunction:: int PyDateTime_TIME_GET_MICROSECOND(PyDateTime_Time *o)
+.. c:function:: int PyDateTime_TIME_GET_MICROSECOND(PyDateTime_Time *o)
Return the microsecond, as an int from 0 through 999999.
Macros for the convenience of modules implementing the DB API:
-.. cfunction:: PyObject* PyDateTime_FromTimestamp(PyObject *args)
+.. 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()``.
-.. cfunction:: PyObject* PyDate_FromTimestamp(PyObject *args)
+.. 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()``.
diff --git a/Doc/c-api/descriptor.rst b/Doc/c-api/descriptor.rst
index 5db2570..c8f6fa5 100644
--- a/Doc/c-api/descriptor.rst
+++ b/Doc/c-api/descriptor.rst
@@ -10,31 +10,31 @@ found in the dictionary of type objects.
.. XXX document these!
-.. cvar:: PyTypeObject PyProperty_Type
+.. c:var:: PyTypeObject PyProperty_Type
The type object for the built-in descriptor types.
-.. cfunction:: PyObject* PyDescr_NewGetSet(PyTypeObject *type, struct PyGetSetDef *getset)
+.. c:function:: PyObject* PyDescr_NewGetSet(PyTypeObject *type, struct PyGetSetDef *getset)
-.. cfunction:: PyObject* PyDescr_NewMember(PyTypeObject *type, struct PyMemberDef *meth)
+.. c:function:: PyObject* PyDescr_NewMember(PyTypeObject *type, struct PyMemberDef *meth)
-.. cfunction:: PyObject* PyDescr_NewMethod(PyTypeObject *type, struct PyMethodDef *meth)
+.. c:function:: PyObject* PyDescr_NewMethod(PyTypeObject *type, struct PyMethodDef *meth)
-.. cfunction:: PyObject* PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *wrapper, void *wrapped)
+.. c:function:: PyObject* PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *wrapper, void *wrapped)
-.. cfunction:: PyObject* PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
+.. c:function:: PyObject* PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
-.. cfunction:: int PyDescr_IsData(PyObject *descr)
+.. c:function:: int PyDescr_IsData(PyObject *descr)
Return true if the descriptor objects *descr* describes a data attribute, or
false if it describes a method. *descr* must be a descriptor object; there is
no error checking.
-.. cfunction:: PyObject* PyWrapper_New(PyObject *, PyObject *)
+.. c:function:: PyObject* PyWrapper_New(PyObject *, PyObject *)
diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst
index 5d355d1..6df84e0 100644
--- a/Doc/c-api/dict.rst
+++ b/Doc/c-api/dict.rst
@@ -8,125 +8,125 @@ Dictionary Objects
.. index:: object: dictionary
-.. ctype:: PyDictObject
+.. c:type:: PyDictObject
- This subtype of :ctype:`PyObject` represents a Python dictionary object.
+ This subtype of :c:type:`PyObject` represents a Python dictionary object.
-.. cvar:: PyTypeObject PyDict_Type
+.. c:var:: PyTypeObject PyDict_Type
- This instance of :ctype:`PyTypeObject` represents the Python dictionary
+ This instance of :c:type:`PyTypeObject` represents the Python dictionary
type. This is the same object as :class:`dict` in the Python layer.
-.. cfunction:: int PyDict_Check(PyObject *p)
+.. c:function:: int PyDict_Check(PyObject *p)
Return true if *p* is a dict object or an instance of a subtype of the dict
type.
-.. cfunction:: int PyDict_CheckExact(PyObject *p)
+.. 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.
-.. cfunction:: PyObject* PyDict_New()
+.. c:function:: PyObject* PyDict_New()
Return a new empty dictionary, or *NULL* on failure.
-.. cfunction:: PyObject* PyDictProxy_New(PyObject *dict)
+.. c:function:: PyObject* PyDictProxy_New(PyObject *dict)
Return a proxy object for a mapping which enforces read-only behavior.
This is normally used to create a proxy to prevent modification of the
dictionary for non-dynamic class types.
-.. cfunction:: void PyDict_Clear(PyObject *p)
+.. c:function:: void PyDict_Clear(PyObject *p)
Empty an existing dictionary of all key-value pairs.
-.. cfunction:: int PyDict_Contains(PyObject *p, PyObject *key)
+.. c:function:: int PyDict_Contains(PyObject *p, PyObject *key)
Determine if dictionary *p* contains *key*. If an item in *p* is matches
*key*, return ``1``, otherwise return ``0``. On error, return ``-1``.
This is equivalent to the Python expression ``key in p``.
-.. cfunction:: PyObject* PyDict_Copy(PyObject *p)
+.. c:function:: PyObject* PyDict_Copy(PyObject *p)
Return a new dictionary that contains the same key-value pairs as *p*.
-.. cfunction:: int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val)
+.. c:function:: int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val)
Insert *value* into the dictionary *p* with a key of *key*. *key* must be
:term:`hashable`; if it isn't, :exc:`TypeError` will be raised. Return
``0`` on success or ``-1`` on failure.
-.. cfunction:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val)
+.. c:function:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val)
.. index:: single: PyUnicode_FromString()
Insert *value* into the dictionary *p* using *key* as a key. *key* should
- be a :ctype:`char\*`. The key object is created using
+ be a :c:type:`char\*`. The key object is created using
``PyUnicode_FromString(key)``. Return ``0`` on success or ``-1`` on
failure.
-.. cfunction:: int PyDict_DelItem(PyObject *p, PyObject *key)
+.. c:function:: int PyDict_DelItem(PyObject *p, PyObject *key)
Remove the entry in dictionary *p* with key *key*. *key* must be hashable;
if it isn't, :exc:`TypeError` is raised. Return ``0`` on success or ``-1``
on failure.
-.. cfunction:: int PyDict_DelItemString(PyObject *p, char *key)
+.. c:function:: int PyDict_DelItemString(PyObject *p, char *key)
Remove the entry in dictionary *p* which has a key specified by the string
*key*. Return ``0`` on success or ``-1`` on failure.
-.. cfunction:: PyObject* PyDict_GetItem(PyObject *p, PyObject *key)
+.. c:function:: PyObject* PyDict_GetItem(PyObject *p, PyObject *key)
Return the object from dictionary *p* which has a key *key*. Return *NULL*
if the key *key* is not present, but *without* setting an exception.
-.. cfunction:: PyObject* PyDict_GetItemWithError(PyObject *p, PyObject *key)
+.. c:function:: PyObject* PyDict_GetItemWithError(PyObject *p, PyObject *key)
- Variant of :cfunc:`PyDict_GetItem` that does not suppress
+ 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.
-.. cfunction:: PyObject* PyDict_GetItemString(PyObject *p, const char *key)
+.. c:function:: PyObject* PyDict_GetItemString(PyObject *p, const char *key)
- This is the same as :cfunc:`PyDict_GetItem`, but *key* is specified as a
- :ctype:`char\*`, rather than a :ctype:`PyObject\*`.
+ This is the same as :c:func:`PyDict_GetItem`, but *key* is specified as a
+ :c:type:`char\*`, rather than a :c:type:`PyObject\*`.
-.. cfunction:: PyObject* PyDict_Items(PyObject *p)
+.. c:function:: PyObject* PyDict_Items(PyObject *p)
- Return a :ctype:`PyListObject` containing all the items from the dictionary.
+ Return a :c:type:`PyListObject` containing all the items from the dictionary.
-.. cfunction:: PyObject* PyDict_Keys(PyObject *p)
+.. c:function:: PyObject* PyDict_Keys(PyObject *p)
- Return a :ctype:`PyListObject` containing all the keys from the dictionary.
+ Return a :c:type:`PyListObject` containing all the keys from the dictionary.
-.. cfunction:: PyObject* PyDict_Values(PyObject *p)
+.. c:function:: PyObject* PyDict_Values(PyObject *p)
- Return a :ctype:`PyListObject` containing all the values from the dictionary
+ Return a :c:type:`PyListObject` containing all the values from the dictionary
*p*.
-.. cfunction:: Py_ssize_t PyDict_Size(PyObject *p)
+.. c:function:: Py_ssize_t PyDict_Size(PyObject *p)
.. index:: builtin: len
@@ -134,14 +134,14 @@ Dictionary Objects
``len(p)`` on a dictionary.
-.. cfunction:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
+.. c:function:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
Iterate over all key-value pairs in the dictionary *p*. The
- :ctype:`Py_ssize_t` referred to by *ppos* must be initialized to ``0``
+ :c:type:`Py_ssize_t` referred to by *ppos* must be initialized to ``0``
prior to the first call to this function to start the iteration; the
function returns true for each pair in the dictionary, and false once all
pairs have been reported. The parameters *pkey* and *pvalue* should either
- point to :ctype:`PyObject\*` variables that will be filled in with each key
+ point to :c:type:`PyObject\*` variables that will be filled in with each key
and value, respectively, or may be *NULL*. Any references returned through
them are borrowed. *ppos* should not be altered during iteration. Its
value represents offsets within the internal dictionary structure, and
@@ -180,23 +180,23 @@ Dictionary Objects
}
-.. cfunction:: int PyDict_Merge(PyObject *a, PyObject *b, int override)
+.. c:function:: int PyDict_Merge(PyObject *a, PyObject *b, int override)
Iterate over mapping object *b* adding key-value pairs to dictionary *a*.
- *b* may be a dictionary, or any object supporting :func:`PyMapping_Keys`
- and :func:`PyObject_GetItem`. If *override* is true, existing pairs in *a*
+ *b* may be a dictionary, or any object supporting :c:func:`PyMapping_Keys`
+ and :c:func:`PyObject_GetItem`. If *override* is true, existing pairs in *a*
will be replaced if a matching key is found in *b*, otherwise pairs will
only be added if there is not a matching key in *a*. Return ``0`` on
success or ``-1`` if an exception was raised.
-.. cfunction:: int PyDict_Update(PyObject *a, PyObject *b)
+.. 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.
-.. cfunction:: int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override)
+.. c:function:: int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override)
Update or merge into dictionary *a*, from the key-value pairs in *seq2*.
*seq2* must be an iterable object producing iterable objects of length 2,
diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
index f465c58..4c946c1 100644
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -9,12 +9,12 @@ Exception Handling
The functions described in this chapter will let you handle and raise Python
exceptions. It is important to understand some of the basics of Python
-exception handling. It works somewhat like the Unix :cdata:`errno` variable:
+exception handling. It works somewhat like the Unix :c:data:`errno` variable:
there is a global indicator (per thread) of the last error that occurred. Most
functions don't clear this on success, but will set it to indicate the cause of
the error on failure. Most functions also return an error indicator, usually
*NULL* if they are supposed to return a pointer, or ``-1`` if they return an
-integer (exception: the :cfunc:`PyArg_\*` functions return ``1`` for success and
+integer (exception: the :c:func:`PyArg_\*` functions return ``1`` for success and
``0`` for failure).
When a function must fail because some function it called failed, it generally
@@ -35,7 +35,7 @@ in various ways. There is a separate error indicator for each thread.
Either alphabetical or some kind of structure.
-.. cfunction:: void PyErr_PrintEx(int set_sys_last_vars)
+.. c:function:: void PyErr_PrintEx(int set_sys_last_vars)
Print a standard traceback to ``sys.stderr`` and clear the error indicator.
Call this function only when the error indicator is set. (Otherwise it will
@@ -46,35 +46,35 @@ in various ways. There is a separate error indicator for each thread.
type, value and traceback of the printed exception, respectively.
-.. cfunction:: void PyErr_Print()
+.. c:function:: void PyErr_Print()
Alias for ``PyErr_PrintEx(1)``.
-.. cfunction:: PyObject* PyErr_Occurred()
+.. c:function:: PyObject* PyErr_Occurred()
Test whether the error indicator is set. If set, return the exception *type*
- (the first argument to the last call to one of the :cfunc:`PyErr_Set\*`
- functions or to :cfunc:`PyErr_Restore`). If not set, return *NULL*. You do not
- own a reference to the return value, so you do not need to :cfunc:`Py_DECREF`
+ (the first argument to the last call to one of the :c:func:`PyErr_Set\*`
+ functions or to :c:func:`PyErr_Restore`). If not set, return *NULL*. You do not
+ own a reference to the return value, so you do not need to :c:func:`Py_DECREF`
it.
.. note::
Do not compare the return value to a specific exception; use
- :cfunc:`PyErr_ExceptionMatches` instead, shown below. (The comparison could
+ :c:func:`PyErr_ExceptionMatches` instead, shown below. (The comparison could
easily fail since the exception may be an instance instead of a class, in the
case of a class exception, or it may the a subclass of the expected exception.)
-.. cfunction:: int PyErr_ExceptionMatches(PyObject *exc)
+.. c:function:: int PyErr_ExceptionMatches(PyObject *exc)
Equivalent to ``PyErr_GivenExceptionMatches(PyErr_Occurred(), exc)``. This
should only be called when an exception is actually set; a memory access
violation will occur if no exception has been raised.
-.. cfunction:: int PyErr_GivenExceptionMatches(PyObject *given, PyObject *exc)
+.. c:function:: int PyErr_GivenExceptionMatches(PyObject *given, PyObject *exc)
Return true if the *given* exception matches the exception in *exc*. If
*exc* is a class object, this also returns true when *given* is an instance
@@ -82,22 +82,22 @@ in various ways. There is a separate error indicator for each thread.
recursively in subtuples) are searched for a match.
-.. cfunction:: void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb)
+.. c:function:: void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb)
- Under certain circumstances, the values returned by :cfunc:`PyErr_Fetch` below
+ Under certain circumstances, the values returned by :c:func:`PyErr_Fetch` below
can be "unnormalized", meaning that ``*exc`` is a class object but ``*val`` is
not an instance of the same class. This function can be used to instantiate
the class in that case. If the values are already normalized, nothing happens.
The delayed normalization is implemented to improve performance.
-.. cfunction:: void PyErr_Clear()
+.. c:function:: void PyErr_Clear()
Clear the error indicator. If the error indicator is not set, there is no
effect.
-.. cfunction:: void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)
+.. c:function:: void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)
Retrieve the error indicator into three variables whose addresses are passed.
If the error indicator is not set, set all three variables to *NULL*. If it is
@@ -110,7 +110,7 @@ in various ways. There is a separate error indicator for each thread.
by code that needs to save and restore the error indicator temporarily.
-.. cfunction:: void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
+.. c:function:: void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
Set the error indicator from the three objects. If the error indicator is
already set, it is cleared first. If the objects are *NULL*, the error
@@ -125,107 +125,129 @@ in various ways. There is a separate error indicator for each thread.
.. note::
This function is normally only used by code that needs to save and restore the
- error indicator temporarily; use :cfunc:`PyErr_Fetch` to save the current
+ error indicator temporarily; use :c:func:`PyErr_Fetch` to save the current
exception state.
-.. cfunction:: void PyErr_SetString(PyObject *type, const char *message)
+.. c:function:: void PyErr_SetString(PyObject *type, const char *message)
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. :cdata:`PyExc_RuntimeError`. You need not increment its reference count.
- The second argument is an error message; it is converted to a string object.
+ e.g. :c:data:`PyExc_RuntimeError`. You need not increment its reference count.
+ The second argument is an error message; it is decoded from ``'utf-8``'.
-.. cfunction:: void PyErr_SetObject(PyObject *type, PyObject *value)
+.. c:function:: void PyErr_SetObject(PyObject *type, PyObject *value)
- This function is similar to :cfunc:`PyErr_SetString` but lets you specify an
+ This function is similar to :c:func:`PyErr_SetString` but lets you specify an
arbitrary Python object for the "value" of the exception.
-.. cfunction:: PyObject* PyErr_Format(PyObject *exception, const char *format, ...)
+.. c:function:: PyObject* PyErr_Format(PyObject *exception, const char *format, ...)
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 :cfunc:`PyUnicode_FromFormat`.
+ values as in :c:func:`PyUnicode_FromFormat`. *format* is an ASCII-encoded
+ string.
-.. cfunction:: void PyErr_SetNone(PyObject *type)
+.. c:function:: void PyErr_SetNone(PyObject *type)
This is a shorthand for ``PyErr_SetObject(type, Py_None)``.
-.. cfunction:: int PyErr_BadArgument()
+.. c:function:: int PyErr_BadArgument()
This is a shorthand for ``PyErr_SetString(PyExc_TypeError, message)``, where
*message* indicates that a built-in operation was invoked with an illegal
argument. It is mostly for internal use.
-.. cfunction:: PyObject* PyErr_NoMemory()
+.. c:function:: PyObject* PyErr_NoMemory()
This is a shorthand for ``PyErr_SetNone(PyExc_MemoryError)``; it returns *NULL*
so an object allocation function can write ``return PyErr_NoMemory();`` when it
runs out of memory.
-.. cfunction:: PyObject* PyErr_SetFromErrno(PyObject *type)
+.. c:function:: PyObject* PyErr_SetFromErrno(PyObject *type)
.. index:: single: strerror()
This is a convenience function to raise an exception when a C library function
- has returned an error and set the C variable :cdata:`errno`. It constructs a
- tuple object whose first item is the integer :cdata:`errno` value and whose
- second item is the corresponding error message (gotten from :cfunc:`strerror`),
+ has returned an error and set the C variable :c:data:`errno`. It constructs a
+ tuple object whose first item is the integer :c:data:`errno` value and whose
+ second item is the corresponding error message (gotten from :c:func:`strerror`),
and then calls ``PyErr_SetObject(type, object)``. On Unix, when the
- :cdata:`errno` value is :const:`EINTR`, indicating an interrupted system call,
- this calls :cfunc:`PyErr_CheckSignals`, and if that set the error indicator,
+ :c:data:`errno` value is :const:`EINTR`, indicating an interrupted system call,
+ this calls :c:func:`PyErr_CheckSignals`, and if that set the error indicator,
leaves it set to that. The function always returns *NULL*, so a wrapper
function around a system call can write ``return PyErr_SetFromErrno(type);``
when the system call returns an error.
-.. cfunction:: PyObject* PyErr_SetFromErrnoWithFilename(PyObject *type, const char *filename)
+.. c:function:: PyObject* PyErr_SetFromErrnoWithFilename(PyObject *type, const char *filename)
- Similar to :cfunc:`PyErr_SetFromErrno`, with the additional behavior that if
+ Similar to :c:func:`PyErr_SetFromErrno`, with the additional behavior that if
*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`).
-.. cfunction:: PyObject* PyErr_SetFromWindowsErr(int ierr)
+.. c:function:: PyObject* PyErr_SetFromWindowsErr(int ierr)
This is a convenience function to raise :exc:`WindowsError`. If called with
- *ierr* of :cdata:`0`, the error code returned by a call to :cfunc:`GetLastError`
- is used instead. It calls the Win32 function :cfunc:`FormatMessage` to retrieve
- the Windows description of error code given by *ierr* or :cfunc:`GetLastError`,
+ *ierr* of :c:data:`0`, the error code returned by a call to :c:func:`GetLastError`
+ is used instead. It calls the Win32 function :c:func:`FormatMessage` to retrieve
+ the Windows description of error code given by *ierr* or :c:func:`GetLastError`,
then it constructs a tuple object whose first item is the *ierr* value and whose
second item is the corresponding error message (gotten from
- :cfunc:`FormatMessage`), and then calls ``PyErr_SetObject(PyExc_WindowsError,
+ :c:func:`FormatMessage`), and then calls ``PyErr_SetObject(PyExc_WindowsError,
object)``. This function always returns *NULL*. Availability: Windows.
-.. cfunction:: PyObject* PyErr_SetExcFromWindowsErr(PyObject *type, int ierr)
+.. c:function:: PyObject* PyErr_SetExcFromWindowsErr(PyObject *type, int ierr)
- Similar to :cfunc:`PyErr_SetFromWindowsErr`, with an additional parameter
+ Similar to :c:func:`PyErr_SetFromWindowsErr`, with an additional parameter
specifying the exception type to be raised. Availability: Windows.
-.. cfunction:: PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename)
+.. c:function:: PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename)
- Similar to :cfunc:`PyErr_SetFromWindowsErr`, with the additional behavior that
+ 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.
-.. cfunction:: PyObject* PyErr_SetExcFromWindowsErrWithFilename(PyObject *type, int ierr, char *filename)
+.. c:function:: PyObject* PyErr_SetExcFromWindowsErrWithFilename(PyObject *type, int ierr, char *filename)
- Similar to :cfunc:`PyErr_SetFromWindowsErrWithFilename`, with an additional
+ Similar to :c:func:`PyErr_SetFromWindowsErrWithFilename`, with an additional
parameter specifying the exception type to be raised. Availability: Windows.
-.. cfunction:: void PyErr_BadInternalCall()
+.. 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()
This is a shorthand for ``PyErr_SetString(PyExc_SystemError, message)``,
where *message* indicates that an internal operation (e.g. a Python/C API
@@ -233,13 +255,13 @@ in various ways. There is a separate error indicator for each thread.
use.
-.. cfunction:: 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
- is the function calling :cfunc:`PyErr_WarnEx`, 2 is the function above that,
+ 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.
This function normally prints a warning message to *sys.stderr*; however, it is
@@ -251,35 +273,45 @@ in various ways. There is a separate error indicator for each thread.
is raised. (It is not possible to determine whether a warning message is
actually printed, nor what the reason is for the exception; this is
intentional.) If an exception is raised, the caller should do its normal
- exception handling (for example, :cfunc:`Py_DECREF` owned references and return
+ exception handling (for example, :c:func:`Py_DECREF` owned references and return
an error value).
- Warning categories must be subclasses of :cdata:`Warning`; the default warning
- category is :cdata:`RuntimeWarning`. The standard Python warning categories are
+ Warning categories must be subclasses of :c:data:`Warning`; the default warning
+ category is :c:data:`RuntimeWarning`. The standard Python warning categories are
available as global variables whose names are ``PyExc_`` followed by the Python
- exception name. These have the type :ctype:`PyObject\*`; they are all class
- objects. Their names are :cdata:`PyExc_Warning`, :cdata:`PyExc_UserWarning`,
- :cdata:`PyExc_UnicodeWarning`, :cdata:`PyExc_DeprecationWarning`,
- :cdata:`PyExc_SyntaxWarning`, :cdata:`PyExc_RuntimeWarning`, and
- :cdata:`PyExc_FutureWarning`. :cdata:`PyExc_Warning` is a subclass of
- :cdata:`PyExc_Exception`; the other warning categories are subclasses of
- :cdata:`PyExc_Warning`.
+ exception name. These have the type :c:type:`PyObject\*`; they are all class
+ objects. Their names are :c:data:`PyExc_Warning`, :c:data:`PyExc_UserWarning`,
+ :c:data:`PyExc_UnicodeWarning`, :c:data:`PyExc_DeprecationWarning`,
+ :c:data:`PyExc_SyntaxWarning`, :c:data:`PyExc_RuntimeWarning`, and
+ :c:data:`PyExc_FutureWarning`. :c:data:`PyExc_Warning` is a subclass of
+ :c:data:`PyExc_Exception`; the other warning categories are subclasses of
+ :c:data:`PyExc_Warning`.
For information about warning control, see the documentation for the
:mod:`warnings` module and the :option:`-W` option in the command line
documentation. There is no C API for warning control.
-.. cfunction:: int PyErr_WarnExplicit(PyObject *category, const char *message, const char *filename, int lineno, const char *module, PyObject *registry)
+.. 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_WarnFormat(PyObject *category, Py_ssize_t stack_level, const char *format, ...)
+ Function similar to :c:func:`PyErr_WarnEx`, but use
+ :c:func:`PyUnicode_FromFormat` to format the warning message. *format* is
+ an ASCII-encoded string.
-.. cfunction:: int PyErr_CheckSignals()
+ .. versionadded:: 3.2
+
+.. c:function:: int PyErr_CheckSignals()
.. index::
module: signal
@@ -296,21 +328,21 @@ in various ways. There is a separate error indicator for each thread.
cleared if it was previously set.
-.. cfunction:: void PyErr_SetInterrupt()
+.. c:function:: void PyErr_SetInterrupt()
.. index::
single: SIGINT
single: KeyboardInterrupt (built-in exception)
This function simulates the effect of a :const:`SIGINT` signal arriving --- the
- next time :cfunc:`PyErr_CheckSignals` is called, :exc:`KeyboardInterrupt` will
+ next time :c:func:`PyErr_CheckSignals` is called, :exc:`KeyboardInterrupt` will
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.
-.. cfunction:: int PySignal_SetWakeupFd(int fd)
+.. c:function:: int PySignal_SetWakeupFd(int fd)
This utility function specifies a file descriptor to which a ``'\0'`` byte will
be written whenever a signal is received. It returns the previous such file
@@ -320,13 +352,13 @@ in various ways. There is a separate error indicator for each thread.
only be called from the main thread.
-.. cfunction:: PyObject* PyErr_NewException(char *name, PyObject *base, PyObject *dict)
+.. c:function:: PyObject* PyErr_NewException(char *name, PyObject *base, PyObject *dict)
This utility function creates and returns a new exception object. The *name*
argument must be the name of the new exception, a C string of the form
``module.class``. The *base* and *dict* arguments are normally *NULL*. This
creates a class object derived from :exc:`Exception` (accessible in C as
- :cdata:`PyExc_Exception`).
+ :c:data:`PyExc_Exception`).
The :attr:`__module__` attribute of the new class is set to the first part (up
to the last dot) of the *name* argument, and the class name is set to the last
@@ -335,7 +367,16 @@ in various ways. There is a separate error indicator for each thread.
argument can be used to specify a dictionary of class variables and methods.
-.. cfunction:: void PyErr_WriteUnraisable(PyObject *obj)
+.. c:function:: PyObject* PyErr_NewExceptionWithDoc(char *name, char *doc, PyObject *base, PyObject *dict)
+
+ Same as :c:func:`PyErr_NewException`, except that the new exception class can
+ easily be given a docstring: If *doc* is non-*NULL*, it will be used as the
+ docstring for the exception class.
+
+ .. versionadded:: 3.2
+
+
+.. c:function:: void PyErr_WriteUnraisable(PyObject *obj)
This utility function prints a warning message to ``sys.stderr`` when an
exception has been set but it is impossible for the interpreter to actually
@@ -350,20 +391,20 @@ in various ways. There is a separate error indicator for each thread.
Exception Objects
=================
-.. cfunction:: PyObject* PyException_GetTraceback(PyObject *ex)
+.. 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*.
-.. cfunction:: int PyException_SetTraceback(PyObject *ex, PyObject *tb)
+.. c:function:: int PyException_SetTraceback(PyObject *ex, PyObject *tb)
Set the traceback associated with the exception to *tb*. Use ``Py_None`` to
clear it.
-.. cfunction:: PyObject* PyException_GetContext(PyObject *ex)
+.. 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
@@ -371,14 +412,14 @@ Exception Objects
returns *NULL*.
-.. cfunction:: void PyException_SetContext(PyObject *ex, PyObject *ctx)
+.. 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*.
-.. cfunction:: PyObject* PyException_GetCause(PyObject *ex)
+.. 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
@@ -386,7 +427,7 @@ Exception Objects
*NULL*.
-.. cfunction:: void PyException_SetCause(PyObject *ex, PyObject *ctx)
+.. 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.
@@ -400,71 +441,73 @@ Unicode Exception Objects
The following functions are used to create and modify Unicode exceptions from C.
-.. cfunction:: PyObject* PyUnicodeDecodeError_Create(const char *encoding, const char *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)
+.. 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.
-.. cfunction:: 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)
+.. 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.
-.. cfunction:: PyObject* PyUnicodeTranslateError_Create(const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)
+.. 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.
-.. cfunction:: PyObject* PyUnicodeDecodeError_GetEncoding(PyObject *exc)
- PyObject* PyUnicodeEncodeError_GetEncoding(PyObject *exc)
+.. c:function:: PyObject* PyUnicodeDecodeError_GetEncoding(PyObject *exc)
+ PyObject* PyUnicodeEncodeError_GetEncoding(PyObject *exc)
Return the *encoding* attribute of the given exception object.
-.. cfunction:: PyObject* PyUnicodeDecodeError_GetObject(PyObject *exc)
- PyObject* PyUnicodeEncodeError_GetObject(PyObject *exc)
- PyObject* PyUnicodeTranslateError_GetObject(PyObject *exc)
+.. c:function:: PyObject* PyUnicodeDecodeError_GetObject(PyObject *exc)
+ PyObject* PyUnicodeEncodeError_GetObject(PyObject *exc)
+ PyObject* PyUnicodeTranslateError_GetObject(PyObject *exc)
Return the *object* attribute of the given exception object.
-.. cfunction:: 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)
+.. 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)
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.
-.. cfunction:: 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)
+.. 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)
Set the *start* attribute of the given exception object to *start*. Return
``0`` on success, ``-1`` on failure.
-.. cfunction:: 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)
+.. 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)
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.
-.. cfunction:: 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)
+.. 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)
Set the *end* attribute of the given exception object to *end*. Return ``0``
on success, ``-1`` on failure.
-.. cfunction:: PyObject* PyUnicodeDecodeError_GetReason(PyObject *exc)
- PyObject* PyUnicodeEncodeError_GetReason(PyObject *exc)
- PyObject* PyUnicodeTranslateError_GetReason(PyObject *exc)
+.. c:function:: PyObject* PyUnicodeDecodeError_GetReason(PyObject *exc)
+ PyObject* PyUnicodeEncodeError_GetReason(PyObject *exc)
+ PyObject* PyUnicodeTranslateError_GetReason(PyObject *exc)
Return the *reason* attribute of the given exception object.
-.. cfunction:: int PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
- int PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
- int PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
+.. 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)
Set the *reason* attribute of the given exception object to *reason*. Return
``0`` on success, ``-1`` on failure.
@@ -478,12 +521,12 @@ level, both in the core and in extension modules. They are needed if the
recursive code does not necessarily invoke Python code (which tracks its
recursion depth automatically).
-.. cfunction:: int Py_EnterRecursiveCall(char *where)
+.. c:function:: int Py_EnterRecursiveCall(char *where)
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 the OS
- stack overflowed using :cfunc:`PyOS_CheckStack`. In this is the case, it
+ stack overflowed using :c:func:`PyOS_CheckStack`. In this is the case, it
sets a :exc:`MemoryError` and returns a nonzero value.
The function then checks if the recursion limit is reached. If this is the
@@ -494,10 +537,39 @@ recursion depth automatically).
concatenated to the :exc:`RuntimeError` message caused by the recursion depth
limit.
-.. cfunction:: void Py_LeaveRecursiveCall()
+.. c:function:: void Py_LeaveRecursiveCall()
+
+ 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 :cfunc:`Py_EnterRecursiveCall`. Must be called once for each
- *successful* invocation of :cfunc:`Py_EnterRecursiveCall`.
+ Ends a :c:func:`Py_ReprEnter`. Must be called once for each
+ invocation of :c:func:`Py_ReprEnter` that returns zero.
.. _standardexceptions:
@@ -507,68 +579,68 @@ Standard Exceptions
All standard Python exceptions are available as global variables whose names are
``PyExc_`` followed by the Python exception name. These have the type
-:ctype:`PyObject\*`; they are all class objects. For completeness, here are all
+:c:type:`PyObject\*`; they are all class objects. For completeness, here are all
the variables:
-+------------------------------------+----------------------------+----------+
-| C Name | Python Name | Notes |
-+====================================+============================+==========+
-| :cdata:`PyExc_BaseException` | :exc:`BaseException` | \(1) |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_Exception` | :exc:`Exception` | \(1) |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_ArithmeticError` | :exc:`ArithmeticError` | \(1) |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_LookupError` | :exc:`LookupError` | \(1) |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_AssertionError` | :exc:`AssertionError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_AttributeError` | :exc:`AttributeError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_EOFError` | :exc:`EOFError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_EnvironmentError` | :exc:`EnvironmentError` | \(1) |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_FloatingPointError` | :exc:`FloatingPointError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_IOError` | :exc:`IOError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_ImportError` | :exc:`ImportError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_IndexError` | :exc:`IndexError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_KeyError` | :exc:`KeyError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_KeyboardInterrupt` | :exc:`KeyboardInterrupt` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_MemoryError` | :exc:`MemoryError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_NameError` | :exc:`NameError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_NotImplementedError` | :exc:`NotImplementedError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_OSError` | :exc:`OSError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_OverflowError` | :exc:`OverflowError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_ReferenceError` | :exc:`ReferenceError` | \(2) |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_RuntimeError` | :exc:`RuntimeError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_SyntaxError` | :exc:`SyntaxError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_SystemError` | :exc:`SystemError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_SystemExit` | :exc:`SystemExit` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_TypeError` | :exc:`TypeError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_ValueError` | :exc:`ValueError` | |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_WindowsError` | :exc:`WindowsError` | \(3) |
-+------------------------------------+----------------------------+----------+
-| :cdata:`PyExc_ZeroDivisionError` | :exc:`ZeroDivisionError` | |
-+------------------------------------+----------------------------+----------+
++-------------------------------------+----------------------------+----------+
+| C Name | Python Name | Notes |
++=====================================+============================+==========+
+| :c:data:`PyExc_BaseException` | :exc:`BaseException` | \(1) |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_Exception` | :exc:`Exception` | \(1) |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_ArithmeticError` | :exc:`ArithmeticError` | \(1) |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_LookupError` | :exc:`LookupError` | \(1) |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_AssertionError` | :exc:`AssertionError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_AttributeError` | :exc:`AttributeError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_EOFError` | :exc:`EOFError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_EnvironmentError` | :exc:`EnvironmentError` | \(1) |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_FloatingPointError` | :exc:`FloatingPointError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_IOError` | :exc:`IOError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_ImportError` | :exc:`ImportError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_IndexError` | :exc:`IndexError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_KeyError` | :exc:`KeyError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_KeyboardInterrupt` | :exc:`KeyboardInterrupt` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_MemoryError` | :exc:`MemoryError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_NameError` | :exc:`NameError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_NotImplementedError` | :exc:`NotImplementedError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_OSError` | :exc:`OSError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_OverflowError` | :exc:`OverflowError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_ReferenceError` | :exc:`ReferenceError` | \(2) |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_RuntimeError` | :exc:`RuntimeError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_SyntaxError` | :exc:`SyntaxError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_SystemError` | :exc:`SystemError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_SystemExit` | :exc:`SystemExit` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_TypeError` | :exc:`TypeError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_ValueError` | :exc:`ValueError` | |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_WindowsError` | :exc:`WindowsError` | \(3) |
++-------------------------------------+----------------------------+----------+
+| :c:data:`PyExc_ZeroDivisionError` | :exc:`ZeroDivisionError` | |
++-------------------------------------+----------------------------+----------+
.. index::
single: PyExc_BaseException
diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst
index cc851e6..c5a4a59 100644
--- a/Doc/c-api/file.rst
+++ b/Doc/c-api/file.rst
@@ -8,7 +8,7 @@ File Objects
.. index:: object: file
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 (:ctype:`FILE\*`) support
+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
@@ -17,13 +17,14 @@ error reporting in the interpreter; third-party code is advised to access
the :mod:`io` APIs instead.
-.. cfunction:: PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *errors, char *newline, int closefd)
+.. c:function:: PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *errors, char *newline, int closefd)
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. Return *NULL* on failure. For a more comprehensive description of
- the arguments, please refer to the :func:`io.open` function documentation.
+ 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::
@@ -31,17 +32,20 @@ the :mod:`io` APIs instead.
OS-level file descriptors can produce various issues (such as unexpected
ordering of data).
+ .. versionchanged:: 3.2
+ Ignore *name* attribute.
-.. cfunction:: int PyObject_AsFileDescriptor(PyObject *p)
- Return the file descriptor associated with *p* as an :ctype:`int`. If the
+.. c:function:: int PyObject_AsFileDescriptor(PyObject *p)
+
+ 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.
-.. cfunction:: PyObject* PyFile_GetLine(PyObject *p, int n)
+.. c:function:: PyObject* PyFile_GetLine(PyObject *p, int n)
.. index:: single: EOFError (built-in exception)
@@ -55,7 +59,7 @@ the :mod:`io` APIs instead.
raised if the end of the file is reached immediately.
-.. cfunction:: int PyFile_WriteObject(PyObject *obj, PyObject *p, int flags)
+.. c:function:: int PyFile_WriteObject(PyObject *obj, PyObject *p, int flags)
.. index:: single: Py_PRINT_RAW
@@ -65,7 +69,7 @@ the :mod:`io` APIs instead.
appropriate exception will be set.
-.. cfunction:: int PyFile_WriteString(const char *s, PyObject *p)
+.. c:function:: int PyFile_WriteString(const char *s, PyObject *p)
Write string *s* to file object *p*. Return ``0`` on success or ``-1`` on
failure; the appropriate exception will be set.
diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst
index 93769aa..757efd3 100644
--- a/Doc/c-api/float.rst
+++ b/Doc/c-api/float.rst
@@ -8,70 +8,70 @@ Floating Point Objects
.. index:: object: floating point
-.. ctype:: PyFloatObject
+.. c:type:: PyFloatObject
- This subtype of :ctype:`PyObject` represents a Python floating point object.
+ This subtype of :c:type:`PyObject` represents a Python floating point object.
-.. cvar:: PyTypeObject PyFloat_Type
+.. c:var:: PyTypeObject PyFloat_Type
- This instance of :ctype:`PyTypeObject` represents the Python floating point
+ This instance of :c:type:`PyTypeObject` represents the Python floating point
type. This is the same object as :class:`float` in the Python layer.
-.. cfunction:: int PyFloat_Check(PyObject *p)
+.. c:function:: int PyFloat_Check(PyObject *p)
- Return true if its argument is a :ctype:`PyFloatObject` or a subtype of
- :ctype:`PyFloatObject`.
+ Return true if its argument is a :c:type:`PyFloatObject` or a subtype of
+ :c:type:`PyFloatObject`.
-.. cfunction:: int PyFloat_CheckExact(PyObject *p)
+.. c:function:: int PyFloat_CheckExact(PyObject *p)
- Return true if its argument is a :ctype:`PyFloatObject`, but not a subtype of
- :ctype:`PyFloatObject`.
+ Return true if its argument is a :c:type:`PyFloatObject`, but not a subtype of
+ :c:type:`PyFloatObject`.
-.. cfunction:: PyObject* PyFloat_FromString(PyObject *str)
+.. c:function:: PyObject* PyFloat_FromString(PyObject *str)
- Create a :ctype:`PyFloatObject` object based on the string value in *str*, or
+ Create a :c:type:`PyFloatObject` object based on the string value in *str*, or
*NULL* on failure.
-.. cfunction:: PyObject* PyFloat_FromDouble(double v)
+.. c:function:: PyObject* PyFloat_FromDouble(double v)
- Create a :ctype:`PyFloatObject` object from *v*, or *NULL* on failure.
+ Create a :c:type:`PyFloatObject` object from *v*, or *NULL* on failure.
-.. cfunction:: double PyFloat_AsDouble(PyObject *pyfloat)
+.. c:function:: double PyFloat_AsDouble(PyObject *pyfloat)
- Return a C :ctype:`double` representation of the contents of *pyfloat*. If
+ Return a C :c:type:`double` representation of the contents of *pyfloat*. If
*pyfloat* is not a Python floating point object but has a :meth:`__float__`
method, this method will first be called to convert *pyfloat* into a float.
-.. cfunction:: double PyFloat_AS_DOUBLE(PyObject *pyfloat)
+.. c:function:: double PyFloat_AS_DOUBLE(PyObject *pyfloat)
- Return a C :ctype:`double` representation of the contents of *pyfloat*, but
+ Return a C :c:type:`double` representation of the contents of *pyfloat*, but
without error checking.
-.. cfunction:: PyObject* PyFloat_GetInfo(void)
+.. c:function:: PyObject* PyFloat_GetInfo(void)
Return a structseq instance which contains information about the
precision, minimum and maximum values of a float. It's a thin wrapper
around the header file :file:`float.h`.
-.. cfunction:: double PyFloat_GetMax()
+.. c:function:: double PyFloat_GetMax()
- Return the maximum representable finite float *DBL_MAX* as C :ctype:`double`.
+ Return the maximum representable finite float *DBL_MAX* as C :c:type:`double`.
-.. cfunction:: double PyFloat_GetMin()
+.. c:function:: double PyFloat_GetMin()
- Return the minimum normalized positive float *DBL_MIN* as C :ctype:`double`.
+ Return the minimum normalized positive float *DBL_MIN* as C :c:type:`double`.
-.. cfunction:: int PyFloat_ClearFreeList()
+.. c:function:: int PyFloat_ClearFreeList()
Clear the float free list. Return the number of items that could not
be freed.
diff --git a/Doc/c-api/function.rst b/Doc/c-api/function.rst
index 3512fe2..31805fd 100644
--- a/Doc/c-api/function.rst
+++ b/Doc/c-api/function.rst
@@ -10,26 +10,26 @@ Function Objects
There are a few functions specific to Python functions.
-.. ctype:: PyFunctionObject
+.. c:type:: PyFunctionObject
The C structure used for functions.
-.. cvar:: PyTypeObject PyFunction_Type
+.. c:var:: PyTypeObject PyFunction_Type
.. index:: single: MethodType (in module types)
- This is an instance of :ctype:`PyTypeObject` and represents the Python function
+ This is an instance of :c:type:`PyTypeObject` and represents the Python function
type. It is exposed to Python programmers as ``types.FunctionType``.
-.. cfunction:: int PyFunction_Check(PyObject *o)
+.. c:function:: int PyFunction_Check(PyObject *o)
- Return true if *o* is a function object (has type :cdata:`PyFunction_Type`).
+ Return true if *o* is a function object (has type :c:data:`PyFunction_Type`).
The parameter must not be *NULL*.
-.. cfunction:: PyObject* PyFunction_New(PyObject *code, PyObject *globals)
+.. c:function:: PyObject* PyFunction_New(PyObject *code, PyObject *globals)
Return a new function object associated with the code object *code*. *globals*
must be a dictionary with the global variables accessible to the function.
@@ -38,30 +38,30 @@ There are a few functions specific to Python functions.
object, the argument defaults and closure are set to *NULL*.
-.. cfunction:: PyObject* PyFunction_GetCode(PyObject *op)
+.. c:function:: PyObject* PyFunction_GetCode(PyObject *op)
Return the code object associated with the function object *op*.
-.. cfunction:: PyObject* PyFunction_GetGlobals(PyObject *op)
+.. c:function:: PyObject* PyFunction_GetGlobals(PyObject *op)
Return the globals dictionary associated with the function object *op*.
-.. cfunction:: PyObject* PyFunction_GetModule(PyObject *op)
+.. c:function:: PyObject* PyFunction_GetModule(PyObject *op)
Return the *__module__* attribute of the function object *op*. This is normally
a string containing the module name, but can be set to any other object by
Python code.
-.. cfunction:: PyObject* PyFunction_GetDefaults(PyObject *op)
+.. c:function:: PyObject* PyFunction_GetDefaults(PyObject *op)
Return the argument default values of the function object *op*. This can be a
tuple of arguments or *NULL*.
-.. cfunction:: int PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
+.. c:function:: int PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
Set the argument default values for the function object *op*. *defaults* must be
*Py_None* or a tuple.
@@ -69,13 +69,13 @@ There are a few functions specific to Python functions.
Raises :exc:`SystemError` and returns ``-1`` on failure.
-.. cfunction:: PyObject* PyFunction_GetClosure(PyObject *op)
+.. c:function:: PyObject* PyFunction_GetClosure(PyObject *op)
Return the closure associated with the function object *op*. This can be *NULL*
or a tuple of cell objects.
-.. cfunction:: int PyFunction_SetClosure(PyObject *op, PyObject *closure)
+.. c:function:: int PyFunction_SetClosure(PyObject *op, PyObject *closure)
Set the closure associated with the function object *op*. *closure* must be
*Py_None* or a tuple of cell objects.
@@ -83,13 +83,13 @@ There are a few functions specific to Python functions.
Raises :exc:`SystemError` and returns ``-1`` on failure.
-.. cfunction:: PyObject *PyFunction_GetAnnotations(PyObject *op)
+.. c:function:: PyObject *PyFunction_GetAnnotations(PyObject *op)
Return the annotations of the function object *op*. This can be a
mutable dictionary or *NULL*.
-.. cfunction:: int PyFunction_SetAnnotations(PyObject *op, PyObject *annotations)
+.. 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*.
diff --git a/Doc/c-api/gcsupport.rst b/Doc/c-api/gcsupport.rst
index 1a280c8..3875ff2 100644
--- a/Doc/c-api/gcsupport.rst
+++ b/Doc/c-api/gcsupport.rst
@@ -27,32 +27,32 @@ include the :const:`Py_TPFLAGS_HAVE_GC` and provide an implementation of the
Constructors for container types must conform to two rules:
-#. The memory for the object must be allocated using :cfunc:`PyObject_GC_New`
- or :cfunc:`PyObject_GC_NewVar`.
+#. The memory for the object must be allocated using :c:func:`PyObject_GC_New`
+ or :c:func:`PyObject_GC_NewVar`.
#. Once all the fields which may contain references to other containers are
- initialized, it must call :cfunc:`PyObject_GC_Track`.
+ initialized, it must call :c:func:`PyObject_GC_Track`.
-.. cfunction:: TYPE* PyObject_GC_New(TYPE, PyTypeObject *type)
+.. c:function:: TYPE* PyObject_GC_New(TYPE, PyTypeObject *type)
- Analogous to :cfunc:`PyObject_New` but for container objects with the
+ Analogous to :c:func:`PyObject_New` but for container objects with the
:const:`Py_TPFLAGS_HAVE_GC` flag set.
-.. cfunction:: TYPE* PyObject_GC_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size)
+.. c:function:: TYPE* PyObject_GC_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size)
- Analogous to :cfunc:`PyObject_NewVar` but for container objects with the
+ Analogous to :c:func:`PyObject_NewVar` but for container objects with the
:const:`Py_TPFLAGS_HAVE_GC` flag set.
-.. cfunction:: TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize)
+.. c:function:: TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize)
- Resize an object allocated by :cfunc:`PyObject_NewVar`. Returns the
+ Resize an object allocated by :c:func:`PyObject_NewVar`. Returns the
resized object or *NULL* on failure.
-.. cfunction:: void PyObject_GC_Track(PyObject *op)
+.. c:function:: void PyObject_GC_Track(PyObject *op)
Adds the object *op* to the set of container objects tracked by the
collector. The collector can run at unexpected times so objects must be
@@ -61,44 +61,44 @@ Constructors for container types must conform to two rules:
end of the constructor.
-.. cfunction:: void _PyObject_GC_TRACK(PyObject *op)
+.. c:function:: void _PyObject_GC_TRACK(PyObject *op)
- A macro version of :cfunc:`PyObject_GC_Track`. It should not be used for
+ A macro version of :c:func:`PyObject_GC_Track`. It should not be used for
extension modules.
Similarly, the deallocator for the object must conform to a similar pair of
rules:
#. Before fields which refer to other containers are invalidated,
- :cfunc:`PyObject_GC_UnTrack` must be called.
+ :c:func:`PyObject_GC_UnTrack` must be called.
-#. The object's memory must be deallocated using :cfunc:`PyObject_GC_Del`.
+#. The object's memory must be deallocated using :c:func:`PyObject_GC_Del`.
-.. cfunction:: void PyObject_GC_Del(void *op)
+.. c:function:: void PyObject_GC_Del(void *op)
- Releases memory allocated to an object using :cfunc:`PyObject_GC_New` or
- :cfunc:`PyObject_GC_NewVar`.
+ Releases memory allocated to an object using :c:func:`PyObject_GC_New` or
+ :c:func:`PyObject_GC_NewVar`.
-.. cfunction:: void PyObject_GC_UnTrack(void *op)
+.. c:function:: void PyObject_GC_UnTrack(void *op)
Remove the object *op* from the set of container objects tracked by the
- collector. Note that :cfunc:`PyObject_GC_Track` can be called again on
+ collector. Note that :c:func:`PyObject_GC_Track` can be called again on
this object to add it back to the set of tracked objects. The deallocator
(:attr:`tp_dealloc` handler) should call this for the object before any of
the fields used by the :attr:`tp_traverse` handler become invalid.
-.. cfunction:: void _PyObject_GC_UNTRACK(PyObject *op)
+.. c:function:: void _PyObject_GC_UNTRACK(PyObject *op)
- A macro version of :cfunc:`PyObject_GC_UnTrack`. It should not be used for
+ A macro version of :c:func:`PyObject_GC_UnTrack`. It should not be used for
extension modules.
The :attr:`tp_traverse` handler accepts a function parameter of this type:
-.. ctype:: int (*visitproc)(PyObject *object, void *arg)
+.. c:type:: int (*visitproc)(PyObject *object, void *arg)
Type of the visitor function passed to the :attr:`tp_traverse` handler.
The function should be called with an object to traverse as *object* and
@@ -110,7 +110,7 @@ The :attr:`tp_traverse` handler accepts a function parameter of this type:
The :attr:`tp_traverse` handler must have the following type:
-.. ctype:: int (*traverseproc)(PyObject *self, visitproc visit, void *arg)
+.. c:type:: int (*traverseproc)(PyObject *self, visitproc visit, void *arg)
Traversal function for a container object. Implementations must call the
*visit* function for each object directly contained by *self*, with the
@@ -119,12 +119,12 @@ The :attr:`tp_traverse` handler must have the following type:
object argument. If *visit* returns a non-zero value that value should be
returned immediately.
-To simplify writing :attr:`tp_traverse` handlers, a :cfunc:`Py_VISIT` macro is
+To simplify writing :attr:`tp_traverse` handlers, a :c:func:`Py_VISIT` macro is
provided. In order to use this macro, the :attr:`tp_traverse` implementation
must name its arguments exactly *visit* and *arg*:
-.. cfunction:: void Py_VISIT(PyObject *o)
+.. c:function:: void Py_VISIT(PyObject *o)
Call the *visit* callback, with arguments *o* and *arg*. If *visit* returns
a non-zero value, then return it. Using this macro, :attr:`tp_traverse`
@@ -138,15 +138,15 @@ must name its arguments exactly *visit* and *arg*:
return 0;
}
-The :attr:`tp_clear` handler must be of the :ctype:`inquiry` type, or *NULL*
+The :attr:`tp_clear` handler must be of the :c:type:`inquiry` type, or *NULL*
if the object is immutable.
-.. ctype:: int (*inquiry)(PyObject *self)
+.. c:type:: int (*inquiry)(PyObject *self)
Drop references that may have created reference cycles. Immutable objects
do not have to define this method since they can never directly create
reference cycles. Note that the object must still be valid after calling
- this method (don't just call :cfunc:`Py_DECREF` on a reference). The
+ this method (don't just call :c:func:`Py_DECREF` on a reference). The
collector will call this method if it detects that this object is involved
in a reference cycle.
diff --git a/Doc/c-api/gen.rst b/Doc/c-api/gen.rst
index 0d3789a..33cd27a 100644
--- a/Doc/c-api/gen.rst
+++ b/Doc/c-api/gen.rst
@@ -7,31 +7,31 @@ Generator Objects
Generator objects are what Python uses to implement generator iterators. They
are normally created by iterating over a function that yields values, rather
-than explicitly calling :cfunc:`PyGen_New`.
+than explicitly calling :c:func:`PyGen_New`.
-.. ctype:: PyGenObject
+.. c:type:: PyGenObject
The C structure used for generator objects.
-.. cvar:: PyTypeObject PyGen_Type
+.. c:var:: PyTypeObject PyGen_Type
The type object corresponding to generator objects
-.. cfunction:: int PyGen_Check(ob)
+.. c:function:: int PyGen_Check(ob)
Return true if *ob* is a generator object; *ob* must not be *NULL*.
-.. cfunction:: int PyGen_CheckExact(ob)
+.. c:function:: int PyGen_CheckExact(ob)
Return true if *ob*'s type is *PyGen_Type* is a generator object; *ob* must not
be *NULL*.
-.. cfunction:: PyObject* PyGen_New(PyFrameObject *frame)
+.. c:function:: PyObject* PyGen_New(PyFrameObject *frame)
Create and return a new generator object based on the *frame* object. A
reference to *frame* is stolen by this function. The parameter must not be
diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst
index ff79112..cf48363 100644
--- a/Doc/c-api/import.rst
+++ b/Doc/c-api/import.rst
@@ -6,14 +6,14 @@ Importing Modules
=================
-.. cfunction:: PyObject* PyImport_ImportModule(const char *name)
+.. c:function:: PyObject* PyImport_ImportModule(const char *name)
.. index::
single: package variable; __all__
single: __all__ (package variable)
single: modules (in module sys)
- This is a simplified interface to :cfunc:`PyImport_ImportModuleEx` below,
+ This is a simplified interface to :c:func:`PyImport_ImportModuleEx` below,
leaving the *globals* and *locals* arguments set to *NULL* and *level* set
to 0. When the *name*
argument contains a dot (when it specifies a submodule of a package), the
@@ -28,18 +28,18 @@ Importing Modules
This function always uses absolute imports.
-.. cfunction:: PyObject* PyImport_ImportModuleNoBlock(const char *name)
+.. c:function:: PyObject* PyImport_ImportModuleNoBlock(const char *name)
- This version of :cfunc:`PyImport_ImportModule` does not block. It's intended
+ This version of :c:func:`PyImport_ImportModule` does not block. It's intended
to be used in C functions that import other modules to execute a function.
The import may block if another thread holds the import lock. The function
- :cfunc:`PyImport_ImportModuleNoBlock` never blocks. It first tries to fetch
- the module from sys.modules and falls back to :cfunc:`PyImport_ImportModule`
+ :c:func:`PyImport_ImportModuleNoBlock` never blocks. It first tries to fetch
+ the module from sys.modules and falls back to :c:func:`PyImport_ImportModule`
unless the lock is held, in which case the function will raise an
:exc:`ImportError`.
-.. cfunction:: PyObject* PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist)
+.. c:function:: PyObject* PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist)
.. index:: builtin: __import__
@@ -54,10 +54,10 @@ Importing Modules
was given.
Failing imports remove incomplete module objects, like with
- :cfunc:`PyImport_ImportModule`.
+ :c:func:`PyImport_ImportModule`.
-.. cfunction:: PyObject* PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level)
+.. c:function:: PyObject* PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level)
Import a module. This is best described by referring to the built-in Python
function :func:`__import__`, as the standard :func:`__import__` function calls
@@ -69,7 +69,7 @@ Importing Modules
top-level package, unless a non-empty *fromlist* was given.
-.. cfunction:: PyObject* PyImport_Import(PyObject *name)
+.. c:function:: PyObject* PyImport_Import(PyObject *name)
This is a higher-level interface that calls the current "import hook
function" (with an explicit *level* of 0, meaning absolute import). It
@@ -80,13 +80,13 @@ Importing Modules
This function always uses absolute imports.
-.. cfunction:: PyObject* PyImport_ReloadModule(PyObject *m)
+.. c:function:: PyObject* PyImport_ReloadModule(PyObject *m)
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).
-.. cfunction:: PyObject* PyImport_AddModule(const char *name)
+.. c:function:: PyObject* PyImport_AddModule(const char *name)
Return the module object corresponding to a module name. The *name* argument
may be of the form ``package.module``. First check the modules dictionary if
@@ -96,12 +96,12 @@ Importing Modules
.. note::
This function does not load or import the module; if the module wasn't already
- loaded, you will get an empty module object. Use :cfunc:`PyImport_ImportModule`
+ loaded, you will get an empty module object. Use :c:func:`PyImport_ImportModule`
or one of its variants to import a module. Package structures implied by a
dotted name for *name* are not created if not already present.
-.. cfunction:: PyObject* PyImport_ExecCodeModule(char *name, PyObject *co)
+.. c:function:: PyObject* PyImport_ExecCodeModule(char *name, PyObject *co)
.. index:: builtin: compile
@@ -110,32 +110,61 @@ Importing Modules
:func:`compile`, load the module. Return a new reference to the module object,
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 :cfunc:`PyImport_ExecCodeModule`. Leaving
+ 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
probably damaged with respect to the module author's intents) state.
+ The module's :attr:`__file__` attribute will be set to the code object's
+ :c:member:`co_filename`.
+
This function will reload the module if it was already imported. See
- :cfunc:`PyImport_ReloadModule` for the intended way to reload a module.
+ :c:func:`PyImport_ReloadModule` for the intended way to reload a module.
If *name* points to a dotted name of the form ``package.module``, any package
structures not already created will still not be created.
+ See also :c:func:`PyImport_ExecCodeModuleEx` and
+ :c:func:`PyImport_ExecCodeModuleWithPathnames`.
+
+
+.. c:function:: PyObject* PyImport_ExecCodeModuleEx(char *name, PyObject *co, char *pathname)
+
+ 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`.
+
-.. cfunction:: long PyImport_GetMagicNumber()
+.. 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()
Return the magic number for Python bytecode files (a.k.a. :file:`.pyc` and
:file:`.pyo` files). The magic number should be present in the first four bytes
of the bytecode file, in little-endian byte order.
-.. cfunction:: PyObject* PyImport_GetModuleDict()
+.. 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.
``sys.modules``). Note that this is a per-interpreter variable.
-.. cfunction:: PyObject* PyImport_GetImporter(PyObject *path)
+.. c:function:: PyObject* PyImport_GetImporter(PyObject *path)
Return an importer object for a :data:`sys.path`/:attr:`pkg.__path__` item
*path*, possibly by fetching it from the :data:`sys.path_importer_cache`
@@ -146,41 +175,41 @@ Importing Modules
to the importer object.
-.. cfunction:: void _PyImport_Init()
+.. c:function:: void _PyImport_Init()
Initialize the import mechanism. For internal use only.
-.. cfunction:: void PyImport_Cleanup()
+.. c:function:: void PyImport_Cleanup()
Empty the module table. For internal use only.
-.. cfunction:: void _PyImport_Fini()
+.. c:function:: void _PyImport_Fini()
Finalize the import mechanism. For internal use only.
-.. cfunction:: PyObject* _PyImport_FindExtension(char *, char *)
+.. c:function:: PyObject* _PyImport_FindExtension(char *, char *)
For internal use only.
-.. cfunction:: PyObject* _PyImport_FixupExtension(char *, char *)
+.. c:function:: PyObject* _PyImport_FixupExtension(char *, char *)
For internal use only.
-.. cfunction:: int PyImport_ImportFrozenModule(char *name)
+.. c:function:: int PyImport_ImportFrozenModule(char *name)
Load a frozen module named *name*. Return ``1`` for success, ``0`` if the
module is not found, and ``-1`` with an exception set if the initialization
failed. To access the imported module on a successful load, use
- :cfunc:`PyImport_ImportModule`. (Note the misnomer --- this function would
+ :c:func:`PyImport_ImportModule`. (Note the misnomer --- this function would
reload the module if it was already imported.)
-.. ctype:: struct _frozen
+.. c:type:: struct _frozen
.. index:: single: freeze utility
@@ -196,30 +225,30 @@ Importing Modules
};
-.. cvar:: struct _frozen* PyImport_FrozenModules
+.. c:var:: struct _frozen* PyImport_FrozenModules
- This pointer is initialized to point to an array of :ctype:`struct _frozen`
+ 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.
-.. cfunction:: int PyImport_AppendInittab(const char *name, PyObject* (*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 :cfunc:`PyImport_ExtendInittab`, returning ``-1`` if
+ convenience wrapper around :c:func:`PyImport_ExtendInittab`, returning ``-1`` if
the table could not be extended. The new module can be imported by the name
*name*, and uses the function *initfunc* as the initialization function called
on the first attempted import. This should be called before
- :cfunc:`Py_Initialize`.
+ :c:func:`Py_Initialize`.
-.. ctype:: struct _inittab
+.. c:type:: struct _inittab
Structure describing a single entry in the list of built-in modules. Each of
these structures gives the name and initialization function for a module built
into the interpreter. Programs which embed Python may use an array of these
- structures in conjunction with :cfunc:`PyImport_ExtendInittab` to provide
+ structures in conjunction with :c:func:`PyImport_ExtendInittab` to provide
additional built-in modules. The structure is defined in
:file:`Include/import.h` as::
@@ -229,11 +258,11 @@ Importing Modules
};
-.. cfunction:: int PyImport_ExtendInittab(struct _inittab *newtab)
+.. c:function:: int PyImport_ExtendInittab(struct _inittab *newtab)
Add a collection of modules to the table of built-in modules. The *newtab*
array must end with a sentinel entry which contains *NULL* for the :attr:`name`
field; failure to provide the sentinel value can result in a memory fault.
Returns ``0`` on success or ``-1`` if insufficient memory could be allocated to
extend the internal table. In the event of failure, no modules are added to the
- internal table. This should be called before :cfunc:`Py_Initialize`.
+ internal table. This should be called before :c:func:`Py_Initialize`.
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index b2fa3ee..1806867 100644
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -12,13 +12,11 @@ Initializing and finalizing the interpreter
===========================================
-.. cfunction:: void Py_Initialize()
+.. c:function:: void Py_Initialize()
.. index::
single: Py_SetProgramName()
single: PyEval_InitThreads()
- single: PyEval_ReleaseLock()
- single: PyEval_AcquireLock()
single: modules (in module sys)
single: path (in module sys)
module: builtins
@@ -31,38 +29,37 @@ 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 :cfunc:`Py_SetProgramName`, :cfunc:`PyEval_InitThreads`,
- :cfunc:`PyEval_ReleaseLock`, and :cfunc:`PyEval_AcquireLock`. This initializes
+ exception of :c:func:`Py_SetProgramName` and :c:func:`Py_SetPath`. This initializes
the table of loaded modules (``sys.modules``), and creates the fundamental
modules :mod:`builtins`, :mod:`__main__` and :mod:`sys`. It also initializes
the module search path (``sys.path``). It does not set ``sys.argv``; use
- :cfunc:`PySys_SetArgvEx` for that. This is a no-op when called for a second time
- (without calling :cfunc:`Py_Finalize` first). There is no return value; it is a
+ :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
fatal error if the initialization fails.
-.. cfunction:: void Py_InitializeEx(int initsigs)
+.. c:function:: void Py_InitializeEx(int initsigs)
- This function works like :cfunc:`Py_Initialize` if *initsigs* is 1. If
+ This function works like :c:func:`Py_Initialize` if *initsigs* is 1. If
*initsigs* is 0, it skips initialization registration of signal handlers, which
might be useful when Python is embedded.
-.. cfunction:: int Py_IsInitialized()
+.. c:function:: int Py_IsInitialized()
Return true (nonzero) when the Python interpreter has been initialized, false
- (zero) if not. After :cfunc:`Py_Finalize` is called, this returns false until
- :cfunc:`Py_Initialize` is called again.
+ (zero) if not. After :c:func:`Py_Finalize` is called, this returns false until
+ :c:func:`Py_Initialize` is called again.
-.. cfunction:: void Py_Finalize()
+.. c:function:: void Py_Finalize()
- Undo all initializations made by :cfunc:`Py_Initialize` and subsequent use of
+ Undo all initializations made by :c:func:`Py_Initialize` and subsequent use of
Python/C API functions, and destroy all sub-interpreters (see
- :cfunc:`Py_NewInterpreter` below) that were created and not yet destroyed since
- the last call to :cfunc:`Py_Initialize`. Ideally, this frees all memory
+ :c:func:`Py_NewInterpreter` below) that were created and not yet destroyed since
+ the last call to :c:func:`Py_Initialize`. Ideally, this frees all memory
allocated by the Python interpreter. This is a no-op when called for a second
- time (without calling :cfunc:`Py_Initialize` again first). There is no return
+ time (without calling :c:func:`Py_Initialize` again first). There is no return
value; errors during finalization are ignored.
This function is provided for a number of reasons. An embedding application
@@ -81,26 +78,26 @@ Initializing and finalizing the interpreter
please report it). Memory tied up in circular references between objects is not
freed. Some memory allocated by extension modules may not be freed. Some
extensions may not work properly if their initialization routine is called more
- than once; this can happen if an application calls :cfunc:`Py_Initialize` and
- :cfunc:`Py_Finalize` more than once.
+ than once; this can happen if an application calls :c:func:`Py_Initialize` and
+ :c:func:`Py_Finalize` more than once.
Process-wide parameters
=======================
-.. cfunction:: void Py_SetProgramName(wchar_t *name)
+.. c:function:: void Py_SetProgramName(wchar_t *name)
.. index::
single: Py_Initialize()
single: main()
single: Py_GetPath()
- This function should be called before :cfunc:`Py_Initialize` is called for
+ 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 :cfunc:`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 :cfunc:`Py_GetPath` and some other functions below to find
+ 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 wide character string in static storage whose contents will not
@@ -108,20 +105,20 @@ Process-wide parameters
interpreter will change the contents of this storage.
-.. cfunction:: wchar* Py_GetProgramName()
+.. c:function:: wchar* Py_GetProgramName()
.. index:: single: Py_SetProgramName()
- Return the program name set with :cfunc:`Py_SetProgramName`, or the default.
+ Return the program name set with :c:func:`Py_SetProgramName`, or the default.
The returned string points into static storage; the caller should not modify its
value.
-.. cfunction:: wchar_t* 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
- :cfunc:`Py_SetProgramName` and some environment variables; for example, if the
+ :c:func:`Py_SetProgramName` and some environment variables; for example, if the
program name is ``'/usr/local/bin/python'``, the prefix is ``'/usr/local'``. The
returned string points into static storage; the caller should not modify its
value. This corresponds to the :makevar:`prefix` variable in the top-level
@@ -130,11 +127,11 @@ Process-wide parameters
It is only useful on Unix. See also the next function.
-.. cfunction:: wchar_t* 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
- :cfunc:`Py_SetProgramName` and some environment variables; for example, if the
+ :c:func:`Py_SetProgramName` and some environment variables; for example, if the
program name is ``'/usr/local/bin/python'``, the exec-prefix is
``'/usr/local'``. The returned string points into static storage; the caller
should not modify its value. This corresponds to the :makevar:`exec_prefix`
@@ -165,7 +162,7 @@ Process-wide parameters
platform.
-.. cfunction:: wchar_t* Py_GetProgramFullPath()
+.. c:function:: wchar_t* Py_GetProgramFullPath()
.. index::
single: Py_SetProgramName()
@@ -173,19 +170,20 @@ Process-wide parameters
Return the full program name of the Python executable; this is computed as a
side-effect of deriving the default module search path from the program name
- (set by :cfunc:`Py_SetProgramName` above). The returned string points into
+ (set by :c:func:`Py_SetProgramName` above). The returned string points into
static storage; the caller should not modify its value. The value is available
to Python code as ``sys.executable``.
-.. cfunction:: wchar_t* 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 :cfunc:`Py_SetProgramName` above) and some environment variables.
+ (set by :c:func:`Py_SetProgramName` above) and some environment variables.
The returned string consists of a series of directory names separated by a
platform dependent delimiter character. The delimiter character is ``':'``
on Unix and Mac OS X, ``';'`` on Windows. The returned string points into
@@ -197,7 +195,26 @@ Process-wide parameters
.. XXX should give the exact rules
-.. cfunction:: const char* Py_GetVersion()
+.. 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 ::
@@ -212,7 +229,7 @@ Process-wide parameters
modify its value. The value is available to Python code as :data:`sys.version`.
-.. cfunction:: const char* Py_GetPlatform()
+.. c:function:: const char* Py_GetPlatform()
.. index:: single: platform (in module sys)
@@ -225,7 +242,7 @@ Process-wide parameters
to Python code as ``sys.platform``.
-.. cfunction:: const char* Py_GetCopyright()
+.. c:function:: const char* Py_GetCopyright()
Return the official copyright string for the current Python version, for example
@@ -237,7 +254,7 @@ Process-wide parameters
value. The value is available to Python code as ``sys.copyright``.
-.. cfunction:: const char* Py_GetCompiler()
+.. c:function:: const char* Py_GetCompiler()
Return an indication of the compiler used to build the current Python version,
in square brackets, for example::
@@ -251,7 +268,7 @@ Process-wide parameters
``sys.version``.
-.. cfunction:: const char* Py_GetBuildInfo()
+.. c:function:: const char* Py_GetBuildInfo()
Return information about the sequence number and build date and time of the
current Python interpreter instance, for example ::
@@ -265,7 +282,7 @@ Process-wide parameters
``sys.version``.
-.. cfunction:: void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
+.. c:function:: void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
.. index::
single: main()
@@ -273,12 +290,12 @@ Process-wide parameters
single: argv (in module sys)
Set :data:`sys.argv` based on *argc* and *argv*. These parameters are
- similar to those passed to the program's :cfunc:`main` function with the
+ similar to those passed to the program's :c:func:`main` function with the
difference that the first entry should refer to the script file to be
executed rather than the executable hosting the Python interpreter. If there
isn't a script that will be run, the first entry in *argv* can be an empty
string. If this function fails to initialize :data:`sys.argv`, a fatal
- condition is signalled using :cfunc:`Py_FatalError`.
+ condition is signalled using :c:func:`Py_FatalError`.
If *updatepath* is zero, this is all the function does. If *updatepath*
is non-zero, the function also modifies :data:`sys.path` according to the
@@ -300,7 +317,7 @@ Process-wide parameters
On versions before 3.1.3, you can achieve the same effect by manually
popping the first :data:`sys.path` element after having called
- :cfunc:`PySys_SetArgv`, for example using::
+ :c:func:`PySys_SetArgv`, for example using::
PyRun_SimpleString("import sys; sys.path.pop(0)\n");
@@ -310,12 +327,12 @@ Process-wide parameters
check w/ Guido.
-.. cfunction:: void PySys_SetArgv(int argc, wchar_t **argv)
+.. c:function:: void PySys_SetArgv(int argc, wchar_t **argv)
- This function works like :cfunc:`PySys_SetArgvEx` with *updatepath* set to 1.
+ This function works like :c:func:`PySys_SetArgvEx` with *updatepath* set to 1.
-.. cfunction:: void Py_SetPythonHome(wchar_t *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
@@ -327,10 +344,10 @@ Process-wide parameters
this storage.
-.. cfunction:: w_char* Py_GetPythonHome()
+.. c:function:: w_char* Py_GetPythonHome()
Return the default "home", that is, the value set by a previous call to
- :cfunc:`Py_SetPythonHome`, or the value of the :envvar:`PYTHONHOME`
+ :c:func:`Py_SetPythonHome`, or the value of the :envvar:`PYTHONHOME`
environment variable if it is set.
@@ -352,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.
@@ -366,9 +383,9 @@ a file, so that other Python threads can run in the meantime.
single: PyThreadState
The Python interpreter keeps some thread-specific bookkeeping information
-inside a data structure called :ctype:`PyThreadState`. There's also one
-global variable pointing to the current :ctype:`PyThreadState`: it can
-be retrieved using :cfunc:`PyThreadState_Get`.
+inside a data structure called :c:type:`PyThreadState`. There's also one
+global variable pointing to the current :c:type:`PyThreadState`: it can
+be retrieved using :c:func:`PyThreadState_Get`.
Releasing the GIL from extension code
-------------------------------------
@@ -392,8 +409,8 @@ This is so common that a pair of macros exists to simplify it::
single: Py_BEGIN_ALLOW_THREADS
single: Py_END_ALLOW_THREADS
-The :cmacro:`Py_BEGIN_ALLOW_THREADS` macro opens a new block and declares a
-hidden local variable; the :cmacro:`Py_END_ALLOW_THREADS` macro closes the
+The :c:macro:`Py_BEGIN_ALLOW_THREADS` macro opens a new block and declares a
+hidden local variable; the :c:macro:`Py_END_ALLOW_THREADS` macro closes the
block. These two macros are still available when Python is compiled without
thread support (they simply have an empty expansion).
@@ -443,7 +460,7 @@ storing their thread state pointer, before you can start using the Python/C
API. When you are done, you should reset the thread state pointer, release
the GIL, and finally free the thread state data structure.
-The :cfunc:`PyGILState_Ensure` and :cfunc:`PyGILState_Release` functions do
+The :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release` functions do
all of the above automatically. The typical idiom for calling into Python
from a C thread is::
@@ -457,14 +474,14 @@ from a C thread is::
/* Release the thread. No Python API allowed beyond this point. */
PyGILState_Release(gstate);
-Note that the :cfunc:`PyGILState_\*` functions assume there is only one global
-interpreter (created automatically by :cfunc:`Py_Initialize`). Python
+Note that the :c:func:`PyGILState_\*` functions assume there is only one global
+interpreter (created automatically by :c:func:`Py_Initialize`). Python
supports the creation of additional interpreters (using
-:cfunc:`Py_NewInterpreter`), but mixing multiple interpreters and the
-:cfunc:`PyGILState_\*` API is unsupported.
+:c:func:`Py_NewInterpreter`), but mixing multiple interpreters and the
+:c:func:`PyGILState_\*` API is unsupported.
Another important thing to note about threads is their behaviour in the face
-of the C :cfunc:`fork` call. On most systems with :cfunc:`fork`, after a
+of the C :c:func:`fork` call. On most systems with :c:func:`fork`, after a
process forks only the thread that issued the fork will exist. That also
means any locks held by other threads will never be released. Python solves
this for :func:`os.fork` by acquiring the locks it uses internally before
@@ -472,12 +489,12 @@ the fork, and releasing them afterwards. In addition, it resets any
:ref:`lock-objects` in the child. When extending or embedding Python, there
is no way to inform Python of additional (non-Python) locks that need to be
acquired before or reset after a fork. OS facilities such as
-:cfunc:`pthread_atfork` would need to be used to accomplish the same thing.
-Additionally, when extending or embedding Python, calling :cfunc:`fork`
+:c:func:`pthread_atfork` would need to be used to accomplish the same thing.
+Additionally, when extending or embedding Python, calling :c:func:`fork`
directly rather than through :func:`os.fork` (and returning to or calling
into Python) may result in a deadlock by one of Python's internal locks
being held by a thread that is defunct after the fork.
-:cfunc:`PyOS_AfterFork` tries to reset the necessary locks, but is not
+:c:func:`PyOS_AfterFork` tries to reset the necessary locks, but is not
always able to.
@@ -487,7 +504,7 @@ High-level API
These are the most commonly used types and functions when writing C extension
code, or when embedding the Python interpreter:
-.. ctype:: PyInterpreterState
+.. c:type:: PyInterpreterState
This data structure represents the state shared by a number of cooperating
threads. Threads belonging to the same interpreter share their module
@@ -500,31 +517,30 @@ code, or when embedding the Python interpreter:
interpreter they belong.
-.. ctype:: PyThreadState
+.. c:type:: PyThreadState
This data structure represents the state of a single thread. The only public
- data member is :ctype:`PyInterpreterState \*`:attr:`interp`, which points to
+ data member is :c:type:`PyInterpreterState \*`:attr:`interp`, which points to
this thread's interpreter state.
-.. cfunction:: void PyEval_InitThreads()
+.. 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 :cfunc:`PyEval_ReleaseLock` or
- ``PyEval_ReleaseThread(tstate)``. It is not needed before calling
- :cfunc:`PyEval_SaveThread` or :cfunc:`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 :cfunc:`Py_Initialize`.
+ .. versionchanged:: 3.2
+ This function cannot be called before :c:func:`Py_Initialize()` anymore.
.. index:: module: _thread
@@ -537,7 +553,7 @@ code, or when embedding the Python interpreter:
when this function initializes the global interpreter lock, it also acquires
it. Before the Python :mod:`_thread` module creates a new thread, knowing
that either it has the lock or the lock hasn't been created yet, it calls
- :cfunc:`PyEval_InitThreads`. When this call returns, it is guaranteed that
+ :c:func:`PyEval_InitThreads`. When this call returns, it is guaranteed that
the lock has been created and that the calling thread has acquired it.
It is **not** safe to call this function when it is unknown which thread (if
@@ -546,15 +562,15 @@ code, or when embedding the Python interpreter:
This function is not available when thread support is disabled at compile time.
-.. cfunction:: int PyEval_ThreadsInitialized()
+.. c:function:: int PyEval_ThreadsInitialized()
- Returns a non-zero value if :cfunc:`PyEval_InitThreads` has been called. This
+ Returns a non-zero value if :c:func:`PyEval_InitThreads` has been called. This
function can be called without holding the GIL, and therefore can be used to
avoid calls to the locking API when running single-threaded. This function is
not available when thread support is disabled at compile time.
-.. cfunction:: PyThreadState* PyEval_SaveThread()
+.. c:function:: PyThreadState* PyEval_SaveThread()
Release the global interpreter lock (if it has been created and thread
support is enabled) and reset the thread state to *NULL*, returning the
@@ -563,7 +579,7 @@ code, or when embedding the Python interpreter:
when thread support is disabled at compile time.)
-.. cfunction:: void PyEval_RestoreThread(PyThreadState *tstate)
+.. c:function:: void PyEval_RestoreThread(PyThreadState *tstate)
Acquire the global interpreter lock (if it has been created and thread
support is enabled) and set the thread state to *tstate*, which must not be
@@ -572,23 +588,23 @@ code, or when embedding the Python interpreter:
when thread support is disabled at compile time.)
-.. cfunction:: PyThreadState* PyThreadState_Get()
+.. c:function:: PyThreadState* PyThreadState_Get()
Return the current thread state. The global interpreter lock must be held.
When the current thread state is *NULL*, this issues a fatal error (so that
the caller needn't check for *NULL*).
-.. cfunction:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate)
+.. c:function:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate)
Swap the current thread state with the thread state given by the argument
*tstate*, which may be *NULL*. The global interpreter lock must be held
and is not released.
-.. cfunction:: void PyEval_ReInitThreads()
+.. c:function:: void PyEval_ReInitThreads()
- This function is called from :cfunc:`PyOS_AfterFork` to ensure that newly
+ This function is called from :c:func:`PyOS_AfterFork` to ensure that newly
created child processes don't hold locks referring to threads which
are not running in the child process.
@@ -596,71 +612,71 @@ code, or when embedding the Python interpreter:
The following functions use thread-local storage, and are not compatible
with sub-interpreters:
-.. cfunction:: PyGILState_STATE PyGILState_Ensure()
+.. c:function:: PyGILState_STATE PyGILState_Ensure()
Ensure that the current thread is ready to call the Python C API regardless
of the current state of Python, or of the global interpreter lock. This may
be called as many times as desired by a thread as long as each call is
- matched with a call to :cfunc:`PyGILState_Release`. In general, other
- thread-related APIs may be used between :cfunc:`PyGILState_Ensure` and
- :cfunc:`PyGILState_Release` calls as long as the thread state is restored to
+ matched with a call to :c:func:`PyGILState_Release`. In general, other
+ thread-related APIs may be used between :c:func:`PyGILState_Ensure` and
+ :c:func:`PyGILState_Release` calls as long as the thread state is restored to
its previous state before the Release(). For example, normal usage of the
- :cmacro:`Py_BEGIN_ALLOW_THREADS` and :cmacro:`Py_END_ALLOW_THREADS` macros is
+ :c:macro:`Py_BEGIN_ALLOW_THREADS` and :c:macro:`Py_END_ALLOW_THREADS` macros is
acceptable.
The return value is an opaque "handle" to the thread state when
- :cfunc:`PyGILState_Ensure` was called, and must be passed to
- :cfunc:`PyGILState_Release` to ensure Python is left in the same state. Even
+ :c:func:`PyGILState_Ensure` was called, and must be passed to
+ :c:func:`PyGILState_Release` to ensure Python is left in the same state. Even
though recursive calls are allowed, these handles *cannot* be shared - each
- unique call to :cfunc:`PyGILState_Ensure` must save the handle for its call
- to :cfunc:`PyGILState_Release`.
+ unique call to :c:func:`PyGILState_Ensure` must save the handle for its call
+ to :c:func:`PyGILState_Release`.
When the function returns, the current thread will hold the GIL and be able
to call arbitrary Python code. Failure is a fatal error.
-.. cfunction:: void PyGILState_Release(PyGILState_STATE)
+.. c:function:: void PyGILState_Release(PyGILState_STATE)
Release any resources previously acquired. After this call, Python's state will
- be the same as it was prior to the corresponding :cfunc:`PyGILState_Ensure` call
+ be the same as it was prior to the corresponding :c:func:`PyGILState_Ensure` call
(but generally this state will be unknown to the caller, hence the use of the
GILState API).
- Every call to :cfunc:`PyGILState_Ensure` must be matched by a call to
- :cfunc:`PyGILState_Release` on the same thread.
+ Every call to :c:func:`PyGILState_Ensure` must be matched by a call to
+ :c:func:`PyGILState_Release` on the same thread.
The following macros are normally used without a trailing semicolon; look for
example usage in the Python source distribution.
-.. cmacro:: Py_BEGIN_ALLOW_THREADS
+.. c:macro:: Py_BEGIN_ALLOW_THREADS
This macro expands to ``{ PyThreadState *_save; _save = PyEval_SaveThread();``.
Note that it contains an opening brace; it must be matched with a following
- :cmacro:`Py_END_ALLOW_THREADS` macro. See above for further discussion of this
+ :c:macro:`Py_END_ALLOW_THREADS` macro. See above for further discussion of this
macro. It is a no-op when thread support is disabled at compile time.
-.. cmacro:: Py_END_ALLOW_THREADS
+.. c:macro:: Py_END_ALLOW_THREADS
This macro expands to ``PyEval_RestoreThread(_save); }``. Note that it contains
a closing brace; it must be matched with an earlier
- :cmacro:`Py_BEGIN_ALLOW_THREADS` macro. See above for further discussion of
+ :c:macro:`Py_BEGIN_ALLOW_THREADS` macro. See above for further discussion of
this macro. It is a no-op when thread support is disabled at compile time.
-.. cmacro:: Py_BLOCK_THREADS
+.. c:macro:: Py_BLOCK_THREADS
This macro expands to ``PyEval_RestoreThread(_save);``: it is equivalent to
- :cmacro:`Py_END_ALLOW_THREADS` without the closing brace. It is a no-op when
+ :c:macro:`Py_END_ALLOW_THREADS` without the closing brace. It is a no-op when
thread support is disabled at compile time.
-.. cmacro:: Py_UNBLOCK_THREADS
+.. c:macro:: Py_UNBLOCK_THREADS
This macro expands to ``_save = PyEval_SaveThread();``: it is equivalent to
- :cmacro:`Py_BEGIN_ALLOW_THREADS` without the opening brace and variable
+ :c:macro:`Py_BEGIN_ALLOW_THREADS` without the opening brace and variable
declaration. It is a no-op when thread support is disabled at compile time.
@@ -672,47 +688,47 @@ at compile time, and must be called only when the global interpreter lock has
been created.
-.. cfunction:: PyInterpreterState* PyInterpreterState_New()
+.. c:function:: PyInterpreterState* PyInterpreterState_New()
Create a new interpreter state object. The global interpreter lock need not
be held, but may be held if it is necessary to serialize calls to this
function.
-.. cfunction:: void PyInterpreterState_Clear(PyInterpreterState *interp)
+.. c:function:: void PyInterpreterState_Clear(PyInterpreterState *interp)
Reset all information in an interpreter state object. The global interpreter
lock must be held.
-.. cfunction:: void PyInterpreterState_Delete(PyInterpreterState *interp)
+.. c:function:: void PyInterpreterState_Delete(PyInterpreterState *interp)
Destroy an interpreter state object. The global interpreter lock need not be
held. The interpreter state must have been reset with a previous call to
- :cfunc:`PyInterpreterState_Clear`.
+ :c:func:`PyInterpreterState_Clear`.
-.. cfunction:: PyThreadState* PyThreadState_New(PyInterpreterState *interp)
+.. c:function:: PyThreadState* PyThreadState_New(PyInterpreterState *interp)
Create a new thread state object belonging to the given interpreter object.
The global interpreter lock need not be held, but may be held if it is
necessary to serialize calls to this function.
-.. cfunction:: void PyThreadState_Clear(PyThreadState *tstate)
+.. c:function:: void PyThreadState_Clear(PyThreadState *tstate)
Reset all information in a thread state object. The global interpreter lock
must be held.
-.. cfunction:: void PyThreadState_Delete(PyThreadState *tstate)
+.. c:function:: void PyThreadState_Delete(PyThreadState *tstate)
Destroy a thread state object. The global interpreter lock need not be held.
The thread state must have been reset with a previous call to
- :cfunc:`PyThreadState_Clear`.
+ :c:func:`PyThreadState_Clear`.
-.. cfunction:: PyObject* PyThreadState_GetDict()
+.. c:function:: PyObject* PyThreadState_GetDict()
Return a dictionary in which extensions can store thread-specific state
information. Each extension should use a unique key to use to store state in
@@ -721,7 +737,7 @@ been created.
the caller should assume no current thread state is available.
-.. cfunction:: int PyThreadState_SetAsyncExc(long id, PyObject *exc)
+.. c:function:: int PyThreadState_SetAsyncExc(long id, PyObject *exc)
Asynchronously raise an exception in a thread. The *id* argument is the thread
id of the target thread; *exc* is the exception object to be raised. This
@@ -732,18 +748,18 @@ been created.
exception (if any) for the thread is cleared. This raises no exceptions.
-.. cfunction:: void PyEval_AcquireThread(PyThreadState *tstate)
+.. c:function:: void PyEval_AcquireThread(PyThreadState *tstate)
Acquire the global interpreter lock and set the current thread state to
*tstate*, which should not be *NULL*. The lock must have been created earlier.
If this thread already has the lock, deadlock ensues.
- :cfunc:`PyEval_RestoreThread` is a higher-level function which is always
+ :c:func:`PyEval_RestoreThread` is a higher-level function which is always
available (even when thread support isn't enabled or when threads have
not been initialized).
-.. cfunction:: void PyEval_ReleaseThread(PyThreadState *tstate)
+.. c:function:: void PyEval_ReleaseThread(PyThreadState *tstate)
Reset the current thread state to *NULL* and release the global interpreter
lock. The lock must have been created earlier and must be held by the current
@@ -751,29 +767,29 @@ been created.
that it represents the current thread state --- if it isn't, a fatal error is
reported.
- :cfunc:`PyEval_SaveThread` is a higher-level function which is always
+ :c:func:`PyEval_SaveThread` is a higher-level function which is always
available (even when thread support isn't enabled or when threads have
not been initialized).
-.. cfunction:: void PyEval_AcquireLock()
+.. c:function:: void PyEval_AcquireLock()
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
- :cfunc:`PyEval_RestoreThread` or :cfunc:`PyEval_AcquireThread`
+ .. deprecated:: 3.2
+ This function does not update the current thread state. Please use
+ :c:func:`PyEval_RestoreThread` or :c:func:`PyEval_AcquireThread`
instead.
-.. cfunction:: void PyEval_ReleaseLock()
+.. c:function:: void PyEval_ReleaseLock()
Release the global interpreter lock. The lock must have been created earlier.
- .. warning::
- This function does not change the current thread state. Please use
- :cfunc:`PyEval_SaveThread` or :cfunc:`PyEval_ReleaseThread`
+ .. deprecated:: 3.2
+ This function does not update the current thread state. Please use
+ :c:func:`PyEval_SaveThread` or :c:func:`PyEval_ReleaseThread`
instead.
@@ -784,11 +800,11 @@ While in most uses, you will only embed a single Python interpreter, there
are cases where you need to create several independent interpreters in the
same process and perhaps even in the same thread. Sub-interpreters allow
you to do that. You can switch between sub-interpreters using the
-:cfunc:`PyThreadState_Swap` function. You can create and destroy them
+:c:func:`PyThreadState_Swap` function. You can create and destroy them
using the following functions:
-.. cfunction:: PyThreadState* Py_NewInterpreter()
+.. c:function:: PyThreadState* Py_NewInterpreter()
.. index::
module: builtins
@@ -830,13 +846,13 @@ using the following functions:
and filled with the contents of this copy; the extension's ``init`` function is
not called. Note that this is different from what happens when an extension is
imported after the interpreter has been completely re-initialized by calling
- :cfunc:`Py_Finalize` and :cfunc:`Py_Initialize`; in that case, the extension's
+ :c:func:`Py_Finalize` and :c:func:`Py_Initialize`; in that case, the extension's
``initmodule`` function *is* called again.
.. index:: single: close() (in module os)
-.. cfunction:: void Py_EndInterpreter(PyThreadState *tstate)
+.. c:function:: void Py_EndInterpreter(PyThreadState *tstate)
.. index:: single: Py_Finalize()
@@ -845,7 +861,7 @@ using the following functions:
states below. When the call returns, the current thread state is *NULL*. All
thread states associated with this interpreter are destroyed. (The global
interpreter lock must be held before calling this function and is still held
- when it returns.) :cfunc:`Py_Finalize` will destroy all sub-interpreters that
+ when it returns.) :c:func:`Py_Finalize` will destroy all sub-interpreters that
haven't been explicitly destroyed at that point.
@@ -866,11 +882,11 @@ instances or classes between sub-interpreters, since import operations executed
by such objects may affect the wrong (sub-)interpreter's dictionary of loaded
modules.
-Also note that combining this functionality with :cfunc:`PyGILState_\*` APIs
+Also note that combining this functionality with :c:func:`PyGILState_\*` APIs
is delicate, because these APIs assume a bijection between Python thread states
and OS-level threads, an assumption broken by the presence of sub-interpreters.
It is highly recommended that you don't switch sub-interpreters between a pair
-of matching :cfunc:`PyGILState_Ensure` and :cfunc:`PyGILState_Release` calls.
+of matching :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release` calls.
Furthermore, extensions (such as :mod:`ctypes`) using these APIs to allow calling
of Python code from non-Python created threads will probably be broken when using
sub-interpreters.
@@ -892,7 +908,7 @@ a worker thread and the actual call than made at the earliest convenience by the
main thread where it has possession of the global interpreter lock and can
perform any Python API calls.
-.. cfunction:: int Py_AddPendingCall(int (*func)(void *), void *arg)
+.. c:function:: int Py_AddPendingCall(int (*func)(void *), void *arg)
.. index:: single: Py_AddPendingCall()
@@ -937,10 +953,10 @@ events reported to the trace function are the same as had been reported to the
Python-level trace functions in previous versions.
-.. ctype:: int (*Py_tracefunc)(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg)
+.. c:type:: int (*Py_tracefunc)(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg)
- The type of the trace function registered using :cfunc:`PyEval_SetProfile` and
- :cfunc:`PyEval_SetTrace`. The first parameter is the object passed to the
+ The type of the trace function registered using :c:func:`PyEval_SetProfile` and
+ :c:func:`PyEval_SetTrace`. The first parameter is the object passed to the
registration function as *obj*, *frame* is the frame object to which the event
pertains, *what* is one of the constants :const:`PyTrace_CALL`,
:const:`PyTrace_EXCEPTION`, :const:`PyTrace_LINE`, :const:`PyTrace_RETURN`,
@@ -968,18 +984,18 @@ Python-level trace functions in previous versions.
+------------------------------+--------------------------------------+
-.. cvar:: int PyTrace_CALL
+.. c:var:: int PyTrace_CALL
- The value of the *what* parameter to a :ctype:`Py_tracefunc` function when a new
+ The value of the *what* parameter to a :c:type:`Py_tracefunc` function when a new
call to a function or method is being reported, or a new entry into a generator.
Note that the creation of the iterator for a generator function is not reported
as there is no control transfer to the Python bytecode in the corresponding
frame.
-.. cvar:: int PyTrace_EXCEPTION
+.. c:var:: int PyTrace_EXCEPTION
- The value of the *what* parameter to a :ctype:`Py_tracefunc` function when an
+ The value of the *what* parameter to a :c:type:`Py_tracefunc` function when an
exception has been raised. The callback function is called with this value for
*what* when after any bytecode is processed after which the exception becomes
set within the frame being executed. The effect of this is that as exception
@@ -988,37 +1004,37 @@ Python-level trace functions in previous versions.
these events; they are not needed by the profiler.
-.. cvar:: int PyTrace_LINE
+.. c:var:: int PyTrace_LINE
The value passed as the *what* parameter to a trace function (but not a
profiling function) when a line-number event is being reported.
-.. cvar:: int PyTrace_RETURN
+.. c:var:: int PyTrace_RETURN
- The value for the *what* parameter to :ctype:`Py_tracefunc` functions when a
+ The value for the *what* parameter to :c:type:`Py_tracefunc` functions when a
call is returning without propagating an exception.
-.. cvar:: int PyTrace_C_CALL
+.. c:var:: int PyTrace_C_CALL
- The value for the *what* parameter to :ctype:`Py_tracefunc` functions when a C
+ The value for the *what* parameter to :c:type:`Py_tracefunc` functions when a C
function is about to be called.
-.. cvar:: int PyTrace_C_EXCEPTION
+.. c:var:: int PyTrace_C_EXCEPTION
- The value for the *what* parameter to :ctype:`Py_tracefunc` functions when a C
+ The value for the *what* parameter to :c:type:`Py_tracefunc` functions when a C
function has raised an exception.
-.. cvar:: int PyTrace_C_RETURN
+.. c:var:: int PyTrace_C_RETURN
- The value for the *what* parameter to :ctype:`Py_tracefunc` functions when a C
+ The value for the *what* parameter to :c:type:`Py_tracefunc` functions when a C
function has returned.
-.. cfunction:: void PyEval_SetProfile(Py_tracefunc func, PyObject *obj)
+.. c:function:: void PyEval_SetProfile(Py_tracefunc func, PyObject *obj)
Set the profiler function to *func*. The *obj* parameter is passed to the
function as its first parameter, and may be any Python object, or *NULL*. If
@@ -1028,13 +1044,13 @@ Python-level trace functions in previous versions.
events.
-.. cfunction:: void PyEval_SetTrace(Py_tracefunc func, PyObject *obj)
+.. c:function:: void PyEval_SetTrace(Py_tracefunc func, PyObject *obj)
Set the tracing function to *func*. This is similar to
- :cfunc:`PyEval_SetProfile`, except the tracing function does receive line-number
+ :c:func:`PyEval_SetProfile`, except the tracing function does receive line-number
events.
-.. cfunction:: PyObject* PyEval_GetCallStats(PyObject *self)
+.. c:function:: PyObject* PyEval_GetCallStats(PyObject *self)
Return a tuple of function call counts. There are constants defined for the
positions within the tuple:
@@ -1086,25 +1102,25 @@ Advanced Debugger Support
These functions are only intended to be used by advanced debugging tools.
-.. cfunction:: PyInterpreterState* PyInterpreterState_Head()
+.. c:function:: PyInterpreterState* PyInterpreterState_Head()
Return the interpreter state object at the head of the list of all such objects.
-.. cfunction:: PyInterpreterState* PyInterpreterState_Next(PyInterpreterState *interp)
+.. c:function:: PyInterpreterState* PyInterpreterState_Next(PyInterpreterState *interp)
Return the next interpreter state object after *interp* from the list of all
such objects.
-.. cfunction:: PyThreadState * PyInterpreterState_ThreadHead(PyInterpreterState *interp)
+.. c:function:: PyThreadState * PyInterpreterState_ThreadHead(PyInterpreterState *interp)
- Return the a pointer to the first :ctype:`PyThreadState` object in the list of
+ Return the a pointer to the first :c:type:`PyThreadState` object in the list of
threads associated with the interpreter *interp*.
-.. cfunction:: PyThreadState* PyThreadState_Next(PyThreadState *tstate)
+.. 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 :ctype:`PyInterpreterState` object.
+ objects belonging to the same :c:type:`PyInterpreterState` object.
diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst
index c008b5c..83b98f9 100644
--- a/Doc/c-api/intro.rst
+++ b/Doc/c-api/intro.rst
@@ -88,15 +88,15 @@ Objects, Types and Reference Counts
.. index:: object: type
Most Python/C API functions have one or more arguments as well as a return value
-of type :ctype:`PyObject\*`. This type is a pointer to an opaque data type
+of type :c:type:`PyObject\*`. This type is a pointer to an opaque data type
representing an arbitrary Python object. Since all Python object types are
treated the same way by the Python language in most situations (e.g.,
assignments, scope rules, and argument passing), it is only fitting that they
should be represented by a single C type. Almost all Python objects live on the
heap: you never declare an automatic or static variable of type
-:ctype:`PyObject`, only pointer variables of type :ctype:`PyObject\*` can be
+:c:type:`PyObject`, only pointer variables of type :c:type:`PyObject\*` can be
declared. The sole exception are the type objects; since these must never be
-deallocated, they are typically static :ctype:`PyTypeObject` objects.
+deallocated, they are typically static :c:type:`PyTypeObject` objects.
All Python objects (even Python integers) have a :dfn:`type` and a
:dfn:`reference count`. An object's type determines what kind of object it is
@@ -127,8 +127,8 @@ that.")
single: Py_DECREF()
Reference counts are always manipulated explicitly. The normal way is to use
-the macro :cfunc:`Py_INCREF` to increment an object's reference count by one,
-and :cfunc:`Py_DECREF` to decrement it by one. The :cfunc:`Py_DECREF` macro
+the macro :c:func:`Py_INCREF` to increment an object's reference count by one,
+and :c:func:`Py_DECREF` to decrement it by one. The :c:func:`Py_DECREF` macro
is considerably more complex than the incref one, since it must check whether
the reference count becomes zero and then cause the object's deallocator to be
called. The deallocator is a function pointer contained in the object's type
@@ -159,13 +159,13 @@ for a while without incrementing its reference count. Some other operation might
conceivably remove the object from the list, decrementing its reference count
and possible deallocating it. The real danger is that innocent-looking
operations may invoke arbitrary Python code which could do this; there is a code
-path which allows control to flow back to the user from a :cfunc:`Py_DECREF`, so
+path which allows control to flow back to the user from a :c:func:`Py_DECREF`, so
almost any operation is potentially dangerous.
A safe approach is to always use the generic operations (functions whose name
begins with ``PyObject_``, ``PyNumber_``, ``PySequence_`` or ``PyMapping_``).
These operations always increment the reference count of the object they return.
-This leaves the caller with the responsibility to call :cfunc:`Py_DECREF` when
+This leaves the caller with the responsibility to call :c:func:`Py_DECREF` when
they are done with the result; this soon becomes second nature.
@@ -180,7 +180,7 @@ to objects (objects are not owned: they are always shared). "Owning a
reference" means being responsible for calling Py_DECREF on it when the
reference is no longer needed. Ownership can also be transferred, meaning that
the code that receives ownership of the reference then becomes responsible for
-eventually decref'ing it by calling :cfunc:`Py_DECREF` or :cfunc:`Py_XDECREF`
+eventually decref'ing it by calling :c:func:`Py_DECREF` or :c:func:`Py_XDECREF`
when it's no longer needed---or passing on this responsibility (usually to its
caller). When a function passes ownership of a reference on to its caller, the
caller is said to receive a *new* reference. When no ownership is transferred,
@@ -198,7 +198,7 @@ responsible for it any longer.
single: PyTuple_SetItem()
Few functions steal references; the two notable exceptions are
-:cfunc:`PyList_SetItem` and :cfunc:`PyTuple_SetItem`, which steal a reference
+:c:func:`PyList_SetItem` and :c:func:`PyTuple_SetItem`, which steal a reference
to the item (but not to the tuple or list into which the item is put!). These
functions were designed to steal a reference because of a common idiom for
populating a tuple or list with newly created objects; for example, the code to
@@ -212,21 +212,21 @@ error handling for the moment; a better way to code this is shown below)::
PyTuple_SetItem(t, 1, PyLong_FromLong(2L));
PyTuple_SetItem(t, 2, PyString_FromString("three"));
-Here, :cfunc:`PyLong_FromLong` returns a new reference which is immediately
-stolen by :cfunc:`PyTuple_SetItem`. When you want to keep using an object
-although the reference to it will be stolen, use :cfunc:`Py_INCREF` to grab
+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.
-Incidentally, :cfunc:`PyTuple_SetItem` is the *only* way to set tuple items;
-:cfunc:`PySequence_SetItem` and :cfunc:`PyObject_SetItem` refuse to do this
+Incidentally, :c:func:`PyTuple_SetItem` is the *only* way to set tuple items;
+:c:func:`PySequence_SetItem` and :c:func:`PyObject_SetItem` refuse to do this
since tuples are an immutable data type. You should only use
-:cfunc:`PyTuple_SetItem` for tuples that you are creating yourself.
+:c:func:`PyTuple_SetItem` for tuples that you are creating yourself.
-Equivalent code for populating a list can be written using :cfunc:`PyList_New`
-and :cfunc:`PyList_SetItem`.
+Equivalent code for populating a list can be written using :c:func:`PyList_New`
+and :c:func:`PyList_SetItem`.
However, in practice, you will rarely use these ways of creating and populating
-a tuple or list. There's a generic function, :cfunc:`Py_BuildValue`, that can
+a tuple or list. There's a generic function, :c:func:`Py_BuildValue`, that can
create most common objects from C values, directed by a :dfn:`format string`.
For example, the above two blocks of code could be replaced by the following
(which also takes care of the error checking)::
@@ -236,7 +236,7 @@ For example, the above two blocks of code could be replaced by the following
tuple = Py_BuildValue("(iis)", 1, 2, "three");
list = Py_BuildValue("[iis]", 1, 2, "three");
-It is much more common to use :cfunc:`PyObject_SetItem` and friends with items
+It is much more common to use :c:func:`PyObject_SetItem` and friends with items
whose references you are only borrowing, like arguments that were passed in to
the function you are writing. In that case, their behaviour regarding reference
counts is much saner, since you don't have to increment a reference count so you
@@ -270,15 +270,15 @@ for that reference, many functions that return a reference to an object give
you ownership of the reference. The reason is simple: in many cases, the
returned object is created on the fly, and the reference you get is the only
reference to the object. Therefore, the generic functions that return object
-references, like :cfunc:`PyObject_GetItem` and :cfunc:`PySequence_GetItem`,
+references, like :c:func:`PyObject_GetItem` and :c:func:`PySequence_GetItem`,
always return a new reference (the caller becomes the owner of the reference).
It is important to realize that whether you own a reference returned by a
function depends on which function you call only --- *the plumage* (the type of
the object passed as an argument to the function) *doesn't enter into it!*
-Thus, if you extract an item from a list using :cfunc:`PyList_GetItem`, you
+Thus, if you extract an item from a list using :c:func:`PyList_GetItem`, you
don't own the reference --- but if you obtain the same item from the same list
-using :cfunc:`PySequence_GetItem` (which happens to take exactly the same
+using :c:func:`PySequence_GetItem` (which happens to take exactly the same
arguments), you do own a reference to the returned object.
.. index::
@@ -286,8 +286,8 @@ arguments), you do own a reference to the returned object.
single: PySequence_GetItem()
Here is an example of how you could write a function that computes the sum of
-the items in a list of integers; once using :cfunc:`PyList_GetItem`, and once
-using :cfunc:`PySequence_GetItem`. ::
+the items in a list of integers; once using :c:func:`PyList_GetItem`, and once
+using :c:func:`PySequence_GetItem`. ::
long
sum_list(PyObject *list)
@@ -340,8 +340,8 @@ Types
-----
There are few other data types that play a significant role in the Python/C
-API; most are simple C types such as :ctype:`int`, :ctype:`long`,
-:ctype:`double` and :ctype:`char\*`. A few structure types are used to
+API; most are simple C types such as :c:type:`int`, :c:type:`long`,
+:c:type:`double` and :c:type:`char\*`. A few structure types are used to
describe static tables used to list the functions exported by a module or the
data attributes of a new object type, and another is used to describe the value
of a complex number. These will be discussed together with the functions that
@@ -370,7 +370,7 @@ indicator is either *NULL* or ``-1``, depending on the function's return type.
A few functions return a Boolean true/false result, with false indicating an
error. Very few functions return no explicit error indicator or have an
ambiguous return value, and require explicit testing for errors with
-:cfunc:`PyErr_Occurred`. These exceptions are always explicitly documented.
+:c:func:`PyErr_Occurred`. These exceptions are always explicitly documented.
.. index::
single: PyErr_SetString()
@@ -379,11 +379,11 @@ ambiguous return value, and require explicit testing for errors with
Exception state is maintained in per-thread storage (this is equivalent to
using global storage in an unthreaded application). A thread can be in one of
two states: an exception has occurred, or not. The function
-:cfunc:`PyErr_Occurred` can be used to check for this: it returns a borrowed
+:c:func:`PyErr_Occurred` can be used to check for this: it returns a borrowed
reference to the exception type object when an exception has occurred, and
*NULL* otherwise. There are a number of functions to set the exception state:
-:cfunc:`PyErr_SetString` is the most common (though not the most general)
-function to set the exception state, and :cfunc:`PyErr_Clear` clears the
+:c:func:`PyErr_SetString` is the most common (though not the most general)
+function to set the exception state, and :c:func:`PyErr_Clear` clears the
exception state.
The full exception state consists of three objects (all of which can be
@@ -419,7 +419,7 @@ and lose important information about the exact cause of the error.
.. index:: single: sum_sequence()
A simple example of detecting exceptions and passing them on is shown in the
-:cfunc:`sum_sequence` example above. It so happens that that example doesn't
+:c:func:`sum_sequence` example above. It so happens that that example doesn't
need to clean up any owned references when it detects an error. The following
example function shows some error cleanup. First, to remind you why you like
Python, we show the equivalent Python code::
@@ -486,10 +486,10 @@ Here is the corresponding C code, in all its glory::
single: Py_XDECREF()
This example represents an endorsed use of the ``goto`` statement in C!
-It illustrates the use of :cfunc:`PyErr_ExceptionMatches` and
-:cfunc:`PyErr_Clear` to handle specific exceptions, and the use of
-:cfunc:`Py_XDECREF` to dispose of owned references that may be *NULL* (note the
-``'X'`` in the name; :cfunc:`Py_DECREF` would crash when confronted with a
+It illustrates the use of :c:func:`PyErr_ExceptionMatches` and
+:c:func:`PyErr_Clear` to handle specific exceptions, and the use of
+:c:func:`Py_XDECREF` to dispose of owned references that may be *NULL* (note the
+``'X'`` in the name; :c:func:`Py_DECREF` would crash when confronted with a
*NULL* reference). It is important that the variables used to hold owned
references are initialized to *NULL* for this to work; likewise, the proposed
return value is initialized to ``-1`` (failure) and only set to success after
@@ -514,20 +514,20 @@ interpreter can only be used after the interpreter has been initialized.
triple: module; search; path
single: path (in module sys)
-The basic initialization function is :cfunc:`Py_Initialize`. This initializes
+The basic initialization function is :c:func:`Py_Initialize`. This initializes
the table of loaded modules, and creates the fundamental modules
:mod:`builtins`, :mod:`__main__`, and :mod:`sys`. It also
initializes the module search path (``sys.path``).
-.. index:: single: PySys_SetArgv()
+.. index:: single: PySys_SetArgvEx()
-:cfunc:`Py_Initialize` does not set the "script argument list" (``sys.argv``).
-If this variable is needed by Python code that will be executed later, it must
-be set explicitly with a call to ``PySys_SetArgv(argc, argv)`` subsequent to
-the call to :cfunc:`Py_Initialize`.
+:c:func:`Py_Initialize` does not set the "script argument list" (``sys.argv``).
+If this variable is needed by Python code that will be executed later, it must
+be set explicitly with a call to ``PySys_SetArgvEx(argc, argv, updatepath)``
+after the call to :c:func:`Py_Initialize`.
On most systems (in particular, on Unix and Windows, although the details are
-slightly different), :cfunc:`Py_Initialize` calculates the module search path
+slightly different), :c:func:`Py_Initialize` calculates the module search path
based upon its best guess for the location of the standard Python interpreter
executable, assuming that the Python library is found in a fixed location
relative to the Python interpreter executable. In particular, it looks for a
@@ -551,22 +551,22 @@ front of the standard path by setting :envvar:`PYTHONPATH`.
single: Py_GetProgramFullPath()
The embedding application can steer the search by calling
-``Py_SetProgramName(file)`` *before* calling :cfunc:`Py_Initialize`. Note that
+``Py_SetProgramName(file)`` *before* calling :c:func:`Py_Initialize`. Note that
:envvar:`PYTHONHOME` still overrides this and :envvar:`PYTHONPATH` is still
inserted in front of the standard path. An application that requires total
-control has to provide its own implementation of :cfunc:`Py_GetPath`,
-:cfunc:`Py_GetPrefix`, :cfunc:`Py_GetExecPrefix`, and
-:cfunc:`Py_GetProgramFullPath` (all defined in :file:`Modules/getpath.c`).
+control has to provide its own implementation of :c:func:`Py_GetPath`,
+:c:func:`Py_GetPrefix`, :c:func:`Py_GetExecPrefix`, and
+:c:func:`Py_GetProgramFullPath` (all defined in :file:`Modules/getpath.c`).
.. index:: single: Py_IsInitialized()
Sometimes, it is desirable to "uninitialize" Python. For instance, the
application may want to start over (make another call to
-:cfunc:`Py_Initialize`) or the application is simply done with its use of
+:c:func:`Py_Initialize`) or the application is simply done with its use of
Python and wants to free memory allocated by Python. This can be accomplished
-by calling :cfunc:`Py_Finalize`. The function :cfunc:`Py_IsInitialized` returns
+by calling :c:func:`Py_Finalize`. The function :c:func:`Py_IsInitialized` returns
true if Python is currently in the initialized state. More information about
-these functions is given in a later chapter. Notice that :cfunc:`Py_Finalize`
+these functions is given in a later chapter. Notice that :c:func:`Py_Finalize`
does *not* free all memory allocated by the Python interpreter, e.g. memory
allocated by extension modules currently cannot be released.
@@ -586,11 +586,11 @@ available that support tracing of reference counts, debugging the memory
allocator, or low-level profiling of the main interpreter loop. Only the most
frequently-used builds will be described in the remainder of this section.
-Compiling the interpreter with the :cmacro:`Py_DEBUG` macro defined produces
-what is generally meant by "a debug build" of Python. :cmacro:`Py_DEBUG` is
+Compiling the interpreter with the :c:macro:`Py_DEBUG` macro defined produces
+what is generally meant by "a debug build" of Python. :c:macro:`Py_DEBUG` is
enabled in the Unix build by adding :option:`--with-pydebug` to the
:file:`configure` command. It is also implied by the presence of the
-not-Python-specific :cmacro:`_DEBUG` macro. When :cmacro:`Py_DEBUG` is enabled
+not-Python-specific :c:macro:`_DEBUG` macro. When :c:macro:`Py_DEBUG` is enabled
in the Unix build, compiler optimization is disabled.
In addition to the reference count debugging described below, the following
@@ -619,11 +619,11 @@ extra checks are performed:
There may be additional checks not mentioned here.
-Defining :cmacro:`Py_TRACE_REFS` enables reference tracing. When defined, a
+Defining :c:macro:`Py_TRACE_REFS` enables reference tracing. When defined, a
circular doubly linked list of active objects is maintained by adding two extra
-fields to every :ctype:`PyObject`. Total allocations are tracked as well. Upon
+fields to every :c:type:`PyObject`. Total allocations are tracked as well. Upon
exit, all existing references are printed. (In interactive mode this happens
-after every statement run by the interpreter.) Implied by :cmacro:`Py_DEBUG`.
+after every statement run by the interpreter.) Implied by :c:macro:`Py_DEBUG`.
Please refer to :file:`Misc/SpecialBuilds.txt` in the Python source distribution
for more detailed information.
diff --git a/Doc/c-api/iter.rst b/Doc/c-api/iter.rst
index ba7e9e3..3f0f554 100644
--- a/Doc/c-api/iter.rst
+++ b/Doc/c-api/iter.rst
@@ -7,12 +7,12 @@ Iterator Protocol
There are only a couple of functions specifically for working with iterators.
-.. cfunction:: int PyIter_Check(PyObject *o)
+.. c:function:: int PyIter_Check(PyObject *o)
Return true if the object *o* supports the iterator protocol.
-.. cfunction:: PyObject* PyIter_Next(PyObject *o)
+.. c:function:: PyObject* PyIter_Next(PyObject *o)
Return the next value from the iteration *o*. If the object is an iterator,
this retrieves the next value from the iteration, and returns *NULL* with no
diff --git a/Doc/c-api/iterator.rst b/Doc/c-api/iterator.rst
index 8665080..82cb4eb 100644
--- a/Doc/c-api/iterator.rst
+++ b/Doc/c-api/iterator.rst
@@ -12,37 +12,37 @@ the callable for each item in the sequence, and ending the iteration when the
sentinel value is returned.
-.. cvar:: PyTypeObject PySeqIter_Type
+.. c:var:: PyTypeObject PySeqIter_Type
- Type object for iterator objects returned by :cfunc:`PySeqIter_New` and the
+ Type object for iterator objects returned by :c:func:`PySeqIter_New` and the
one-argument form of the :func:`iter` built-in function for built-in sequence
types.
-.. cfunction:: int PySeqIter_Check(op)
+.. c:function:: int PySeqIter_Check(op)
- Return true if the type of *op* is :cdata:`PySeqIter_Type`.
+ Return true if the type of *op* is :c:data:`PySeqIter_Type`.
-.. cfunction:: PyObject* PySeqIter_New(PyObject *seq)
+.. c:function:: PyObject* PySeqIter_New(PyObject *seq)
Return an iterator that works with a general sequence object, *seq*. The
iteration ends when the sequence raises :exc:`IndexError` for the subscripting
operation.
-.. cvar:: PyTypeObject PyCallIter_Type
+.. c:var:: PyTypeObject PyCallIter_Type
- Type object for iterator objects returned by :cfunc:`PyCallIter_New` and the
+ Type object for iterator objects returned by :c:func:`PyCallIter_New` and the
two-argument form of the :func:`iter` built-in function.
-.. cfunction:: int PyCallIter_Check(op)
+.. c:function:: int PyCallIter_Check(op)
- Return true if the type of *op* is :cdata:`PyCallIter_Type`.
+ Return true if the type of *op* is :c:data:`PyCallIter_Type`.
-.. cfunction:: PyObject* PyCallIter_New(PyObject *callable, PyObject *sentinel)
+.. c:function:: PyObject* PyCallIter_New(PyObject *callable, PyObject *sentinel)
Return a new iterator. The first parameter, *callable*, can be any Python
callable object that can be called with no parameters; each call to it should
diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst
index 4e3d500..feb9015 100644
--- a/Doc/c-api/list.rst
+++ b/Doc/c-api/list.rst
@@ -8,30 +8,30 @@ List Objects
.. index:: object: list
-.. ctype:: PyListObject
+.. c:type:: PyListObject
- This subtype of :ctype:`PyObject` represents a Python list object.
+ This subtype of :c:type:`PyObject` represents a Python list object.
-.. cvar:: PyTypeObject PyList_Type
+.. c:var:: PyTypeObject PyList_Type
- This instance of :ctype:`PyTypeObject` represents the Python list type.
+ This instance of :c:type:`PyTypeObject` represents the Python list type.
This is the same object as :class:`list` in the Python layer.
-.. cfunction:: int PyList_Check(PyObject *p)
+.. c:function:: int PyList_Check(PyObject *p)
Return true if *p* is a list object or an instance of a subtype of the list
type.
-.. cfunction:: int PyList_CheckExact(PyObject *p)
+.. 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.
-.. cfunction:: PyObject* PyList_New(Py_ssize_t len)
+.. c:function:: PyObject* PyList_New(Py_ssize_t len)
Return a new list of length *len* on success, or *NULL* on failure.
@@ -39,11 +39,11 @@ List Objects
If *len* is greater than zero, the returned list object's items are
set to ``NULL``. Thus you cannot use abstract API functions such as
- :cfunc:`PySequence_SetItem` or expose the object to Python code before
- setting all items to a real object with :cfunc:`PyList_SetItem`.
+ :c:func:`PySequence_SetItem` or expose the object to Python code before
+ setting all items to a real object with :c:func:`PyList_SetItem`.
-.. cfunction:: Py_ssize_t PyList_Size(PyObject *list)
+.. c:function:: Py_ssize_t PyList_Size(PyObject *list)
.. index:: builtin: len
@@ -51,12 +51,12 @@ List Objects
``len(list)`` on a list object.
-.. cfunction:: Py_ssize_t PyList_GET_SIZE(PyObject *list)
+.. c:function:: Py_ssize_t PyList_GET_SIZE(PyObject *list)
- Macro form of :cfunc:`PyList_Size` without error checking.
+ Macro form of :c:func:`PyList_Size` without error checking.
-.. cfunction:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index)
+.. c:function:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index)
Return the object at position *index* in the list pointed to by *list*. The
position must be positive, indexing from the end of the list is not
@@ -64,12 +64,12 @@ List Objects
:exc:`IndexError` exception.
-.. cfunction:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i)
+.. c:function:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i)
- Macro form of :cfunc:`PyList_GetItem` without error checking.
+ Macro form of :c:func:`PyList_GetItem` without error checking.
-.. cfunction:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item)
+.. c:function:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item)
Set the item at index *index* in list to *item*. Return ``0`` on success
or ``-1`` on failure.
@@ -80,34 +80,34 @@ List Objects
an item already in the list at the affected position.
-.. cfunction:: void PyList_SET_ITEM(PyObject *list, Py_ssize_t i, PyObject *o)
+.. c:function:: void PyList_SET_ITEM(PyObject *list, Py_ssize_t i, PyObject *o)
- Macro form of :cfunc:`PyList_SetItem` without error checking. This is
+ Macro form of :c:func:`PyList_SetItem` without error checking. This is
normally only used to fill in new lists where there is no previous content.
.. note::
This macro "steals" a reference to *item*, and, unlike
- :cfunc:`PyList_SetItem`, does *not* discard a reference to any item that
+ :c:func:`PyList_SetItem`, does *not* discard a reference to any item that
is being replaced; any reference in *list* at position *i* will be
leaked.
-.. cfunction:: int PyList_Insert(PyObject *list, Py_ssize_t index, PyObject *item)
+.. c:function:: int PyList_Insert(PyObject *list, Py_ssize_t index, PyObject *item)
Insert the item *item* into list *list* in front of index *index*. Return
``0`` if successful; return ``-1`` and set an exception if unsuccessful.
Analogous to ``list.insert(index, item)``.
-.. cfunction:: int PyList_Append(PyObject *list, PyObject *item)
+.. c:function:: int PyList_Append(PyObject *list, PyObject *item)
Append the object *item* at the end of list *list*. Return ``0`` if
successful; return ``-1`` and set an exception if unsuccessful. Analogous
to ``list.append(item)``.
-.. cfunction:: PyObject* PyList_GetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high)
+.. c:function:: PyObject* PyList_GetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high)
Return a list of the objects in *list* containing the objects *between* *low*
and *high*. Return *NULL* and set an exception if unsuccessful. Analogous
@@ -115,7 +115,7 @@ List Objects
supported.
-.. cfunction:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist)
+.. c:function:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist)
Set the slice of *list* between *low* and *high* to the contents of
*itemlist*. Analogous to ``list[low:high] = itemlist``. The *itemlist* may
@@ -124,19 +124,19 @@ List Objects
slicing from Python, are not supported.
-.. cfunction:: int PyList_Sort(PyObject *list)
+.. c:function:: int PyList_Sort(PyObject *list)
Sort the items of *list* in place. Return ``0`` on success, ``-1`` on
failure. This is equivalent to ``list.sort()``.
-.. cfunction:: int PyList_Reverse(PyObject *list)
+.. c:function:: int PyList_Reverse(PyObject *list)
Reverse the items of *list* in place. Return ``0`` on success, ``-1`` on
failure. This is the equivalent of ``list.reverse()``.
-.. cfunction:: PyObject* PyList_AsTuple(PyObject *list)
+.. c:function:: PyObject* PyList_AsTuple(PyObject *list)
.. index:: builtin: tuple
diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst
index 9f8e3c5..b2295e0 100644
--- a/Doc/c-api/long.rst
+++ b/Doc/c-api/long.rst
@@ -10,32 +10,32 @@ Integer Objects
All integers are implemented as "long" integer objects of arbitrary size.
-.. ctype:: PyLongObject
+.. c:type:: PyLongObject
- This subtype of :ctype:`PyObject` represents a Python integer object.
+ This subtype of :c:type:`PyObject` represents a Python integer object.
-.. cvar:: PyTypeObject PyLong_Type
+.. c:var:: PyTypeObject PyLong_Type
- This instance of :ctype:`PyTypeObject` represents the Python integer type.
+ This instance of :c:type:`PyTypeObject` represents the Python integer type.
This is the same object as :class:`int` in the Python layer.
-.. cfunction:: int PyLong_Check(PyObject *p)
+.. c:function:: int PyLong_Check(PyObject *p)
- Return true if its argument is a :ctype:`PyLongObject` or a subtype of
- :ctype:`PyLongObject`.
+ Return true if its argument is a :c:type:`PyLongObject` or a subtype of
+ :c:type:`PyLongObject`.
-.. cfunction:: int PyLong_CheckExact(PyObject *p)
+.. c:function:: int PyLong_CheckExact(PyObject *p)
- Return true if its argument is a :ctype:`PyLongObject`, but not a subtype of
- :ctype:`PyLongObject`.
+ Return true if its argument is a :c:type:`PyLongObject`, but not a subtype of
+ :c:type:`PyLongObject`.
-.. cfunction:: PyObject* PyLong_FromLong(long v)
+.. c:function:: PyObject* PyLong_FromLong(long v)
- Return a new :ctype:`PyLongObject` object from *v*, or *NULL* on failure.
+ 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
@@ -44,47 +44,47 @@ All integers are implemented as "long" integer objects of arbitrary size.
undefined. :-)
-.. cfunction:: PyObject* PyLong_FromUnsignedLong(unsigned long v)
+.. c:function:: PyObject* PyLong_FromUnsignedLong(unsigned long v)
- Return a new :ctype:`PyLongObject` object from a C :ctype:`unsigned long`, or
+ Return a new :c:type:`PyLongObject` object from a C :c:type:`unsigned long`, or
*NULL* on failure.
-.. cfunction:: PyObject* PyLong_FromSsize_t(Py_ssize_t v)
+.. c:function:: PyObject* PyLong_FromSsize_t(Py_ssize_t v)
- Return a new :ctype:`PyLongObject` object from a C :ctype:`Py_ssize_t`, or
+ Return a new :c:type:`PyLongObject` object from a C :c:type:`Py_ssize_t`, or
*NULL* on failure.
-.. cfunction:: PyObject* PyLong_FromSize_t(size_t v)
+.. c:function:: PyObject* PyLong_FromSize_t(size_t v)
- Return a new :ctype:`PyLongObject` object from a C :ctype:`size_t`, or
+ Return a new :c:type:`PyLongObject` object from a C :c:type:`size_t`, or
*NULL* on failure.
-.. cfunction:: PyObject* PyLong_FromLongLong(PY_LONG_LONG v)
+.. c:function:: PyObject* PyLong_FromLongLong(PY_LONG_LONG v)
- Return a new :ctype:`PyLongObject` object from a C :ctype:`long long`, or *NULL*
+ Return a new :c:type:`PyLongObject` object from a C :c:type:`long long`, or *NULL*
on failure.
-.. cfunction:: PyObject* PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG v)
+.. c:function:: PyObject* PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG v)
- Return a new :ctype:`PyLongObject` object from a C :ctype:`unsigned long long`,
+ Return a new :c:type:`PyLongObject` object from a C :c:type:`unsigned long long`,
or *NULL* on failure.
-.. cfunction:: PyObject* PyLong_FromDouble(double v)
+.. c:function:: PyObject* PyLong_FromDouble(double v)
- Return a new :ctype:`PyLongObject` object from the integer part of *v*, or
+ Return a new :c:type:`PyLongObject` object from the integer part of *v*, or
*NULL* on failure.
-.. cfunction:: PyObject* PyLong_FromString(char *str, char **pend, int base)
+.. c:function:: PyObject* PyLong_FromString(char *str, char **pend, int base)
- Return a new :ctype:`PyLongObject` based on the string value in *str*, which
+ 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
+ *\*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 ``'0o'`` or
@@ -94,85 +94,101 @@ All integers are implemented as "long" integer objects of arbitrary size.
ignored. If there are no digits, :exc:`ValueError` will be raised.
-.. cfunction:: PyObject* PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
+.. c:function:: PyObject* PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
Convert a sequence of Unicode digits to a Python integer value. The Unicode
- string is first encoded to a byte string using :cfunc:`PyUnicode_EncodeDecimal`
- and then converted using :cfunc:`PyLong_FromString`.
+ string is first encoded to a byte string using :c:func:`PyUnicode_EncodeDecimal`
+ and then converted using :c:func:`PyLong_FromString`.
-.. cfunction:: PyObject* PyLong_FromVoidPtr(void *p)
+.. c:function:: PyObject* PyLong_FromVoidPtr(void *p)
Create a Python integer from the pointer *p*. The pointer value can be
- retrieved from the resulting value using :cfunc:`PyLong_AsVoidPtr`.
+ retrieved from the resulting value using :c:func:`PyLong_AsVoidPtr`.
.. XXX alias PyLong_AS_LONG (for now)
-.. cfunction:: long PyLong_AsLong(PyObject *pylong)
+.. c:function:: long PyLong_AsLong(PyObject *pylong)
.. index::
single: LONG_MAX
single: OverflowError (built-in exception)
- Return a C :ctype:`long` representation of the contents of *pylong*. If
+ Return a C :c:type:`long` representation of the contents of *pylong*. If
*pylong* is greater than :const:`LONG_MAX`, raise an :exc:`OverflowError`,
and return -1. Convert non-long objects automatically to long first,
and return -1 if that raises exceptions.
-.. cfunction:: long PyLong_AsLongAndOverflow(PyObject *pylong, int* overflow)
+.. c:function:: long PyLong_AsLongAndOverflow(PyObject *pylong, int *overflow)
- Return a C :ctype:`long` representation of the contents of *pylong*. If
- *pylong* is greater than :const:`LONG_MAX`, return -1 and
- set `*overflow` to 1 (for overflow) or -1 (for underflow).
- If an exception is set because of type errors, also return -1.
+ 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``.
-.. cfunction:: Py_ssize_t PyLong_AsSsize_t(PyObject *pylong)
+.. 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:: 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 :ctype:`Py_ssize_t` representation of the contents of *pylong*.
+ 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.
-.. cfunction:: unsigned long PyLong_AsUnsignedLong(PyObject *pylong)
+.. c:function:: unsigned long PyLong_AsUnsignedLong(PyObject *pylong)
.. index::
single: ULONG_MAX
single: OverflowError (built-in exception)
- Return a C :ctype:`unsigned long` representation of the contents of *pylong*.
+ 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.
-.. cfunction:: size_t PyLong_AsSize_t(PyObject *pylong)
+.. c:function:: size_t PyLong_AsSize_t(PyObject *pylong)
- Return a :ctype:`size_t` representation of the contents of *pylong*. If
- *pylong* is greater than the maximum value for a :ctype:`size_t`, an
+ Return a :c:type:`size_t` representation of the contents of *pylong*. If
+ *pylong* is greater than the maximum value for a :c:type:`size_t`, an
:exc:`OverflowError` is raised.
-.. cfunction:: PY_LONG_LONG PyLong_AsLongLong(PyObject *pylong)
+.. c:function:: PY_LONG_LONG PyLong_AsLongLong(PyObject *pylong)
.. index::
single: OverflowError (built-in exception)
- Return a C :ctype:`long long` from a Python integer. If *pylong*
- cannot be represented as a :ctype:`long long`, an
+ Return a C :c:type:`long long` from a Python integer. If *pylong*
+ cannot be represented as a :c:type:`long long`, an
:exc:`OverflowError` is raised and ``-1`` is returned.
-.. cfunction:: unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong(PyObject *pylong)
+.. c:function:: unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong(PyObject *pylong)
.. index::
single: OverflowError (built-in exception)
- Return a C :ctype:`unsigned long long` from a Python integer. If
- *pylong* cannot be represented as an :ctype:`unsigned long long`,
+ Return a C :c:type:`unsigned long long` from a Python 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.
@@ -180,28 +196,28 @@ All integers are implemented as "long" integer objects of arbitrary size.
A negative *pylong* now raises :exc:`OverflowError`, not :exc:`TypeError`.
-.. cfunction:: unsigned long PyLong_AsUnsignedLongMask(PyObject *io)
+.. c:function:: unsigned long PyLong_AsUnsignedLongMask(PyObject *io)
- Return a C :ctype:`unsigned long` from a Python integer, without checking for
+ Return a C :c:type:`unsigned long` from a Python integer, without checking for
overflow.
-.. cfunction:: unsigned PY_LONG_LONG PyLong_AsUnsignedLongLongMask(PyObject *io)
+.. c:function:: unsigned PY_LONG_LONG PyLong_AsUnsignedLongLongMask(PyObject *io)
- Return a C :ctype:`unsigned long long` from a Python integer, without
+ Return a C :c:type:`unsigned long long` from a Python integer, without
checking for overflow.
-.. cfunction:: double PyLong_AsDouble(PyObject *pylong)
+.. c:function:: double PyLong_AsDouble(PyObject *pylong)
- Return a C :ctype:`double` representation of the contents of *pylong*. If
- *pylong* cannot be approximately represented as a :ctype:`double`, an
+ 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.
-.. cfunction:: void* PyLong_AsVoidPtr(PyObject *pylong)
+.. c:function:: void* PyLong_AsVoidPtr(PyObject *pylong)
- Convert a Python integer *pylong* to a C :ctype:`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 :ctype:`void` pointer for values created
- with :cfunc:`PyLong_FromVoidPtr`.
+ is only assured to produce a usable :c:type:`void` pointer for values created
+ with :c:func:`PyLong_FromVoidPtr`.
diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst
index 5b2de14..0ef2961 100644
--- a/Doc/c-api/mapping.rst
+++ b/Doc/c-api/mapping.rst
@@ -6,13 +6,13 @@ Mapping Protocol
================
-.. cfunction:: int PyMapping_Check(PyObject *o)
+.. c:function:: int PyMapping_Check(PyObject *o)
Return ``1`` if the object provides mapping protocol, and ``0`` otherwise. This
function always succeeds.
-.. cfunction:: Py_ssize_t PyMapping_Size(PyObject *o)
+.. c:function:: Py_ssize_t PyMapping_Size(PyObject *o)
Py_ssize_t PyMapping_Length(PyObject *o)
.. index:: builtin: len
@@ -22,58 +22,58 @@ Mapping Protocol
expression ``len(o)``.
-.. cfunction:: int PyMapping_DelItemString(PyObject *o, char *key)
+.. c:function:: int PyMapping_DelItemString(PyObject *o, char *key)
Remove the mapping for object *key* from the object *o*. Return ``-1`` on
failure. This is equivalent to the Python statement ``del o[key]``.
-.. cfunction:: int PyMapping_DelItem(PyObject *o, PyObject *key)
+.. c:function:: int PyMapping_DelItem(PyObject *o, PyObject *key)
Remove the mapping for object *key* from the object *o*. Return ``-1`` on
failure. This is equivalent to the Python statement ``del o[key]``.
-.. cfunction:: int PyMapping_HasKeyString(PyObject *o, char *key)
+.. 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 the Python expression ``key in o``.
This function always succeeds.
-.. cfunction:: int PyMapping_HasKey(PyObject *o, PyObject *key)
+.. 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 the Python expression ``key in o``. This function always
succeeds.
-.. cfunction:: PyObject* PyMapping_Keys(PyObject *o)
+.. 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 ``list(o.keys())``.
-.. cfunction:: PyObject* PyMapping_Values(PyObject *o)
+.. 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 ``list(o.values())``.
-.. cfunction:: PyObject* PyMapping_Items(PyObject *o)
+.. 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 ``list(o.items())``.
-.. cfunction:: PyObject* PyMapping_GetItemString(PyObject *o, char *key)
+.. c:function:: PyObject* PyMapping_GetItemString(PyObject *o, char *key)
Return element of *o* corresponding to the object *key* or *NULL* on failure.
This is the equivalent of the Python expression ``o[key]``.
-.. cfunction:: int PyMapping_SetItemString(PyObject *o, char *key, PyObject *v)
+.. c:function:: int PyMapping_SetItemString(PyObject *o, char *key, PyObject *v)
Map the object *key* to the value *v* in object *o*. Returns ``-1`` on failure.
This is the equivalent of the Python statement ``o[key] = v``.
diff --git a/Doc/c-api/marshal.rst b/Doc/c-api/marshal.rst
index 04b0b88..da402a8 100644
--- a/Doc/c-api/marshal.rst
+++ b/Doc/c-api/marshal.rst
@@ -19,20 +19,20 @@ unmarshalling. Version 2 uses a binary format for floating point numbers.
*Py_MARSHAL_VERSION* indicates the current file format (currently 2).
-.. cfunction:: void PyMarshal_WriteLongToFile(long value, FILE *file, int version)
+.. c:function:: void PyMarshal_WriteLongToFile(long value, FILE *file, int version)
- Marshal a :ctype:`long` integer, *value*, to *file*. This will only write
+ 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 :ctype:`long` type. *version* indicates the file format.
+ native :c:type:`long` type. *version* indicates the file format.
-.. cfunction:: void PyMarshal_WriteObjectToFile(PyObject *value, FILE *file, int version)
+.. c:function:: void PyMarshal_WriteObjectToFile(PyObject *value, FILE *file, int version)
Marshal a Python object, *value*, to *file*.
*version* indicates the file format.
-.. cfunction:: PyObject* PyMarshal_WriteObjectToString(PyObject *value, int version)
+.. c:function:: PyObject* PyMarshal_WriteObjectToString(PyObject *value, int version)
Return a string object containing the marshalled representation of *value*.
*version* indicates the file format.
@@ -47,31 +47,31 @@ no error. What's the right way to tell? Should only non-negative values be
written using these routines?
-.. cfunction:: long PyMarshal_ReadLongFromFile(FILE *file)
+.. c:function:: long PyMarshal_ReadLongFromFile(FILE *file)
- Return a C :ctype:`long` from the data stream in a :ctype:`FILE\*` opened
+ Return a C :c:type:`long` from the data stream in a :c:type:`FILE\*` opened
for reading. Only a 32-bit value can be read in using this function,
- regardless of the native size of :ctype:`long`.
+ regardless of the native size of :c:type:`long`.
-.. cfunction:: int PyMarshal_ReadShortFromFile(FILE *file)
+.. c:function:: int PyMarshal_ReadShortFromFile(FILE *file)
- Return a C :ctype:`short` from the data stream in a :ctype:`FILE\*` opened
+ Return a C :c:type:`short` from the data stream in a :c:type:`FILE\*` opened
for reading. Only a 16-bit value can be read in using this function,
- regardless of the native size of :ctype:`short`.
+ regardless of the native size of :c:type:`short`.
-.. cfunction:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file)
+.. c:function:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file)
- Return a Python object from the data stream in a :ctype:`FILE\*` opened for
+ Return a Python object from the data stream in a :c:type:`FILE\*` opened for
reading. On error, sets the appropriate exception (:exc:`EOFError` or
:exc:`TypeError`) and returns *NULL*.
-.. cfunction:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file)
+.. c:function:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file)
- Return a Python object from the data stream in a :ctype:`FILE\*` opened for
- reading. Unlike :cfunc:`PyMarshal_ReadObjectFromFile`, this function
+ Return a Python object from the data stream in a :c:type:`FILE\*` opened for
+ reading. Unlike :c:func:`PyMarshal_ReadObjectFromFile`, this function
assumes that no further objects will be read from the file, allowing it to
aggressively load file data into memory so that the de-serialization can
operate from data in memory rather than reading a byte at a time from the
@@ -80,7 +80,7 @@ written using these routines?
(:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*.
-.. cfunction:: PyObject* PyMarshal_ReadObjectFromString(char *string, Py_ssize_t len)
+.. c:function:: PyObject* PyMarshal_ReadObjectFromString(char *string, Py_ssize_t len)
Return a Python object from the data stream in a character buffer
containing *len* bytes pointed to by *string*. On error, sets the
diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst
index 81d7cd9..b80b3d5 100644
--- a/Doc/c-api/memory.rst
+++ b/Doc/c-api/memory.rst
@@ -47,8 +47,8 @@ API functions listed in this document.
single: free()
To avoid memory corruption, extension writers should never try to operate on
-Python objects with the functions exported by the C library: :cfunc:`malloc`,
-:cfunc:`calloc`, :cfunc:`realloc` and :cfunc:`free`. This will result in mixed
+Python objects with the functions exported by the C library: :c:func:`malloc`,
+:c:func:`calloc`, :c:func:`realloc` and :c:func:`free`. This will result in mixed
calls between the C allocator and the Python memory manager with fatal
consequences, because they implement different algorithms and operate on
different heaps. However, one may safely allocate and release memory blocks
@@ -94,65 +94,65 @@ behavior when requesting zero bytes, are available for allocating and releasing
memory from the Python heap:
-.. cfunction:: void* PyMem_Malloc(size_t n)
+.. c:function:: void* PyMem_Malloc(size_t n)
- Allocates *n* bytes and returns a pointer of type :ctype:`void\*` to the
+ Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the
allocated memory, or *NULL* if the request fails. Requesting zero bytes returns
- a distinct non-*NULL* pointer if possible, as if :cfunc:`PyMem_Malloc(1)` had
+ a distinct non-*NULL* pointer if possible, as if :c:func:`PyMem_Malloc(1)` had
been called instead. The memory will not have been initialized in any way.
-.. cfunction:: void* PyMem_Realloc(void *p, size_t n)
+.. c:function:: void* PyMem_Realloc(void *p, size_t n)
Resizes the memory block pointed to by *p* to *n* bytes. The contents will be
unchanged to the minimum of the old and the new sizes. If *p* is *NULL*, the
- call is equivalent to :cfunc:`PyMem_Malloc(n)`; else if *n* is equal to zero,
+ call is equivalent to :c:func:`PyMem_Malloc(n)`; else if *n* is equal to zero,
the memory block is resized but is not freed, and the returned pointer is
non-*NULL*. Unless *p* is *NULL*, it must have been returned by a previous call
- to :cfunc:`PyMem_Malloc` or :cfunc:`PyMem_Realloc`. If the request fails,
- :cfunc:`PyMem_Realloc` returns *NULL* and *p* remains a valid pointer to the
+ to :c:func:`PyMem_Malloc` or :c:func:`PyMem_Realloc`. If the request fails,
+ :c:func:`PyMem_Realloc` returns *NULL* and *p* remains a valid pointer to the
previous memory area.
-.. cfunction:: void PyMem_Free(void *p)
+.. c:function:: void PyMem_Free(void *p)
Frees the memory block pointed to by *p*, which must have been returned by a
- previous call to :cfunc:`PyMem_Malloc` or :cfunc:`PyMem_Realloc`. Otherwise, or
- if :cfunc:`PyMem_Free(p)` has been called before, undefined behavior occurs. If
+ previous call to :c:func:`PyMem_Malloc` or :c:func:`PyMem_Realloc`. Otherwise, or
+ if :c:func:`PyMem_Free(p)` has been called before, undefined behavior occurs. If
*p* is *NULL*, no operation is performed.
The following type-oriented macros are provided for convenience. Note that
*TYPE* refers to any C type.
-.. cfunction:: TYPE* PyMem_New(TYPE, size_t n)
+.. c:function:: TYPE* PyMem_New(TYPE, size_t n)
- Same as :cfunc:`PyMem_Malloc`, but allocates ``(n * sizeof(TYPE))`` bytes of
- memory. Returns a pointer cast to :ctype:`TYPE\*`. The memory will not have
+ Same as :c:func:`PyMem_Malloc`, but allocates ``(n * sizeof(TYPE))`` bytes of
+ memory. Returns a pointer cast to :c:type:`TYPE\*`. The memory will not have
been initialized in any way.
-.. cfunction:: TYPE* PyMem_Resize(void *p, TYPE, size_t n)
+.. c:function:: TYPE* PyMem_Resize(void *p, TYPE, size_t n)
- Same as :cfunc:`PyMem_Realloc`, but the memory block is resized to ``(n *
- sizeof(TYPE))`` bytes. Returns a pointer cast to :ctype:`TYPE\*`. On return,
+ Same as :c:func:`PyMem_Realloc`, but the memory block is resized to ``(n *
+ sizeof(TYPE))`` bytes. Returns a pointer cast to :c:type:`TYPE\*`. On return,
*p* will be a pointer to the new memory area, or *NULL* in the event of
failure. This is a C preprocessor macro; p is always reassigned. Save
the original value of p to avoid losing memory when handling errors.
-.. cfunction:: void PyMem_Del(void *p)
+.. c:function:: void PyMem_Del(void *p)
- Same as :cfunc:`PyMem_Free`.
+ Same as :c:func:`PyMem_Free`.
In addition, the following macro sets are provided for calling the Python memory
allocator directly, without involving the C API functions listed above. However,
note that their use does not preserve binary compatibility across Python
versions and is therefore deprecated in extension modules.
-:cfunc:`PyMem_MALLOC`, :cfunc:`PyMem_REALLOC`, :cfunc:`PyMem_FREE`.
+:c:func:`PyMem_MALLOC`, :c:func:`PyMem_REALLOC`, :c:func:`PyMem_FREE`.
-:cfunc:`PyMem_NEW`, :cfunc:`PyMem_RESIZE`, :cfunc:`PyMem_DEL`.
+:c:func:`PyMem_NEW`, :c:func:`PyMem_RESIZE`, :c:func:`PyMem_DEL`.
.. _memoryexamples:
@@ -201,8 +201,8 @@ allocators operating on different heaps. ::
free(buf1); /* Fatal -- should be PyMem_Del() */
In addition to the functions aimed at handling raw memory blocks from the Python
-heap, objects in Python are allocated and released with :cfunc:`PyObject_New`,
-:cfunc:`PyObject_NewVar` and :cfunc:`PyObject_Del`.
+heap, objects in Python are allocated and released with :c:func:`PyObject_New`,
+:c:func:`PyObject_NewVar` and :c:func:`PyObject_Del`.
These will be explained in the next chapter on defining and implementing new
object types in C.
diff --git a/Doc/c-api/memoryview.rst b/Doc/c-api/memoryview.rst
index 9003d3e..34ecd12 100644
--- a/Doc/c-api/memoryview.rst
+++ b/Doc/c-api/memoryview.rst
@@ -13,22 +13,22 @@ A :class:`memoryview` object exposes the C level :ref:`buffer interface
any other object.
-.. cfunction:: PyObject *PyMemoryView_FromObject(PyObject *obj)
+.. 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, other it will be read-only.
-.. cfunction:: PyObject *PyMemoryView_FromBuffer(Py_buffer *view)
+.. 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 :cfunc:`PyBuffer_Release` yourself: it
+ means you shouldn't try to call :c:func:`PyBuffer_Release` yourself: it
will be done on deallocation of the memoryview object.
-.. cfunction:: PyObject *PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order)
+.. 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
@@ -37,13 +37,13 @@ any other object.
new bytes object.
-.. cfunction:: int PyMemoryView_Check(PyObject *obj)
+.. 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`.
-.. cfunction:: Py_buffer *PyMemoryView_GET_BUFFER(PyObject *obj)
+.. 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;
diff --git a/Doc/c-api/method.rst b/Doc/c-api/method.rst
index d8b2ed8..27f9576 100644
--- a/Doc/c-api/method.rst
+++ b/Doc/c-api/method.rst
@@ -7,38 +7,38 @@ Instance Method Objects
.. index:: object: instancemethod
-An instance method is a wrapper for a :cdata:`PyCFunction` and the new way
-to bind a :cdata:`PyCFunction` to a class object. It replaces the former call
+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)``.
-.. cvar:: PyTypeObject PyInstanceMethod_Type
+.. c:var:: PyTypeObject PyInstanceMethod_Type
- This instance of :ctype:`PyTypeObject` represents the Python instance
+ This instance of :c:type:`PyTypeObject` represents the Python instance
method type. It is not exposed to Python programs.
-.. cfunction:: int PyInstanceMethod_Check(PyObject *o)
+.. c:function:: int PyInstanceMethod_Check(PyObject *o)
Return true if *o* is an instance method object (has type
- :cdata:`PyInstanceMethod_Type`). The parameter must not be *NULL*.
+ :c:data:`PyInstanceMethod_Type`). The parameter must not be *NULL*.
-.. cfunction:: PyObject* PyInstanceMethod_New(PyObject *func)
+.. c:function:: PyObject* PyInstanceMethod_New(PyObject *func)
Return a new instance method object, with *func* being any callable object
*func* is is the function that will be called when the instance method is
called.
-.. cfunction:: PyObject* PyInstanceMethod_Function(PyObject *im)
+.. c:function:: PyObject* PyInstanceMethod_Function(PyObject *im)
Return the function object associated with the instance method *im*.
-.. cfunction:: PyObject* PyInstanceMethod_GET_FUNCTION(PyObject *im)
+.. c:function:: PyObject* PyInstanceMethod_GET_FUNCTION(PyObject *im)
- Macro version of :cfunc:`PyInstanceMethod_Function` which avoids error checking.
+ Macro version of :c:func:`PyInstanceMethod_Function` which avoids error checking.
.. _method-objects:
@@ -53,48 +53,48 @@ an user-defined class. Unbound methods (methods bound to a class object) are
no longer available.
-.. cvar:: PyTypeObject PyMethod_Type
+.. c:var:: PyTypeObject PyMethod_Type
.. index:: single: MethodType (in module types)
- This instance of :ctype:`PyTypeObject` represents the Python method type. This
+ This instance of :c:type:`PyTypeObject` represents the Python method type. This
is exposed to Python programs as ``types.MethodType``.
-.. cfunction:: int PyMethod_Check(PyObject *o)
+.. c:function:: int PyMethod_Check(PyObject *o)
- Return true if *o* is a method object (has type :cdata:`PyMethod_Type`). The
+ Return true if *o* is a method object (has type :c:data:`PyMethod_Type`). The
parameter must not be *NULL*.
-.. cfunction:: PyObject* PyMethod_New(PyObject *func, PyObject *self)
+.. c:function:: PyObject* PyMethod_New(PyObject *func, PyObject *self)
Return a new method object, with *func* being any callable object and *self*
the instance the method should be bound. *func* is is the function that will
be called when the method is called. *self* must not be *NULL*.
-.. cfunction:: PyObject* PyMethod_Function(PyObject *meth)
+.. c:function:: PyObject* PyMethod_Function(PyObject *meth)
Return the function object associated with the method *meth*.
-.. cfunction:: PyObject* PyMethod_GET_FUNCTION(PyObject *meth)
+.. c:function:: PyObject* PyMethod_GET_FUNCTION(PyObject *meth)
- Macro version of :cfunc:`PyMethod_Function` which avoids error checking.
+ Macro version of :c:func:`PyMethod_Function` which avoids error checking.
-.. cfunction:: PyObject* PyMethod_Self(PyObject *meth)
+.. c:function:: PyObject* PyMethod_Self(PyObject *meth)
Return the instance associated with the method *meth*.
-.. cfunction:: PyObject* PyMethod_GET_SELF(PyObject *meth)
+.. c:function:: PyObject* PyMethod_GET_SELF(PyObject *meth)
- Macro version of :cfunc:`PyMethod_Self` which avoids error checking.
+ Macro version of :c:func:`PyMethod_Self` which avoids error checking.
-.. cfunction:: int PyMethod_ClearFreeList()
+.. c:function:: int PyMethod_ClearFreeList()
Clear the free list. Return the total number of freed items.
diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst
index 12816c9..ffd68e3 100644
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -10,26 +10,26 @@ Module Objects
There are only a few functions special to module objects.
-.. cvar:: PyTypeObject PyModule_Type
+.. c:var:: PyTypeObject PyModule_Type
.. index:: single: ModuleType (in module types)
- This instance of :ctype:`PyTypeObject` represents the Python module type. This
+ This instance of :c:type:`PyTypeObject` represents the Python module type. This
is exposed to Python programs as ``types.ModuleType``.
-.. cfunction:: int PyModule_Check(PyObject *p)
+.. c:function:: int PyModule_Check(PyObject *p)
Return true if *p* is a module object, or a subtype of a module object.
-.. cfunction:: int PyModule_CheckExact(PyObject *p)
+.. c:function:: int PyModule_CheckExact(PyObject *p)
Return true if *p* is a module object, but not a subtype of
- :cdata:`PyModule_Type`.
+ :c:data:`PyModule_Type`.
-.. cfunction:: PyObject* PyModule_New(const char *name)
+.. c:function:: PyObject* PyModule_New(const char *name)
.. index::
single: __name__ (module attribute)
@@ -41,18 +41,18 @@ There are only a few functions special to module objects.
the caller is responsible for providing a :attr:`__file__` attribute.
-.. cfunction:: PyObject* PyModule_GetDict(PyObject *module)
+.. c:function:: PyObject* PyModule_GetDict(PyObject *module)
.. index:: single: __dict__ (module attribute)
Return the dictionary object that implements *module*'s namespace; this object
is the same as the :attr:`__dict__` attribute of the module object. This
function never fails. It is recommended extensions use other
- :cfunc:`PyModule_\*` and :cfunc:`PyObject_\*` functions rather than directly
+ :c:func:`PyModule_\*` and :c:func:`PyObject_\*` functions rather than directly
manipulate a module's :attr:`__dict__`.
-.. cfunction:: char* PyModule_GetName(PyObject *module)
+.. c:function:: char* PyModule_GetName(PyObject *module)
.. index::
single: __name__ (module attribute)
@@ -62,29 +62,42 @@ There are only a few functions special to module objects.
or if it is not a string, :exc:`SystemError` is raised and *NULL* is returned.
-.. cfunction:: char* PyModule_GetFilename(PyObject *module)
+.. 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
-.. cfunction:: void* PyModule_GetState(PyObject *module)
+.. 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
- :cmember:`PyModuleDef.m_size`.
+ :c:member:`PyModuleDef.m_size`.
-.. cfunction:: PyModuleDef* PyModule_GetDef(PyObject *module)
+.. c:function:: PyModuleDef* PyModule_GetDef(PyObject *module)
- Return a pointer to the :ctype:`PyModuleDef` struct from which the module was
+ Return a pointer to the :c:type:`PyModuleDef` struct from which the module was
created, or *NULL* if the module wasn't created with
- :cfunc:`PyModule_Create`.
+ :c:func:`PyModule_Create`.
Initializing C modules
@@ -92,14 +105,14 @@ Initializing C modules
These functions are usually used in the module initialization function.
-.. cfunction:: PyObject* PyModule_Create(PyModuleDef *module)
+.. c:function:: PyObject* PyModule_Create(PyModuleDef *module)
Create a new module object, given the definition in *module*. This behaves
- like :cfunc:`PyModule_Create2` with *module_api_version* set to
+ like :c:func:`PyModule_Create2` with *module_api_version* set to
:const:`PYTHON_API_VERSION`.
-.. cfunction:: PyObject* PyModule_Create2(PyModuleDef *module, int module_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
@@ -107,89 +120,89 @@ These functions are usually used in the module initialization function.
.. note::
- Most uses of this function should be using :cfunc:`PyModule_Create`
+ Most uses of this function should be using :c:func:`PyModule_Create`
instead; only use this if you are sure you need it.
-.. ctype:: PyModuleDef
+.. 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 :cfunc:`PyModule_Create` in the
+ is statically initialized and then passed to :c:func:`PyModule_Create` in the
module initialization function.
- .. cmember:: PyModuleDef_Base m_base
+ .. c:member:: PyModuleDef_Base m_base
Always initialize this member to :const:`PyModuleDef_HEAD_INIT`.
- .. cmember:: char* m_name
+ .. c:member:: char* m_name
Name for the new module.
- .. cmember:: char* m_doc
+ .. c:member:: char* m_doc
Docstring for the module; usually a docstring variable created with
- :cfunc:`PyDoc_STRVAR` is used.
+ :c:func:`PyDoc_STRVAR` is used.
- .. cmember:: Py_ssize_t m_size
+ .. 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 :cfunc:`PyModule_GetState`. If no memory is needed, set
+ 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 :cmember:`m_free`
+ freed when the module object is deallocated, after the :c:member:`m_free`
function has been called, if present.
- .. cmember:: PyMethodDef* m_methods
+ .. c:member:: PyMethodDef* m_methods
A pointer to a table of module-level functions, described by
- :ctype:`PyMethodDef` values. Can be *NULL* if no functions are present.
+ :c:type:`PyMethodDef` values. Can be *NULL* if no functions are present.
- .. cmember:: inquiry m_reload
+ .. c:member:: inquiry m_reload
Currently unused, should be *NULL*.
- .. cmember:: traverseproc m_traverse
+ .. c:member:: traverseproc m_traverse
A traversal function to call during GC traversal of the module object, or
*NULL* if not needed.
- .. cmember:: inquiry m_clear
+ .. c:member:: inquiry m_clear
A clear function to call during GC clearing of the module object, or
*NULL* if not needed.
- .. cmember:: freefunc m_free
+ .. c:member:: freefunc m_free
A function to call during deallocation of the module object, or *NULL* if
not needed.
-.. cfunction:: int PyModule_AddObject(PyObject *module, const char *name, PyObject *value)
+.. c:function:: int PyModule_AddObject(PyObject *module, const char *name, PyObject *value)
Add an object to *module* as *name*. This is a convenience function which can
be used from the module's initialization function. This steals a reference to
*value*. Return ``-1`` on error, ``0`` on success.
-.. cfunction:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value)
+.. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value)
Add an integer constant to *module* as *name*. This convenience function can be
used from the module's initialization function. Return ``-1`` on error, ``0`` on
success.
-.. cfunction:: int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value)
+.. c:function:: int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value)
Add a string constant to *module* as *name*. This convenience function can be
used from the module's initialization function. The string *value* must be
null-terminated. Return ``-1`` on error, ``0`` on success.
-.. cfunction:: int PyModule_AddIntMacro(PyObject *module, macro)
+.. c:function:: int PyModule_AddIntMacro(PyObject *module, macro)
Add an int constant to *module*. The name and the value are taken from
*macro*. For example ``PyModule_AddIntMacro(module, AF_INET)`` adds the int
@@ -197,6 +210,6 @@ These functions are usually used in the module initialization function.
Return ``-1`` on error, ``0`` on success.
-.. cfunction:: int PyModule_AddStringMacro(PyObject *module, macro)
+.. c:function:: int PyModule_AddStringMacro(PyObject *module, macro)
Add a string constant to *module*.
diff --git a/Doc/c-api/none.rst b/Doc/c-api/none.rst
index 70e2c04..b9ac269 100644
--- a/Doc/c-api/none.rst
+++ b/Doc/c-api/none.rst
@@ -7,20 +7,20 @@ The None Object
.. index:: object: None
-Note that the :ctype:`PyTypeObject` for ``None`` is not directly exposed in the
+Note that the :c:type:`PyTypeObject` for ``None`` is not directly exposed in the
Python/C API. Since ``None`` is a singleton, testing for object identity (using
-``==`` in C) is sufficient. There is no :cfunc:`PyNone_Check` function for the
+``==`` in C) is sufficient. There is no :c:func:`PyNone_Check` function for the
same reason.
-.. cvar:: PyObject* Py_None
+.. c:var:: PyObject* Py_None
The Python ``None`` object, denoting lack of value. This object has no methods.
It needs to be treated just like any other object with respect to reference
counts.
-.. cmacro:: Py_RETURN_NONE
+.. c:macro:: Py_RETURN_NONE
- Properly handle returning :cdata:`Py_None` from within a C function (that is,
+ 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 57ef293..eda722d 100644
--- a/Doc/c-api/number.rst
+++ b/Doc/c-api/number.rst
@@ -6,37 +6,37 @@ Number Protocol
===============
-.. cfunction:: int PyNumber_Check(PyObject *o)
+.. c:function:: int PyNumber_Check(PyObject *o)
Returns ``1`` if the object *o* provides numeric protocols, and false otherwise.
This function always succeeds.
-.. cfunction:: PyObject* PyNumber_Add(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_Add(PyObject *o1, PyObject *o2)
Returns the result of adding *o1* and *o2*, or *NULL* on failure. This is the
equivalent of the Python expression ``o1 + o2``.
-.. cfunction:: PyObject* PyNumber_Subtract(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_Subtract(PyObject *o1, PyObject *o2)
Returns the result of subtracting *o2* from *o1*, or *NULL* on failure. This is
the equivalent of the Python expression ``o1 - o2``.
-.. cfunction:: PyObject* PyNumber_Multiply(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_Multiply(PyObject *o1, PyObject *o2)
Returns the result of multiplying *o1* and *o2*, or *NULL* on failure. This is
the equivalent of the Python expression ``o1 * o2``.
-.. cfunction:: PyObject* PyNumber_FloorDivide(PyObject *o1, PyObject *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.
-.. cfunction:: PyObject* PyNumber_TrueDivide(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_TrueDivide(PyObject *o1, PyObject *o2)
Return a reasonable approximation for the mathematical value of *o1* divided by
*o2*, or *NULL* on failure. The return value is "approximate" because binary
@@ -45,13 +45,13 @@ Number Protocol
passed two integers.
-.. cfunction:: PyObject* PyNumber_Remainder(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_Remainder(PyObject *o1, PyObject *o2)
Returns the remainder of dividing *o1* by *o2*, or *NULL* on failure. This is
the equivalent of the Python expression ``o1 % o2``.
-.. cfunction:: PyObject* PyNumber_Divmod(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_Divmod(PyObject *o1, PyObject *o2)
.. index:: builtin: divmod
@@ -59,29 +59,29 @@ Number Protocol
the equivalent of the Python expression ``divmod(o1, o2)``.
-.. cfunction:: PyObject* PyNumber_Power(PyObject *o1, PyObject *o2, PyObject *o3)
+.. c:function:: PyObject* PyNumber_Power(PyObject *o1, PyObject *o2, PyObject *o3)
.. index:: builtin: pow
See the built-in function :func:`pow`. Returns *NULL* on failure. This is the
equivalent of the Python expression ``pow(o1, o2, o3)``, where *o3* is optional.
- If *o3* is to be ignored, pass :cdata:`Py_None` in its place (passing *NULL* for
+ If *o3* is to be ignored, pass :c:data:`Py_None` in its place (passing *NULL* for
*o3* would cause an illegal memory access).
-.. cfunction:: PyObject* PyNumber_Negative(PyObject *o)
+.. c:function:: PyObject* PyNumber_Negative(PyObject *o)
Returns the negation of *o* on success, or *NULL* on failure. This is the
equivalent of the Python expression ``-o``.
-.. cfunction:: PyObject* PyNumber_Positive(PyObject *o)
+.. c:function:: PyObject* PyNumber_Positive(PyObject *o)
Returns *o* on success, or *NULL* on failure. This is the equivalent of the
Python expression ``+o``.
-.. cfunction:: PyObject* PyNumber_Absolute(PyObject *o)
+.. c:function:: PyObject* PyNumber_Absolute(PyObject *o)
.. index:: builtin: abs
@@ -89,71 +89,71 @@ Number Protocol
of the Python expression ``abs(o)``.
-.. cfunction:: PyObject* PyNumber_Invert(PyObject *o)
+.. c:function:: PyObject* PyNumber_Invert(PyObject *o)
Returns the bitwise negation of *o* on success, or *NULL* on failure. This is
the equivalent of the Python expression ``~o``.
-.. cfunction:: PyObject* PyNumber_Lshift(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_Lshift(PyObject *o1, PyObject *o2)
Returns the result of left shifting *o1* by *o2* on success, or *NULL* on
failure. This is the equivalent of the Python expression ``o1 << o2``.
-.. cfunction:: PyObject* PyNumber_Rshift(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_Rshift(PyObject *o1, PyObject *o2)
Returns the result of right shifting *o1* by *o2* on success, or *NULL* on
failure. This is the equivalent of the Python expression ``o1 >> o2``.
-.. cfunction:: PyObject* PyNumber_And(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_And(PyObject *o1, PyObject *o2)
Returns the "bitwise and" of *o1* and *o2* on success and *NULL* on failure.
This is the equivalent of the Python expression ``o1 & o2``.
-.. cfunction:: PyObject* PyNumber_Xor(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_Xor(PyObject *o1, PyObject *o2)
Returns the "bitwise exclusive or" of *o1* by *o2* on success, or *NULL* on
failure. This is the equivalent of the Python expression ``o1 ^ o2``.
-.. cfunction:: PyObject* PyNumber_Or(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_Or(PyObject *o1, PyObject *o2)
Returns the "bitwise or" of *o1* and *o2* on success, or *NULL* on failure.
This is the equivalent of the Python expression ``o1 | o2``.
-.. cfunction:: PyObject* PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2)
Returns the result of adding *o1* and *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``.
-.. cfunction:: PyObject* PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2)
Returns the result of subtracting *o2* from *o1*, or *NULL* on failure. The
operation is done *in-place* when *o1* supports it. This is the equivalent of
the Python statement ``o1 -= o2``.
-.. cfunction:: PyObject* PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2)
Returns the result of multiplying *o1* and *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``.
-.. cfunction:: PyObject* PyNumber_InPlaceFloorDivide(PyObject *o1, PyObject *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``.
-.. cfunction:: PyObject* PyNumber_InPlaceTrueDivide(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_InPlaceTrueDivide(PyObject *o1, PyObject *o2)
Return a reasonable approximation for the mathematical value of *o1* divided by
*o2*, or *NULL* on failure. The return value is "approximate" because binary
@@ -162,72 +162,60 @@ Number Protocol
passed two integers. The operation is done *in-place* when *o1* supports it.
-.. cfunction:: PyObject* PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2)
Returns the remainder 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``.
-.. cfunction:: PyObject* PyNumber_InPlacePower(PyObject *o1, PyObject *o2, PyObject *o3)
+.. c:function:: PyObject* PyNumber_InPlacePower(PyObject *o1, PyObject *o2, PyObject *o3)
.. index:: builtin: pow
See the built-in function :func:`pow`. Returns *NULL* on failure. The operation
is done *in-place* when *o1* supports it. This is the equivalent of the Python
- statement ``o1 **= o2`` when o3 is :cdata:`Py_None`, or an in-place variant of
- ``pow(o1, o2, o3)`` otherwise. If *o3* is to be ignored, pass :cdata:`Py_None`
+ statement ``o1 **= o2`` when o3 is :c:data:`Py_None`, or an in-place variant of
+ ``pow(o1, o2, o3)`` otherwise. If *o3* is to be ignored, pass :c:data:`Py_None`
in its place (passing *NULL* for *o3* would cause an illegal memory access).
-.. cfunction:: PyObject* PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2)
Returns the result of left shifting *o1* by *o2* on success, or *NULL* on
failure. The operation is done *in-place* when *o1* supports it. This is the
equivalent of the Python statement ``o1 <<= o2``.
-.. cfunction:: PyObject* PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2)
Returns the result of right shifting *o1* by *o2* on success, or *NULL* on
failure. The operation is done *in-place* when *o1* supports it. This is the
equivalent of the Python statement ``o1 >>= o2``.
-.. cfunction:: PyObject* PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2)
Returns the "bitwise and" of *o1* and *o2* on success and *NULL* on failure. The
operation is done *in-place* when *o1* supports it. This is the equivalent of
the Python statement ``o1 &= o2``.
-.. cfunction:: PyObject* PyNumber_InPlaceXor(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_InPlaceXor(PyObject *o1, PyObject *o2)
Returns the "bitwise exclusive or" of *o1* by *o2* on success, or *NULL* on
failure. The operation is done *in-place* when *o1* supports it. This is the
equivalent of the Python statement ``o1 ^= o2``.
-.. cfunction:: PyObject* PyNumber_InPlaceOr(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PyNumber_InPlaceOr(PyObject *o1, PyObject *o2)
Returns the "bitwise or" of *o1* and *o2* on success, or *NULL* on failure. The
operation is done *in-place* when *o1* supports it. This is the equivalent of
the Python statement ``o1 |= o2``.
-.. cfunction:: PyObject* PyNumber_Int(PyObject *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)``.
-
- .. note::
-
- This function is defined in the transitional :file:`intobject.h`
- header file. It will be removed completely in Python 3.1. Use
- the :cfunc:`PyNumber_Long` function instead.
-
-
-.. cfunction:: PyObject* PyNumber_Long(PyObject *o)
+.. c:function:: PyObject* PyNumber_Long(PyObject *o)
.. index:: builtin: int
@@ -235,7 +223,7 @@ Number Protocol
failure. This is the equivalent of the Python expression ``int(o)``.
-.. cfunction:: PyObject* PyNumber_Float(PyObject *o)
+.. c:function:: PyObject* PyNumber_Float(PyObject *o)
.. index:: builtin: float
@@ -243,22 +231,22 @@ Number Protocol
This is the equivalent of the Python expression ``float(o)``.
-.. cfunction:: PyObject* PyNumber_Index(PyObject *o)
+.. c:function:: PyObject* PyNumber_Index(PyObject *o)
Returns the *o* converted to a Python int on success or *NULL* with a
:exc:`TypeError` exception raised on failure.
-.. cfunction:: PyObject* PyNumber_ToBase(PyObject *n, int base)
+.. 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
- :cfunc:`PyNumber_Index` first.
+ :c:func:`PyNumber_Index` first.
-.. cfunction:: Py_ssize_t PyNumber_AsSsize_t(PyObject *o, PyObject *exc)
+.. 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 but the attempt to
@@ -269,7 +257,7 @@ Number Protocol
integer or *PY_SSIZE_T_MAX* for a positive integer.
-.. cfunction:: int PyIndex_Check(PyObject *o)
+.. 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).
diff --git a/Doc/c-api/objbuffer.rst b/Doc/c-api/objbuffer.rst
index 728d383..e7f4fde 100644
--- a/Doc/c-api/objbuffer.rst
+++ b/Doc/c-api/objbuffer.rst
@@ -12,13 +12,13 @@ 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.
-Therefore, it is recommended that you call :cfunc:`PyObject_GetBuffer`
+Therefore, it is recommended that you call :c:func:`PyObject_GetBuffer`
(or the ``y*`` or ``w*`` :ref:`format codes <arg-parsing>` with the
-:cfunc:`PyArg_ParseTuple` family of functions) to get a buffer view over
-an object, and :cfunc:`PyBuffer_Release` when the buffer view can be released.
+: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.
-.. cfunction:: int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len)
+.. c:function:: int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len)
Returns a pointer to a read-only memory location usable as character-based
input. The *obj* argument must support the single-segment character buffer
@@ -27,7 +27,7 @@ an object, and :cfunc:`PyBuffer_Release` when the buffer view can be released.
:exc:`TypeError` on error.
-.. cfunction:: int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len)
+.. c:function:: int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len)
Returns a pointer to a read-only memory location containing arbitrary data.
The *obj* argument must support the single-segment readable buffer
@@ -36,13 +36,13 @@ an object, and :cfunc:`PyBuffer_Release` when the buffer view can be released.
:exc:`TypeError` on error.
-.. cfunction:: int PyObject_CheckReadBuffer(PyObject *o)
+.. c:function:: int PyObject_CheckReadBuffer(PyObject *o)
Returns ``1`` if *o* supports the single-segment readable buffer interface.
Otherwise returns ``0``.
-.. cfunction:: int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len)
+.. c:function:: int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len)
Returns a pointer to a writable memory location. The *obj* argument must
support the single-segment, character buffer interface. On success,
diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst
index fd3a6d2..d0d45ad 100644
--- a/Doc/c-api/object.rst
+++ b/Doc/c-api/object.rst
@@ -6,7 +6,7 @@ Object Protocol
===============
-.. cfunction:: int PyObject_Print(PyObject *o, FILE *fp, int flags)
+.. c:function:: int PyObject_Print(PyObject *o, FILE *fp, int flags)
Print an object *o*, on file *fp*. Returns ``-1`` on error. The flags argument
is used to enable certain printing options. The only option currently supported
@@ -14,35 +14,35 @@ Object Protocol
instead of the :func:`repr`.
-.. cfunction:: int PyObject_HasAttr(PyObject *o, PyObject *attr_name)
+.. c:function:: int PyObject_HasAttr(PyObject *o, PyObject *attr_name)
Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise. This
is equivalent to the Python expression ``hasattr(o, attr_name)``. This function
always succeeds.
-.. cfunction:: int PyObject_HasAttrString(PyObject *o, const char *attr_name)
+.. c:function:: int PyObject_HasAttrString(PyObject *o, const char *attr_name)
Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise. This
is equivalent to the Python expression ``hasattr(o, attr_name)``. This function
always succeeds.
-.. cfunction:: PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name)
+.. c:function:: PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name)
Retrieve an attribute named *attr_name* from object *o*. Returns the attribute
value on success, or *NULL* on failure. This is the equivalent of the Python
expression ``o.attr_name``.
-.. cfunction:: PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name)
+.. c:function:: PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name)
Retrieve an attribute named *attr_name* from object *o*. Returns the attribute
value on success, or *NULL* on failure. This is the equivalent of the Python
expression ``o.attr_name``.
-.. cfunction:: PyObject* PyObject_GenericGetAttr(PyObject *o, PyObject *name)
+.. c:function:: PyObject* PyObject_GenericGetAttr(PyObject *o, PyObject *name)
Generic attribute getter function that is meant to be put into a type
object's ``tp_getattro`` slot. It looks for a descriptor in the dictionary
@@ -52,21 +52,21 @@ Object Protocol
descriptors don't. Otherwise, an :exc:`AttributeError` is raised.
-.. cfunction:: int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v)
+.. c:function:: int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v)
Set the value of the attribute named *attr_name*, for object *o*, to the value
*v*. Returns ``-1`` on failure. This is the equivalent of the Python statement
``o.attr_name = v``.
-.. cfunction:: int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v)
+.. c:function:: int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v)
Set the value of the attribute named *attr_name*, for object *o*, to the value
*v*. Returns ``-1`` on failure. This is the equivalent of the Python statement
``o.attr_name = v``.
-.. cfunction:: int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject *value)
+.. c:function:: int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject *value)
Generic attribute setter function that is meant to be put into a type
object's ``tp_setattro`` slot. It looks for a data descriptor in the
@@ -76,19 +76,19 @@ Object Protocol
an :exc:`AttributeError` is raised and ``-1`` is returned.
-.. cfunction:: int PyObject_DelAttr(PyObject *o, PyObject *attr_name)
+.. c:function:: int PyObject_DelAttr(PyObject *o, PyObject *attr_name)
Delete attribute named *attr_name*, for object *o*. Returns ``-1`` on failure.
This is the equivalent of the Python statement ``del o.attr_name``.
-.. cfunction:: int PyObject_DelAttrString(PyObject *o, const char *attr_name)
+.. c:function:: int PyObject_DelAttrString(PyObject *o, const char *attr_name)
Delete attribute named *attr_name*, for object *o*. Returns ``-1`` on failure.
This is the equivalent of the Python statement ``del o.attr_name``.
-.. cfunction:: PyObject* PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid)
+.. c:function:: PyObject* PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid)
Compare the values of *o1* and *o2* using the operation specified by *opid*,
which must be one of :const:`Py_LT`, :const:`Py_LE`, :const:`Py_EQ`,
@@ -98,7 +98,7 @@ Object Protocol
to *opid*. Returns the value of the comparison on success, or *NULL* on failure.
-.. cfunction:: int PyObject_RichCompareBool(PyObject *o1, PyObject *o2, int opid)
+.. c:function:: int PyObject_RichCompareBool(PyObject *o1, PyObject *o2, int opid)
Compare the values of *o1* and *o2* using the operation specified by *opid*,
which must be one of :const:`Py_LT`, :const:`Py_LE`, :const:`Py_EQ`,
@@ -109,10 +109,10 @@ Object Protocol
*opid*.
.. note::
- If *o1* and *o2* are the same object, :cfunc:`PyObject_RichCompareBool`
+ 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`.
-.. cfunction:: PyObject* PyObject_Repr(PyObject *o)
+.. c:function:: PyObject* PyObject_Repr(PyObject *o)
.. index:: builtin: repr
@@ -121,18 +121,18 @@ Object Protocol
Python expression ``repr(o)``. Called by the :func:`repr` built-in function.
-.. cfunction:: PyObject* PyObject_ASCII(PyObject *o)
+.. c:function:: PyObject* PyObject_ASCII(PyObject *o)
.. index:: builtin: ascii
- As :cfunc:`PyObject_Repr`, compute a string representation of object *o*, but
+ As :c:func:`PyObject_Repr`, compute a string representation of object *o*, but
escape the non-ASCII characters in the string returned by
- :cfunc:`PyObject_Repr` with ``\x``, ``\u`` or ``\U`` escapes. This generates
- a string similar to that returned by :cfunc:`PyObject_Repr` in Python 2.
+ :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.
-.. cfunction:: PyObject* PyObject_Str(PyObject *o)
+.. c:function:: PyObject* PyObject_Str(PyObject *o)
.. index:: builtin: str
@@ -141,20 +141,21 @@ Object Protocol
Python expression ``str(o)``. Called by the :func:`str` built-in function
and, therefore, by the :func:`print` function.
-.. cfunction:: PyObject* PyObject_Bytes(PyObject *o)
+.. c:function:: PyObject* PyObject_Bytes(PyObject *o)
.. index:: builtin: bytes
- 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)``.
+ 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.
-
-.. cfunction:: int PyObject_IsInstance(PyObject *inst, PyObject *cls)
+.. c:function:: int PyObject_IsInstance(PyObject *inst, PyObject *cls)
Returns ``1`` if *inst* is an instance of the class *cls* or a subclass of
*cls*, or ``0`` if not. On error, returns ``-1`` and sets an exception. If
- *cls* is a type object rather than a class object, :cfunc:`PyObject_IsInstance`
+ *cls* is a type object rather than a class object, :c:func:`PyObject_IsInstance`
returns ``1`` if *inst* is of type *cls*. If *cls* is a tuple, the check will
be done against every entry in *cls*. The result will be ``1`` when at least one
of the checks returns ``1``, otherwise it will be ``0``. If *inst* is not a
@@ -170,13 +171,13 @@ of. If :class:`A` and :class:`B` are class objects, :class:`B` is a subclass of
:class:`A` if it inherits from :class:`A` either directly or indirectly. If
either is not a class object, a more general mechanism is used to determine the
class relationship of the two objects. When testing if *B* is a subclass of
-*A*, if *A* is *B*, :cfunc:`PyObject_IsSubclass` returns true. If *A* and *B*
+*A*, if *A* is *B*, :c:func:`PyObject_IsSubclass` returns true. If *A* and *B*
are different objects, *B*'s :attr:`__bases__` attribute is searched in a
depth-first fashion for *A* --- the presence of the :attr:`__bases__` attribute
is considered sufficient for this determination.
-.. cfunction:: int PyObject_IsSubclass(PyObject *derived, PyObject *cls)
+.. c:function:: int PyObject_IsSubclass(PyObject *derived, PyObject *cls)
Returns ``1`` if the class *derived* is identical to or derived from the class
*cls*, otherwise returns ``0``. In case of an error, returns ``-1``. If *cls*
@@ -186,13 +187,13 @@ is considered sufficient for this determination.
this function uses the generic algorithm described above.
-.. cfunction:: int PyCallable_Check(PyObject *o)
+.. c:function:: int PyCallable_Check(PyObject *o)
Determine if the object *o* is callable. Return ``1`` if the object is callable
and ``0`` otherwise. This function always succeeds.
-.. cfunction:: PyObject* PyObject_Call(PyObject *callable_object, PyObject *args, PyObject *kw)
+.. c:function:: PyObject* PyObject_Call(PyObject *callable_object, PyObject *args, PyObject *kw)
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
@@ -202,7 +203,7 @@ is considered sufficient for this determination.
``callable_object(*args, **kw)``.
-.. cfunction:: PyObject* PyObject_CallObject(PyObject *callable_object, PyObject *args)
+.. c:function:: PyObject* PyObject_CallObject(PyObject *callable_object, PyObject *args)
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
@@ -210,54 +211,58 @@ is considered sufficient for this determination.
of the Python expression ``callable_object(*args)``.
-.. cfunction:: PyObject* PyObject_CallFunction(PyObject *callable, char *format, ...)
+.. c:function:: PyObject* PyObject_CallFunction(PyObject *callable, char *format, ...)
Call a callable Python object *callable*, with a variable number of C arguments.
- The C arguments are described using a :cfunc:`Py_BuildValue` style format
+ 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 ``callable(*args)``. Note that if you only
- pass :ctype:`PyObject \*` args, :cfunc:`PyObject_CallFunctionObjArgs` is a
+ pass :c:type:`PyObject \*` args, :c:func:`PyObject_CallFunctionObjArgs` is a
faster alternative.
-.. cfunction:: PyObject* PyObject_CallMethod(PyObject *o, char *method, char *format, ...)
+.. c:function:: PyObject* PyObject_CallMethod(PyObject *o, char *method, char *format, ...)
Call the method named *method* of object *o* with a variable number of C
- arguments. The C arguments are described by a :cfunc:`Py_BuildValue` format
+ arguments. The C arguments are described by a :c:func:`Py_BuildValue` format
string that should produce a tuple. 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 ``o.method(args)``.
- Note that if you only pass :ctype:`PyObject \*` args,
- :cfunc:`PyObject_CallMethodObjArgs` is a faster alternative.
+ Note that if you only pass :c:type:`PyObject \*` args,
+ :c:func:`PyObject_CallMethodObjArgs` is a faster alternative.
-.. cfunction:: PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ..., NULL)
+.. c:function:: PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ..., NULL)
Call a callable Python object *callable*, with a variable number of
- :ctype:`PyObject\*` arguments. The arguments are provided as a variable number
+ :c:type:`PyObject\*` arguments. The arguments are provided as a variable number
of parameters followed by *NULL*. Returns the result of the call on success, or
*NULL* on failure.
-.. cfunction:: PyObject* PyObject_CallMethodObjArgs(PyObject *o, PyObject *name, ..., NULL)
+.. c:function:: PyObject* PyObject_CallMethodObjArgs(PyObject *o, PyObject *name, ..., NULL)
Calls a method of the object *o*, where the name of the method is given as a
Python string object in *name*. It is called with a variable number of
- :ctype:`PyObject\*` arguments. The arguments are provided as a variable number
+ :c:type:`PyObject\*` arguments. The arguments are provided as a variable number
of parameters followed by *NULL*. Returns the result of the call on success, or
*NULL* on failure.
-.. cfunction:: 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.
+
-.. cfunction:: 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,
@@ -265,21 +270,21 @@ is considered sufficient for this determination.
hashable.
-.. cfunction:: int PyObject_IsTrue(PyObject *o)
+.. c:function:: int PyObject_IsTrue(PyObject *o)
Returns ``1`` if the object *o* is considered to be true, and ``0`` otherwise.
This is equivalent to the Python expression ``not not o``. On failure, return
``-1``.
-.. cfunction:: int PyObject_Not(PyObject *o)
+.. c:function:: int PyObject_Not(PyObject *o)
Returns ``0`` if the object *o* is considered to be true, and ``1`` otherwise.
This is equivalent to the Python expression ``not o``. On failure, return
``-1``.
-.. cfunction:: PyObject* PyObject_Type(PyObject *o)
+.. c:function:: PyObject* PyObject_Type(PyObject *o)
.. index:: builtin: type
@@ -288,17 +293,17 @@ is considered sufficient for this determination.
is equivalent to the Python expression ``type(o)``. This function increments the
reference count of the return value. There's really no reason to use this
function instead of the common expression ``o->ob_type``, which returns a
- pointer of type :ctype:`PyTypeObject\*`, except when the incremented reference
+ pointer of type :c:type:`PyTypeObject\*`, except when the incremented reference
count is needed.
-.. cfunction:: int PyObject_TypeCheck(PyObject *o, PyTypeObject *type)
+.. c:function:: int PyObject_TypeCheck(PyObject *o, PyTypeObject *type)
Return true if the object *o* is of type *type* or a subtype of *type*. Both
parameters must be non-*NULL*.
-.. cfunction:: Py_ssize_t PyObject_Length(PyObject *o)
+.. c:function:: Py_ssize_t PyObject_Length(PyObject *o)
Py_ssize_t PyObject_Size(PyObject *o)
.. index:: builtin: len
@@ -308,34 +313,34 @@ is considered sufficient for this determination.
returned. This is the equivalent to the Python expression ``len(o)``.
-.. cfunction:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key)
+.. c:function:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key)
Return element of *o* corresponding to the object *key* or *NULL* on failure.
This is the equivalent of the Python expression ``o[key]``.
-.. cfunction:: int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v)
+.. c:function:: int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v)
Map the object *key* to the value *v*. Returns ``-1`` on failure. This is the
equivalent of the Python statement ``o[key] = v``.
-.. cfunction:: int PyObject_DelItem(PyObject *o, PyObject *key)
+.. c:function:: int PyObject_DelItem(PyObject *o, PyObject *key)
Delete the mapping for *key* from *o*. Returns ``-1`` on failure. This is the
equivalent of the Python statement ``del o[key]``.
-.. cfunction:: PyObject* PyObject_Dir(PyObject *o)
+.. c:function:: PyObject* PyObject_Dir(PyObject *o)
This is equivalent to the Python expression ``dir(o)``, returning a (possibly
empty) list of strings appropriate for the object argument, or *NULL* if there
was an error. If the argument is *NULL*, this is like the Python ``dir()``,
returning the names of the current locals; in this case, if no execution frame
- is active then *NULL* is returned but :cfunc:`PyErr_Occurred` will return false.
+ is active then *NULL* is returned but :c:func:`PyErr_Occurred` will return false.
-.. cfunction:: PyObject* PyObject_GetIter(PyObject *o)
+.. c:function:: PyObject* PyObject_GetIter(PyObject *o)
This is equivalent to the Python expression ``iter(o)``. It returns a new
iterator for the object argument, or the object itself if the object is already
diff --git a/Doc/c-api/refcounting.rst b/Doc/c-api/refcounting.rst
index c0f4ca1..4f512ec 100644
--- a/Doc/c-api/refcounting.rst
+++ b/Doc/c-api/refcounting.rst
@@ -11,22 +11,22 @@ The macros in this section are used for managing reference counts of Python
objects.
-.. cfunction:: void Py_INCREF(PyObject *o)
+.. c:function:: void Py_INCREF(PyObject *o)
Increment the reference count for object *o*. The object must not be *NULL*; if
- you aren't sure that it isn't *NULL*, use :cfunc:`Py_XINCREF`.
+ you aren't sure that it isn't *NULL*, use :c:func:`Py_XINCREF`.
-.. cfunction:: void Py_XINCREF(PyObject *o)
+.. c:function:: void Py_XINCREF(PyObject *o)
Increment the reference count for object *o*. The object may be *NULL*, in
which case the macro has no effect.
-.. cfunction:: void Py_DECREF(PyObject *o)
+.. c:function:: void Py_DECREF(PyObject *o)
Decrement the reference count for object *o*. The object must not be *NULL*; if
- you aren't sure that it isn't *NULL*, use :cfunc:`Py_XDECREF`. If the reference
+ you aren't sure that it isn't *NULL*, use :c:func:`Py_XDECREF`. If the reference
count reaches zero, the object's type's deallocation function (which must not be
*NULL*) is invoked.
@@ -36,25 +36,25 @@ objects.
when a class instance with a :meth:`__del__` method is deallocated). While
exceptions in such code are not propagated, the executed code has free access to
all Python global variables. This means that any object that is reachable from
- a global variable should be in a consistent state before :cfunc:`Py_DECREF` is
+ a global variable should be in a consistent state before :c:func:`Py_DECREF` is
invoked. For example, code to delete an object from a list should copy a
reference to the deleted object in a temporary variable, update the list data
- structure, and then call :cfunc:`Py_DECREF` for the temporary variable.
+ structure, and then call :c:func:`Py_DECREF` for the temporary variable.
-.. cfunction:: void Py_XDECREF(PyObject *o)
+.. c:function:: void Py_XDECREF(PyObject *o)
Decrement the reference count for object *o*. The object may be *NULL*, in
which case the macro has no effect; otherwise the effect is the same as for
- :cfunc:`Py_DECREF`, and the same warning applies.
+ :c:func:`Py_DECREF`, and the same warning applies.
-.. cfunction:: void Py_CLEAR(PyObject *o)
+.. c:function:: void Py_CLEAR(PyObject *o)
Decrement the reference count for object *o*. The object may be *NULL*, in
which case the macro has no effect; otherwise the effect is the same as for
- :cfunc:`Py_DECREF`, except that the argument is also set to *NULL*. The warning
- for :cfunc:`Py_DECREF` does not apply with respect to the object passed because
+ :c:func:`Py_DECREF`, except that the argument is also set to *NULL*. The warning
+ for :c:func:`Py_DECREF` does not apply with respect to the object passed because
the macro carefully uses a temporary variable and sets the argument to *NULL*
before decrementing its reference count.
@@ -64,10 +64,10 @@ objects.
The following functions are for runtime dynamic embedding of Python:
``Py_IncRef(PyObject *o)``, ``Py_DecRef(PyObject *o)``. They are
-simply exported function versions of :cfunc:`Py_XINCREF` and
-:cfunc:`Py_XDECREF`, respectively.
+simply exported function versions of :c:func:`Py_XINCREF` and
+:c:func:`Py_XDECREF`, respectively.
The following functions or macros are only for use within the interpreter core:
-:cfunc:`_Py_Dealloc`, :cfunc:`_Py_ForgetReference`, :cfunc:`_Py_NewReference`,
-as well as the global variable :cdata:`_Py_RefTotal`.
+:c:func:`_Py_Dealloc`, :c:func:`_Py_ForgetReference`, :c:func:`_Py_NewReference`,
+as well as the global variable :c:data:`_Py_RefTotal`.
diff --git a/Doc/c-api/reflection.rst b/Doc/c-api/reflection.rst
index 4f46c7f..9689365 100644
--- a/Doc/c-api/reflection.rst
+++ b/Doc/c-api/reflection.rst
@@ -5,40 +5,45 @@
Reflection
==========
-.. cfunction:: PyObject* PyEval_GetBuiltins()
+.. c:function:: PyObject* PyEval_GetBuiltins()
Return a dictionary of the builtins in the current execution frame,
or the interpreter of the thread state if no frame is currently executing.
-.. cfunction:: PyObject* PyEval_GetLocals()
+.. c:function:: PyObject* PyEval_GetLocals()
Return a dictionary of the local variables in the current execution frame,
or *NULL* if no frame is currently executing.
-.. cfunction:: PyObject* PyEval_GetGlobals()
+.. c:function:: PyObject* PyEval_GetGlobals()
Return a dictionary of the global variables in the current execution frame,
or *NULL* if no frame is currently executing.
-.. cfunction:: PyFrameObject* PyEval_GetFrame()
+.. c:function:: PyFrameObject* PyEval_GetFrame()
Return the current thread state's frame, which is *NULL* if no frame is
currently executing.
-.. cfunction:: const char* PyEval_GetFuncName(PyObject *func)
+.. c:function:: int PyFrame_GetLineNumber(PyFrameObject *frame)
+
+ Return the line number that *frame* is currently executing.
+
+
+.. c:function:: const char* PyEval_GetFuncName(PyObject *func)
Return the name of *func* if it is a function, class or instance object, else the
name of *func*\s type.
-.. cfunction:: const char* PyEval_GetFuncDesc(PyObject *func)
+.. c:function:: const char* PyEval_GetFuncDesc(PyObject *func)
Return a description string, depending on the type of *func*.
Return values include "()" for functions and methods, " constructor",
" instance", and " object". Concatenated with the result of
- :cfunc:`PyEval_GetFuncName`, the result will be a description of
+ :c:func:`PyEval_GetFuncName`, the result will be a description of
*func*.
diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst
index d863177..599074c 100644
--- a/Doc/c-api/sequence.rst
+++ b/Doc/c-api/sequence.rst
@@ -6,13 +6,13 @@ Sequence Protocol
=================
-.. cfunction:: int PySequence_Check(PyObject *o)
+.. c:function:: int PySequence_Check(PyObject *o)
Return ``1`` if the object provides sequence protocol, and ``0`` otherwise.
This function always succeeds.
-.. cfunction:: Py_ssize_t PySequence_Size(PyObject *o)
+.. c:function:: Py_ssize_t PySequence_Size(PyObject *o)
Py_ssize_t PySequence_Length(PyObject *o)
.. index:: builtin: len
@@ -22,96 +22,96 @@ Sequence Protocol
Python expression ``len(o)``.
-.. cfunction:: PyObject* PySequence_Concat(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PySequence_Concat(PyObject *o1, PyObject *o2)
Return the concatenation of *o1* and *o2* on success, and *NULL* on failure.
This is the equivalent of the Python expression ``o1 + o2``.
-.. cfunction:: PyObject* PySequence_Repeat(PyObject *o, Py_ssize_t count)
+.. c:function:: PyObject* PySequence_Repeat(PyObject *o, Py_ssize_t count)
Return the result of repeating sequence object *o* *count* times, or *NULL* on
failure. This is the equivalent of the Python expression ``o * count``.
-.. cfunction:: PyObject* PySequence_InPlaceConcat(PyObject *o1, PyObject *o2)
+.. c:function:: PyObject* PySequence_InPlaceConcat(PyObject *o1, PyObject *o2)
Return the concatenation of *o1* and *o2* on success, and *NULL* on failure.
The operation is done *in-place* when *o1* supports it. This is the equivalent
of the Python expression ``o1 += o2``.
-.. cfunction:: PyObject* PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count)
+.. c:function:: PyObject* PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count)
Return the result of repeating sequence object *o* *count* times, or *NULL* on
failure. The operation is done *in-place* when *o* supports it. This is the
equivalent of the Python expression ``o *= count``.
-.. cfunction:: PyObject* PySequence_GetItem(PyObject *o, Py_ssize_t i)
+.. 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]``.
-.. cfunction:: PyObject* PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2)
+.. 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]``.
-.. cfunction:: int PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v)
+.. c:function:: int PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v)
Assign object *v* to the *i*\ th element of *o*. Returns ``-1`` on failure. This
is the equivalent of the Python statement ``o[i] = v``. This function *does
not* steal a reference to *v*.
-.. cfunction:: int PySequence_DelItem(PyObject *o, Py_ssize_t i)
+.. 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]``.
-.. cfunction:: int PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, PyObject *v)
+.. 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``.
-.. cfunction:: int PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2)
+.. 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]``.
-.. cfunction:: Py_ssize_t PySequence_Count(PyObject *o, PyObject *value)
+.. c:function:: Py_ssize_t PySequence_Count(PyObject *o, PyObject *value)
Return the number of occurrences of *value* in *o*, that is, return the number
of keys for which ``o[key] == value``. On failure, return ``-1``. This is
equivalent to the Python expression ``o.count(value)``.
-.. cfunction:: int PySequence_Contains(PyObject *o, PyObject *value)
+.. c:function:: int PySequence_Contains(PyObject *o, PyObject *value)
Determine if *o* contains *value*. If an item in *o* is equal to *value*,
return ``1``, otherwise return ``0``. On error, return ``-1``. This is
equivalent to the Python expression ``value in o``.
-.. cfunction:: Py_ssize_t PySequence_Index(PyObject *o, PyObject *value)
+.. c:function:: Py_ssize_t PySequence_Index(PyObject *o, PyObject *value)
Return the first index *i* for which ``o[i] == value``. On error, return
``-1``. This is equivalent to the Python expression ``o.index(value)``.
-.. cfunction:: PyObject* PySequence_List(PyObject *o)
+.. c:function:: PyObject* PySequence_List(PyObject *o)
Return a list object with the same contents as the arbitrary sequence *o*. The
returned list is guaranteed to be new.
-.. cfunction:: PyObject* PySequence_Tuple(PyObject *o)
+.. c:function:: PyObject* PySequence_Tuple(PyObject *o)
.. index:: builtin: tuple
@@ -121,42 +121,42 @@ Sequence Protocol
equivalent to the Python expression ``tuple(o)``.
-.. cfunction:: PyObject* PySequence_Fast(PyObject *o, const char *m)
+.. c:function:: PyObject* PySequence_Fast(PyObject *o, const char *m)
Returns the sequence *o* as a tuple, unless it is already a tuple or list, in
- which case *o* is returned. Use :cfunc:`PySequence_Fast_GET_ITEM` to access the
+ which case *o* is returned. Use :c:func:`PySequence_Fast_GET_ITEM` to access the
members of the result. Returns *NULL* on failure. If the object is not a
sequence, raises :exc:`TypeError` with *m* as the message text.
-.. cfunction:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i)
+.. c:function:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i)
Return the *i*\ th element of *o*, assuming that *o* was returned by
- :cfunc:`PySequence_Fast`, *o* is not *NULL*, and that *i* is within bounds.
+ :c:func:`PySequence_Fast`, *o* is not *NULL*, and that *i* is within bounds.
-.. cfunction:: PyObject** PySequence_Fast_ITEMS(PyObject *o)
+.. c:function:: PyObject** PySequence_Fast_ITEMS(PyObject *o)
Return the underlying array of PyObject pointers. Assumes that *o* was returned
- by :cfunc:`PySequence_Fast` and *o* is not *NULL*.
+ by :c:func:`PySequence_Fast` and *o* is not *NULL*.
Note, if a list gets resized, the reallocation may relocate the items array.
So, only use the underlying array pointer in contexts where the sequence
cannot change.
-.. cfunction:: PyObject* PySequence_ITEM(PyObject *o, Py_ssize_t i)
+.. c:function:: PyObject* PySequence_ITEM(PyObject *o, Py_ssize_t i)
Return the *i*\ th element of *o* or *NULL* on failure. Macro form of
- :cfunc:`PySequence_GetItem` but without checking that
- :cfunc:`PySequence_Check(o)` is true and without adjustment for negative
+ :c:func:`PySequence_GetItem` but without checking that
+ :c:func:`PySequence_Check(o)` is true and without adjustment for negative
indices.
-.. cfunction:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o)
+.. c:function:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o)
Returns the length of *o*, assuming that *o* was returned by
- :cfunc:`PySequence_Fast` and that *o* is not *NULL*. The size can also be
- gotten by calling :cfunc:`PySequence_Size` on *o*, but
- :cfunc:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list
+ :c:func:`PySequence_Fast` and that *o* is not *NULL*. The size can also be
+ gotten by calling :c:func:`PySequence_Size` on *o*, but
+ :c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list
or tuple.
diff --git a/Doc/c-api/set.rst b/Doc/c-api/set.rst
index 4348108..66b47c4 100644
--- a/Doc/c-api/set.rst
+++ b/Doc/c-api/set.rst
@@ -14,20 +14,20 @@ Set Objects
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 :cfunc:`PyObject_CallMethod`,
-:cfunc:`PyObject_RichCompareBool`, :cfunc:`PyObject_Hash`,
-:cfunc:`PyObject_Repr`, :cfunc:`PyObject_IsTrue`, :cfunc:`PyObject_Print`, and
-:cfunc:`PyObject_GetIter`) or the abstract number protocol (including
-:cfunc:`PyNumber_And`, :cfunc:`PyNumber_Subtract`, :cfunc:`PyNumber_Or`,
-:cfunc:`PyNumber_Xor`, :cfunc:`PyNumber_InPlaceAnd`,
-:cfunc:`PyNumber_InPlaceSubtract`, :cfunc:`PyNumber_InPlaceOr`, and
-:cfunc:`PyNumber_InPlaceXor`).
+the abstract object protocol (including :c:func:`PyObject_CallMethod`,
+:c:func:`PyObject_RichCompareBool`, :c:func:`PyObject_Hash`,
+:c:func:`PyObject_Repr`, :c:func:`PyObject_IsTrue`, :c:func:`PyObject_Print`, and
+:c:func:`PyObject_GetIter`) or the abstract number protocol (including
+:c:func:`PyNumber_And`, :c:func:`PyNumber_Subtract`, :c:func:`PyNumber_Or`,
+:c:func:`PyNumber_Xor`, :c:func:`PyNumber_InPlaceAnd`,
+:c:func:`PyNumber_InPlaceSubtract`, :c:func:`PyNumber_InPlaceOr`, and
+:c:func:`PyNumber_InPlaceXor`).
-.. ctype:: PySetObject
+.. c:type:: PySetObject
- This subtype of :ctype:`PyObject` is used to hold the internal data for both
- :class:`set` and :class:`frozenset` objects. It is like a :ctype:`PyDictObject`
+ This subtype of :c:type:`PyObject` is used to hold the internal data for both
+ :class:`set` and :class:`frozenset` objects. It is like a :c:type:`PyDictObject`
in that it is a fixed size for small sets (much like tuple storage) and will
point to a separate, variable sized block of memory for medium and large sized
sets (much like list storage). None of the fields of this structure should be
@@ -35,49 +35,49 @@ the abstract object protocol (including :cfunc:`PyObject_CallMethod`,
the documented API rather than by manipulating the values in the structure.
-.. cvar:: PyTypeObject PySet_Type
+.. c:var:: PyTypeObject PySet_Type
- This is an instance of :ctype:`PyTypeObject` representing the Python
+ This is an instance of :c:type:`PyTypeObject` representing the Python
:class:`set` type.
-.. cvar:: PyTypeObject PyFrozenSet_Type
+.. c:var:: PyTypeObject PyFrozenSet_Type
- This is an instance of :ctype:`PyTypeObject` representing the Python
+ This is an instance of :c:type:`PyTypeObject` representing the Python
:class:`frozenset` type.
The following type check macros work on pointers to any Python object. Likewise,
the constructor functions work with any iterable Python object.
-.. cfunction:: int PySet_Check(PyObject *p)
+.. c:function:: int PySet_Check(PyObject *p)
Return true if *p* is a :class:`set` object or an instance of a subtype.
-.. cfunction:: int PyFrozenSet_Check(PyObject *p)
+.. c:function:: int PyFrozenSet_Check(PyObject *p)
Return true if *p* is a :class:`frozenset` object or an instance of a
subtype.
-.. cfunction:: int PyAnySet_Check(PyObject *p)
+.. c:function:: int PyAnySet_Check(PyObject *p)
Return true if *p* is a :class:`set` object, a :class:`frozenset` object, or an
instance of a subtype.
-.. cfunction:: int PyAnySet_CheckExact(PyObject *p)
+.. c:function:: int PyAnySet_CheckExact(PyObject *p)
Return true if *p* is a :class:`set` object or a :class:`frozenset` object but
not an instance of a subtype.
-.. cfunction:: int PyFrozenSet_CheckExact(PyObject *p)
+.. c:function:: int PyFrozenSet_CheckExact(PyObject *p)
Return true if *p* is a :class:`frozenset` object but not an instance of a
subtype.
-.. cfunction:: PyObject* PySet_New(PyObject *iterable)
+.. c:function:: PyObject* PySet_New(PyObject *iterable)
Return a new :class:`set` containing objects returned by the *iterable*. The
*iterable* may be *NULL* to create a new empty set. Return the new set on
@@ -86,7 +86,7 @@ the constructor functions work with any iterable Python object.
(``c=set(s)``).
-.. cfunction:: PyObject* PyFrozenSet_New(PyObject *iterable)
+.. c:function:: PyObject* PyFrozenSet_New(PyObject *iterable)
Return a new :class:`frozenset` containing objects returned by the *iterable*.
The *iterable* may be *NULL* to create a new empty frozenset. Return the new
@@ -98,7 +98,7 @@ The following functions and macros are available for instances of :class:`set`
or :class:`frozenset` or instances of their subtypes.
-.. cfunction:: Py_ssize_t PySet_Size(PyObject *anyset)
+.. c:function:: Py_ssize_t PySet_Size(PyObject *anyset)
.. index:: builtin: len
@@ -107,12 +107,12 @@ or :class:`frozenset` or instances of their subtypes.
:class:`set`, :class:`frozenset`, or an instance of a subtype.
-.. cfunction:: Py_ssize_t PySet_GET_SIZE(PyObject *anyset)
+.. c:function:: Py_ssize_t PySet_GET_SIZE(PyObject *anyset)
- Macro form of :cfunc:`PySet_Size` without error checking.
+ Macro form of :c:func:`PySet_Size` without error checking.
-.. cfunction:: int PySet_Contains(PyObject *anyset, PyObject *key)
+.. c:function:: int PySet_Contains(PyObject *anyset, PyObject *key)
Return 1 if found, 0 if not found, and -1 if an error is encountered. Unlike
the Python :meth:`__contains__` method, this function does not automatically
@@ -121,10 +121,10 @@ or :class:`frozenset` or instances of their subtypes.
:class:`set`, :class:`frozenset`, or an instance of a subtype.
-.. cfunction:: int PySet_Add(PyObject *set, PyObject *key)
+.. c:function:: int PySet_Add(PyObject *set, PyObject *key)
Add *key* to a :class:`set` instance. Also works with :class:`frozenset`
- instances (like :cfunc:`PyTuple_SetItem` it can be used to fill-in the values
+ 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
@@ -136,7 +136,7 @@ The following functions are available for instances of :class:`set` or its
subtypes but not for instances of :class:`frozenset` or its subtypes.
-.. cfunction:: int PySet_Discard(PyObject *set, PyObject *key)
+.. c:function:: int PySet_Discard(PyObject *set, PyObject *key)
Return 1 if found and removed, 0 if not found (no action taken), and -1 if an
error is encountered. Does not raise :exc:`KeyError` for missing keys. Raise a
@@ -146,7 +146,7 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
instance of :class:`set` or its subtype.
-.. cfunction:: PyObject* PySet_Pop(PyObject *set)
+.. c:function:: PyObject* PySet_Pop(PyObject *set)
Return a new reference to an arbitrary object in the *set*, and removes the
object from the *set*. Return *NULL* on failure. Raise :exc:`KeyError` if the
@@ -154,6 +154,6 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
:class:`set` or its subtype.
-.. cfunction:: int PySet_Clear(PyObject *set)
+.. c:function:: int PySet_Clear(PyObject *set)
Empty an existing set of all elements.
diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst
index f33cd53..e157df2 100644
--- a/Doc/c-api/slice.rst
+++ b/Doc/c-api/slice.rst
@@ -6,18 +6,18 @@ Slice Objects
-------------
-.. cvar:: PyTypeObject PySlice_Type
+.. c:var:: PyTypeObject PySlice_Type
The type object for slice objects. This is the same as :class:`slice` in the
Python layer.
-.. cfunction:: int PySlice_Check(PyObject *ob)
+.. c:function:: int PySlice_Check(PyObject *ob)
Return true if *ob* is a slice object; *ob* must not be *NULL*.
-.. cfunction:: PyObject* PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
+.. c:function:: PyObject* PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
Return a new slice object with the given values. The *start*, *stop*, and
*step* parameters are used as the values of the slice object attributes of
@@ -26,7 +26,7 @@ Slice Objects
the new object could not be allocated.
-.. cfunction:: 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,13 +38,21 @@ Slice Objects
You probably do not want to use this function.
+ .. versionchanged:: 3.2
+ The parameter type for the *slice* parameter was ``PySliceObject*``
+ before.
-.. cfunction:: 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)
- Usable replacement for :cfunc:`PySlice_GetIndices`. Retrieve the start,
+.. 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
length *length*, and store the length of the slice in *slicelength*. Out
of bounds indices are clipped in a manner consistent with the handling of
normal slices.
Returns 0 on success and -1 on error with exception set.
+
+ .. versionchanged:: 3.2
+ The parameter type for the *slice* parameter was ``PySliceObject*``
+ before.
diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst
index dbacedf..bb741fb 100644
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -11,12 +11,12 @@ are used.
All Python objects ultimately share a small number of fields at the beginning
of the object's representation in memory. These are represented by the
-:ctype:`PyObject` and :ctype:`PyVarObject` types, which are defined, in turn,
+:c:type:`PyObject` and :c:type:`PyVarObject` types, which are defined, in turn,
by the expansions of some macros also used, whether directly or indirectly, in
the definition of all other Python objects.
-.. ctype:: PyObject
+.. c:type:: PyObject
All object types are extensions of this type. This is a type which
contains the information Python needs to treat a pointer to an object as an
@@ -26,88 +26,88 @@ the definition of all other Python objects.
macro.
-.. ctype:: PyVarObject
+.. c:type:: PyVarObject
- This is an extension of :ctype:`PyObject` that adds the :attr:`ob_size`
+ This is an extension of :c:type:`PyObject` that adds the :attr:`ob_size`
field. This is only used for objects that have some notion of *length*.
This type does not often appear in the Python/C API. It corresponds to the
fields defined by the expansion of the ``PyObject_VAR_HEAD`` macro.
-These macros are used in the definition of :ctype:`PyObject` and
-:ctype:`PyVarObject`:
+These macros are used in the definition of :c:type:`PyObject` and
+:c:type:`PyVarObject`:
.. XXX need to document PEP 3123 changes here
-.. cmacro:: PyObject_HEAD
+.. c:macro:: PyObject_HEAD
This is a macro which expands to the declarations of the fields of the
- :ctype:`PyObject` type; it is used when declaring new types which represent
+ :c:type:`PyObject` type; it is used when declaring new types which represent
objects without a varying length. The specific fields it expands to depend
- on the definition of :cmacro:`Py_TRACE_REFS`. By default, that macro is
- not defined, and :cmacro:`PyObject_HEAD` expands to::
+ on the definition of :c:macro:`Py_TRACE_REFS`. By default, that macro is
+ not defined, and :c:macro:`PyObject_HEAD` expands to::
Py_ssize_t ob_refcnt;
PyTypeObject *ob_type;
- When :cmacro:`Py_TRACE_REFS` is defined, it expands to::
+ When :c:macro:`Py_TRACE_REFS` is defined, it expands to::
PyObject *_ob_next, *_ob_prev;
Py_ssize_t ob_refcnt;
PyTypeObject *ob_type;
-.. cmacro:: PyObject_VAR_HEAD
+.. c:macro:: PyObject_VAR_HEAD
This is a macro which expands to the declarations of the fields of the
- :ctype:`PyVarObject` type; it is used when declaring new types which
+ :c:type:`PyVarObject` type; it is used when declaring new types which
represent objects with a length that varies from instance to instance.
This macro always expands to::
PyObject_HEAD
Py_ssize_t ob_size;
- Note that :cmacro:`PyObject_HEAD` is part of the expansion, and that its own
- expansion varies depending on the definition of :cmacro:`Py_TRACE_REFS`.
+ Note that :c:macro:`PyObject_HEAD` is part of the expansion, and that its own
+ expansion varies depending on the definition of :c:macro:`Py_TRACE_REFS`.
-.. cmacro:: PyObject_HEAD_INIT(type)
+.. c:macro:: PyObject_HEAD_INIT(type)
This is a macro which expands to initialization values for a new
- :ctype:`PyObject` type. This macro expands to::
+ :c:type:`PyObject` type. This macro expands to::
_PyObject_EXTRA_INIT
1, type,
-.. cmacro:: PyVarObject_HEAD_INIT(type, size)
+.. c:macro:: PyVarObject_HEAD_INIT(type, size)
This is a macro which expands to initialization values for a new
- :ctype:`PyVarObject` type, including the :attr:`ob_size` field.
+ :c:type:`PyVarObject` type, including the :attr:`ob_size` field.
This macro expands to::
_PyObject_EXTRA_INIT
1, type, size,
-.. ctype:: PyCFunction
+.. c:type:: PyCFunction
Type of the functions used to implement most Python callables in C.
- Functions of this type take two :ctype:`PyObject\*` parameters and return
+ Functions of this type take two :c:type:`PyObject\*` parameters and return
one such value. If the return value is *NULL*, an exception shall have
been set. If not *NULL*, the return value is interpreted as the return
value of the function as exposed in Python. The function must return a new
reference.
-.. ctype:: PyCFunctionWithKeywords
+.. c:type:: PyCFunctionWithKeywords
Type of the functions used to implement Python callables in C that take
- keyword arguments: they take three :ctype:`PyObject\*` parameters and return
- one such value. See :ctype:`PyCFunction` above for the meaning of the return
+ 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.
-.. ctype:: PyMethodDef
+.. c:type:: PyMethodDef
Structure used to describe a method of an extension type. This structure has
four fields:
@@ -128,10 +128,10 @@ These macros are used in the definition of :ctype:`PyObject` and
+------------------+-------------+-------------------------------+
The :attr:`ml_meth` is a C function pointer. The functions may be of different
-types, but they always return :ctype:`PyObject\*`. If the function is not of
-the :ctype:`PyCFunction`, the compiler will require a cast in the method table.
-Even though :ctype:`PyCFunction` defines the first parameter as
-:ctype:`PyObject\*`, it is common that the method implementation uses a the
+types, but they always return :c:type:`PyObject\*`. If the function is not of
+the :c:type:`PyCFunction`, the compiler will require a cast in the method table.
+Even though :c:type:`PyCFunction` defines the first parameter as
+:c:type:`PyObject\*`, it is common that the method implementation uses a the
specific C type of the *self* object.
The :attr:`ml_flags` field is a bitfield which can include the following flags.
@@ -145,27 +145,27 @@ convention flags can be combined with a binding flag.
.. data:: METH_VARARGS
This is the typical calling convention, where the methods have the type
- :ctype:`PyCFunction`. The function expects two :ctype:`PyObject\*` values.
+ :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
- using :cfunc:`PyArg_ParseTuple` or :cfunc:`PyArg_UnpackTuple`.
+ using :c:func:`PyArg_ParseTuple` or :c:func:`PyArg_UnpackTuple`.
.. data:: METH_KEYWORDS
- Methods with these flags must be of type :ctype:`PyCFunctionWithKeywords`.
+ Methods with these flags must be of type :c:type:`PyCFunctionWithKeywords`.
The function expects three parameters: *self*, *args*, and a dictionary of
all the keyword arguments. The flag is typically combined with
:const:`METH_VARARGS`, and the parameters are typically processed using
- :cfunc:`PyArg_ParseTupleAndKeywords`.
+ :c:func:`PyArg_ParseTupleAndKeywords`.
.. data:: METH_NOARGS
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
- :ctype:`PyCFunction`. The first parameter is typically named *self* and will
+ :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*.
@@ -173,9 +173,9 @@ convention flags can be combined with a binding flag.
.. data:: METH_O
Methods with a single object argument can be listed with the :const:`METH_O`
- flag, instead of invoking :cfunc:`PyArg_ParseTuple` with a ``"O"`` argument.
- They have the type :ctype:`PyCFunction`, with the *self* parameter, and a
- :ctype:`PyObject\*` parameter representing the single argument.
+ flag, instead of invoking :c:func:`PyArg_ParseTuple` with a ``"O"`` argument.
+ They have the type :c:type:`PyCFunction`, with the *self* parameter, and a
+ :c:type:`PyObject\*` parameter representing the single argument.
These two constants are not used to indicate the calling convention but the
@@ -219,7 +219,7 @@ definition with the same method name.
than wrapper object calls.
-.. ctype:: PyMemberDef
+.. c:type:: PyMemberDef
Structure which describes an attribute of a type which corresponds to a C
struct member. Its fields are:
@@ -271,14 +271,14 @@ definition with the same method name.
T_PYSSIZET Py_ssize_t
=============== ==================
- :cmacro:`T_OBJECT` and :cmacro:`T_OBJECT_EX` differ in that
- :cmacro:`T_OBJECT` returns ``None`` if the member is *NULL* and
- :cmacro:`T_OBJECT_EX` raises an :exc:`AttributeError`. Try to use
- :cmacro:`T_OBJECT_EX` over :cmacro:`T_OBJECT` because :cmacro:`T_OBJECT_EX`
+ :c:macro:`T_OBJECT` and :c:macro:`T_OBJECT_EX` differ in that
+ :c:macro:`T_OBJECT` returns ``None`` if the member is *NULL* and
+ :c:macro:`T_OBJECT_EX` raises an :exc:`AttributeError`. Try to use
+ :c:macro:`T_OBJECT_EX` over :c:macro:`T_OBJECT` because :c:macro:`T_OBJECT_EX`
handles use of the :keyword:`del` statement on that attribute more correctly
- than :cmacro:`T_OBJECT`.
+ than :c:macro:`T_OBJECT`.
- :attr:`flags` can be 0 for write and read access or :cmacro:`READONLY` for
- read-only access. Using :cmacro:`T_STRING` for :attr:`type` implies
- :cmacro:`READONLY`. Only :cmacro:`T_OBJECT` and :cmacro:`T_OBJECT_EX`
+ :attr:`flags` can be 0 for write and read access or :c:macro:`READONLY` for
+ 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*).
diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst
index adadfe5..252bd1a 100644
--- a/Doc/c-api/sys.rst
+++ b/Doc/c-api/sys.rst
@@ -6,16 +6,16 @@ Operating System Utilities
==========================
-.. cfunction:: int Py_FdIsInteractive(FILE *fp, const char *filename)
+.. c:function:: int Py_FdIsInteractive(FILE *fp, const char *filename)
Return true (nonzero) if the standard I/O file *fp* with name *filename* is
deemed interactive. This is the case for files for which ``isatty(fileno(fp))``
- is true. If the global flag :cdata:`Py_InteractiveFlag` is true, this function
+ is true. If the global flag :c:data:`Py_InteractiveFlag` is true, this function
also returns true if the *filename* pointer is *NULL* or if the name is equal to
one of the strings ``'<stdin>'`` or ``'???'``.
-.. cfunction:: void PyOS_AfterFork()
+.. c:function:: void PyOS_AfterFork()
Function to update some internal state after a process fork; this should be
called in the new process if the Python interpreter will continue to be used.
@@ -23,7 +23,7 @@ Operating System Utilities
to be called.
-.. cfunction:: int PyOS_CheckStack()
+.. c:function:: int PyOS_CheckStack()
Return true when the interpreter runs out of stack space. This is a reliable
check, but is only available when :const:`USE_STACKCHECK` is defined (currently
@@ -32,20 +32,20 @@ Operating System Utilities
own code.
-.. cfunction:: PyOS_sighandler_t PyOS_getsig(int i)
+.. c:function:: PyOS_sighandler_t PyOS_getsig(int i)
Return the current signal handler for signal *i*. This is a thin wrapper around
- either :cfunc:`sigaction` or :cfunc:`signal`. Do not call those functions
- directly! :ctype:`PyOS_sighandler_t` is a typedef alias for :ctype:`void
+ either :c:func:`sigaction` or :c:func:`signal`. Do not call those functions
+ directly! :c:type:`PyOS_sighandler_t` is a typedef alias for :c:type:`void
(\*)(int)`.
-.. cfunction:: PyOS_sighandler_t PyOS_setsig(int i, PyOS_sighandler_t h)
+.. c:function:: PyOS_sighandler_t PyOS_setsig(int i, PyOS_sighandler_t h)
Set the signal handler for signal *i* to be *h*; return the old signal handler.
- This is a thin wrapper around either :cfunc:`sigaction` or :cfunc:`signal`. Do
- not call those functions directly! :ctype:`PyOS_sighandler_t` is a typedef
- alias for :ctype:`void (\*)(int)`.
+ This is a thin wrapper around either :c:func:`sigaction` or :c:func:`signal`. Do
+ not call those functions directly! :c:type:`PyOS_sighandler_t` is a typedef
+ alias for :c:type:`void (\*)(int)`.
.. _systemfunctions:
@@ -56,38 +56,42 @@ These are utility functions that make functionality from the :mod:`sys` module
accessible to C code. They all work with the current interpreter thread's
:mod:`sys` module's dict, which is contained in the internal thread state structure.
-.. cfunction:: PyObject *PySys_GetObject(char *name)
+.. c:function:: PyObject *PySys_GetObject(char *name)
Return the object *name* from the :mod:`sys` module or *NULL* if it does
not exist, without setting an exception.
-.. cfunction:: FILE *PySys_GetFile(char *name, FILE *def)
+.. c:function:: FILE *PySys_GetFile(char *name, FILE *def)
- Return the :ctype:`FILE*` associated with the object *name* in the
+ 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 :ctype:`FILE*`.
+ with a :c:type:`FILE*`.
-.. cfunction:: int PySys_SetObject(char *name, PyObject *v)
+.. c:function:: int PySys_SetObject(char *name, PyObject *v)
Set *name* in the :mod:`sys` module to *v* unless *v* is *NULL*, in which
case *name* is deleted from the sys module. Returns ``0`` on success, ``-1``
on error.
-.. cfunction:: void PySys_ResetWarnOptions()
+.. c:function:: void PySys_ResetWarnOptions()
Reset :data:`sys.warnoptions` to an empty list.
-.. cfunction:: void PySys_AddWarnOption(wchar_t *s)
+.. c:function:: void PySys_AddWarnOption(wchar_t *s)
Append *s* to :data:`sys.warnoptions`.
-.. cfunction:: void PySys_SetPath(wchar_t *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
(``:`` on Unix, ``;`` on Windows).
-.. cfunction:: void PySys_WriteStdout(const char *format, ...)
+.. c:function:: void PySys_WriteStdout(const char *format, ...)
Write the output string described by *format* to :data:`sys.stdout`. No
exceptions are raised, even if truncation occurs (see below).
@@ -103,9 +107,40 @@ accessible to C code. They all work with the current interpreter thread's
If a problem occurs, or :data:`sys.stdout` is unset, the formatted message
is written to the real (C level) *stdout*.
-.. cfunction:: void PySys_WriteStderr(const char *format, ...)
+.. c:function:: void PySys_WriteStderr(const char *format, ...)
+
+ 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.
- As above, but write to :data:`sys.stderr` or *stderr* instead.
+ .. versionadded:: 3.2
.. _processcontrol:
@@ -114,7 +149,7 @@ Process Control
===============
-.. cfunction:: void Py_FatalError(const char *message)
+.. c:function:: void Py_FatalError(const char *message)
.. index:: single: abort()
@@ -122,30 +157,30 @@ Process Control
This function should only be invoked when a condition is detected that would
make it dangerous to continue using the Python interpreter; e.g., when the
object administration appears to be corrupted. On Unix, the standard C library
- function :cfunc:`abort` is called which will attempt to produce a :file:`core`
+ function :c:func:`abort` is called which will attempt to produce a :file:`core`
file.
-.. cfunction:: void Py_Exit(int status)
+.. c:function:: void Py_Exit(int status)
.. index::
single: Py_Finalize()
single: exit()
- Exit the current process. This calls :cfunc:`Py_Finalize` and then calls the
+ Exit the current process. This calls :c:func:`Py_Finalize` and then calls the
standard C library function ``exit(status)``.
-.. cfunction:: int Py_AtExit(void (*func) ())
+.. c:function:: int Py_AtExit(void (*func) ())
.. index::
single: Py_Finalize()
single: cleanup functions
- Register a cleanup function to be called by :cfunc:`Py_Finalize`. The cleanup
+ Register a cleanup function to be called by :c:func:`Py_Finalize`. The cleanup
function will be called with no arguments and should return no value. At most
32 cleanup functions can be registered. When the registration is successful,
- :cfunc:`Py_AtExit` returns ``0``; on failure, it returns ``-1``. The cleanup
+ :c:func:`Py_AtExit` returns ``0``; on failure, it returns ``-1``. The cleanup
function registered last is called first. Each cleanup function will be called
at most once. Since Python's internal finalization will have completed before
the cleanup function, no Python APIs should be called by *func*.
diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst
index 612acc7..3cbfe5b 100644
--- a/Doc/c-api/tuple.rst
+++ b/Doc/c-api/tuple.rst
@@ -8,70 +8,70 @@ Tuple Objects
.. index:: object: tuple
-.. ctype:: PyTupleObject
+.. c:type:: PyTupleObject
- This subtype of :ctype:`PyObject` represents a Python tuple object.
+ This subtype of :c:type:`PyObject` represents a Python tuple object.
-.. cvar:: PyTypeObject PyTuple_Type
+.. c:var:: PyTypeObject PyTuple_Type
- This instance of :ctype:`PyTypeObject` represents the Python tuple type; it
+ This instance of :c:type:`PyTypeObject` represents the Python tuple type; it
is the same object as :class:`tuple` in the Python layer.
-.. cfunction:: int PyTuple_Check(PyObject *p)
+.. c:function:: int PyTuple_Check(PyObject *p)
Return true if *p* is a tuple object or an instance of a subtype of the tuple
type.
-.. cfunction:: int PyTuple_CheckExact(PyObject *p)
+.. 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.
-.. cfunction:: PyObject* PyTuple_New(Py_ssize_t len)
+.. c:function:: PyObject* PyTuple_New(Py_ssize_t len)
Return a new tuple object of size *len*, or *NULL* on failure.
-.. cfunction:: PyObject* PyTuple_Pack(Py_ssize_t n, ...)
+.. c:function:: PyObject* PyTuple_Pack(Py_ssize_t n, ...)
Return a new tuple object of size *n*, or *NULL* on failure. The tuple values
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)``.
-.. cfunction:: Py_ssize_t PyTuple_Size(PyObject *p)
+.. c:function:: Py_ssize_t PyTuple_Size(PyObject *p)
Take a pointer to a tuple object, and return the size of that tuple.
-.. cfunction:: Py_ssize_t PyTuple_GET_SIZE(PyObject *p)
+.. 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.
-.. cfunction:: PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos)
+.. 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.
-.. cfunction:: PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos)
+.. c:function:: PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos)
- Like :cfunc:`PyTuple_GetItem`, but does no checking of its arguments.
+ Like :c:func:`PyTuple_GetItem`, but does no checking of its arguments.
-.. cfunction:: PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high)
+.. 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.
-.. cfunction:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o)
+.. c:function:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o)
Insert a reference to object *o* at position *pos* of the tuple pointed to by
*p*. Return ``0`` on success.
@@ -81,9 +81,9 @@ Tuple Objects
This function "steals" a reference to *o*.
-.. cfunction:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o)
+.. c:function:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o)
- Like :cfunc:`PyTuple_SetItem`, but does no error checking, and should *only* be
+ Like :c:func:`PyTuple_SetItem`, but does no error checking, and should *only* be
used to fill in brand new tuples.
.. note::
@@ -91,7 +91,7 @@ Tuple Objects
This function "steals" a reference to *o*.
-.. cfunction:: int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize)
+.. c:function:: int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize)
Can be used to resize a tuple. *newsize* will be the new length of the tuple.
Because tuples are *supposed* to be immutable, this should only be used if there
@@ -105,6 +105,6 @@ Tuple Objects
raises :exc:`MemoryError` or :exc:`SystemError`.
-.. cfunction:: int PyTuple_ClearFreeList()
+.. c:function:: int PyTuple_ClearFreeList()
Clear the free list. Return the total number of freed items.
diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst
index d2a5676..b3386ea 100644
--- a/Doc/c-api/type.rst
+++ b/Doc/c-api/type.rst
@@ -8,69 +8,77 @@ Type Objects
.. index:: object: type
-.. ctype:: PyTypeObject
+.. c:type:: PyTypeObject
The C structure of the objects used to describe built-in types.
-.. cvar:: PyObject* PyType_Type
+.. c:var:: PyObject* PyType_Type
This is the type object for type objects; it is the same object as
:class:`type` in the Python layer.
-.. cfunction:: int PyType_Check(PyObject *o)
+.. c:function:: int PyType_Check(PyObject *o)
Return true if the object *o* is a type object, including instances of types
derived from the standard type object. Return false in all other cases.
-.. cfunction:: int PyType_CheckExact(PyObject *o)
+.. c:function:: int PyType_CheckExact(PyObject *o)
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.
-.. cfunction:: unsigned int PyType_ClearCache()
+.. c:function:: unsigned int PyType_ClearCache()
Clear the internal lookup cache. Return the current version tag.
+.. c:function:: long PyType_GetFlags(PyTypeObject* type)
-.. cfunction:: void PyType_Modified(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)
Invalidate the internal lookup cache for the type and all of its
subtypes. This function must be called after any manual
modification of the attributes or base classes of the type.
-.. cfunction:: int PyType_HasFeature(PyObject *o, int feature)
+.. c:function:: int PyType_HasFeature(PyObject *o, int feature)
Return true if the type object *o* sets the feature *feature*. Type features
are denoted by single bit flags.
-.. cfunction:: int PyType_IS_GC(PyObject *o)
+.. c:function:: int PyType_IS_GC(PyObject *o)
Return true if the type object includes support for the cycle detector; this
tests the type flag :const:`Py_TPFLAGS_HAVE_GC`.
-.. cfunction:: int PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
+.. c:function:: int PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
Return true if *a* is a subtype of *b*.
-.. cfunction:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
+.. c:function:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
XXX: Document.
-.. cfunction:: PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
+.. c:function:: PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
XXX: Document.
-.. cfunction:: int PyType_Ready(PyTypeObject *type)
+.. c:function:: int PyType_Ready(PyTypeObject *type)
Finalize a type object. This should be called on all type objects to finish
their initialization. This function is responsible for adding inherited slots
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index 7aa827a..4a6335c 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -6,9 +6,9 @@ Type Objects
============
Perhaps one of the most important structures of the Python object system is the
-structure that defines a new type: the :ctype:`PyTypeObject` structure. Type
-objects can be handled using any of the :cfunc:`PyObject_\*` or
-:cfunc:`PyType_\*` functions, but do not offer much that's interesting to most
+structure that defines a new type: the :c:type:`PyTypeObject` structure. Type
+objects can be handled using any of the :c:func:`PyObject_\*` or
+:c:func:`PyType_\*` functions, but do not offer much that's interesting to most
Python applications. These objects are fundamental to how objects behave, so
they are very important to the interpreter itself and to any extension module
that implements new types.
@@ -25,21 +25,21 @@ intintargfunc, intobjargproc, intintobjargproc, objobjargproc, destructor,
freefunc, printfunc, getattrfunc, getattrofunc, setattrfunc, setattrofunc,
reprfunc, hashfunc
-The structure definition for :ctype:`PyTypeObject` can be found in
+The structure definition for :c:type:`PyTypeObject` can be found in
:file:`Include/object.h`. For convenience of reference, this repeats the
definition found there:
.. literalinclude:: ../includes/typestruct.h
-The type object structure extends the :ctype:`PyVarObject` structure. The
+The type object structure extends the :c:type:`PyVarObject` structure. The
:attr:`ob_size` field is used for dynamic types (created by :func:`type_new`,
-usually called from a class statement). Note that :cdata:`PyType_Type` (the
+usually called from a class statement). Note that :c:data:`PyType_Type` (the
metatype) initializes :attr:`tp_itemsize`, which means that its instances (i.e.
type objects) *must* have the :attr:`ob_size` field.
-.. cmember:: PyObject* PyObject._ob_next
+.. c:member:: PyObject* PyObject._ob_next
PyObject* PyObject._ob_prev
These fields are only present when the macro ``Py_TRACE_REFS`` is defined.
@@ -54,7 +54,7 @@ type objects) *must* have the :attr:`ob_size` field.
These fields are not inherited by subtypes.
-.. cmember:: Py_ssize_t PyObject.ob_refcnt
+.. c:member:: Py_ssize_t PyObject.ob_refcnt
This is the type object's reference count, initialized to ``1`` by the
``PyObject_HEAD_INIT`` macro. Note that for statically allocated type objects,
@@ -65,7 +65,7 @@ type objects) *must* have the :attr:`ob_size` field.
This field is not inherited by subtypes.
-.. cmember:: PyTypeObject* PyObject.ob_type
+.. c:member:: PyTypeObject* PyObject.ob_type
This is the type's type, in other words its metatype. It is initialized by the
argument to the ``PyObject_HEAD_INIT`` macro, and its value should normally be
@@ -79,14 +79,14 @@ type objects) *must* have the :attr:`ob_size` field.
Foo_Type.ob_type = &PyType_Type;
This should be done before any instances of the type are created.
- :cfunc:`PyType_Ready` checks if :attr:`ob_type` is *NULL*, and if so,
+ :c:func:`PyType_Ready` checks if :attr:`ob_type` is *NULL*, and if so,
initializes it to the :attr:`ob_type` field of the base class.
- :cfunc:`PyType_Ready` will not change this field if it is non-zero.
+ :c:func:`PyType_Ready` will not change this field if it is non-zero.
This field is inherited by subtypes.
-.. cmember:: Py_ssize_t PyVarObject.ob_size
+.. c:member:: Py_ssize_t PyVarObject.ob_size
For statically allocated type objects, this should be initialized to zero. For
dynamically allocated type objects, this field has a special internal meaning.
@@ -94,7 +94,7 @@ type objects) *must* have the :attr:`ob_size` field.
This field is not inherited by subtypes.
-.. cmember:: char* PyTypeObject.tp_name
+.. c:member:: char* PyTypeObject.tp_name
Pointer to a NUL-terminated string containing the name of the type. For types
that are accessible as module globals, the string should be the full module
@@ -121,7 +121,7 @@ type objects) *must* have the :attr:`ob_size` field.
This field is not inherited by subtypes.
-.. cmember:: Py_ssize_t PyTypeObject.tp_basicsize
+.. c:member:: Py_ssize_t PyTypeObject.tp_basicsize
Py_ssize_t PyTypeObject.tp_itemsize
These fields allow calculating the size in bytes of instances of the type.
@@ -143,7 +143,7 @@ type objects) *must* have the :attr:`ob_size` field.
field).
The basic size includes the fields in the instance declared by the macro
- :cmacro:`PyObject_HEAD` or :cmacro:`PyObject_VAR_HEAD` (whichever is used to
+ :c:macro:`PyObject_HEAD` or :c:macro:`PyObject_VAR_HEAD` (whichever is used to
declare the instance struct) and this in turn includes the :attr:`_ob_prev` and
: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
@@ -163,14 +163,14 @@ type objects) *must* have the :attr:`ob_size` field.
alignment requirement for ``double``).
-.. cmember:: destructor PyTypeObject.tp_dealloc
+.. c:member:: destructor PyTypeObject.tp_dealloc
A pointer to the instance destructor function. This function must be defined
unless the type guarantees that its instances will never be deallocated (as is
the case for the singletons ``None`` and ``Ellipsis``).
- The destructor function is called by the :cfunc:`Py_DECREF` and
- :cfunc:`Py_XDECREF` macros when the new reference count is zero. At this point,
+ The destructor function is called by the :c:func:`Py_DECREF` and
+ :c:func:`Py_XDECREF` macros when the new reference count is zero. At this point,
the instance is still in existence, but there are no references to it. The
destructor function should free all references which the instance owns, free all
memory buffers owned by the instance (using the freeing function corresponding
@@ -179,15 +179,15 @@ type objects) *must* have the :attr:`ob_size` field.
subtypable (doesn't have the :const:`Py_TPFLAGS_BASETYPE` flag bit set), it is
permissible to call the object deallocator directly instead of via
:attr:`tp_free`. The object deallocator should be the one used to allocate the
- instance; this is normally :cfunc:`PyObject_Del` if the instance was allocated
- using :cfunc:`PyObject_New` or :cfunc:`PyObject_VarNew`, or
- :cfunc:`PyObject_GC_Del` if the instance was allocated using
- :cfunc:`PyObject_GC_New` or :cfunc:`PyObject_GC_NewVar`.
+ instance; this is normally :c:func:`PyObject_Del` if the instance was allocated
+ using :c:func:`PyObject_New` or :c:func:`PyObject_VarNew`, or
+ :c:func:`PyObject_GC_Del` if the instance was allocated using
+ :c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar`.
This field is inherited by subtypes.
-.. cmember:: printfunc PyTypeObject.tp_print
+.. c:member:: printfunc PyTypeObject.tp_print
An optional pointer to the instance print function.
@@ -198,7 +198,7 @@ type objects) *must* have the :attr:`ob_size` field.
*NULL*. A type should never implement :attr:`tp_print` in a way that produces
different output than :attr:`tp_repr` or :attr:`tp_str` would.
- The print function is called with the same signature as :cfunc:`PyObject_Print`:
+ The print function is called with the same signature as :c:func:`PyObject_Print`:
``int tp_print(PyObject *self, FILE *file, int flags)``. The *self* argument is
the instance to be printed. The *file* argument is the stdio file to which it
is to be printed. The *flags* argument is composed of flag bits. The only flag
@@ -216,47 +216,47 @@ type objects) *must* have the :attr:`ob_size` field.
This field is inherited by subtypes.
-.. cmember:: getattrfunc PyTypeObject.tp_getattr
+.. c:member:: getattrfunc PyTypeObject.tp_getattr
An optional pointer to the get-attribute-string function.
This field is deprecated. When it is defined, it should point to a function
that acts the same as the :attr:`tp_getattro` function, but taking a C string
instead of a Python string object to give the attribute name. The signature is
- the same as for :cfunc:`PyObject_GetAttrString`.
+ the same as for :c:func:`PyObject_GetAttrString`.
This field is inherited by subtypes together with :attr:`tp_getattro`: a subtype
inherits both :attr:`tp_getattr` and :attr:`tp_getattro` from its base type when
the subtype's :attr:`tp_getattr` and :attr:`tp_getattro` are both *NULL*.
-.. cmember:: setattrfunc PyTypeObject.tp_setattr
+.. c:member:: setattrfunc PyTypeObject.tp_setattr
An optional pointer to the set-attribute-string function.
This field is deprecated. When it is defined, it should point to a function
that acts the same as the :attr:`tp_setattro` function, but taking a C string
instead of a Python string object to give the attribute name. The signature is
- the same as for :cfunc:`PyObject_SetAttrString`.
+ the same as for :c:func:`PyObject_SetAttrString`.
This field is inherited by subtypes together with :attr:`tp_setattro`: a subtype
inherits both :attr:`tp_setattr` and :attr:`tp_setattro` from its base type when
the subtype's :attr:`tp_setattr` and :attr:`tp_setattro` are both *NULL*.
-.. cmember:: void* PyTypeObject.tp_reserved
+.. c:member:: void* PyTypeObject.tp_reserved
Reserved slot, formerly known as tp_compare.
-.. cmember:: reprfunc PyTypeObject.tp_repr
+.. c:member:: reprfunc PyTypeObject.tp_repr
.. index:: builtin: repr
An optional pointer to a function that implements the built-in function
:func:`repr`.
- The signature is the same as for :cfunc:`PyObject_Repr`; it must return a string
+ The signature is the same as for :c:func:`PyObject_Repr`; it must return a string
or a Unicode object. Ideally, this function should return a string that, when
passed to :func:`eval`, given a suitable environment, returns an object with the
same value. If this is not feasible, it should return a string starting with
@@ -269,7 +269,7 @@ type objects) *must* have the :attr:`ob_size` field.
This field is inherited by subtypes.
-.. cmember:: PyNumberMethods* tp_as_number
+.. c:member:: PyNumberMethods* tp_as_number
Pointer to an additional structure that contains fields relevant only to
objects which implement the number protocol. These fields are documented in
@@ -279,7 +279,7 @@ type objects) *must* have the :attr:`ob_size` field.
inherited individually.
-.. cmember:: PySequenceMethods* tp_as_sequence
+.. c:member:: PySequenceMethods* tp_as_sequence
Pointer to an additional structure that contains fields relevant only to
objects which implement the sequence protocol. These fields are documented
@@ -289,7 +289,7 @@ type objects) *must* have the :attr:`ob_size` field.
are inherited individually.
-.. cmember:: PyMappingMethods* tp_as_mapping
+.. c:member:: PyMappingMethods* tp_as_mapping
Pointer to an additional structure that contains fields relevant only to
objects which implement the mapping protocol. These fields are documented in
@@ -299,25 +299,25 @@ type objects) *must* have the :attr:`ob_size` field.
are inherited individually.
-.. cmember:: hashfunc PyTypeObject.tp_hash
+.. c:member:: hashfunc PyTypeObject.tp_hash
.. index:: builtin: hash
An optional pointer to a function that implements the built-in function
:func:`hash`.
- The signature is the same as for :cfunc:`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 :cfunc:`PyObject_HashNotImplemented` to
+ 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
as the equivalent of ``__hash__ = None`` at the Python level, causing
``isinstance(o, collections.Hashable)`` to correctly return ``False``. Note
that the converse is also true - setting ``__hash__ = None`` on a class at
the Python level will result in the ``tp_hash`` slot being set to
- :cfunc:`PyObject_HashNotImplemented`.
+ :c:func:`PyObject_HashNotImplemented`.
When this field is not set, an attempt to take the hash of the
object raises :exc:`TypeError`.
@@ -328,39 +328,39 @@ type objects) *must* have the :attr:`ob_size` field.
:attr:`tp_richcompare` and :attr:`tp_hash` are both *NULL*.
-.. cmember:: ternaryfunc PyTypeObject.tp_call
+.. c:member:: ternaryfunc PyTypeObject.tp_call
An optional pointer to a function that implements calling the object. This
should be *NULL* if the object is not callable. The signature is the same as
- for :cfunc:`PyObject_Call`.
+ for :c:func:`PyObject_Call`.
This field is inherited by subtypes.
-.. cmember:: reprfunc PyTypeObject.tp_str
+.. c:member:: reprfunc PyTypeObject.tp_str
An optional pointer to a function that implements the built-in operation
:func:`str`. (Note that :class:`str` is a type now, and :func:`str` calls the
- constructor for that type. This constructor calls :cfunc:`PyObject_Str` to do
- the actual work, and :cfunc:`PyObject_Str` will call this handler.)
+ constructor for that type. This constructor calls :c:func:`PyObject_Str` to do
+ the actual work, and :c:func:`PyObject_Str` will call this handler.)
- The signature is the same as for :cfunc:`PyObject_Str`; it must return a string
+ 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,
among other things, by the :func:`print` function.
- When this field is not set, :cfunc:`PyObject_Repr` is called to return a string
+ When this field is not set, :c:func:`PyObject_Repr` is called to return a string
representation.
This field is inherited by subtypes.
-.. cmember:: getattrofunc PyTypeObject.tp_getattro
+.. c:member:: getattrofunc PyTypeObject.tp_getattro
An optional pointer to the get-attribute function.
- The signature is the same as for :cfunc:`PyObject_GetAttr`. It is usually
- convenient to set this field to :cfunc:`PyObject_GenericGetAttr`, which
+ The signature is the same as for :c:func:`PyObject_GetAttr`. It is usually
+ convenient to set this field to :c:func:`PyObject_GenericGetAttr`, which
implements the normal way of looking for object attributes.
This field is inherited by subtypes together with :attr:`tp_getattr`: a subtype
@@ -368,12 +368,12 @@ type objects) *must* have the :attr:`ob_size` field.
the subtype's :attr:`tp_getattr` and :attr:`tp_getattro` are both *NULL*.
-.. cmember:: setattrofunc PyTypeObject.tp_setattro
+.. c:member:: setattrofunc PyTypeObject.tp_setattro
An optional pointer to the set-attribute function.
- The signature is the same as for :cfunc:`PyObject_SetAttr`. It is usually
- convenient to set this field to :cfunc:`PyObject_GenericSetAttr`, which
+ The signature is the same as for :c:func:`PyObject_SetAttr`. It is usually
+ convenient to set this field to :c:func:`PyObject_GenericSetAttr`, which
implements the normal way of setting object attributes.
This field is inherited by subtypes together with :attr:`tp_setattr`: a subtype
@@ -381,7 +381,7 @@ type objects) *must* have the :attr:`ob_size` field.
the subtype's :attr:`tp_setattr` and :attr:`tp_setattro` are both *NULL*.
-.. cmember:: PyBufferProcs* PyTypeObject.tp_as_buffer
+.. c:member:: PyBufferProcs* PyTypeObject.tp_as_buffer
Pointer to an additional structure that contains fields relevant only to objects
which implement the buffer interface. These fields are documented in
@@ -391,7 +391,7 @@ type objects) *must* have the :attr:`ob_size` field.
inherited individually.
-.. cmember:: long PyTypeObject.tp_flags
+.. c:member:: long PyTypeObject.tp_flags
This field is a bit mask of various flags. Some flags indicate variant
semantics for certain situations; others are used to indicate that certain
@@ -414,7 +414,7 @@ type objects) *must* have the :attr:`ob_size` field.
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
- :cfunc:`PyType_HasFeature` takes a type and a flags value, *tp* and *f*, and
+ :c:func:`PyType_HasFeature` takes a type and a flags value, *tp* and *f*, and
checks whether ``tp->tp_flags & f`` is non-zero.
@@ -438,20 +438,20 @@ type objects) *must* have the :attr:`ob_size` field.
.. data:: Py_TPFLAGS_READY
This bit is set when the type object has been fully initialized by
- :cfunc:`PyType_Ready`.
+ :c:func:`PyType_Ready`.
.. data:: Py_TPFLAGS_READYING
- This bit is set while :cfunc:`PyType_Ready` is in the process of initializing
+ This bit is set while :c:func:`PyType_Ready` is in the process of initializing
the type object.
.. data:: Py_TPFLAGS_HAVE_GC
This bit is set when the object supports garbage collection. If this bit
- is set, instances must be created using :cfunc:`PyObject_GC_New` and
- destroyed using :cfunc:`PyObject_GC_Del`. More information in section
+ is set, instances must be created using :c:func:`PyObject_GC_New` and
+ 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.
@@ -465,7 +465,7 @@ type objects) *must* have the :attr:`ob_size` field.
:const:`Py_TPFLAGS_HAVE_VERSION_TAG`.
-.. cmember:: char* PyTypeObject.tp_doc
+.. c:member:: char* PyTypeObject.tp_doc
An optional pointer to a NUL-terminated C string giving the docstring for this
type object. This is exposed as the :attr:`__doc__` attribute on the type and
@@ -474,7 +474,7 @@ type objects) *must* have the :attr:`ob_size` field.
This field is *not* inherited by subtypes.
-.. cmember:: traverseproc PyTypeObject.tp_traverse
+.. c:member:: traverseproc PyTypeObject.tp_traverse
An optional pointer to a traversal function for the garbage collector. This is
only used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. More information
@@ -483,8 +483,8 @@ type objects) *must* have the :attr:`ob_size` field.
The :attr:`tp_traverse` pointer is used by the garbage collector to detect
reference cycles. A typical implementation of a :attr:`tp_traverse` function
- simply calls :cfunc:`Py_VISIT` on each of the instance's members that are Python
- objects. For example, this is function :cfunc:`local_traverse` from the
+ 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::
static int
@@ -496,7 +496,7 @@ type objects) *must* have the :attr:`ob_size` field.
return 0;
}
- Note that :cfunc:`Py_VISIT` is called only on those members that can participate
+ Note that :c:func:`Py_VISIT` is called only on those members that can participate
in reference cycles. Although there is also a ``self->key`` member, it can only
be *NULL* or a Python string and therefore cannot be part of a reference cycle.
@@ -504,8 +504,8 @@ type objects) *must* have the :attr:`ob_size` field.
debugging aid you may want to visit it anyway just so the :mod:`gc` module's
:func:`get_referents` function will include it.
- Note that :cfunc:`Py_VISIT` requires the *visit* and *arg* parameters to
- :cfunc:`local_traverse` to have these specific names; don't name them just
+ Note that :c:func:`Py_VISIT` requires the *visit* and *arg* parameters to
+ :c:func:`local_traverse` to have these specific names; don't name them just
anything.
This field is inherited by subtypes together with :attr:`tp_clear` and the
@@ -514,7 +514,7 @@ type objects) *must* have the :attr:`ob_size` field.
the subtype.
-.. cmember:: inquiry PyTypeObject.tp_clear
+.. c:member:: inquiry PyTypeObject.tp_clear
An optional pointer to a clear function for the garbage collector. This is only
used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set.
@@ -543,7 +543,7 @@ type objects) *must* have the :attr:`ob_size` field.
return 0;
}
- The :cfunc:`Py_CLEAR` macro should be used, because clearing references is
+ The :c:func:`Py_CLEAR` macro should be used, because clearing references is
delicate: the reference to the contained object must not be decremented until
after the pointer to the contained object is set to *NULL*. This is because
decrementing the reference count may cause the contained object to become trash,
@@ -552,7 +552,7 @@ type objects) *must* have the :attr:`ob_size` field.
contained object). If it's possible for such code to reference *self* again,
it's important that the pointer to the contained object be *NULL* at that time,
so that *self* knows the contained object can no longer be used. The
- :cfunc:`Py_CLEAR` macro performs the operations in a safe order.
+ :c:func:`Py_CLEAR` macro performs the operations in a safe order.
Because the goal of :attr:`tp_clear` functions is to break reference cycles,
it's not necessary to clear contained objects like Python strings or Python
@@ -569,7 +569,7 @@ type objects) *must* have the :attr:`ob_size` field.
the subtype.
-.. cmember:: richcmpfunc PyTypeObject.tp_richcompare
+.. c:member:: richcmpfunc PyTypeObject.tp_richcompare
An optional pointer to the rich comparison function, whose signature is
``PyObject *tp_richcompare(PyObject *a, PyObject *b, int op)``.
@@ -591,7 +591,7 @@ type objects) *must* have the :attr:`ob_size` field.
*NULL*.
The following constants are defined to be used as the third argument for
- :attr:`tp_richcompare` and for :cfunc:`PyObject_RichCompare`:
+ :attr:`tp_richcompare` and for :c:func:`PyObject_RichCompare`:
+----------------+------------+
| Constant | Comparison |
@@ -610,13 +610,13 @@ type objects) *must* have the :attr:`ob_size` field.
+----------------+------------+
-.. cmember:: long PyTypeObject.tp_weaklistoffset
+.. c:member:: long PyTypeObject.tp_weaklistoffset
If the instances of this type are weakly referenceable, this field is greater
than zero and contains the offset in the instance structure of the weak
reference list head (ignoring the GC header, if present); this offset is used by
- :cfunc:`PyObject_ClearWeakRefs` and the :cfunc:`PyWeakref_\*` functions. The
- instance structure needs to include a field of type :ctype:`PyObject\*` which is
+ :c:func:`PyObject_ClearWeakRefs` and the :c:func:`PyWeakref_\*` functions. The
+ instance structure needs to include a field of type :c:type:`PyObject\*` which is
initialized to *NULL*.
Do not confuse this field with :attr:`tp_weaklist`; that is the list head for
@@ -641,18 +641,18 @@ type objects) *must* have the :attr:`ob_size` field.
:attr:`__weakref__`, the type inherits its :attr:`tp_weaklistoffset` from its
base type.
-.. cmember:: getiterfunc PyTypeObject.tp_iter
+.. 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).
- This function has the same signature as :cfunc:`PyObject_GetIter`.
+ This function has the same signature as :c:func:`PyObject_GetIter`.
This field is inherited by subtypes.
-.. cmember:: iternextfunc PyTypeObject.tp_iternext
+.. c:member:: iternextfunc PyTypeObject.tp_iternext
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`
@@ -664,14 +664,14 @@ type objects) *must* have the :attr:`ob_size` field.
function should return the iterator instance itself (not a new iterator
instance).
- This function has the same signature as :cfunc:`PyIter_Next`.
+ This function has the same signature as :c:func:`PyIter_Next`.
This field is inherited by subtypes.
-.. cmember:: struct PyMethodDef* PyTypeObject.tp_methods
+.. c:member:: struct PyMethodDef* PyTypeObject.tp_methods
- An optional pointer to a static *NULL*-terminated array of :ctype:`PyMethodDef`
+ An optional pointer to a static *NULL*-terminated array of :c:type:`PyMethodDef`
structures, declaring regular methods of this type.
For each entry in the array, an entry is added to the type's dictionary (see
@@ -681,9 +681,9 @@ type objects) *must* have the :attr:`ob_size` field.
different mechanism).
-.. cmember:: struct PyMemberDef* PyTypeObject.tp_members
+.. c:member:: struct PyMemberDef* PyTypeObject.tp_members
- An optional pointer to a static *NULL*-terminated array of :ctype:`PyMemberDef`
+ An optional pointer to a static *NULL*-terminated array of :c:type:`PyMemberDef`
structures, declaring regular data members (fields or slots) of instances of
this type.
@@ -694,9 +694,9 @@ type objects) *must* have the :attr:`ob_size` field.
different mechanism).
-.. cmember:: struct PyGetSetDef* PyTypeObject.tp_getset
+.. c:member:: struct PyGetSetDef* PyTypeObject.tp_getset
- An optional pointer to a static *NULL*-terminated array of :ctype:`PyGetSetDef`
+ An optional pointer to a static *NULL*-terminated array of :c:type:`PyGetSetDef`
structures, declaring computed attributes of instances of this type.
For each entry in the array, an entry is added to the type's dictionary (see
@@ -721,7 +721,7 @@ type objects) *must* have the :attr:`ob_size` field.
} PyGetSetDef;
-.. cmember:: PyTypeObject* PyTypeObject.tp_base
+.. c:member:: PyTypeObject* PyTypeObject.tp_base
An optional pointer to a base type from which type properties are inherited. At
this level, only single inheritance is supported; multiple inheritance require
@@ -732,13 +732,13 @@ type objects) *must* have the :attr:`ob_size` field.
:class:`object`).
-.. cmember:: PyObject* PyTypeObject.tp_dict
+.. c:member:: PyObject* PyTypeObject.tp_dict
- The type's dictionary is stored here by :cfunc:`PyType_Ready`.
+ The type's dictionary is stored here by :c:func:`PyType_Ready`.
This field should normally be initialized to *NULL* before PyType_Ready is
called; it may also be initialized to a dictionary containing initial attributes
- for the type. Once :cfunc:`PyType_Ready` has initialized the type, extra
+ for the type. Once :c:func:`PyType_Ready` has initialized the type, extra
attributes for the type may be added to this dictionary only if they don't
correspond to overloaded operations (like :meth:`__add__`).
@@ -746,7 +746,7 @@ type objects) *must* have the :attr:`ob_size` field.
are inherited through a different mechanism).
-.. cmember:: descrgetfunc PyTypeObject.tp_descr_get
+.. c:member:: descrgetfunc PyTypeObject.tp_descr_get
An optional pointer to a "descriptor get" function.
@@ -759,7 +759,7 @@ type objects) *must* have the :attr:`ob_size` field.
This field is inherited by subtypes.
-.. cmember:: descrsetfunc PyTypeObject.tp_descr_set
+.. c:member:: descrsetfunc PyTypeObject.tp_descr_set
An optional pointer to a "descriptor set" function.
@@ -772,12 +772,12 @@ type objects) *must* have the :attr:`ob_size` field.
.. XXX explain.
-.. cmember:: long PyTypeObject.tp_dictoffset
+.. c:member:: long PyTypeObject.tp_dictoffset
If the instances of this type have a dictionary containing instance variables,
this field is non-zero and contains the offset in the instances of the type of
the instance variable dictionary; this offset is used by
- :cfunc:`PyObject_GenericGetAttr`.
+ :c:func:`PyObject_GenericGetAttr`.
Do not confuse this field with :attr:`tp_dict`; that is the dictionary for
attributes of the type object itself.
@@ -805,7 +805,7 @@ type objects) *must* have the :attr:`ob_size` field.
taken from the type object, and :attr:`ob_size` is taken from the instance. The
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 :cfunc:`_PyObject_GetDictPtr`.)
+ yourself; it is done for you by :c:func:`_PyObject_GetDictPtr`.)
This field is inherited by subtypes, but see the rules listed below. A subtype
may override this offset; this means that the subtype instances store the
@@ -825,7 +825,7 @@ type objects) *must* have the :attr:`ob_size` field.
added as a feature just like :attr:`__weakref__` though.)
-.. cmember:: initproc PyTypeObject.tp_init
+.. c:member:: initproc PyTypeObject.tp_init
An optional pointer to an instance initialization function.
@@ -852,7 +852,7 @@ type objects) *must* have the :attr:`ob_size` field.
This field is inherited by subtypes.
-.. cmember:: allocfunc PyTypeObject.tp_alloc
+.. c:member:: allocfunc PyTypeObject.tp_alloc
An optional pointer to an instance allocation function.
@@ -875,11 +875,11 @@ type objects) *must* have the :attr:`ob_size` field.
This field is inherited by static subtypes, but not by dynamic subtypes
(subtypes created by a class statement); in the latter, this field is always set
- to :cfunc:`PyType_GenericAlloc`, to force a standard heap allocation strategy.
+ to :c:func:`PyType_GenericAlloc`, to force a standard heap allocation strategy.
That is also the recommended value for statically defined types.
-.. cmember:: newfunc PyTypeObject.tp_new
+.. c:member:: newfunc PyTypeObject.tp_new
An optional pointer to an instance creation function.
@@ -909,22 +909,22 @@ type objects) *must* have the :attr:`ob_size` field.
whose :attr:`tp_base` is *NULL* or ``&PyBaseObject_Type``.
-.. cmember:: destructor PyTypeObject.tp_free
+.. c:member:: destructor PyTypeObject.tp_free
An optional pointer to an instance deallocation function. Its signature is
- :ctype:`freefunc`::
+ :c:type:`freefunc`::
void tp_free(void *)
- An initializer that is compatible with this signature is :cfunc:`PyObject_Free`.
+ 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
- deallocator suitable to match :cfunc:`PyType_GenericAlloc` and the value of the
+ deallocator suitable to match :c:func:`PyType_GenericAlloc` and the value of the
:const:`Py_TPFLAGS_HAVE_GC` flag bit.
-.. cmember:: inquiry PyTypeObject.tp_is_gc
+.. c:member:: inquiry PyTypeObject.tp_is_gc
An optional pointer to a function called by the garbage collector.
@@ -939,13 +939,13 @@ type objects) *must* have the :attr:`ob_size` field.
int tp_is_gc(PyObject *self)
(The only example of this are types themselves. The metatype,
- :cdata:`PyType_Type`, defines this function to distinguish between statically
+ :c:data:`PyType_Type`, defines this function to distinguish between statically
and dynamically allocated types.)
This field is inherited by subtypes.
-.. cmember:: PyObject* PyTypeObject.tp_bases
+.. c:member:: PyObject* PyTypeObject.tp_bases
Tuple of base types.
@@ -955,25 +955,25 @@ type objects) *must* have the :attr:`ob_size` field.
This field is not inherited.
-.. cmember:: PyObject* PyTypeObject.tp_mro
+.. c:member:: PyObject* PyTypeObject.tp_mro
Tuple containing the expanded set of base types, starting with the type itself
and ending with :class:`object`, in Method Resolution Order.
- This field is not inherited; it is calculated fresh by :cfunc:`PyType_Ready`.
+ This field is not inherited; it is calculated fresh by :c:func:`PyType_Ready`.
-.. cmember:: PyObject* PyTypeObject.tp_cache
+.. c:member:: PyObject* PyTypeObject.tp_cache
Unused. Not inherited. Internal use only.
-.. cmember:: PyObject* PyTypeObject.tp_subclasses
+.. c:member:: PyObject* PyTypeObject.tp_subclasses
List of weak references to subclasses. Not inherited. Internal use only.
-.. cmember:: PyObject* PyTypeObject.tp_weaklist
+.. c:member:: PyObject* PyTypeObject.tp_weaklist
Weak reference list head, for weak references to this type object. Not
inherited. Internal use only.
@@ -984,22 +984,22 @@ documented here for completeness. None of these fields are inherited by
subtypes.
-.. cmember:: Py_ssize_t PyTypeObject.tp_allocs
+.. c:member:: Py_ssize_t PyTypeObject.tp_allocs
Number of allocations.
-.. cmember:: Py_ssize_t PyTypeObject.tp_frees
+.. c:member:: Py_ssize_t PyTypeObject.tp_frees
Number of frees.
-.. cmember:: Py_ssize_t PyTypeObject.tp_maxalloc
+.. c:member:: Py_ssize_t PyTypeObject.tp_maxalloc
Maximum simultaneously allocated objects.
-.. cmember:: PyTypeObject* PyTypeObject.tp_next
+.. c:member:: PyTypeObject* PyTypeObject.tp_next
Pointer to the next type object with a non-zero :attr:`tp_allocs` field.
@@ -1022,7 +1022,7 @@ Number Object Structures
.. sectionauthor:: Amaury Forgeot d'Arc
-.. ctype:: PyNumberMethods
+.. c:type:: PyNumberMethods
This structure holds pointers to the functions which an object uses to
implement the number protocol. Each function is used by the function of
@@ -1081,8 +1081,8 @@ Number Object Structures
.. note::
- The :cdata:`nb_reserved` field should always be ``NULL``. It
- was previously called :cdata:`nb_long`, and was renamed in
+ 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.
@@ -1094,26 +1094,26 @@ Mapping Object Structures
.. sectionauthor:: Amaury Forgeot d'Arc
-.. ctype:: PyMappingMethods
+.. c:type:: PyMappingMethods
This structure holds pointers to the functions which an object uses to
implement the mapping protocol. It has three members:
-.. cmember:: lenfunc PyMappingMethods.mp_length
+.. c:member:: lenfunc PyMappingMethods.mp_length
- This function is used by :cfunc:`PyMapping_Length` and
- :cfunc:`PyObject_Size`, and has the same signature. This slot may be set to
+ This function is used by :c:func:`PyMapping_Length` and
+ :c:func:`PyObject_Size`, and has the same signature. This slot may be set to
*NULL* if the object has no defined length.
-.. cmember:: binaryfunc PyMappingMethods.mp_subscript
+.. c:member:: binaryfunc PyMappingMethods.mp_subscript
- This function is used by :cfunc:`PyObject_GetItem` and has the same
- signature. This slot must be filled for the :cfunc:`PyMapping_Check`
+ This function is used by :c:func:`PyObject_GetItem` and has the same
+ signature. This slot must be filled for the :c:func:`PyMapping_Check`
function to return ``1``, it can be *NULL* otherwise.
-.. cmember:: objobjargproc PyMappingMethods.mp_ass_subscript
+.. c:member:: objobjargproc PyMappingMethods.mp_ass_subscript
- This function is used by :cfunc:`PyObject_SetItem` and has the same
+ This function is used by :c:func:`PyObject_SetItem` and has the same
signature. If this slot is *NULL*, the object does not support item
assignment.
@@ -1126,32 +1126,32 @@ Sequence Object Structures
.. sectionauthor:: Amaury Forgeot d'Arc
-.. ctype:: PySequenceMethods
+.. c:type:: PySequenceMethods
This structure holds pointers to the functions which an object uses to
implement the sequence protocol.
-.. cmember:: lenfunc PySequenceMethods.sq_length
+.. c:member:: lenfunc PySequenceMethods.sq_length
- This function is used by :cfunc:`PySequence_Size` and :cfunc:`PyObject_Size`,
+ This function is used by :c:func:`PySequence_Size` and :c:func:`PyObject_Size`,
and has the same signature.
-.. cmember:: binaryfunc PySequenceMethods.sq_concat
+.. c:member:: binaryfunc PySequenceMethods.sq_concat
- This function is used by :cfunc:`PySequence_Concat` and has the same
+ This function is used by :c:func:`PySequence_Concat` and has the same
signature. It is also used by the ``+`` operator, after trying the numeric
addition via the :attr:`tp_as_number.nb_add` slot.
-.. cmember:: ssizeargfunc PySequenceMethods.sq_repeat
+.. c:member:: ssizeargfunc PySequenceMethods.sq_repeat
- This function is used by :cfunc:`PySequence_Repeat` and has the same
+ This function is used by :c:func:`PySequence_Repeat` and has the same
signature. It is also used by the ``*`` operator, after trying numeric
multiplication via the :attr:`tp_as_number.nb_mul` slot.
-.. cmember:: ssizeargfunc PySequenceMethods.sq_item
+.. c:member:: ssizeargfunc PySequenceMethods.sq_item
- This function is used by :cfunc:`PySequence_GetItem` and has the same
- signature. This slot must be filled for the :cfunc:`PySequence_Check`
+ This function is used by :c:func:`PySequence_GetItem` and has the same
+ signature. This slot must be filled for the :c:func:`PySequence_Check`
function to return ``1``, it can be *NULL* otherwise.
Negative indexes are handled as follows: if the :attr:`sq_length` slot is
@@ -1159,27 +1159,27 @@ Sequence Object Structures
index which is passed to :attr:`sq_item`. If :attr:`sq_length` is *NULL*,
the index is passed as is to the function.
-.. cmember:: ssizeobjargproc PySequenceMethods.sq_ass_item
+.. c:member:: ssizeobjargproc PySequenceMethods.sq_ass_item
- This function is used by :cfunc:`PySequence_SetItem` and has the same
+ This function is used by :c:func:`PySequence_SetItem` and has the same
signature. This slot may be left to *NULL* if the object does not support
item assignment.
-.. cmember:: objobjproc PySequenceMethods.sq_contains
+.. c:member:: objobjproc PySequenceMethods.sq_contains
- This function may be used by :cfunc:`PySequence_Contains` and has the same
+ This function may be used by :c:func:`PySequence_Contains` and has the same
signature. This slot may be left to *NULL*, in this case
- :cfunc:`PySequence_Contains` simply traverses the sequence until it finds a
+ :c:func:`PySequence_Contains` simply traverses the sequence until it finds a
match.
-.. cmember:: binaryfunc PySequenceMethods.sq_inplace_concat
+.. c:member:: binaryfunc PySequenceMethods.sq_inplace_concat
- This function is used by :cfunc:`PySequence_InPlaceConcat` and has the same
+ This function is used by :c:func:`PySequence_InPlaceConcat` and has the same
signature. It should modify its first operand, and return it.
-.. cmember:: ssizeargfunc PySequenceMethods.sq_inplace_repeat
+.. c:member:: ssizeargfunc PySequenceMethods.sq_inplace_repeat
- This function is used by :cfunc:`PySequence_InPlaceRepeat` and has the same
+ This function is used by :c:func:`PySequence_InPlaceRepeat` and has the same
signature. It should modify its first operand, and return it.
.. XXX need to explain precedence between mapping and sequence
@@ -1199,40 +1199,40 @@ The :ref:`buffer interface <bufferobjects>` exports a model where an object can
data.
If an object does not export the buffer interface, then its :attr:`tp_as_buffer`
-member in the :ctype:`PyTypeObject` structure should be *NULL*. Otherwise, the
-:attr:`tp_as_buffer` will point to a :ctype:`PyBufferProcs` structure.
+member in the :c:type:`PyTypeObject` structure should be *NULL*. Otherwise, the
+:attr:`tp_as_buffer` will point to a :c:type:`PyBufferProcs` structure.
-.. ctype:: PyBufferProcs
+.. c:type:: PyBufferProcs
Structure used to hold the function pointers which define an implementation of
the buffer protocol.
- .. cmember:: getbufferproc bf_getbuffer
+ .. c:member:: getbufferproc bf_getbuffer
- This should fill a :ctype:`Py_buffer` with the necessary data for
+ 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 :ctype:`Py_buffer` struct to fill, and *flags* gives
+ export, *view* is the :c:type:`Py_buffer` struct to fill, and *flags* gives
the conditions the caller wants the memory under. (See
- :cfunc:`PyObject_GetBuffer` for all flags.) :cmember:`bf_getbuffer` is
+ :c:func:`PyObject_GetBuffer` for all flags.) :c:member:`bf_getbuffer` is
responsible for filling *view* with the appropriate information.
- (:cfunc:`PyBuffer_FillView` can be used in simple cases.) See
- :ctype:`Py_buffer`\s docs for what needs to be filled in.
+ (:c:func:`PyBuffer_FillView` can be used in simple cases.) See
+ :c:type:`Py_buffer`\s docs for what needs to be filled in.
- .. cmember:: releasebufferproc bf_releasebuffer
+ .. c:member:: releasebufferproc bf_releasebuffer
This should release the resources of the buffer. The signature of
- :cdata:`releasebufferproc` is ``void (PyObject *obj, Py_buffer *view)``.
- If the :cdata:`bf_releasebuffer` function is not provided (i.e. it is
+ :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.
The exporter of the buffer interface must make sure that any memory
- pointed to in the :ctype:`Py_buffer` structure remains valid until
+ pointed to in the :c:type:`Py_buffer` structure remains valid until
releasebuffer is called. Exporters will need to define a
- :cdata:`bf_releasebuffer` function if they can re-allocate their memory,
+ :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.
- See :cfunc:`PyBuffer_Release`.
+ See :c:func:`PyBuffer_Release`.
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index a91f258..f48eb73 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -17,75 +17,75 @@ These are the basic Unicode object types used for the Unicode implementation in
Python:
-.. ctype:: Py_UNICODE
+.. c:type:: Py_UNICODE
This type represents the storage type which is used by Python internally as
basis for holding Unicode ordinals. Python's default builds use a 16-bit type
- for :ctype:`Py_UNICODE` and store Unicode values internally as UCS2. It is also
+ for :c:type:`Py_UNICODE` and store Unicode values internally as UCS2. It is also
possible to build a UCS4 version of Python (most recent Linux distributions come
with UCS4 builds of Python). These builds then use a 32-bit type for
- :ctype:`Py_UNICODE` and store Unicode data internally as UCS4. On platforms
- where :ctype:`wchar_t` is available and compatible with the chosen Python
- Unicode build variant, :ctype:`Py_UNICODE` is a typedef alias for
- :ctype:`wchar_t` to enhance native platform compatibility. On all other
- platforms, :ctype:`Py_UNICODE` is a typedef alias for either :ctype:`unsigned
- short` (UCS2) or :ctype:`unsigned long` (UCS4).
+ :c:type:`Py_UNICODE` and store Unicode data internally as UCS4. On platforms
+ where :c:type:`wchar_t` is available and compatible with the chosen Python
+ Unicode build variant, :c:type:`Py_UNICODE` is a typedef alias for
+ :c:type:`wchar_t` to enhance native platform compatibility. On all other
+ platforms, :c:type:`Py_UNICODE` is a typedef alias for either :c:type:`unsigned
+ short` (UCS2) or :c:type:`unsigned long` (UCS4).
Note that UCS2 and UCS4 Python builds are not binary compatible. Please keep
this in mind when writing extensions or interfaces.
-.. ctype:: PyUnicodeObject
+.. c:type:: PyUnicodeObject
- This subtype of :ctype:`PyObject` represents a Python Unicode object.
+ This subtype of :c:type:`PyObject` represents a Python Unicode object.
-.. cvar:: PyTypeObject PyUnicode_Type
+.. c:var:: PyTypeObject PyUnicode_Type
- This instance of :ctype:`PyTypeObject` represents the Python Unicode type. It
+ This instance of :c:type:`PyTypeObject` represents the Python Unicode type. It
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:
-.. cfunction:: int PyUnicode_Check(PyObject *o)
+.. c:function:: int PyUnicode_Check(PyObject *o)
Return true if the object *o* is a Unicode object or an instance of a Unicode
subtype.
-.. cfunction:: int PyUnicode_CheckExact(PyObject *o)
+.. c:function:: int PyUnicode_CheckExact(PyObject *o)
Return true if the object *o* is a Unicode object, but not an instance of a
subtype.
-.. cfunction:: Py_ssize_t PyUnicode_GET_SIZE(PyObject *o)
+.. c:function:: Py_ssize_t PyUnicode_GET_SIZE(PyObject *o)
- Return the size of the object. *o* has to be a :ctype:`PyUnicodeObject` (not
+ Return the size of the object. *o* has to be a :c:type:`PyUnicodeObject` (not
checked).
-.. cfunction:: Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject *o)
+.. 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
- :ctype:`PyUnicodeObject` (not checked).
+ :c:type:`PyUnicodeObject` (not checked).
-.. cfunction:: Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *o)
+.. c:function:: Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *o)
- Return a pointer to the internal :ctype:`Py_UNICODE` buffer of the object. *o*
- has to be a :ctype:`PyUnicodeObject` (not checked).
+ Return a pointer to the internal :c:type:`Py_UNICODE` buffer of the object. *o*
+ has to be a :c:type:`PyUnicodeObject` (not checked).
-.. cfunction:: const char* PyUnicode_AS_DATA(PyObject *o)
+.. c:function:: const char* PyUnicode_AS_DATA(PyObject *o)
Return a pointer to the internal buffer of the object. *o* has to be a
- :ctype:`PyUnicodeObject` (not checked).
+ :c:type:`PyUnicodeObject` (not checked).
-.. cfunction:: int PyUnicode_ClearFreeList()
+.. c:function:: int PyUnicode_ClearFreeList()
Clear the free list. Return the total number of freed items.
@@ -98,57 +98,57 @@ are available through these macros which are mapped to C functions depending on
the Python configuration.
-.. cfunction:: int Py_UNICODE_ISSPACE(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISSPACE(Py_UNICODE ch)
Return 1 or 0 depending on whether *ch* is a whitespace character.
-.. cfunction:: int Py_UNICODE_ISLOWER(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISLOWER(Py_UNICODE ch)
Return 1 or 0 depending on whether *ch* is a lowercase character.
-.. cfunction:: int Py_UNICODE_ISUPPER(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISUPPER(Py_UNICODE ch)
Return 1 or 0 depending on whether *ch* is an uppercase character.
-.. cfunction:: int Py_UNICODE_ISTITLE(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISTITLE(Py_UNICODE ch)
Return 1 or 0 depending on whether *ch* is a titlecase character.
-.. cfunction:: int Py_UNICODE_ISLINEBREAK(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISLINEBREAK(Py_UNICODE ch)
Return 1 or 0 depending on whether *ch* is a linebreak character.
-.. cfunction:: int Py_UNICODE_ISDECIMAL(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISDECIMAL(Py_UNICODE ch)
Return 1 or 0 depending on whether *ch* is a decimal character.
-.. cfunction:: int Py_UNICODE_ISDIGIT(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISDIGIT(Py_UNICODE ch)
Return 1 or 0 depending on whether *ch* is a digit character.
-.. cfunction:: int Py_UNICODE_ISNUMERIC(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISNUMERIC(Py_UNICODE ch)
Return 1 or 0 depending on whether *ch* is a numeric character.
-.. cfunction:: int Py_UNICODE_ISALPHA(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISALPHA(Py_UNICODE ch)
Return 1 or 0 depending on whether *ch* is an alphabetic character.
-.. cfunction:: int Py_UNICODE_ISALNUM(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISALNUM(Py_UNICODE ch)
Return 1 or 0 depending on whether *ch* is an alphanumeric character.
-.. cfunction:: int Py_UNICODE_ISPRINTABLE(Py_UNICODE ch)
+.. 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
@@ -162,34 +162,34 @@ the Python configuration.
These APIs can be used for fast direct character conversions:
-.. cfunction:: Py_UNICODE Py_UNICODE_TOLOWER(Py_UNICODE ch)
+.. c:function:: Py_UNICODE Py_UNICODE_TOLOWER(Py_UNICODE ch)
Return the character *ch* converted to lower case.
-.. cfunction:: Py_UNICODE Py_UNICODE_TOUPPER(Py_UNICODE ch)
+.. c:function:: Py_UNICODE Py_UNICODE_TOUPPER(Py_UNICODE ch)
Return the character *ch* converted to upper case.
-.. cfunction:: Py_UNICODE Py_UNICODE_TOTITLE(Py_UNICODE ch)
+.. c:function:: Py_UNICODE Py_UNICODE_TOTITLE(Py_UNICODE ch)
Return the character *ch* converted to title case.
-.. cfunction:: int Py_UNICODE_TODECIMAL(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_TODECIMAL(Py_UNICODE ch)
Return the character *ch* converted to a decimal positive integer. Return
``-1`` if this is not possible. This macro does not raise exceptions.
-.. cfunction:: int Py_UNICODE_TODIGIT(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_TODIGIT(Py_UNICODE ch)
Return the character *ch* converted to a single digit integer. Return ``-1`` if
this is not possible. This macro does not raise exceptions.
-.. cfunction:: double Py_UNICODE_TONUMERIC(Py_UNICODE ch)
+.. c:function:: double Py_UNICODE_TONUMERIC(Py_UNICODE ch)
Return the character *ch* converted to a double. Return ``-1.0`` if this is not
possible. This macro does not raise exceptions.
@@ -202,7 +202,7 @@ To create Unicode objects and access their basic sequence properties, use these
APIs:
-.. cfunction:: PyObject* PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size)
+.. c:function:: PyObject* PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size)
Create a Unicode object from the Py_UNICODE buffer *u* of the given size. *u*
may be *NULL* which causes the contents to be undefined. It is the user's
@@ -212,7 +212,7 @@ APIs:
is *NULL*.
-.. cfunction:: PyObject* PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size)
+.. c:function:: PyObject* PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size)
Create a Unicode object from the char buffer *u*. The bytes will be interpreted
as being UTF-8 encoded. *u* may also be *NULL* which
@@ -222,23 +222,26 @@ APIs:
the resulting Unicode object is only allowed when *u* is *NULL*.
-.. cfunction:: PyObject *PyUnicode_FromString(const char *u)
+.. c:function:: PyObject *PyUnicode_FromString(const char *u)
Create a Unicode object from an UTF-8 encoded null-terminated char buffer
*u*.
-.. cfunction:: PyObject* PyUnicode_FromFormat(const char *format, ...)
+.. c:function:: PyObject* PyUnicode_FromFormat(const char *format, ...)
- Take a C :cfunc:`printf`\ -style *format* string and a variable number of
+ Take a C :c:func:`printf`\ -style *format* string and a variable number of
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 |
@@ -260,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")``. |
+-------------------+---------------------+--------------------------------+
@@ -296,34 +305,59 @@ APIs:
| | | *NULL*). |
+-------------------+---------------------+--------------------------------+
| :attr:`%S` | PyObject\* | The result of calling |
- | | | :func:`PyObject_Str`. |
+ | | | :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.
+ .. 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.
-.. cfunction:: PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs)
- Identical to :func:`PyUnicode_FromFormat` except that it takes exactly two
+.. c:function:: PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs)
+
+ Identical to :c:func:`PyUnicode_FromFormat` except that it takes exactly two
arguments.
+.. 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.
-.. cfunction:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode)
- Return a read-only pointer to the Unicode object's internal :ctype:`Py_UNICODE`
+.. c:function:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode)
+
+ Return a read-only pointer to the Unicode object's internal :c:type:`Py_UNICODE`
buffer, *NULL* if *unicode* is not a Unicode object.
-.. cfunction:: Py_ssize_t PyUnicode_GetSize(PyObject *unicode)
+.. 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).
+
+ .. versionadded:: 3.2
+
+
+.. c:function:: Py_ssize_t PyUnicode_GetSize(PyObject *unicode)
Return the length of the Unicode object.
-.. cfunction:: PyObject* PyUnicode_FromEncodedObject(PyObject *obj, const char *encoding, const char *errors)
+.. 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.
@@ -340,77 +374,125 @@ APIs:
decref'ing the returned objects.
-.. cfunction:: PyObject* PyUnicode_FromObject(PyObject *obj)
+.. c:function:: PyObject* PyUnicode_FromObject(PyObject *obj)
Shortcut for ``PyUnicode_FromEncodedObject(obj, NULL, "strict")`` which is used
throughout the interpreter whenever coercion to Unicode is needed.
-If the platform supports :ctype:`wchar_t` and provides a header file wchar.h,
+If the platform supports :c:type:`wchar_t` and provides a header file wchar.h,
Python can interface directly to this type using the following functions.
-Support is optimized if Python's own :ctype:`Py_UNICODE` type is identical to
-the system's :ctype:`wchar_t`.
+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,
-:cdata:`Py_FileSystemEncoding` should be used as the encoding, and
+: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 :cfunc:`PyUnicode_FSConverter` as the conversion function:
+used, passing :c:func:`PyUnicode_FSConverter` as the conversion function:
-.. cfunction:: int PyUnicode_FSConverter(PyObject* obj, void* result)
+.. c:function:: int PyUnicode_FSConverter(PyObject* obj, void* result)
- Convert *obj* into *result*, using :cdata:`Py_FileSystemDefaultEncoding`,
- and the ``"surrogateescape"`` error handler. *result* must be a
- ``PyObject*``, return a :func:`bytes` object which must be released if it
- is no longer used.
+ 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
-.. cfunction:: PyObject* PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size)
+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 null-terminated string using :cdata:`Py_FileSystemDefaultEncoding`
- and the ``"surrogateescape"`` error handler.
+ Decode a string using :c:data:`Py_FileSystemDefaultEncoding` and the
+ ``'surrogateescape'`` error handler, or ``'strict'`` on Windows.
- If :cdata:`Py_FileSystemDefaultEncoding` is not set, fall back to UTF-8.
+ If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the
+ locale encoding.
- Use :func:`PyUnicode_DecodeFSDefaultAndSize` if you know the string length.
+ .. versionchanged:: 3.2
+ Use ``'strict'`` error handler on Windows.
-.. cfunction:: PyObject* PyUnicode_DecodeFSDefault(const char *s)
- Decode a string using :cdata:`Py_FileSystemDefaultEncoding` and
- the ``"surrogateescape"`` error handler.
+.. c:function:: PyObject* PyUnicode_DecodeFSDefault(const char *s)
- If :cdata:`Py_FileSystemDefaultEncoding` is not set, fall back to UTF-8.
+ 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`.
+
+ If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the
+ locale encoding.
+
+ .. versionadded:: 3.2
wchar_t Support
"""""""""""""""
-:ctype:`wchar_t` support for platforms which support it:
+:c:type:`wchar_t` support for platforms which support it:
-.. cfunction:: PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size)
+.. c:function:: PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size)
- Create a Unicode object from the :ctype:`wchar_t` buffer *w* of the given *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.
-.. cfunction:: Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size)
+.. c:function:: Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size)
- Copy the Unicode object contents into the :ctype:`wchar_t` buffer *w*. At most
- *size* :ctype:`wchar_t` characters are copied (excluding a possibly trailing
- 0-termination character). Return the number of :ctype:`wchar_t` characters
- copied or -1 in case of an error. Note that the resulting :ctype:`wchar_t`
+ Copy the Unicode object contents into the :c:type:`wchar_t` buffer *w*. At most
+ *size* :c:type:`wchar_t` characters are copied (excluding a possibly trailing
+ 0-termination character). Return the number of :c:type:`wchar_t` characters
+ copied or -1 in case of an error. Note that the resulting :c:type:`wchar_t`
string may or may not be 0-terminated. It is the responsibility of the caller
- to make sure that the :ctype:`wchar_t` string is 0-terminated in case this is
+ to make sure that the :c:type:`wchar_t` string is 0-terminated in case this is
required by the application.
+.. 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`.
+
+ .. versionadded:: 3.2
+
+
.. _builtincodecs:
Built-in Codecs
@@ -425,8 +507,8 @@ constructor.
Setting encoding to *NULL* causes the default encoding to be used
which is ASCII. The file system calls should use
-:cfunc:`PyUnicode_FSConverter` for encoding file names. This uses the
-variable :cdata:`Py_FileSystemDefaultEncoding` internally. This
+: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).
@@ -445,7 +527,7 @@ Generic Codecs
These are the generic codec APIs:
-.. cfunction:: PyObject* PyUnicode_Decode(const char *s, Py_ssize_t size, const char *encoding, const char *errors)
+.. c:function:: PyObject* PyUnicode_Decode(const char *s, Py_ssize_t size, const char *encoding, const char *errors)
Create a Unicode object by decoding *size* bytes of the encoded string *s*.
*encoding* and *errors* have the same meaning as the parameters of the same name
@@ -454,16 +536,16 @@ These are the generic codec APIs:
the codec.
-.. cfunction:: PyObject* PyUnicode_Encode(const Py_UNICODE *s, Py_ssize_t size, const char *encoding, const char *errors)
+.. c:function:: PyObject* PyUnicode_Encode(const Py_UNICODE *s, Py_ssize_t size, const char *encoding, const char *errors)
- Encode the :ctype:`Py_UNICODE` buffer *s* of the given *size* and return a Python
+ Encode the :c:type:`Py_UNICODE` buffer *s* of the given *size* and return a 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.
-.. cfunction:: PyObject* PyUnicode_AsEncodedString(PyObject *unicode, const char *encoding, const char *errors)
+.. c:function:: PyObject* PyUnicode_AsEncodedString(PyObject *unicode, const char *encoding, const char *errors)
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
@@ -478,28 +560,28 @@ UTF-8 Codecs
These are the UTF-8 codec APIs:
-.. cfunction:: PyObject* PyUnicode_DecodeUTF8(const char *s, Py_ssize_t size, const char *errors)
+.. c:function:: PyObject* PyUnicode_DecodeUTF8(const char *s, Py_ssize_t size, const char *errors)
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.
-.. cfunction:: PyObject* PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed)
+.. c:function:: PyObject* PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed)
- If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeUTF8`. If
+ If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeUTF8`. If
*consumed* is not *NULL*, trailing incomplete UTF-8 byte sequences will not be
treated as an error. Those bytes will not be decoded and the number of bytes
that have been decoded will be stored in *consumed*.
-.. cfunction:: PyObject* PyUnicode_EncodeUTF8(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
+.. c:function:: PyObject* PyUnicode_EncodeUTF8(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
- Encode the :ctype:`Py_UNICODE` buffer *s* of the given *size* using UTF-8 and
+ 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.
-.. cfunction:: PyObject* PyUnicode_AsUTF8String(PyObject *unicode)
+.. c:function:: PyObject* PyUnicode_AsUTF8String(PyObject *unicode)
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
@@ -512,7 +594,7 @@ UTF-32 Codecs
These are the UTF-32 codec APIs:
-.. cfunction:: PyObject* PyUnicode_DecodeUTF32(const char *s, Py_ssize_t size, const char *errors, int *byteorder)
+.. c:function:: PyObject* PyUnicode_DecodeUTF32(const char *s, Py_ssize_t size, const char *errors, int *byteorder)
Decode *size* bytes from a UTF-32 encoded buffer string and return the
corresponding Unicode object. *errors* (if non-*NULL*) defines the error
@@ -540,16 +622,16 @@ These are the UTF-32 codec APIs:
Return *NULL* if an exception was raised by the codec.
-.. cfunction:: PyObject* PyUnicode_DecodeUTF32Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed)
+.. c:function:: PyObject* PyUnicode_DecodeUTF32Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed)
- If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeUTF32`. If
- *consumed* is not *NULL*, :cfunc:`PyUnicode_DecodeUTF32Stateful` will not treat
+ If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeUTF32`. If
+ *consumed* is not *NULL*, :c:func:`PyUnicode_DecodeUTF32Stateful` will not treat
trailing incomplete UTF-32 byte sequences (such as a number of bytes not divisible
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*.
-.. cfunction:: PyObject* PyUnicode_EncodeUTF32(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder)
+.. c:function:: PyObject* PyUnicode_EncodeUTF32(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder)
Return a Python bytes object holding the UTF-32 encoded value of the Unicode
data in *s*. Output is written according to the following byte order::
@@ -567,7 +649,7 @@ These are the UTF-32 codec APIs:
Return *NULL* if an exception was raised by the codec.
-.. cfunction:: PyObject* PyUnicode_AsUTF32String(PyObject *unicode)
+.. c:function:: PyObject* PyUnicode_AsUTF32String(PyObject *unicode)
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".
@@ -580,7 +662,7 @@ UTF-16 Codecs
These are the UTF-16 codec APIs:
-.. cfunction:: PyObject* PyUnicode_DecodeUTF16(const char *s, Py_ssize_t size, const char *errors, int *byteorder)
+.. c:function:: PyObject* PyUnicode_DecodeUTF16(const char *s, Py_ssize_t size, const char *errors, int *byteorder)
Decode *size* bytes from a UTF-16 encoded buffer string and return the
corresponding Unicode object. *errors* (if non-*NULL*) defines the error
@@ -607,16 +689,16 @@ These are the UTF-16 codec APIs:
Return *NULL* if an exception was raised by the codec.
-.. cfunction:: PyObject* PyUnicode_DecodeUTF16Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed)
+.. c:function:: PyObject* PyUnicode_DecodeUTF16Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed)
- If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeUTF16`. If
- *consumed* is not *NULL*, :cfunc:`PyUnicode_DecodeUTF16Stateful` will not treat
+ If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeUTF16`. If
+ *consumed* is not *NULL*, :c:func:`PyUnicode_DecodeUTF16Stateful` will not treat
trailing incomplete UTF-16 byte sequences (such as an odd number of bytes or a
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*.
-.. cfunction:: PyObject* PyUnicode_EncodeUTF16(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder)
+.. c:function:: PyObject* PyUnicode_EncodeUTF16(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder)
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::
@@ -628,14 +710,14 @@ These are the UTF-16 codec APIs:
If byteorder is ``0``, the output string will always start with the Unicode BOM
mark (U+FEFF). In the other two modes, no BOM mark is prepended.
- If *Py_UNICODE_WIDE* is defined, a single :ctype:`Py_UNICODE` value may get
- represented as a surrogate pair. If it is not defined, each :ctype:`Py_UNICODE`
+ If *Py_UNICODE_WIDE* is defined, a single :c:type:`Py_UNICODE` value may get
+ represented as a surrogate pair. If it is not defined, each :c:type:`Py_UNICODE`
values is interpreted as an UCS-2 character.
Return *NULL* if an exception was raised by the codec.
-.. cfunction:: PyObject* PyUnicode_AsUTF16String(PyObject *unicode)
+.. c:function:: PyObject* PyUnicode_AsUTF16String(PyObject *unicode)
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".
@@ -648,23 +730,23 @@ UTF-7 Codecs
These are the UTF-7 codec APIs:
-.. cfunction:: PyObject* PyUnicode_DecodeUTF7(const char *s, Py_ssize_t size, const char *errors)
+.. c:function:: PyObject* PyUnicode_DecodeUTF7(const char *s, Py_ssize_t size, const char *errors)
Create a Unicode object by decoding *size* bytes of the UTF-7 encoded string
*s*. Return *NULL* if an exception was raised by the codec.
-.. cfunction:: PyObject* PyUnicode_DecodeUTF7Stateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed)
+.. c:function:: PyObject* PyUnicode_DecodeUTF7Stateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed)
- If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeUTF7`. If
+ If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeUTF7`. If
*consumed* is not *NULL*, trailing incomplete UTF-7 base-64 sections will not
be treated as an error. Those bytes will not be decoded and the number of
bytes that have been decoded will be stored in *consumed*.
-.. cfunction:: PyObject* PyUnicode_EncodeUTF7(const Py_UNICODE *s, Py_ssize_t size, int base64SetO, int base64WhiteSpace, const char *errors)
+.. c:function:: PyObject* PyUnicode_EncodeUTF7(const Py_UNICODE *s, Py_ssize_t size, int base64SetO, int base64WhiteSpace, const char *errors)
- Encode the :ctype:`Py_UNICODE` buffer of the given size using UTF-7 and
+ Encode the :c:type:`Py_UNICODE` buffer of the given size using UTF-7 and
return a Python bytes object. Return *NULL* if an exception was raised by
the codec.
@@ -680,20 +762,20 @@ Unicode-Escape Codecs
These are the "Unicode Escape" codec APIs:
-.. cfunction:: PyObject* PyUnicode_DecodeUnicodeEscape(const char *s, Py_ssize_t size, const char *errors)
+.. c:function:: PyObject* PyUnicode_DecodeUnicodeEscape(const char *s, Py_ssize_t size, const char *errors)
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.
-.. cfunction:: PyObject* PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size)
+.. c:function:: PyObject* PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size)
- Encode the :ctype:`Py_UNICODE` buffer of the given size using Unicode-Escape and
+ Encode the :c:type:`Py_UNICODE` buffer of the given *size* using Unicode-Escape and
return a Python string object. Return *NULL* if an exception was raised by the
codec.
-.. cfunction:: PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode)
+.. c:function:: PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode)
Encode a Unicode object using Unicode-Escape and return the result as Python
string object. Error handling is "strict". Return *NULL* if an exception was
@@ -706,20 +788,20 @@ Raw-Unicode-Escape Codecs
These are the "Raw Unicode Escape" codec APIs:
-.. cfunction:: PyObject* PyUnicode_DecodeRawUnicodeEscape(const char *s, Py_ssize_t size, const char *errors)
+.. c:function:: PyObject* PyUnicode_DecodeRawUnicodeEscape(const char *s, Py_ssize_t size, const char *errors)
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.
-.. cfunction:: PyObject* PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
+.. c:function:: PyObject* PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
- Encode the :ctype:`Py_UNICODE` buffer of the given *size* using Raw-Unicode-Escape
+ Encode the :c:type:`Py_UNICODE` buffer of the given *size* using Raw-Unicode-Escape
and return a Python string object. Return *NULL* if an exception was raised by
the codec.
-.. cfunction:: PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode)
+.. c:function:: PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode)
Encode a Unicode object using Raw-Unicode-Escape and return the result as
Python string object. Error handling is "strict". Return *NULL* if an exception
@@ -733,20 +815,20 @@ These are the Latin-1 codec APIs: Latin-1 corresponds to the first 256 Unicode
ordinals and only these are accepted by the codecs during encoding.
-.. cfunction:: PyObject* PyUnicode_DecodeLatin1(const char *s, Py_ssize_t size, const char *errors)
+.. c:function:: PyObject* PyUnicode_DecodeLatin1(const char *s, Py_ssize_t size, const char *errors)
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.
-.. cfunction:: PyObject* PyUnicode_EncodeLatin1(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
+.. c:function:: PyObject* PyUnicode_EncodeLatin1(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
- Encode the :ctype:`Py_UNICODE` buffer of the given *size* using Latin-1 and
+ 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.
-.. cfunction:: PyObject* PyUnicode_AsLatin1String(PyObject *unicode)
+.. c:function:: PyObject* PyUnicode_AsLatin1String(PyObject *unicode)
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
@@ -760,20 +842,20 @@ These are the ASCII codec APIs. Only 7-bit ASCII data is accepted. All other
codes generate errors.
-.. cfunction:: PyObject* PyUnicode_DecodeASCII(const char *s, Py_ssize_t size, const char *errors)
+.. c:function:: PyObject* PyUnicode_DecodeASCII(const char *s, Py_ssize_t size, const char *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.
-.. cfunction:: PyObject* PyUnicode_EncodeASCII(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
+.. c:function:: PyObject* PyUnicode_EncodeASCII(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
- Encode the :ctype:`Py_UNICODE` buffer of the given *size* using ASCII and
+ 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.
-.. cfunction:: PyObject* PyUnicode_AsASCIIString(PyObject *unicode)
+.. c:function:: PyObject* PyUnicode_AsASCIIString(PyObject *unicode)
Encode a Unicode object using ASCII and return the result as Python bytes
object. Error handling is "strict". Return *NULL* if an exception was
@@ -806,7 +888,7 @@ characters to different code points.
These are the mapping codec APIs:
-.. cfunction:: PyObject* PyUnicode_DecodeCharmap(const char *s, Py_ssize_t size, PyObject *mapping, const char *errors)
+.. c:function:: PyObject* PyUnicode_DecodeCharmap(const char *s, Py_ssize_t size, PyObject *mapping, const char *errors)
Create a Unicode object by decoding *size* bytes of the encoded string *s* using
the given *mapping* object. Return *NULL* if an exception was raised by the
@@ -816,14 +898,14 @@ These are the mapping codec APIs:
treated as "undefined mapping".
-.. cfunction:: PyObject* PyUnicode_EncodeCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *mapping, const char *errors)
+.. c:function:: PyObject* PyUnicode_EncodeCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *mapping, const char *errors)
- Encode the :ctype:`Py_UNICODE` buffer of the given *size* using the given
+ Encode the :c:type:`Py_UNICODE` buffer of the given *size* using the given
*mapping* object and return a Python string object. Return *NULL* if an
exception was raised by the codec.
-.. cfunction:: PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping)
+.. c:function:: PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping)
Encode a Unicode object using the given *mapping* object and return the result
as Python string object. Error handling is "strict". Return *NULL* if an
@@ -832,9 +914,9 @@ These are the mapping codec APIs:
The following codec API is special in that maps Unicode to Unicode.
-.. cfunction:: PyObject* PyUnicode_TranslateCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *table, const char *errors)
+.. c:function:: PyObject* PyUnicode_TranslateCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *table, const char *errors)
- Translate a :ctype:`Py_UNICODE` buffer of the given *size* by applying a
+ Translate a :c:type:`Py_UNICODE` buffer of the given *size* by applying a
character mapping *table* to it and return the resulting Unicode object. Return
*NULL* when an exception was raised by the codec.
@@ -846,6 +928,7 @@ The following codec API is special in that maps Unicode to Unicode.
:exc:`LookupError`) are left untouched and are copied as-is.
+
MBCS codecs for Windows
"""""""""""""""""""""""
@@ -854,29 +937,28 @@ 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.
-
-.. cfunction:: PyObject* PyUnicode_DecodeMBCS(const char *s, Py_ssize_t size, const char *errors)
+.. 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.
-.. cfunction:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, int size, const char *errors, int *consumed)
+.. c:function:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, int size, const char *errors, int *consumed)
- If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeMBCS`. If
- *consumed* is not *NULL*, :cfunc:`PyUnicode_DecodeMBCSStateful` will not decode
+ If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeMBCS`. If
+ *consumed* is not *NULL*, :c:func:`PyUnicode_DecodeMBCSStateful` will not decode
trailing lead byte and the number of bytes that have been decoded will be stored
in *consumed*.
-.. cfunction:: PyObject* PyUnicode_EncodeMBCS(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
+.. c:function:: PyObject* PyUnicode_EncodeMBCS(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
- Encode the :ctype:`Py_UNICODE` buffer of the given *size* using MBCS and return
+ 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.
-.. cfunction:: PyObject* PyUnicode_AsMBCSString(PyObject *unicode)
+.. c:function:: PyObject* PyUnicode_AsMBCSString(PyObject *unicode)
Encode a Unicode object using MBCS and return the result as Python bytes
object. Error handling is "strict". Return *NULL* if an exception was
@@ -899,12 +981,12 @@ integers as appropriate.
They all return *NULL* or ``-1`` if an exception occurs.
-.. cfunction:: PyObject* PyUnicode_Concat(PyObject *left, PyObject *right)
+.. c:function:: PyObject* PyUnicode_Concat(PyObject *left, PyObject *right)
Concat two strings giving a new Unicode string.
-.. cfunction:: PyObject* PyUnicode_Split(PyObject *s, PyObject *sep, Py_ssize_t maxsplit)
+.. c:function:: PyObject* PyUnicode_Split(PyObject *s, PyObject *sep, Py_ssize_t maxsplit)
Split a string giving a list of Unicode strings. If *sep* is *NULL*, splitting
will be done at all whitespace substrings. Otherwise, splits occur at the given
@@ -912,14 +994,14 @@ They all return *NULL* or ``-1`` if an exception occurs.
set. Separators are not included in the resulting list.
-.. cfunction:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend)
+.. c:function:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend)
Split a Unicode string at line breaks, returning a list of Unicode strings.
CRLF is considered to be one line break. If *keepend* is 0, the Line break
characters are not included in the resulting strings.
-.. cfunction:: PyObject* PyUnicode_Translate(PyObject *str, PyObject *table, const char *errors)
+.. c:function:: PyObject* PyUnicode_Translate(PyObject *str, PyObject *table, const char *errors)
Translate a string by applying a character mapping table to it and return the
resulting Unicode object.
@@ -935,20 +1017,20 @@ They all return *NULL* or ``-1`` if an exception occurs.
use the default error handling.
-.. cfunction:: PyObject* PyUnicode_Join(PyObject *separator, PyObject *seq)
+.. c:function:: PyObject* PyUnicode_Join(PyObject *separator, PyObject *seq)
Join a sequence of strings using the given *separator* and return the resulting
Unicode string.
-.. cfunction:: int PyUnicode_Tailmatch(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction)
+.. c:function:: int PyUnicode_Tailmatch(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction)
Return 1 if *substr* matches ``str[start:end]`` at the given tail end
(*direction* == -1 means to do a prefix match, *direction* == 1 a suffix match),
0 otherwise. Return ``-1`` if an error occurred.
-.. cfunction:: Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction)
+.. c:function:: Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction)
Return the first position of *substr* in ``str[start:end]`` using the given
*direction* (*direction* == 1 means to do a forward search, *direction* == -1 a
@@ -957,32 +1039,34 @@ They all return *NULL* or ``-1`` if an exception occurs.
occurred and an exception has been set.
-.. cfunction:: Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end)
+.. 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.
-.. cfunction:: PyObject* PyUnicode_Replace(PyObject *str, PyObject *substr, PyObject *replstr, Py_ssize_t maxcount)
+.. c:function:: PyObject* PyUnicode_Replace(PyObject *str, PyObject *substr, PyObject *replstr, Py_ssize_t maxcount)
Replace at most *maxcount* occurrences of *substr* in *str* with *replstr* and
return the resulting Unicode object. *maxcount* == -1 means replace all
occurrences.
-.. cfunction:: int PyUnicode_Compare(PyObject *left, PyObject *right)
+.. c:function:: int PyUnicode_Compare(PyObject *left, PyObject *right)
Compare two strings and return -1, 0, 1 for less than, equal, and greater than,
respectively.
-.. cfunction:: int PyUnicode_CompareWithASCIIString(PyObject *uni, char *string)
+.. 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.
+ 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".
-.. cfunction:: int PyUnicode_RichCompare(PyObject *left, PyObject *right, int op)
+.. c:function:: int PyUnicode_RichCompare(PyObject *left, PyObject *right, int op)
Rich compare two unicode strings and return one of the following:
@@ -998,13 +1082,13 @@ They all return *NULL* or ``-1`` if an exception occurs.
:const:`Py_NE`, :const:`Py_LT`, and :const:`Py_LE`.
-.. cfunction:: PyObject* PyUnicode_Format(PyObject *format, PyObject *args)
+.. c:function:: PyObject* PyUnicode_Format(PyObject *format, PyObject *args)
Return a new string object from *format* and *args*; this is analogous to
``format % args``. The *args* argument must be a tuple.
-.. cfunction:: int PyUnicode_Contains(PyObject *container, PyObject *element)
+.. c:function:: int PyUnicode_Contains(PyObject *container, PyObject *element)
Check whether *element* is contained in *container* and return true or false
accordingly.
@@ -1013,7 +1097,7 @@ They all return *NULL* or ``-1`` if an exception occurs.
there was an error.
-.. cfunction:: void PyUnicode_InternInPlace(PyObject **string)
+.. 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
@@ -1026,10 +1110,10 @@ They all return *NULL* or ``-1`` if an exception occurs.
if and only if you owned it before the call.)
-.. cfunction:: PyObject* PyUnicode_InternFromString(const char *v)
+.. c:function:: PyObject* PyUnicode_InternFromString(const char *v)
- A combination of :cfunc:`PyUnicode_FromString` and
- :cfunc:`PyUnicode_InternInPlace`, returning either a new unicode string object
+ 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/veryhigh.rst b/Doc/c-api/veryhigh.rst
index 66789a9..26e0716 100644
--- a/Doc/c-api/veryhigh.rst
+++ b/Doc/c-api/veryhigh.rst
@@ -16,21 +16,21 @@ parameter. The available start symbols are :const:`Py_eval_input`,
:const:`Py_file_input`, and :const:`Py_single_input`. These are described
following the functions which accept them as parameters.
-Note also that several of these functions take :ctype:`FILE\*` parameters. One
-particular issue which needs to be handled carefully is that the :ctype:`FILE`
+Note also that several of these functions take :c:type:`FILE\*` parameters. One
+particular issue which needs to be handled carefully is that the :c:type:`FILE`
structure for different C libraries can be different and incompatible. Under
Windows (at least), it is possible for dynamically linked extensions to actually
-use different libraries, so care should be taken that :ctype:`FILE\*` parameters
+use different libraries, so care should be taken that :c:type:`FILE\*` parameters
are only passed to these functions if it is certain that they were created by
the same library that the Python runtime is using.
-.. cfunction:: int Py_Main(int argc, wchar_t **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 :cfunc:`main` function (converted to wchar_t
+ a C program's :c:func:`main` 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
@@ -43,40 +43,41 @@ the same library that the Python runtime is using.
``Py_InspectFlag`` is not set.
-.. cfunction:: int PyRun_AnyFile(FILE *fp, const char *filename)
+.. c:function:: int PyRun_AnyFile(FILE *fp, const char *filename)
- This is a simplified interface to :cfunc:`PyRun_AnyFileExFlags` below, leaving
+ This is a simplified interface to :c:func:`PyRun_AnyFileExFlags` below, leaving
*closeit* set to ``0`` and *flags* set to *NULL*.
-.. cfunction:: int PyRun_AnyFileFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
+.. c:function:: int PyRun_AnyFileFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
- This is a simplified interface to :cfunc:`PyRun_AnyFileExFlags` below, leaving
+ This is a simplified interface to :c:func:`PyRun_AnyFileExFlags` below, leaving
the *closeit* argument set to ``0``.
-.. cfunction:: int PyRun_AnyFileEx(FILE *fp, const char *filename, int closeit)
+.. c:function:: int PyRun_AnyFileEx(FILE *fp, const char *filename, int closeit)
- This is a simplified interface to :cfunc:`PyRun_AnyFileExFlags` below, leaving
+ This is a simplified interface to :c:func:`PyRun_AnyFileExFlags` below, leaving
the *flags* argument set to *NULL*.
-.. cfunction:: int PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, PyCompilerFlags *flags)
+.. c:function:: int PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, PyCompilerFlags *flags)
If *fp* refers to a file associated with an interactive device (console or
terminal input or Unix pseudo-terminal), return the value of
- :cfunc:`PyRun_InteractiveLoop`, otherwise return the result of
- :cfunc:`PyRun_SimpleFile`. If *filename* is *NULL*, this function uses
- ``"???"`` as the filename.
+ :c:func:`PyRun_InteractiveLoop`, otherwise return the result of
+ :c:func:`PyRun_SimpleFile`. *filename* is decoded from the filesystem
+ encoding (:func:`sys.getfilesystemencoding`). If *filename* is *NULL*, this
+ function uses ``"???"`` as the filename.
-.. cfunction:: int PyRun_SimpleString(const char *command)
+.. c:function:: int PyRun_SimpleString(const char *command)
- This is a simplified interface to :cfunc:`PyRun_SimpleStringFlags` below,
+ This is a simplified interface to :c:func:`PyRun_SimpleStringFlags` below,
leaving the *PyCompilerFlags\** argument set to NULL.
-.. cfunction:: int PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
+.. c:function:: int PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
Executes the Python source code from *command* in the :mod:`__main__` module
according to the *flags* argument. If :mod:`__main__` does not already exist, it
@@ -89,103 +90,109 @@ the same library that the Python runtime is using.
``Py_InspectFlag`` is not set.
-.. cfunction:: int PyRun_SimpleFile(FILE *fp, const char *filename)
+.. c:function:: int PyRun_SimpleFile(FILE *fp, const char *filename)
- This is a simplified interface to :cfunc:`PyRun_SimpleFileExFlags` below,
+ This is a simplified interface to :c:func:`PyRun_SimpleFileExFlags` below,
leaving *closeit* set to ``0`` and *flags* set to *NULL*.
-.. cfunction:: int PyRun_SimpleFileFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
+.. c:function:: int PyRun_SimpleFileFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
- This is a simplified interface to :cfunc:`PyRun_SimpleFileExFlags` below,
+ This is a simplified interface to :c:func:`PyRun_SimpleFileExFlags` below,
leaving *closeit* set to ``0``.
-.. cfunction:: int PyRun_SimpleFileEx(FILE *fp, const char *filename, int closeit)
+.. c:function:: int PyRun_SimpleFileEx(FILE *fp, const char *filename, int closeit)
- This is a simplified interface to :cfunc:`PyRun_SimpleFileExFlags` below,
+ This is a simplified interface to :c:func:`PyRun_SimpleFileExFlags` below,
leaving *flags* set to *NULL*.
-.. cfunction:: int PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, PyCompilerFlags *flags)
+.. c:function:: int PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, PyCompilerFlags *flags)
- Similar to :cfunc:`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.
+ 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, it is decoded from the filesystem encoding
+ (:func:`sys.getfilesystemencoding`). If *closeit* is true, the file is
+ closed before PyRun_SimpleFileExFlags returns.
-.. cfunction:: int PyRun_InteractiveOne(FILE *fp, const char *filename)
+.. c:function:: int PyRun_InteractiveOne(FILE *fp, const char *filename)
- This is a simplified interface to :cfunc:`PyRun_InteractiveOneFlags` below,
+ This is a simplified interface to :c:func:`PyRun_InteractiveOneFlags` below,
leaving *flags* set to *NULL*.
-.. cfunction:: int PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
+.. c:function:: int PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
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
:file:`Python.h`, so must be included specifically if needed.)
-.. cfunction:: int PyRun_InteractiveLoop(FILE *fp, const char *filename)
+.. c:function:: int PyRun_InteractiveLoop(FILE *fp, const char *filename)
- This is a simplified interface to :cfunc:`PyRun_InteractiveLoopFlags` below,
+ This is a simplified interface to :c:func:`PyRun_InteractiveLoopFlags` below,
leaving *flags* set to *NULL*.
-.. cfunction:: int PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
+.. c:function:: int PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
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.
-.. cfunction:: struct _node* PyParser_SimpleParseString(const char *str, int start)
+.. c:function:: struct _node* PyParser_SimpleParseString(const char *str, int start)
This is a simplified interface to
- :cfunc:`PyParser_SimpleParseStringFlagsFilename` below, leaving *filename* set
+ :c:func:`PyParser_SimpleParseStringFlagsFilename` below, leaving *filename* set
to *NULL* and *flags* set to ``0``.
-.. cfunction:: struct _node* PyParser_SimpleParseStringFlags( const char *str, int start, int flags)
+.. c:function:: struct _node* PyParser_SimpleParseStringFlags( const char *str, int start, int flags)
This is a simplified interface to
- :cfunc:`PyParser_SimpleParseStringFlagsFilename` below, leaving *filename* set
+ :c:func:`PyParser_SimpleParseStringFlagsFilename` below, leaving *filename* set
to *NULL*.
-.. cfunction:: struct _node* PyParser_SimpleParseStringFlagsFilename( const char *str, const char *filename, int start, int flags)
+.. c:function:: struct _node* PyParser_SimpleParseStringFlagsFilename( const char *str, const char *filename, int start, int flags)
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`).
-.. cfunction:: struct _node* PyParser_SimpleParseFile(FILE *fp, const char *filename, int start)
+.. c:function:: struct _node* PyParser_SimpleParseFile(FILE *fp, const char *filename, int start)
- This is a simplified interface to :cfunc:`PyParser_SimpleParseFileFlags` below,
+ This is a simplified interface to :c:func:`PyParser_SimpleParseFileFlags` below,
leaving *flags* set to ``0``
-.. cfunction:: struct _node* PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags)
+.. c:function:: struct _node* PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags)
- Similar to :cfunc:`PyParser_SimpleParseStringFlagsFilename`, but the Python
+ Similar to :c:func:`PyParser_SimpleParseStringFlagsFilename`, but the Python
source code is read from *fp* instead of an in-memory string.
-.. cfunction:: PyObject* PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals)
+.. c:function:: PyObject* PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals)
- This is a simplified interface to :cfunc:`PyRun_StringFlags` below, leaving
+ This is a simplified interface to :c:func:`PyRun_StringFlags` below, leaving
*flags* set to *NULL*.
-.. cfunction:: PyObject* PyRun_StringFlags(const char *str, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags)
+.. c:function:: PyObject* PyRun_StringFlags(const char *str, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags)
Execute Python source code from *str* in the context specified by the
dictionaries *globals* and *locals* with the compiler flags specified by
@@ -196,57 +203,73 @@ the same library that the Python runtime is using.
exception was raised.
-.. cfunction:: PyObject* PyRun_File(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals)
+.. c:function:: PyObject* PyRun_File(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals)
- This is a simplified interface to :cfunc:`PyRun_FileExFlags` below, leaving
+ This is a simplified interface to :c:func:`PyRun_FileExFlags` below, leaving
*closeit* set to ``0`` and *flags* set to *NULL*.
-.. cfunction:: PyObject* PyRun_FileEx(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, int closeit)
+.. c:function:: PyObject* PyRun_FileEx(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, int closeit)
- This is a simplified interface to :cfunc:`PyRun_FileExFlags` below, leaving
+ This is a simplified interface to :c:func:`PyRun_FileExFlags` below, leaving
*flags* set to *NULL*.
-.. cfunction:: PyObject* PyRun_FileFlags(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags)
+.. c:function:: PyObject* PyRun_FileFlags(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags)
- This is a simplified interface to :cfunc:`PyRun_FileExFlags` below, leaving
+ This is a simplified interface to :c:func:`PyRun_FileExFlags` below, leaving
*closeit* set to ``0``.
-.. cfunction:: PyObject* PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, int closeit, PyCompilerFlags *flags)
+.. c:function:: PyObject* PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, int closeit, PyCompilerFlags *flags)
- Similar to :cfunc:`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.
- If *closeit* is true, the file is closed before :cfunc:`PyRun_FileExFlags`
+ 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,
+ it is decoded from the filesystem encoding (:func:`sys.getfilesystemencoding`).
+ If *closeit* is true, the file is closed before :c:func:`PyRun_FileExFlags`
returns.
-.. cfunction:: PyObject* Py_CompileString(const char *str, const char *filename, int start)
+.. c:function:: PyObject* Py_CompileString(const char *str, const char *filename, int start)
- This is a simplified interface to :cfunc:`Py_CompileStringFlags` below, leaving
+ This is a simplified interface to :c:func:`Py_CompileStringFlags` below, leaving
*flags* set to *NULL*.
-.. cfunction:: PyObject* Py_CompileStringFlags(const char *str, const char *filename, int start, PyCompilerFlags *flags)
+.. 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
-.. cfunction:: 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 :cfunc:`PyEval_EvalCodeEx`, with just
+ 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*.
-.. cfunction:: 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
@@ -254,13 +277,13 @@ the same library that the Python runtime is using.
cells.
-.. cfunction:: PyObject* PyEval_EvalFrame(PyFrameObject *f)
+.. c:function:: PyObject* PyEval_EvalFrame(PyFrameObject *f)
Evaluate an execution frame. This is a simplified interface to
PyEval_EvalFrameEx, for backward compatibility.
-.. cfunction:: PyObject* PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
+.. c:function:: PyObject* PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
This is the main, unvarnished function of Python interpretation. It is
literally 2000 lines long. The code object associated with the execution
@@ -270,39 +293,39 @@ the same library that the Python runtime is using.
:meth:`throw` methods of generator objects.
-.. cfunction:: int PyEval_MergeCompilerFlags(PyCompilerFlags *cf)
+.. c:function:: int PyEval_MergeCompilerFlags(PyCompilerFlags *cf)
This function changes the flags of the current evaluation frame, and returns
true on success, false on failure.
-.. cvar:: int Py_eval_input
+.. c:var:: int Py_eval_input
.. index:: single: Py_CompileString()
The start symbol from the Python grammar for isolated expressions; for use with
- :cfunc:`Py_CompileString`.
+ :c:func:`Py_CompileString`.
-.. cvar:: int Py_file_input
+.. c:var:: int Py_file_input
.. index:: single: Py_CompileString()
The start symbol from the Python grammar for sequences of statements as read
- from a file or other source; for use with :cfunc:`Py_CompileString`. This is
+ from a file or other source; for use with :c:func:`Py_CompileString`. This is
the symbol to use when compiling arbitrarily long Python source code.
-.. cvar:: int Py_single_input
+.. c:var:: int Py_single_input
.. index:: single: Py_CompileString()
The start symbol from the Python grammar for a single statement; for use with
- :cfunc:`Py_CompileString`. This is the symbol used for the interactive
+ :c:func:`Py_CompileString`. This is the symbol used for the interactive
interpreter loop.
-.. ctype:: struct PyCompilerFlags
+.. c:type:: struct PyCompilerFlags
This is the structure used to hold compiler flags. In cases where code is only
being compiled, it is passed as ``int flags``, and in cases where code is being
@@ -318,7 +341,7 @@ the same library that the Python runtime is using.
}
-.. cvar:: int CO_FUTURE_DIVISION
+.. c:var:: int CO_FUTURE_DIVISION
This bit can be set in *flags* to cause division operator ``/`` to be
interpreted as "true division" according to :pep:`238`.
diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst
index 8a36110..6b053c8 100644
--- a/Doc/c-api/weakref.rst
+++ b/Doc/c-api/weakref.rst
@@ -11,22 +11,22 @@ simple reference object, and the second acts as a proxy for the original object
as much as it can.
-.. cfunction:: int PyWeakref_Check(ob)
+.. c:function:: int PyWeakref_Check(ob)
Return true if *ob* is either a reference or proxy object.
-.. cfunction:: int PyWeakref_CheckRef(ob)
+.. c:function:: int PyWeakref_CheckRef(ob)
Return true if *ob* is a reference object.
-.. cfunction:: int PyWeakref_CheckProxy(ob)
+.. c:function:: int PyWeakref_CheckProxy(ob)
Return true if *ob* is a proxy object.
-.. cfunction:: PyObject* PyWeakref_NewRef(PyObject *ob, PyObject *callback)
+.. c:function:: PyObject* PyWeakref_NewRef(PyObject *ob, PyObject *callback)
Return a weak reference object for the object *ob*. This will always return
a new reference, but is not guaranteed to create a new object; an existing
@@ -38,7 +38,7 @@ as much as it can.
*NULL*, this will return *NULL* and raise :exc:`TypeError`.
-.. cfunction:: PyObject* PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
+.. c:function:: PyObject* PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
Return a weak reference proxy object for the object *ob*. This will always
return a new reference, but is not guaranteed to create a new object; an
@@ -50,7 +50,7 @@ as much as it can.
``None``, or *NULL*, this will return *NULL* and raise :exc:`TypeError`.
-.. cfunction:: PyObject* PyWeakref_GetObject(PyObject *ref)
+.. 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`.
@@ -58,12 +58,12 @@ as much as it can.
.. warning::
This function returns a **borrowed reference** to the referenced object.
- This means that you should always call :cfunc:`Py_INCREF` on the object
+ This means that you should always call :c:func:`Py_INCREF` on the object
except if you know that it cannot be destroyed while you are still
using it.
-.. cfunction:: PyObject* PyWeakref_GET_OBJECT(PyObject *ref)
+.. c:function:: PyObject* PyWeakref_GET_OBJECT(PyObject *ref)
- Similar to :cfunc:`PyWeakref_GetObject`, but implemented as a macro that does no
+ Similar to :c:func:`PyWeakref_GetObject`, but implemented as a macro that does no
error checking.
diff --git a/Doc/conf.py b/Doc/conf.py
index 5939f7a..ce64f06 100644
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Python documentation build configuration file
#
@@ -66,6 +65,9 @@ highlight_language = 'python3'
# Options for HTML output
# -----------------------
+html_theme = 'default'
+html_theme_options = {'collapsiblesidebar': True}
+
# 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 +88,7 @@ html_additional_pages = {
}
# Output an OpenSearch description file.
-html_use_opensearch = 'http://docs.python.org/3.1'
+html_use_opensearch = 'http://docs.python.org/dev/py3k'
# Additional static files.
html_static_path = ['tools/sphinxext/static']
@@ -154,7 +156,7 @@ latex_preamble = r'''
latex_appendices = ['glossary', 'about', 'license', 'copyright']
# Get LaTeX to handle Unicode correctly
-latex_elements = {'inputenc': r'\usepackage[utf8x]{inputenc}'}
+latex_elements = {'inputenc': r'\usepackage[utf8x]{inputenc}', 'utf8extra': ''}
# Options for the coverage checker
# --------------------------------
diff --git a/Doc/copyright.rst b/Doc/copyright.rst
index 893b541..ff6b677 100644
--- a/Doc/copyright.rst
+++ b/Doc/copyright.rst
@@ -4,7 +4,7 @@ Copyright
Python and this documentation is:
-Copyright © 2001-2010 Python Software Foundation. All rights reserved.
+Copyright © 2001-2011 Python Software Foundation. All rights reserved.
Copyright © 2000 BeOpen.com. All rights reserved.
diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat
index dc058d5..f2a8767 100644
--- a/Doc/data/refcounts.dat
+++ b/Doc/data/refcounts.dat
@@ -281,6 +281,12 @@ PyErr_NewException:char*:name::
PyErr_NewException:PyObject*:base:0:
PyErr_NewException:PyObject*:dict:0:
+PyErr_NewExceptionWithDoc:PyObject*::+1:
+PyErr_NewExceptionWithDoc:char*:name::
+PyErr_NewExceptionWithDoc:char*:doc::
+PyErr_NewExceptionWithDoc:PyObject*:base:0:
+PyErr_NewExceptionWithDoc:PyObject*:dict:0:
+
PyErr_NoMemory:PyObject*::null:
PyErr_NormalizeException:void:::
@@ -493,6 +499,11 @@ PyImport_ExecCodeModule:PyObject*::+1:
PyImport_ExecCodeModule:char*:name::
PyImport_ExecCodeModule:PyObject*:co:0:
+PyImport_ExecCodeModuleEx:PyObject*::+1:
+PyImport_ExecCodeModuleEx:char*:name::
+PyImport_ExecCodeModuleEx:PyObject*:co:0:
+PyImport_ExecCodeModuleEx:char*:pathname::
+
PyImport_GetMagicNumber:long:::
PyImport_GetModuleDict:PyObject*::0:
@@ -512,6 +523,13 @@ PyImport_ImportModuleEx:PyObject*:globals:0:???
PyImport_ImportModuleEx:PyObject*:locals:0:???
PyImport_ImportModuleEx:PyObject*:fromlist:0:???
+PyImport_ImportModuleLevel:PyObject*::+1:
+PyImport_ImportModuleLevel:char*:name::
+PyImport_ImportModuleLevel:PyObject*:globals:0:???
+PyImport_ImportModuleLevel:PyObject*:locals:0:???
+PyImport_ImportModuleLevel:PyObject*:fromlist:0:???
+PyImport_ImportModuleLevel:int:level::
+
PyImport_ReloadModule:PyObject*::+1:
PyImport_ReloadModule:PyObject*:m:0:
@@ -828,9 +846,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:
@@ -1290,6 +1305,9 @@ PyString_AsEncodedString:const char*:errors::
PySys_AddWarnOption:void:::
PySys_AddWarnOption:char*:s::
+PySys_AddXOption:void:::
+PySys_AddXOption:const wchar_t*:s::
+
PySys_GetFile:FILE*:::
PySys_GetFile:char*:name::
PySys_GetFile:FILE*:def::
@@ -1297,6 +1315,8 @@ PySys_GetFile:FILE*:def::
PySys_GetObject:PyObject*::0:
PySys_GetObject:char*:name::
+PySys_GetXOptions:PyObject*::0:
+
PySys_SetArgv:int:::
PySys_SetArgv:int:argc::
PySys_SetArgv:char**:argv::
diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst
index 81de1ad..a7dc68e 100644
--- a/Doc/distutils/apiref.rst
+++ b/Doc/distutils/apiref.rst
@@ -147,11 +147,11 @@ setup script). Indirectly provides the :class:`distutils.dist.Distribution` and
In addition, the :mod:`distutils.core` module exposed a number of classes that
live elsewhere.
-* :class:`~distutils.extension.Extension` from :mod:`distutils.extension`
+* :class:`Extension` from :mod:`distutils.extension`
-* :class:`~distutils.cmd.Command` from :mod:`distutils.cmd`
+* :class:`Command` from :mod:`distutils.cmd`
-* :class:`~distutils.dist.Distribution` from :mod:`distutils.dist`
+* :class:`Distribution` from :mod:`distutils.dist`
A short description of each of these follows, but see the relevant module for
the full reference.
@@ -1311,8 +1311,7 @@ provides the following additional features:
the "negative alias" of :option:`--verbose`, then :option:`--quiet` on the
command line sets *verbose* to false.
-.. XXX Should be replaced with :mod:`optparse`.
-
+.. XXX Should be replaced with optparse
.. function:: fancy_getopt(options, negative_opt, object, args)
@@ -1679,8 +1678,8 @@ lines, and joining lines with backslashes.
===================================================================
.. module:: distutils.cmd
- :synopsis: This module provides the abstract base class Command. This class
- is subclassed by the modules in the distutils.command subpackage.
+ :synopsis: This module provides the abstract base class Command. This class is subclassed
+ by the modules in the distutils.command subpackage.
This module supplies the abstract base class :class:`Command`.
@@ -1690,84 +1689,20 @@ This module supplies the abstract base class :class:`Command`.
Abstract base class for defining command classes, the "worker bees" of the
Distutils. A useful analogy for command classes is to think of them as
- subroutines with local variables called *options*. The options are declared
- in :meth:`initialize_options` and defined (given their final values) in
- :meth:`finalize_options`, both of which must be defined by every command
- class. The distinction between the two is necessary because option values
- might come from the outside world (command line, config file, ...), and any
- options dependent on other options must be computed after these outside
- influences have been processed --- hence :meth:`finalize_options`. The body
- of the subroutine, where it does all its work based on the values of its
- options, is the :meth:`run` method, which must also be implemented by every
- command class.
-
- The class constructor takes a single argument *dist*, a :class:`Distribution`
+ subroutines with local variables called *options*. The options are declared in
+ :meth:`initialize_options` and defined (given their final values) in
+ :meth:`finalize_options`, both of which must be defined by every command class.
+ The distinction between the two is necessary because option values might come
+ from the outside world (command line, config file, ...), and any options
+ dependent on other options must be computed after these outside influences have
+ been processed --- hence :meth:`finalize_options`. The body of the subroutine,
+ where it does all its work based on the values of its options, is the
+ :meth:`run` method, which must also be implemented by every command class.
+
+ The class constructor takes a single argument *dist*, a :class:`Distribution`
instance.
-Creating a new Distutils command
-================================
-
-This section outlines the steps to create a new Distutils command.
-
-A new command lives in a module in the :mod:`distutils.command` package. There
-is a sample template in that directory called :file:`command_template`. Copy
-this file to a new module with the same name as the new command you're
-implementing. This module should implement a class with the same name as the
-module (and the command). So, for instance, to create the command
-``peel_banana`` (so that users can run ``setup.py peel_banana``), you'd copy
-:file:`command_template` to :file:`distutils/command/peel_banana.py`, then edit
-it so that it's implementing the class :class:`peel_banana`, a subclass of
-:class:`distutils.cmd.Command`.
-
-Subclasses of :class:`Command` must define the following methods.
-
-.. method:: Command.initialize_options()
-
- Set default values for all the options that this command supports. Note that
- these defaults may be overridden by other commands, by the setup script, by
- config files, or by the command-line. Thus, this is not the place to code
- dependencies between options; generally, :meth:`initialize_options`
- implementations are just a bunch of ``self.foo = None`` assignments.
-
-
-.. method:: Command.finalize_options()
-
- Set final values for all the options that this command supports. This is
- always called as late as possible, ie. after any option assignments from the
- command-line or from other commands have been done. Thus, this is the place
- to to code option dependencies: if *foo* depends on *bar*, then it is safe to
- set *foo* from *bar* as long as *foo* still has the same value it was
- assigned in :meth:`initialize_options`.
-
-
-.. method:: Command.run()
-
- A command's raison d'etre: carry out the action it exists to perform, controlled
- by the options initialized in :meth:`initialize_options`, customized by other
- commands, the setup script, the command-line, and config files, and finalized in
- :meth:`finalize_options`. All terminal output and filesystem interaction should
- be done by :meth:`run`.
-
-
-.. attribute:: Command.sub_commands
-
- *sub_commands* formalizes the notion of a "family" of commands,
- e.g. ``install`` as the parent with sub-commands ``install_lib``,
- ``install_headers``, etc. The parent of a family of commands defines
- *sub_commands* as a class attribute; it's a list of 2-tuples ``(command_name,
- predicate)``, with *command_name* a string and *predicate* a function, a
- string or ``None``. *predicate* is a method of the parent command that
- determines whether the corresponding command is applicable in the current
- situation. (E.g. we ``install_headers`` is only applicable if we have any C
- header files to install.) If *predicate* is ``None``, that command is always
- applicable.
-
- *sub_commands* is usually defined at the *end* of a class, because
- predicates can be methods of the class, so they must already have been
- defined. The canonical example is the :command:`install` command.
-
-
:mod:`distutils.command` --- Individual Distutils commands
==========================================================
@@ -2006,3 +1941,76 @@ The ``register`` command registers the package with the Python Package Index.
This is described in more detail in :pep:`301`.
.. % todo
+
+:mod:`distutils.command.check` --- Check the meta-data of a package
+===================================================================
+
+.. module:: distutils.command.check
+ :synopsis: Check the metadata of a package
+
+
+The ``check`` command performs some tests on the meta-data of a package.
+For example, it verifies that all required meta-data are provided as
+the arguments passed to the :func:`setup` function.
+
+.. % todo
+
+
+Creating a new Distutils command
+================================
+
+This section outlines the steps to create a new Distutils command.
+
+A new command lives in a module in the :mod:`distutils.command` package. There
+is a sample template in that directory called :file:`command_template`. Copy
+this file to a new module with the same name as the new command you're
+implementing. This module should implement a class with the same name as the
+module (and the command). So, for instance, to create the command
+``peel_banana`` (so that users can run ``setup.py peel_banana``), you'd copy
+:file:`command_template` to :file:`distutils/command/peel_banana.py`, then edit
+it so that it's implementing the class :class:`peel_banana`, a subclass of
+:class:`distutils.cmd.Command`.
+
+Subclasses of :class:`Command` must define the following methods.
+
+
+.. method:: Command.initialize_options()
+
+ Set default values for all the options that this command supports. Note that
+ these defaults may be overridden by other commands, by the setup script, by
+ config files, or by the command-line. Thus, this is not the place to code
+ dependencies between options; generally, :meth:`initialize_options`
+ implementations are just a bunch of ``self.foo = None`` assignments.
+
+
+.. method:: Command.finalize_options()
+
+ Set final values for all the options that this command supports. This is
+ always called as late as possible, ie. after any option assignments from the
+ command-line or from other commands have been done. Thus, this is the place
+ to to code option dependencies: if *foo* depends on *bar*, then it is safe to
+ set *foo* from *bar* as long as *foo* still has the same value it was
+ assigned in :meth:`initialize_options`.
+
+
+.. method:: Command.run()
+
+ A command's raison d'etre: carry out the action it exists to perform, controlled
+ by the options initialized in :meth:`initialize_options`, customized by other
+ commands, the setup script, the command-line, and config files, and finalized in
+ :meth:`finalize_options`. All terminal output and filesystem interaction should
+ be done by :meth:`run`.
+
+*sub_commands* formalizes the notion of a "family" of commands, eg. ``install``
+as the parent with sub-commands ``install_lib``, ``install_headers``, etc. The
+parent of a family of commands defines *sub_commands* as a class attribute; it's
+a list of 2-tuples ``(command_name, predicate)``, with *command_name* a string
+and *predicate* a function, a string or None. *predicate* is a method of
+the parent command that determines whether the corresponding command is
+applicable in the current situation. (Eg. we ``install_headers`` is only
+applicable if we have any C header files to install.) If *predicate* is None,
+that command is always applicable.
+
+*sub_commands* is usually defined at the \*end\* of a class, because predicates
+can be methods of the class, so they must already have been defined. The
+canonical example is the :command:`install` command.
diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst
index 2697ba0..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:
@@ -425,7 +425,7 @@ built-in functions in the installation script.
Which folders are available depends on the exact Windows version, and probably
also the configuration. For details refer to Microsoft's documentation of the
- :cfunc:`SHGetSpecialFolderPath` function.
+ :c:func:`SHGetSpecialFolderPath` function.
.. function:: create_shortcut(target, description, filename[, arguments[, workdir[, iconpath[, iconindex]]]])
diff --git a/Doc/distutils/commandref.rst b/Doc/distutils/commandref.rst
index fbe40de..6a2ac96 100644
--- a/Doc/distutils/commandref.rst
+++ b/Doc/distutils/commandref.rst
@@ -53,7 +53,7 @@ This command installs all (Python) scripts in the distribution.
Creating a source distribution: the :command:`sdist` command
============================================================
-**\*\*** fragment moved down from above: needs context! **\*\***
+.. XXX fragment moved down from above: needs context!
The manifest template commands are:
@@ -90,7 +90,7 @@ character, and ``[range]`` matches any of the characters in *range* (e.g.,
character" is platform-specific: on Unix it is anything except slash; on Windows
anything except backslash or colon.
-**\*\*** Windows support not there yet **\*\***
+.. XXX Windows support not there yet
.. % \section{Creating a built distribution: the
.. % \protect\command{bdist} command family}
diff --git a/Doc/distutils/examples.rst b/Doc/distutils/examples.rst
index e8d1ec9..b268486 100644
--- a/Doc/distutils/examples.rst
+++ b/Doc/distutils/examples.rst
@@ -258,9 +258,8 @@ Running the ``check`` command will display some warnings::
If you use the reStructuredText syntax in the ``long_description`` field and
-`docutils <http://docutils.sourceforge.net/>`_ is installed you can check if
-the syntax is fine with the ``check`` command, using the ``restructuredtext``
-option.
+`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::
@@ -291,3 +290,4 @@ by using the :mod:`docutils` parser::
.. % \section{Putting it all together}
+.. _docutils: http://docutils.sourceforge.net
diff --git a/Doc/distutils/extending.rst b/Doc/distutils/extending.rst
index 5a70d03..972ff02 100644
--- a/Doc/distutils/extending.rst
+++ b/Doc/distutils/extending.rst
@@ -15,8 +15,8 @@ want to modify existing commands; many simply add a few file extensions that
should be copied into packages in addition to :file:`.py` files as a
convenience.
-Most distutils command implementations are subclasses of the
-:class:`distutils.cmd.Command` class. New commands may directly inherit from
+Most distutils command implementations are subclasses of the :class:`Command`
+class from :mod:`distutils.cmd`. New commands may directly inherit from
:class:`Command`, while replacements often derive from :class:`Command`
indirectly, directly subclassing the command they are replacing. Commands are
required to derive from :class:`Command`.
diff --git a/Doc/distutils/sourcedist.rst b/Doc/distutils/sourcedist.rst
index 2dea83d..15d0baf 100644
--- a/Doc/distutils/sourcedist.rst
+++ b/Doc/distutils/sourcedist.rst
@@ -68,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`.
diff --git a/Doc/distutils/uploading.rst b/Doc/distutils/uploading.rst
index fd0c508..1b3cb58 100644
--- a/Doc/distutils/uploading.rst
+++ b/Doc/distutils/uploading.rst
@@ -67,9 +67,10 @@ 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
-:mod:`docutils` will display a warning if there's something wrong with your syntax.
+:mod:`docutils` will display a warning if there's something wrong with your
+syntax.
diff --git a/Doc/documenting/building.rst b/Doc/documenting/building.rst
index 9ab2519..19cf26b 100644
--- a/Doc/documenting/building.rst
+++ b/Doc/documenting/building.rst
@@ -16,9 +16,9 @@ installed Python and Subversion, you can just run ::
make html
-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 check out the necessary toolset in the :file:`tools/` subdirectory and build
+the HTML output files. To view the generated HTML, point your favorite browser
+at the top-level index :file:`build/html/index.html` after running "make".
Available make targets are:
@@ -49,10 +49,10 @@ Available make targets are:
* "pydoc-topics", which builds a Python module containing a dictionary with
plain text documentation for the labels defined in
- `tools/sphinxext/pyspecific.py` -- pydoc needs these to show topic and
+ :file:`tools/sphinxext/pyspecific.py` -- pydoc needs these to show topic and
keyword help.
-A "make update" updates the Subversion checkouts in `tools/`.
+A "make update" updates the Subversion checkouts in :file:`tools/`.
Without make
diff --git a/Doc/documenting/markup.rst b/Doc/documenting/markup.rst
index a2b9123..57d9eeb 100644
--- a/Doc/documenting/markup.rst
+++ b/Doc/documenting/markup.rst
@@ -107,11 +107,11 @@ index entries more informative.
The directives are:
-.. describe:: cfunction
+.. describe:: c:function
Describes a C function. The signature should be given as in C, e.g.::
- .. cfunction:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
+ .. c:function:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
This is also used to describe function-like preprocessor macros. The names
of the arguments should be given so they may be used in the description.
@@ -119,29 +119,29 @@ The directives are:
Note that you don't have to backslash-escape asterisks in the signature,
as it is not parsed by the reST inliner.
-.. describe:: cmember
+.. describe:: c:member
Describes a C struct member. Example signature::
- .. cmember:: PyObject* PyTypeObject.tp_bases
+ .. c:member:: PyObject* PyTypeObject.tp_bases
The text of the description should include the range of values allowed, how
the value should be interpreted, and whether the value can be changed.
References to structure members in text should use the ``member`` role.
-.. describe:: cmacro
+.. describe:: c:macro
Describes a "simple" C macro. Simple macros are macros which are used
for code expansion, but which do not take arguments so cannot be described as
functions. This is not to be used for simple constant definitions. Examples
- of its use in the Python documentation include :cmacro:`PyObject_HEAD` and
- :cmacro:`Py_BEGIN_ALLOW_THREADS`.
+ of its use in the Python documentation include :c:macro:`PyObject_HEAD` and
+ :c:macro:`Py_BEGIN_ALLOW_THREADS`.
-.. describe:: ctype
+.. describe:: c:type
Describes a C type. The signature should just be the type name.
-.. describe:: cvar
+.. describe:: c:var
Describes a global C variable. The signature should include the type, such
as::
@@ -177,6 +177,37 @@ The directives are:
are modified), side effects, and possible exceptions. A small example may be
provided.
+.. describe:: decorator
+
+ Describes a decorator function. The signature should *not* represent the
+ signature of the actual function, but the usage as a decorator. For example,
+ given the functions
+
+ .. code-block:: python
+
+ def removename(func):
+ func.__name__ = ''
+ return func
+
+ def setnewname(name):
+ def decorator(func):
+ func.__name__ = name
+ return func
+ return decorator
+
+ the descriptions should look like this::
+
+ .. decorator:: removename
+
+ Remove name of the decorated function.
+
+ .. decorator:: setnewname(name)
+
+ Set name of the decorated function to *name*.
+
+ There is no ``deco`` role to link to a decorator that is marked up with
+ this directive; rather, use the ``:func:`` role.
+
.. describe:: class
Describes a class. The signature can include parentheses with parameters
@@ -211,6 +242,12 @@ The directives are:
described for ``function``. This directive should be nested in a class
directive, like in the example above.
+.. describe:: decoratormethod
+
+ Same as ``decorator``, but for decorators that are methods.
+
+ Refer to a decorator method using the ``:meth:`` role.
+
.. describe:: opcode
Describes a Python :term:`bytecode` instruction.
@@ -383,22 +420,26 @@ the currently documented class.
The following roles create cross-references to C-language constructs if they
are defined in the API documentation:
-.. describe:: cdata
+.. describe:: c:data
The name of a C-language variable.
-.. describe:: cfunc
+.. describe:: c:func
The name of a C-language function. Should include trailing parentheses.
-.. describe:: cmacro
+.. describe:: c:macro
The name of a "simple" C macro, as defined above.
-.. describe:: ctype
+.. describe:: c:type
The name of a C-language type.
+.. describe:: c:member
+
+ The name of a C type member, as defined above.
+
The following role does possibly create a cross-reference, but does not refer
to objects:
@@ -541,10 +582,6 @@ in a different style:
If you don't need the "variable part" indication, use the standard
````code```` instead.
-.. describe:: var
-
- A Python or C variable or parameter name.
-
The following roles generate external links:
@@ -590,6 +627,8 @@ Example::
The ``:ref:`` invocation is replaced with the section title.
+Alternatively, you can reference any label (not just section titles)
+if you provide the link text ``:ref:`link text <reference-label>```.
Paragraph-level markup
----------------------
diff --git a/Doc/documenting/style.rst b/Doc/documenting/style.rst
index c3dded9..d055711 100644
--- a/Doc/documenting/style.rst
+++ b/Doc/documenting/style.rst
@@ -1,14 +1,18 @@
.. highlightlang:: rest
-Style Guide
+Style guide
===========
The Python documentation should follow the `Apple Publications Style Guide`_
wherever possible. This particular style guide was selected mostly because it
seems reasonable and is easy to get online.
-Topics which are not covered in Apple's style guide will be discussed in
-this document.
+Topics which are either not covered in Apple's style guide or treated
+differently in Python documentation will be discussed in this
+document.
+
+Use of whitespace
+-----------------
All reST files use an indentation of 3 spaces. The maximum line length is 80
characters for normal text, but tables, deeply indented code samples and long
@@ -21,6 +25,9 @@ A sentence-ending period may be followed by one or two spaces; while reST
ignores the second space, it is customarily put in by some users, for example
to aid Emacs' auto-fill mode.
+Footnotes
+---------
+
Footnotes are generally discouraged, though they may be used when they are the
best way to present specific information. When a footnote reference is added at
the end of the sentence, it should follow the sentence-ending punctuation. The
@@ -34,6 +41,36 @@ the footnote reference.
Footnotes may appear in the middle of sentences where appropriate.
+Capitalization
+--------------
+
+.. sidebar:: Sentence case
+
+ Sentence case is a set of capitalization rules used in English
+ sentences: the first word is always capitalized and other words are
+ only capitalized if there is a specific rule requiring it.
+
+Apple style guide recommends the use of title case in section titles.
+However, rules for which words should be capitalized in title case
+vary greaty between publications.
+
+In Python documentation, use of sentence case in section titles is
+preferable, but consistency within a unit is more important than
+following this rule. If you add a section to the chapter where most
+sections are in title case you can either convert all titles to
+sentence case or use the dominant style in the new section title.
+
+Sentences that start with a word for which specific rules require
+starting it with a lower case letter should be avoided in titles and
+elsewhere.
+
+.. note::
+
+ Sections that describe a library module often have titles in the
+ form of "modulename --- Short description of the module." In this
+ case, the description should be capitalized as a stand-alone
+ sentence.
+
Many special names are used in the Python documentation, including the names of
operating systems, programming languages, standards bodies, and the like. Most
of these entities are not assigned any special markup, but the preferred
@@ -44,26 +81,32 @@ Other terms and words deserve special mention as well; these conventions should
be used to ensure consistency throughout the documentation:
CPU
- For "central processing unit." Many style guides say this should be spelled
- out on the first use (and if you must use it, do so!). For the Python
- documentation, this abbreviation should be avoided since there's no
- reasonable way to predict which occurrence will be the first seen by the
- reader. It is better to use the word "processor" instead.
+ For "central processing unit." Many style guides say this should be
+ spelled out on the first use (and if you must use it, do so!). For
+ the Python documentation, this abbreviation should be avoided since
+ there's no reasonable way to predict which occurrence will be the
+ first seen by the reader. It is better to use the word "processor"
+ instead.
POSIX
- The name assigned to a particular group of standards. This is always
- uppercase.
+ The name assigned to a particular group of standards. This is always
+ uppercase.
Python
- The name of our favorite programming language is always capitalized.
+ The name of our favorite programming language is always capitalized.
+
+reST
+ For "reStructuredText," an easy to read, plaintext markup syntax
+ used to produce Python documentation. When spelled out, it is
+ always one word and both forms start with a lower case 'r'.
Unicode
- The name of a character set and matching encoding. This is always written
- capitalized.
+ The name of a character coding system. This is always written
+ capitalized.
Unix
- The name of the operating system developed at AT&T Bell Labs in the early
- 1970s.
+ The name of the operating system developed at AT&T Bell Labs in the early
+ 1970s.
.. _Apple Publications Style Guide: http://developer.apple.com/mac/library/documentation/UserExperience/Conceptual/APStyleGuide/APSG_2009.pdf
diff --git a/Doc/extending/embedding.rst b/Doc/extending/embedding.rst
index 2ea1253..e261048 100644
--- a/Doc/extending/embedding.rst
+++ b/Doc/extending/embedding.rst
@@ -25,19 +25,16 @@ the Python interpreter to run some Python code.
So if you are embedding Python, you are providing your own main program. One of
the things this main program has to do is initialize the Python interpreter. At
-the very least, you have to call the function :cfunc:`Py_Initialize`. There are
+the very least, you have to call the function :c:func:`Py_Initialize`. There are
optional calls to pass command line arguments to Python. Then later you can
call the interpreter from any part of the application.
There are several different ways to call the interpreter: you can pass a string
-containing Python statements to :cfunc:`PyRun_SimpleString`, or you can pass a
+containing Python statements to :c:func:`PyRun_SimpleString`, or you can pass a
stdio file pointer and a file name (for identification in error messages only)
-to :cfunc:`PyRun_SimpleFile`. You can also call the lower-level operations
+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::
@@ -69,12 +66,12 @@ perform some operation on a file. ::
}
The above code first initializes the Python interpreter with
-:cfunc:`Py_Initialize`, followed by the execution of a hard-coded Python script
-that print the date and time. Afterwards, the :cfunc:`Py_Finalize` call shuts
+:c:func:`Py_Initialize`, followed by the execution of a hard-coded Python script
+that print the date and time. Afterwards, the :c:func:`Py_Finalize` call shuts
the interpreter down, followed by the end of the program. In a real program,
you may want to get the Python script from another source, perhaps a text-editor
routine, a file, or a database. Getting the Python code from a file can better
-be done by using the :cfunc:`PyRun_SimpleFile` function, which saves you the
+be done by using the :c:func:`PyRun_SimpleFile` function, which saves you the
trouble of allocating memory space and loading the file contents.
@@ -162,8 +159,8 @@ interesting part with respect to embedding Python starts with ::
pModule = PyImport_Import(pName);
After initializing the interpreter, the script is loaded using
-:cfunc:`PyImport_Import`. This routine needs a Python string as its argument,
-which is constructed using the :cfunc:`PyString_FromString` data conversion
+:c:func:`PyImport_Import`. This routine needs a Python string as its argument,
+which is constructed using the :c:func:`PyString_FromString` data conversion
routine. ::
pFunc = PyObject_GetAttrString(pModule, argv[2]);
@@ -175,7 +172,7 @@ routine. ::
Py_XDECREF(pFunc);
Once the script is loaded, the name we're looking for is retrieved using
-:cfunc:`PyObject_GetAttrString`. If the name exists, and the object returned is
+:c:func:`PyObject_GetAttrString`. If the name exists, and the object returned is
callable, you can safely assume that it is a function. The program then
proceeds by constructing a tuple of arguments as normal. The call to the Python
function is then made with::
@@ -229,8 +226,8 @@ Python extension. For example::
return PyModule_Create(&EmbModule);
}
-Insert the above code just above the :cfunc:`main` function. Also, insert the
-following two statements before the call to :cfunc:`Py_Initialize`::
+Insert the above code just above the :c:func:`main` function. Also, insert the
+following two statements before the call to :c:func:`Py_Initialize`::
numargs = argc;
PyImport_AppendInittab("emb", &PyInit_emb);
diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst
index 68dc9d6..c4ced1a 100644
--- a/Doc/extending/extending.rst
+++ b/Doc/extending/extending.rst
@@ -20,6 +20,13 @@ source file by including the header ``"Python.h"``.
The compilation of an extension module depends on its intended use as well as on
your system setup; details are given in later chapters.
+Do note that if your use case is calling C library functions or system calls,
+you should consider using the :mod:`ctypes` module rather than writing custom
+C code. Not only does :mod:`ctypes` let you write Python code to interface
+with C code, but it is more portable between implementations of Python than
+writing and compiling an extension module which typically ties you to CPython.
+
+
.. _extending-simpleexample:
@@ -28,7 +35,7 @@ A Simple Example
Let's create an extension module called ``spam`` (the favorite food of Monty
Python fans...) and let's say we want to create a Python interface to the C
-library function :cfunc:`system`. [#]_ This function takes a null-terminated
+library function :c:func:`system`. [#]_ This function takes a null-terminated
character string as argument and returns an integer. We want this function to
be callable from Python as follows::
@@ -58,8 +65,8 @@ All user-visible symbols defined by :file:`Python.h` have a prefix of ``Py`` or
since they are used extensively by the Python interpreter, ``"Python.h"``
includes a few standard header files: ``<stdio.h>``, ``<string.h>``,
``<errno.h>``, and ``<stdlib.h>``. If the latter header file does not exist on
-your system, it declares the functions :cfunc:`malloc`, :cfunc:`free` and
-:cfunc:`realloc` directly.
+your system, it declares the functions :c:func:`malloc`, :c:func:`free` and
+:c:func:`realloc` directly.
The next thing we add to our module file is the C function that will be called
when the Python expression ``spam.system(string)`` is evaluated (we'll see
@@ -89,12 +96,12 @@ The *args* argument will be a pointer to a Python tuple object containing the
arguments. Each item of the tuple corresponds to an argument in the call's
argument list. The arguments are Python objects --- in order to do anything
with them in our C function we have to convert them to C values. The function
-:cfunc:`PyArg_ParseTuple` in the Python API checks the argument types and
+:c:func:`PyArg_ParseTuple` in the Python API checks the argument types and
converts them to C values. It uses a template string to determine the required
types of the arguments as well as the types of the C variables into which to
store the converted values. More about this later.
-:cfunc:`PyArg_ParseTuple` returns true (nonzero) if all arguments have the right
+:c:func:`PyArg_ParseTuple` returns true (nonzero) if all arguments have the right
type and its components have been stored in the variables whose addresses are
passed. It returns false (zero) if an invalid argument list was passed. In the
latter case it also raises an appropriate exception so the calling function can
@@ -119,77 +126,77 @@ 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.
-The most common one is :cfunc:`PyErr_SetString`. Its arguments are an exception
+The most common one is :c:func:`PyErr_SetString`. Its arguments are an exception
object and a C string. The exception object is usually a predefined object like
-:cdata:`PyExc_ZeroDivisionError`. The C string indicates the cause of the error
+:c:data:`PyExc_ZeroDivisionError`. The C string indicates the cause of the error
and is converted to a Python string object and stored as the "associated value"
of the exception.
-Another useful function is :cfunc:`PyErr_SetFromErrno`, which only takes an
+Another useful function is :c:func:`PyErr_SetFromErrno`, which only takes an
exception argument and constructs the associated value by inspection of the
-global variable :cdata:`errno`. The most general function is
-:cfunc:`PyErr_SetObject`, which takes two object arguments, the exception and
-its associated value. You don't need to :cfunc:`Py_INCREF` the objects passed
+global variable :c:data:`errno`. The most general function is
+:c:func:`PyErr_SetObject`, which takes two object arguments, the exception and
+its associated value. You don't need to :c:func:`Py_INCREF` the objects passed
to any of these functions.
You can test non-destructively whether an exception has been set with
-:cfunc:`PyErr_Occurred`. This returns the current exception object, or *NULL*
+:c:func:`PyErr_Occurred`. This returns the current exception object, or *NULL*
if no exception has occurred. You normally don't need to call
-:cfunc:`PyErr_Occurred` to see whether an error occurred in a function call,
+:c:func:`PyErr_Occurred` to see whether an error occurred in a function call,
since you should be able to tell from the return value.
When a function *f* that calls another function *g* detects that the latter
fails, *f* should itself return an error value (usually *NULL* or ``-1``). It
-should *not* call one of the :cfunc:`PyErr_\*` functions --- one has already
+should *not* call one of the :c:func:`PyErr_\*` functions --- one has already
been called by *g*. *f*'s caller is then supposed to also return an error
-indication to *its* caller, again *without* calling :cfunc:`PyErr_\*`, and so on
+indication to *its* caller, again *without* calling :c:func:`PyErr_\*`, and so on
--- the most detailed cause of the error was already reported by the function
that first detected it. Once the error reaches the Python interpreter's main
loop, this aborts the currently executing Python code and tries to find an
exception handler specified by the Python programmer.
(There are situations where a module can actually give a more detailed error
-message by calling another :cfunc:`PyErr_\*` function, and in such cases it is
+message by calling another :c:func:`PyErr_\*` function, and in such cases it is
fine to do so. As a general rule, however, this is not necessary, and can cause
information about the cause of the error to be lost: most operations can fail
for a variety of reasons.)
To ignore an exception set by a function call that failed, the exception
-condition must be cleared explicitly by calling :cfunc:`PyErr_Clear`. The only
-time C code should call :cfunc:`PyErr_Clear` is if it doesn't want to pass the
+condition must be cleared explicitly by calling :c:func:`PyErr_Clear`. The only
+time C code should call :c:func:`PyErr_Clear` is if it doesn't want to pass the
error on to the interpreter but wants to handle it completely by itself
(possibly by trying something else, or pretending nothing went wrong).
-Every failing :cfunc:`malloc` call must be turned into an exception --- the
-direct caller of :cfunc:`malloc` (or :cfunc:`realloc`) must call
-:cfunc:`PyErr_NoMemory` and return a failure indicator itself. All the
-object-creating functions (for example, :cfunc:`PyLong_FromLong`) already do
-this, so this note is only relevant to those who call :cfunc:`malloc` directly.
+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:`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 :cfunc:`PyArg_ParseTuple` and
+Also note that, with the important exception of :c:func:`PyArg_ParseTuple` and
friends, functions that return an integer status usually return a positive value
or zero for success and ``-1`` for failure, like Unix system calls.
-Finally, be careful to clean up garbage (by making :cfunc:`Py_XDECREF` or
-:cfunc:`Py_DECREF` calls for objects you have already created) when you return
+Finally, be careful to clean up garbage (by making :c:func:`Py_XDECREF` or
+:c:func:`Py_DECREF` calls for objects you have already created) when you return
an error indicator!
The choice of which exception to raise is entirely yours. There are predeclared
C objects corresponding to all built-in Python exceptions, such as
-:cdata:`PyExc_ZeroDivisionError`, which you can use directly. Of course, you
-should choose exceptions wisely --- don't use :cdata:`PyExc_TypeError` to mean
-that a file couldn't be opened (that should probably be :cdata:`PyExc_IOError`).
-If something's wrong with the argument list, the :cfunc:`PyArg_ParseTuple`
-function usually raises :cdata:`PyExc_TypeError`. If you have an argument whose
+:c:data:`PyExc_ZeroDivisionError`, which you can use directly. Of course, you
+should choose exceptions wisely --- don't use :c:data:`PyExc_TypeError` to mean
+that a file couldn't be opened (that should probably be :c:data:`PyExc_IOError`).
+If something's wrong with the argument list, the :c:func:`PyArg_ParseTuple`
+function usually raises :c:data:`PyExc_TypeError`. If you have an argument whose
value must be in a particular range or must satisfy other conditions,
-:cdata:`PyExc_ValueError` is appropriate.
+:c:data:`PyExc_ValueError` is appropriate.
You can also define a new exception that is unique to your module. For this, you
usually declare a static object variable at the beginning of your file::
static PyObject *SpamError;
-and initialize it in your module's initialization function (:cfunc:`PyInit_spam`)
+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
@@ -208,14 +215,14 @@ with an exception object (leaving out the error checking for now)::
}
Note that the Python name for the exception object is :exc:`spam.error`. The
-:cfunc:`PyErr_NewException` function may create a class with the base class
+:c:func:`PyErr_NewException` function may create a class with the base class
being :exc:`Exception` (unless another class is passed in instead of *NULL*),
described in :ref:`bltin-exceptions`.
-Note also that the :cdata:`SpamError` variable retains a reference to the newly
+Note also that the :c:data:`SpamError` variable retains a reference to the newly
created exception class; this is intentional! Since the exception could be
removed from the module by external code, an owned reference to the class is
-needed to ensure that it will not be discarded, causing :cdata:`SpamError` to
+needed to ensure that it will not be discarded, causing :c:data:`SpamError` to
become a dangling pointer. Should it become a dangling pointer, C code which
raises the exception could cause a core dump or other unintended side effects.
@@ -223,7 +230,7 @@ We discuss the use of ``PyMODINIT_FUNC`` as a function return type later in this
sample.
The :exc:`spam.error` exception can be raised in your extension module using a
-call to :cfunc:`PyErr_SetString` as shown below::
+call to :c:func:`PyErr_SetString` as shown below::
static PyObject *
spam_system(PyObject *self, PyObject *args)
@@ -255,19 +262,19 @@ statement::
It returns *NULL* (the error indicator for functions returning object pointers)
if an error is detected in the argument list, relying on the exception set by
-:cfunc:`PyArg_ParseTuple`. Otherwise the string value of the argument has been
-copied to the local variable :cdata:`command`. This is a pointer assignment and
+:c:func:`PyArg_ParseTuple`. Otherwise the string value of the argument has been
+copied to the local variable :c:data:`command`. This is a pointer assignment and
you are not supposed to modify the string to which it points (so in Standard C,
-the variable :cdata:`command` should properly be declared as ``const char
+the variable :c:data:`command` should properly be declared as ``const char
*command``).
-The next statement is a call to the Unix function :cfunc:`system`, passing it
-the string we just got from :cfunc:`PyArg_ParseTuple`::
+The next statement is a call to the Unix function :c:func:`system`, passing it
+the string we just got from :c:func:`PyArg_ParseTuple`::
sts = system(command);
-Our :func:`spam.system` function must return the value of :cdata:`sts` as a
-Python object. This is done using the function :cfunc:`PyLong_FromLong`. ::
+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:`PyLong_FromLong`. ::
return PyLong_FromLong(sts);
@@ -275,14 +282,14 @@ In this case, it will return an integer object. (Yes, even integers are objects
on the heap in Python!)
If you have a C function that returns no useful argument (a function returning
-:ctype:`void`), the corresponding Python function must return ``None``. You
-need this idiom to do so (which is implemented by the :cmacro:`Py_RETURN_NONE`
+:c:type:`void`), the corresponding Python function must return ``None``. You
+need this idiom to do so (which is implemented by the :c:macro:`Py_RETURN_NONE`
macro)::
Py_INCREF(Py_None);
return Py_None;
-:cdata:`Py_None` is the C name for the special Python object ``None``. It is a
+:c:data:`Py_None` is the C name for the special Python object ``None``. It is a
genuine Python object rather than a *NULL* pointer, which means "error" in most
contexts, as we have seen.
@@ -292,7 +299,7 @@ contexts, as we have seen.
The Module's Method Table and Initialization Function
=====================================================
-I promised to show how :cfunc:`spam_system` is called from Python programs.
+I promised to show how :c:func:`spam_system` is called from Python programs.
First, we need to list its name and address in a "method table"::
static PyMethodDef SpamMethods[] = {
@@ -306,16 +313,16 @@ First, we need to list its name and address in a "method table"::
Note the third entry (``METH_VARARGS``). This is a flag telling the interpreter
the calling convention to be used for the C function. It should normally always
be ``METH_VARARGS`` or ``METH_VARARGS | METH_KEYWORDS``; a value of ``0`` means
-that an obsolete variant of :cfunc:`PyArg_ParseTuple` is used.
+that an obsolete variant of :c:func:`PyArg_ParseTuple` is used.
When using only ``METH_VARARGS``, the function should expect the Python-level
parameters to be passed in as a tuple acceptable for parsing via
-:cfunc:`PyArg_ParseTuple`; more information on this function is provided below.
+:c:func:`PyArg_ParseTuple`; more information on this function is provided below.
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.
-Use :cfunc:`PyArg_ParseTupleAndKeywords` to parse the arguments to such a
+Use :c:func:`PyArg_ParseTupleAndKeywords` to parse the arguments to such a
function.
The method table must be referenced in the module definition structure::
@@ -331,7 +338,7 @@ The method table must be referenced in the module definition structure::
This structure, in turn, must be passed to the interpreter in the module's
initialization function. The initialization function must be named
-:cfunc:`PyInit_name`, 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
@@ -345,25 +352,25 @@ 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,
-:cfunc:`PyInit_spam` is called. (See below for comments about embedding Python.)
-It calls :cfunc:`PyModule_Create`, which returns a module object, 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 :ctype:`PyMethodDef` structures) found in the module definition.
-:cfunc:`PyModule_Create` returns a pointer to the module object
+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. The init function must return the module object to its caller,
so that it then gets inserted into ``sys.modules``.
-When embedding Python, the :cfunc:`PyInit_spam` function is not called
-automatically unless there's an entry in the :cdata:`PyImport_Inittab` table.
-To add the module to the initialization table, use :cfunc:`PyImport_AppendInittab`,
+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 builtin module, before Py_Initialize */
+ /* Add a built-in module, before Py_Initialize */
PyImport_AppendInittab("spam", PyInit_spam);
/* Pass argv[0] to the Python interpreter */
@@ -383,19 +390,14 @@ source distribution.
.. note::
Removing entries from ``sys.modules`` or importing compiled modules into
- multiple interpreters within a process (or following a :cfunc:`fork` without an
- intervening :cfunc:`exec`) can create problems for some extension modules.
+ 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.
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
-read as an example. The :program:`modulator.py` script included in the source
-distribution or Windows install provides a simple graphical user interface for
-declaring the functions and objects which a module should implement, and can
-generate a template which can be filled in. The script lives in the
-:file:`Tools/modulator/` directory; see the :file:`README` file there for more
-information.
+read as an example.
.. _compilation:
@@ -453,7 +455,7 @@ look at the implementation of the :option:`-c` command line option in
Calling a Python function is easy. First, the Python program must somehow pass
you the Python function object. You should provide a function (or some other
interface) to do this. When this function is called, save a pointer to the
-Python function object (be careful to :cfunc:`Py_INCREF` it!) in a global
+Python function object (be careful to :c:func:`Py_INCREF` it!) in a global
variable --- or wherever you see fit. For example, the following function might
be part of a module definition::
@@ -482,10 +484,10 @@ be part of a module definition::
This function must be registered with the interpreter using the
:const:`METH_VARARGS` flag; this is described in section :ref:`methodtable`. The
-:cfunc:`PyArg_ParseTuple` function and its arguments are documented in section
+:c:func:`PyArg_ParseTuple` function and its arguments are documented in section
:ref:`parsetuple`.
-The macros :cfunc:`Py_XINCREF` and :cfunc:`Py_XDECREF` increment/decrement the
+The macros :c:func:`Py_XINCREF` and :c:func:`Py_XDECREF` increment/decrement the
reference count of an object and are safe in the presence of *NULL* pointers
(but note that *temp* will not be *NULL* in this context). More info on them
in section :ref:`refcounts`.
@@ -493,12 +495,12 @@ in section :ref:`refcounts`.
.. index:: single: PyObject_CallObject()
Later, when it is time to call the function, you call the C function
-:cfunc:`PyObject_CallObject`. This function has two arguments, both pointers to
+:c:func:`PyObject_CallObject`. This function has two arguments, both pointers to
arbitrary Python objects: the Python function, and the argument list. The
argument list must always be a tuple object, whose length is the number of
arguments. To call the Python function with no arguments, pass in NULL, or
an empty tuple; to call it with one argument, pass a singleton tuple.
-:cfunc:`Py_BuildValue` returns a tuple when its format string consists of zero
+:c:func:`Py_BuildValue` returns a tuple when its format string consists of zero
or more format codes between parentheses. For example::
int arg;
@@ -512,25 +514,25 @@ or more format codes between parentheses. For example::
result = PyObject_CallObject(my_callback, arglist);
Py_DECREF(arglist);
-:cfunc:`PyObject_CallObject` returns a Python object pointer: this is the return
-value of the Python function. :cfunc:`PyObject_CallObject` is
+:c:func:`PyObject_CallObject` returns a Python object pointer: this is the return
+value of the Python function. :c:func:`PyObject_CallObject` is
"reference-count-neutral" with respect to its arguments. In the example a new
-tuple was created to serve as the argument list, which is :cfunc:`Py_DECREF`\
+tuple was created to serve as the argument list, which is :c:func:`Py_DECREF`\
-ed immediately after the call.
-The return value of :cfunc:`PyObject_CallObject` is "new": either it is a brand
+The return value of :c:func:`PyObject_CallObject` is "new": either it is a brand
new object, or it is an existing object whose reference count has been
incremented. So, unless you want to save it in a global variable, you should
-somehow :cfunc:`Py_DECREF` the result, even (especially!) if you are not
+somehow :c:func:`Py_DECREF` the result, even (especially!) if you are not
interested in its value.
Before you do this, however, it is important to check that the return value
isn't *NULL*. If it is, the Python function terminated by raising an exception.
-If the C code that called :cfunc:`PyObject_CallObject` is called from Python, it
+If the C code that called :c:func:`PyObject_CallObject` is called from Python, it
should now return an error indication to its Python caller, so the interpreter
can print a stack trace, or the calling Python code can handle the exception.
If this is not possible or desirable, the exception should be cleared by calling
-:cfunc:`PyErr_Clear`. For example::
+:c:func:`PyErr_Clear`. For example::
if (result == NULL)
return NULL; /* Pass error back */
@@ -538,12 +540,12 @@ If this is not possible or desirable, the exception should be cleared by calling
Py_DECREF(result);
Depending on the desired interface to the Python callback function, you may also
-have to provide an argument list to :cfunc:`PyObject_CallObject`. In some cases
+have to provide an argument list to :c:func:`PyObject_CallObject`. In some cases
the argument list is also provided by the Python program, through the same
interface that specified the callback function. It can then be saved and used
in the same manner as the function object. In other cases, you may have to
construct a new tuple to pass as the argument list. The simplest way to do this
-is to call :cfunc:`Py_BuildValue`. For example, if you want to pass an integral
+is to call :c:func:`Py_BuildValue`. For example, if you want to pass an integral
event code, you might use the following code::
PyObject *arglist;
@@ -558,11 +560,11 @@ event code, you might use the following code::
Note the placement of ``Py_DECREF(arglist)`` immediately after the call, before
the error check! Also note that strictly speaking this code is not complete:
-:cfunc:`Py_BuildValue` may run out of memory, and this should be checked.
+:c:func:`Py_BuildValue` may run out of memory, and this should be checked.
You may also call a function with keyword arguments by using
-:cfunc:`PyObject_Call`, which supports arguments and keyword arguments. As in
-the above example, we use :cfunc:`Py_BuildValue` to construct the dictionary. ::
+:c:func:`PyObject_Call`, which supports arguments and keyword arguments. As in
+the above example, we use :c:func:`Py_BuildValue` to construct the dictionary. ::
PyObject *dict;
...
@@ -582,7 +584,7 @@ Extracting Parameters in Extension Functions
.. index:: single: PyArg_ParseTuple()
-The :cfunc:`PyArg_ParseTuple` function is declared as follows::
+The :c:func:`PyArg_ParseTuple` function is declared as follows::
int PyArg_ParseTuple(PyObject *arg, char *format, ...);
@@ -592,7 +594,7 @@ whose syntax is explained in :ref:`arg-parsing` in the Python/C API Reference
Manual. The remaining arguments must be addresses of variables whose type is
determined by the format string.
-Note that while :cfunc:`PyArg_ParseTuple` checks that the Python arguments have
+Note that while :c:func:`PyArg_ParseTuple` checks that the Python arguments have
the required types, it cannot check the validity of the addresses of C variables
passed to the call: if you make mistakes there, your code will probably crash or
at least overwrite random bits in memory. So be careful!
@@ -674,17 +676,17 @@ Keyword Parameters for Extension Functions
.. index:: single: PyArg_ParseTupleAndKeywords()
-The :cfunc:`PyArg_ParseTupleAndKeywords` function is declared as follows::
+The :c:func:`PyArg_ParseTupleAndKeywords` function is declared as follows::
int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict,
char *format, char *kwlist[], ...);
The *arg* and *format* parameters are identical to those of the
-:cfunc:`PyArg_ParseTuple` function. The *kwdict* parameter is the dictionary of
+:c:func:`PyArg_ParseTuple` function. The *kwdict* parameter is the dictionary of
keywords received as the third parameter from the Python runtime. The *kwlist*
parameter is a *NULL*-terminated list of strings which identify the parameters;
the names are matched with the type information from *format* from left to
-right. On success, :cfunc:`PyArg_ParseTupleAndKeywords` returns true, otherwise
+right. On success, :c:func:`PyArg_ParseTupleAndKeywords` returns true, otherwise
it returns false and raises an appropriate exception.
.. note::
@@ -748,19 +750,19 @@ Philbrick (philbrick@hks.com)::
Building Arbitrary Values
=========================
-This function is the counterpart to :cfunc:`PyArg_ParseTuple`. It is declared
+This function is the counterpart to :c:func:`PyArg_ParseTuple`. It is declared
as follows::
PyObject *Py_BuildValue(char *format, ...);
It recognizes a set of format units similar to the ones recognized by
-:cfunc:`PyArg_ParseTuple`, but the arguments (which are input to the function,
+:c:func:`PyArg_ParseTuple`, but the arguments (which are input to the function,
not output) must not be pointers, just values. It returns a new Python object,
suitable for returning from a C function called from Python.
-One difference with :cfunc:`PyArg_ParseTuple`: while the latter requires its
+One difference with :c:func:`PyArg_ParseTuple`: while the latter requires its
first argument to be a tuple (since Python argument lists are always represented
-as tuples internally), :cfunc:`Py_BuildValue` does not always build a tuple. It
+as tuples internally), :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
@@ -794,18 +796,18 @@ Reference Counts
In languages like C or C++, the programmer is responsible for dynamic allocation
and deallocation of memory on the heap. In C, this is done using the functions
-:cfunc:`malloc` and :cfunc:`free`. In C++, the operators ``new`` and
+:c:func:`malloc` and :c:func:`free`. In C++, the operators ``new`` and
``delete`` are used with essentially the same meaning and we'll restrict
the following discussion to the C case.
-Every block of memory allocated with :cfunc:`malloc` should eventually be
-returned to the pool of available memory by exactly one call to :cfunc:`free`.
-It is important to call :cfunc:`free` at the right time. If a block's address
-is forgotten but :cfunc:`free` is not called for it, the memory it occupies
+Every block of memory allocated with :c:func:`malloc` should eventually be
+returned to the pool of available memory by exactly one call to :c:func:`free`.
+It is important to call :c:func:`free` at the right time. If a block's address
+is forgotten but :c:func:`free` is not called for it, the memory it occupies
cannot be reused until the program terminates. This is called a :dfn:`memory
-leak`. On the other hand, if a program calls :cfunc:`free` for a block and then
+leak`. On the other hand, if a program calls :c:func:`free` for a block and then
continues to use the block, it creates a conflict with re-use of the block
-through another :cfunc:`malloc` call. This is called :dfn:`using freed memory`.
+through another :c:func:`malloc` call. This is called :dfn:`using freed memory`.
It has the same bad consequences as referencing uninitialized data --- core
dumps, wrong results, mysterious crashes.
@@ -822,7 +824,7 @@ long-running process that uses the leaking function frequently. Therefore, it's
important to prevent leaks from happening by having a coding convention or
strategy that minimizes this kind of errors.
-Since Python makes heavy use of :cfunc:`malloc` and :cfunc:`free`, it needs a
+Since Python makes heavy use of :c:func:`malloc` and :c:func:`free`, it needs a
strategy to avoid memory leaks as well as the use of freed memory. The chosen
method is called :dfn:`reference counting`. The principle is simple: every
object contains a counter, which is incremented when a reference to the object
@@ -834,11 +836,11 @@ An alternative strategy is called :dfn:`automatic garbage collection`.
(Sometimes, reference counting is also referred to as a garbage collection
strategy, hence my use of "automatic" to distinguish the two.) The big
advantage of automatic garbage collection is that the user doesn't need to call
-:cfunc:`free` explicitly. (Another claimed advantage is an improvement in speed
+:c:func:`free` explicitly. (Another claimed advantage is an improvement in speed
or memory usage --- this is no hard fact however.) The disadvantage is that for
C, there is no truly portable automatic garbage collector, while reference
-counting can be implemented portably (as long as the functions :cfunc:`malloc`
-and :cfunc:`free` are available --- which the C Standard guarantees). Maybe some
+counting can be implemented portably (as long as the functions :c:func:`malloc`
+and :c:func:`free` are available --- which the C Standard guarantees). Maybe some
day a sufficiently portable automatic garbage collector will be available for C.
Until then, we'll have to live with reference counts.
@@ -873,9 +875,9 @@ Reference Counting in Python
----------------------------
There are two macros, ``Py_INCREF(x)`` and ``Py_DECREF(x)``, which handle the
-incrementing and decrementing of the reference count. :cfunc:`Py_DECREF` also
+incrementing and decrementing of the reference count. :c:func:`Py_DECREF` also
frees the object when the count reaches zero. For flexibility, it doesn't call
-:cfunc:`free` directly --- rather, it makes a call through a function pointer in
+:c:func:`free` directly --- rather, it makes a call through a function pointer in
the object's :dfn:`type object`. For this purpose (and others), every object
also contains a pointer to its type object.
@@ -883,13 +885,13 @@ The big question now remains: when to use ``Py_INCREF(x)`` and ``Py_DECREF(x)``?
Let's first introduce some terms. Nobody "owns" an object; however, you can
:dfn:`own a reference` to an object. An object's reference count is now defined
as the number of owned references to it. The owner of a reference is
-responsible for calling :cfunc:`Py_DECREF` when the reference is no longer
+responsible for calling :c:func:`Py_DECREF` when the reference is no longer
needed. Ownership of a reference can be transferred. There are three ways to
-dispose of an owned reference: pass it on, store it, or call :cfunc:`Py_DECREF`.
+dispose of an owned reference: pass it on, store it, or call :c:func:`Py_DECREF`.
Forgetting to dispose of an owned reference creates a memory leak.
It is also possible to :dfn:`borrow` [#]_ a reference to an object. The
-borrower of a reference should not call :cfunc:`Py_DECREF`. The borrower must
+borrower of a reference should not call :c:func:`Py_DECREF`. The borrower must
not hold on to the object longer than the owner from which it was borrowed.
Using a borrowed reference after the owner has disposed of it risks using freed
memory and should be avoided completely. [#]_
@@ -903,7 +905,7 @@ reference can be used after the owner from which it was borrowed has in fact
disposed of it.
A borrowed reference can be changed into an owned reference by calling
-:cfunc:`Py_INCREF`. This does not affect the status of the owner from which the
+:c:func:`Py_INCREF`. This does not affect the status of the owner from which the
reference was borrowed --- it creates a new owned reference, and gives full
owner responsibilities (the new owner must dispose of the reference properly, as
well as the previous owner).
@@ -920,36 +922,36 @@ 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 :cfunc:`PyLong_FromLong` and :cfunc:`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,
-:cfunc:`PyLong_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
-with the reference, for instance :cfunc:`PyObject_GetAttrString`. The picture
+with the reference, for instance :c:func:`PyObject_GetAttrString`. The picture
is less clear, here, however, since a few common routines are exceptions:
-:cfunc:`PyTuple_GetItem`, :cfunc:`PyList_GetItem`, :cfunc:`PyDict_GetItem`, and
-:cfunc:`PyDict_GetItemString` all return references that you borrow from the
+:c:func:`PyTuple_GetItem`, :c:func:`PyList_GetItem`, :c:func:`PyDict_GetItem`, and
+:c:func:`PyDict_GetItemString` all return references that you borrow from the
tuple, list or dictionary.
-The function :cfunc:`PyImport_AddModule` also returns a borrowed reference, even
+The function :c:func:`PyImport_AddModule` also returns a borrowed reference, even
though it may actually create the object it returns: this is possible because an
owned reference to the object is stored in ``sys.modules``.
When you pass an object reference into another function, in general, the
function borrows the reference from you --- if it needs to store it, it will use
-:cfunc:`Py_INCREF` to become an independent owner. There are exactly two
-important exceptions to this rule: :cfunc:`PyTuple_SetItem` and
-:cfunc:`PyList_SetItem`. These functions take over ownership of the item passed
-to them --- even if they fail! (Note that :cfunc:`PyDict_SetItem` and friends
+:c:func:`Py_INCREF` to become an independent owner. There are exactly two
+important exceptions to this rule: :c:func:`PyTuple_SetItem` and
+:c:func:`PyList_SetItem`. These functions take over ownership of the item passed
+to them --- even if they fail! (Note that :c:func:`PyDict_SetItem` and friends
don't take over ownership --- they are "normal.")
When a C function is called from Python, it borrows references to its arguments
from the caller. The caller owns a reference to the object, so the borrowed
reference's lifetime is guaranteed until the function returns. Only when such a
borrowed reference must be stored or passed on, it must be turned into an owned
-reference by calling :cfunc:`Py_INCREF`.
+reference by calling :c:func:`Py_INCREF`.
The object reference returned from a C function that is called from Python must
be an owned reference --- ownership is transferred from the function to its
@@ -965,7 +967,7 @@ There are a few situations where seemingly harmless use of a borrowed reference
can lead to problems. These all have to do with implicit invocations of the
interpreter, which can cause the owner of a reference to dispose of it.
-The first and most important case to know about is using :cfunc:`Py_DECREF` on
+The first and most important case to know about is using :c:func:`Py_DECREF` on
an unrelated object while borrowing a reference to a list item. For instance::
void
@@ -981,7 +983,7 @@ This function first borrows a reference to ``list[0]``, then replaces
``list[1]`` with the value ``0``, and finally prints the borrowed reference.
Looks harmless, right? But it's not!
-Let's follow the control flow into :cfunc:`PyList_SetItem`. The list owns
+Let's follow the control flow into :c:func:`PyList_SetItem`. The list owns
references to all its items, so when item 1 is replaced, it has to dispose of
the original item 1. Now let's suppose the original item 1 was an instance of a
user-defined class, and let's further suppose that the class defined a
@@ -990,8 +992,8 @@ disposing of it will call its :meth:`__del__` method.
Since it is written in Python, the :meth:`__del__` method can execute arbitrary
Python code. Could it perhaps do something to invalidate the reference to
-``item`` in :cfunc:`bug`? You bet! Assuming that the list passed into
-:cfunc:`bug` is accessible to the :meth:`__del__` method, it could execute a
+``item`` in :c:func:`bug`? You bet! Assuming that the list passed into
+:c:func:`bug` is accessible to the :meth:`__del__` method, it could execute a
statement to the effect of ``del list[0]``, and assuming this was the last
reference to that object, it would free the memory associated with it, thereby
invalidating ``item``.
@@ -1018,8 +1020,8 @@ The second case of problems with a borrowed reference is a variant involving
threads. Normally, multiple threads in the Python interpreter can't get in each
other's way, because there is a global lock protecting Python's entire object
space. However, it is possible to temporarily release this lock using the macro
-:cmacro:`Py_BEGIN_ALLOW_THREADS`, and to re-acquire it using
-:cmacro:`Py_END_ALLOW_THREADS`. This is common around blocking I/O calls, to
+:c:macro:`Py_BEGIN_ALLOW_THREADS`, and to re-acquire it using
+:c:macro:`Py_END_ALLOW_THREADS`. This is common around blocking I/O calls, to
let other threads use the processor while waiting for the I/O to complete.
Obviously, the following function has the same problem as the previous one::
@@ -1048,11 +1050,11 @@ function --- if each function were to test for *NULL*, there would be a lot of
redundant tests and the code would run more slowly.
It is better to test for *NULL* only at the "source:" when a pointer that may be
-*NULL* is received, for example, from :cfunc:`malloc` or from a function that
+*NULL* is received, for example, from :c:func:`malloc` or from a function that
may raise an exception.
-The macros :cfunc:`Py_INCREF` and :cfunc:`Py_DECREF` do not check for *NULL*
-pointers --- however, their variants :cfunc:`Py_XINCREF` and :cfunc:`Py_XDECREF`
+The macros :c:func:`Py_INCREF` and :c:func:`Py_DECREF` do not check for *NULL*
+pointers --- however, their variants :c:func:`Py_XINCREF` and :c:func:`Py_XDECREF`
do.
The macros for checking for a particular object type (``Pytype_Check()``) don't
@@ -1126,7 +1128,7 @@ other extension modules must be exported in a different way.
Python provides a special mechanism to pass C-level information (pointers) from
one extension module to another one: Capsules. A Capsule is a Python data type
-which stores a pointer (:ctype:`void \*`). Capsules can only be created and
+which stores a pointer (:c:type:`void \*`). Capsules can only be created and
accessed via their C API, but they can be passed around like any other Python
object. In particular, they can be assigned to a name in an extension module's
namespace. Other extension modules can then import this module, retrieve the
@@ -1139,8 +1141,8 @@ various tasks of storing and retrieving the pointers can be distributed in
different ways between the module providing the code and the client modules.
Whichever method you choose, it's important to name your Capsules properly.
-The function :cfunc:`PyCapsule_New` takes a name parameter
-(:ctype:`const char \*`); you're permitted to pass in a *NULL* name, but
+The function :c:func:`PyCapsule_New` takes a name parameter
+(:c:type:`const char \*`); you're permitted to pass in a *NULL* name, but
we strongly encourage you to specify a name. Properly named Capsules provide
a degree of runtime type-safety; there is no feasible way to tell one unnamed
Capsule from another.
@@ -1150,7 +1152,7 @@ this convention::
modulename.attributename
-The convenience function :cfunc:`PyCapsule_Import` makes it easy to
+The convenience function :c:func:`PyCapsule_Import` makes it easy to
load a C API provided via a Capsule, but only if the Capsule's name
matches this convention. This behavior gives C API users a high degree
of certainty that the Capsule they load contains the correct C API.
@@ -1158,19 +1160,19 @@ of certainty that the Capsule they load contains the correct C API.
The following example demonstrates an approach that puts most of the burden on
the writer of the exporting module, which is appropriate for commonly used
library modules. It stores all C API pointers (just one in the example!) in an
-array of :ctype:`void` pointers which becomes the value of a Capsule. The header
+array of :c:type:`void` pointers which becomes the value of a Capsule. The header
file corresponding to the module provides a macro that takes care of importing
the module and retrieving its C API pointers; client modules only have to call
this macro before accessing the C API.
The exporting module is a modification of the :mod:`spam` module from section
:ref:`extending-simpleexample`. The function :func:`spam.system` does not call
-the C library function :cfunc:`system` directly, but a function
-:cfunc:`PySpam_System`, which would of course do something more complicated in
+the C library function :c:func:`system` directly, but a function
+:c:func:`PySpam_System`, which would of course do something more complicated in
reality (such as adding "spam" to every command). This function
-:cfunc:`PySpam_System` is also exported to other extension modules.
+:c:func:`PySpam_System` is also exported to other extension modules.
-The function :cfunc:`PySpam_System` is a plain C function, declared
+The function :c:func:`PySpam_System` is a plain C function, declared
``static`` like everything else::
static int
@@ -1179,7 +1181,7 @@ The function :cfunc:`PySpam_System` is a plain C function, declared
return system(command);
}
-The function :cfunc:`spam_system` is modified in a trivial way::
+The function :c:func:`spam_system` is modified in a trivial way::
static PyObject *
spam_system(PyObject *self, PyObject *args)
@@ -1283,8 +1285,8 @@ like this::
#endif /* !defined(Py_SPAMMODULE_H) */
All that a client module must do in order to have access to the function
-:cfunc:`PySpam_System` is to call the function (or rather macro)
-:cfunc:`import_spam` in its initialization function::
+:c:func:`PySpam_System` is to call the function (or rather macro)
+:c:func:`import_spam` in its initialization function::
PyMODINIT_FUNC
PyInit_client(void)
diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst
index d48efc9..75836c7 100644
--- a/Doc/extending/newtypes.rst
+++ b/Doc/extending/newtypes.rst
@@ -26,7 +26,7 @@ The Basics
==========
The Python runtime sees all Python objects as variables of type
-:ctype:`PyObject\*`. A :ctype:`PyObject` is not a very magnificent object - it
+:c:type:`PyObject\*`. A :c:type:`PyObject` is not a very magnificent object - it
just contains the refcount and a pointer to the object's "type object". This is
where the action is; the type object determines which (C) functions get called
when, for instance, an attribute gets looked up on an object or it is multiplied
@@ -95,7 +95,7 @@ Moving on, we come to the crunch --- the type object. ::
"Noddy objects", /* tp_doc */
};
-Now if you go and look up the definition of :ctype:`PyTypeObject` in
+Now if you go and look up the definition of :c:type:`PyTypeObject` in
:file:`object.h` you'll see that it has many more fields that the definition
above. The remaining fields will be filled with zeros by the C compiler, and
it's common practice to not specify them explicitly unless you need them.
@@ -111,7 +111,7 @@ This line is a bit of a wart; what we'd like to write is::
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
-:cfunc:`PyType_Ready`. ::
+:c:func:`PyType_Ready`. ::
"noddy.Noddy", /* tp_name */
@@ -130,7 +130,7 @@ the type is :class:`Noddy`, so we set the type name to :class:`noddy.Noddy`. ::
sizeof(noddy_NoddyObject), /* tp_basicsize */
This is so that Python knows how much memory to allocate when you call
-:cfunc:`PyObject_New`.
+:c:func:`PyObject_New`.
.. note::
@@ -170,12 +170,12 @@ the module. We'll expand this example later to have more interesting behavior.
For now, all we want to be able to do is to create new :class:`Noddy` objects.
To enable object creation, we have to provide a :attr:`tp_new` implementation.
In this case, we can just use the default implementation provided by the API
-function :cfunc:`PyType_GenericNew`. We'd like to just assign this to the
+function :c:func:`PyType_GenericNew`. We'd like to just assign this to the
:attr:`tp_new` slot, but we can't, for portability sake, On some platforms or
compilers, we can't statically initialize a structure member with a function
defined in another C module, so, instead, we'll assign the :attr:`tp_new` slot
in the module initialization function just before calling
-:cfunc:`PyType_Ready`::
+:c:func:`PyType_Ready`::
noddy_NoddyType.tp_new = PyType_GenericNew;
if (PyType_Ready(&noddy_NoddyType) < 0)
@@ -185,7 +185,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
-:cfunc:`PyInit_noddy`::
+:c:func:`PyInit_noddy`::
if (PyType_Ready(&noddy_NoddyType) < 0)
return;
@@ -273,7 +273,7 @@ which is assigned to the :attr:`tp_dealloc` member::
(destructor)Noddy_dealloc, /*tp_dealloc*/
This method decrements the reference counts of the two Python attributes. We use
-:cfunc:`Py_XDECREF` here because the :attr:`first` and :attr:`last` members
+:c:func:`Py_XDECREF` here because the :attr:`first` and :attr:`last` members
could be *NULL*. It then calls the :attr:`tp_free` member of the object's type
to free the object's memory. Note that the object's type might not be
:class:`NoddyType`, because the object may be an instance of a subclass.
@@ -319,8 +319,8 @@ the :meth:`__new__` method. One reason to implement a new method is to assure
the initial values of instance variables. In this case, we use the new method
to make sure that the initial values of the members :attr:`first` and
:attr:`last` are not *NULL*. If we didn't care whether the initial values were
-*NULL*, we could have used :cfunc:`PyType_GenericNew` as our new method, as we
-did before. :cfunc:`PyType_GenericNew` initializes all of the instance variable
+*NULL*, we could have used :c:func:`PyType_GenericNew` as our new method, as we
+did before. :c:func:`PyType_GenericNew` initializes all of the instance variable
members to *NULL*.
The new method is a static method that is passed the type being instantiated and
@@ -330,7 +330,7 @@ often ignore the arguments, leaving the argument handling to initializer
methods. Note that if the type supports subclassing, the type passed may not be
the type being defined. The new method calls the tp_alloc slot to allocate
memory. We don't fill the :attr:`tp_alloc` slot ourselves. Rather
-:cfunc:`PyType_Ready` fills it for us by inheriting it from our base class,
+:c:func:`PyType_Ready` fills it for us by inheriting it from our base class,
which is :class:`object` by default. Most types use the default allocation.
.. note::
@@ -515,8 +515,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 :cfunc:`PyInit_noddy` to :cfunc:`PyInit_noddy2` and update the module
-name in the :ctype:`PyModuleDef` struct.
+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::
@@ -582,7 +582,7 @@ closure. The new value may be *NULL*, in which case the attribute is being
deleted. In our setter, we raise an error if the attribute is deleted or if the
attribute value is not a string.
-We create an array of :ctype:`PyGetSetDef` structures::
+We create an array of :c:type:`PyGetSetDef` structures::
static PyGetSetDef Noddy_getseters[] = {
{"first",
@@ -602,7 +602,7 @@ and register it in the :attr:`tp_getset` slot::
to register our attribute getters and setters.
-The last item in a :ctype:`PyGetSetDef` structure is the closure mentioned
+The last item in a :c:type:`PyGetSetDef` structure is the closure mentioned
above. In this case, we aren't using the closure, so we just pass *NULL*.
We also remove the member definitions for these attributes::
@@ -647,8 +647,8 @@ be passed::
With these changes, we can assure that the :attr:`first` and :attr:`last`
members are never *NULL* so we can remove checks for *NULL* values in almost all
-cases. This means that most of the :cfunc:`Py_XDECREF` calls can be converted to
-:cfunc:`Py_DECREF` calls. The only place we can't change these calls is in the
+cases. This means that most of the :c:func:`Py_XDECREF` calls can be converted to
+:c:func:`Py_DECREF` calls. The only place we can't change these calls is in the
deallocator, where there is the possibility that the initialization of these
members failed in the constructor.
@@ -713,13 +713,13 @@ cycles::
}
For each subobject that can participate in cycles, we need to call the
-:cfunc:`visit` function, which is passed to the traversal method. The
-:cfunc:`visit` function takes as arguments the subobject and the extra argument
+:c:func:`visit` function, which is passed to the traversal method. The
+:c:func:`visit` function takes as arguments the subobject and the extra argument
*arg* passed to the traversal method. It returns an integer value that must be
returned if it is non-zero.
-Python provides a :cfunc:`Py_VISIT` macro that automates calling visit
-functions. With :cfunc:`Py_VISIT`, :cfunc:`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)
@@ -732,7 +732,7 @@ functions. With :cfunc:`Py_VISIT`, :cfunc:`Noddy_traverse` can be simplified::
.. note::
Note that the :attr:`tp_traverse` implementation must name its arguments exactly
- *visit* and *arg* in order to use :cfunc:`Py_VISIT`. This is to encourage
+ *visit* and *arg* in order to use :c:func:`Py_VISIT`. This is to encourage
uniformity across these boring implementations.
We also need to provide a method for clearing any subobjects that can
@@ -762,18 +762,18 @@ to use it::
Py_TYPE(self)->tp_free((PyObject*)self);
}
-Notice the use of a temporary variable in :cfunc:`Noddy_clear`. We use the
+Notice the use of a temporary variable in :c:func:`Noddy_clear`. We use the
temporary variable so that we can set each member to *NULL* before decrementing
its reference count. We do this because, as was discussed earlier, if the
reference count drops to zero, we might cause code to run that calls back into
the object. In addition, because we now support garbage collection, we also
have to worry about code being run that triggers garbage collection. If garbage
collection is run, our :attr:`tp_traverse` handler could get called. We can't
-take a chance of having :cfunc:`Noddy_traverse` called when a member's reference
+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 provides a :cfunc:`Py_CLEAR` that automates the careful decrementing of
-reference counts. With :cfunc:`Py_CLEAR`, the :cfunc:`Noddy_clear` function can
+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
@@ -829,7 +829,7 @@ previous sections. We will break down the main differences between them. ::
The primary difference for derived type objects is that the base type's object
structure must be the first value. The base type will already include the
-:cfunc:`PyObject_HEAD` at the beginning of its structure.
+:c:func:`PyObject_HEAD` at the beginning of its structure.
When a Python object is a :class:`Shoddy` instance, its *PyObject\** pointer can
be safely cast to both *PyListObject\** and *Shoddy\**. ::
@@ -851,10 +851,10 @@ This pattern is important when writing a type with custom :attr:`new` and
memory for the object with :attr:`tp_alloc`, that will be handled by the base
class when calling its :attr:`tp_new`.
-When filling out the :cfunc:`PyTypeObject` for the :class:`Shoddy` type, you see
-a slot for :cfunc:`tp_base`. Due to cross platform compiler issues, you can't
-fill that field directly with the :cfunc:`PyList_Type`; it can be done later in
-the module's :cfunc:`init` function. ::
+When filling out the :c:func:`PyTypeObject` for the :class:`Shoddy` type, you see
+a slot for :c:func:`tp_base`. Due to cross platform compiler issues, you can't
+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
PyInit_shoddy(void)
@@ -874,12 +874,12 @@ the module's :cfunc:`init` function. ::
return m;
}
-Before calling :cfunc:`PyType_Ready`, the type structure must have the
+Before calling :c:func:`PyType_Ready`, the type structure must have the
:attr:`tp_base` slot filled in. When we are deriving a new type, it is not
-necessary to fill out the :attr:`tp_alloc` slot with :cfunc:`PyType_GenericNew`
+necessary to fill out the :attr:`tp_alloc` slot with :c:func:`PyType_GenericNew`
-- the allocate function from the base type will be inherited.
-After that, calling :cfunc:`PyType_Ready` and adding the type object to the
+After that, calling :c:func:`PyType_Ready` and adding the type object to the
module is the same as with the basic :class:`Noddy` examples.
@@ -891,7 +891,7 @@ Type Methods
This section aims to give a quick fly-by on the various type methods you can
implement and what they do.
-Here is the definition of :ctype:`PyTypeObject`, with some fields only used in
+Here is the definition of :c:type:`PyTypeObject`, with some fields only used in
debug builds omitted:
.. literalinclude:: ../includes/typestruct.h
@@ -969,8 +969,8 @@ which a deallocator performs which may cause additional Python code to be
executed may detect that an exception has been set. This can lead to misleading
errors from the interpreter. The proper way to protect against this is to save
a pending exception before performing the unsafe action, and restoring it when
-done. This can be done using the :cfunc:`PyErr_Fetch` and
-:cfunc:`PyErr_Restore` functions::
+done. This can be done using the :c:func:`PyErr_Fetch` and
+:c:func:`PyErr_Restore` functions::
static void
my_dealloc(PyObject *obj)
@@ -1060,8 +1060,8 @@ a special case, for which the new value passed to the handler is *NULL*.
Python supports two pairs of attribute handlers; a type that supports attributes
only needs to implement the functions for one pair. The difference is that one
-pair takes the name of the attribute as a :ctype:`char\*`, while the other
-accepts a :ctype:`PyObject\*`. Each type can use whichever pair makes more
+pair takes the name of the attribute as a :c:type:`char\*`, while the other
+accepts a :c:type:`PyObject\*`. Each type can use whichever pair makes more
sense for the implementation's convenience. ::
getattrfunc tp_getattr; /* char * version */
@@ -1072,7 +1072,7 @@ sense for the implementation's convenience. ::
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
-provide the :ctype:`PyObject\*` version of the attribute management functions.
+provide the :c:type:`PyObject\*` version of the attribute management functions.
The actual need for type-specific attribute handlers almost completely
disappeared starting with Python 2.2, though there are many examples which have
not been updated to use some of the new generic mechanism that is available.
@@ -1086,7 +1086,7 @@ Generic Attribute Management
Most extension types only use *simple* attributes. So, what makes the
attributes simple? There are only a couple of conditions that must be met:
-#. The name of the attributes must be known when :cfunc:`PyType_Ready` is
+#. The name of the attributes must be known when :c:func:`PyType_Ready` is
called.
#. No special processing is needed to record that an attribute was looked up or
@@ -1095,7 +1095,7 @@ attributes simple? There are only a couple of conditions that must be met:
Note that this list does not place any restrictions on the values of the
attributes, when the values are computed, or how relevant data is stored.
-When :cfunc:`PyType_Ready` is called, it uses three tables referenced by the
+When :c:func:`PyType_Ready` is called, it uses three tables referenced by the
type object to create :term:`descriptor`\s which are placed in the dictionary of the
type object. Each descriptor controls access to one attribute of the instance
object. Each of the tables is optional; if all three are *NULL*, instances of
@@ -1110,7 +1110,7 @@ The tables are declared as three fields of the type object::
struct PyGetSetDef *tp_getset;
If :attr:`tp_methods` is not *NULL*, it must refer to an array of
-:ctype:`PyMethodDef` structures. Each entry in the table is an instance of this
+:c:type:`PyMethodDef` structures. Each entry in the table is an instance of this
structure::
typedef struct PyMethodDef {
@@ -1192,9 +1192,9 @@ of *NULL* is required.
Type-specific Attribute Management
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-For simplicity, only the :ctype:`char\*` version will be demonstrated here; the
-type of the name parameter is the only difference between the :ctype:`char\*`
-and :ctype:`PyObject\*` flavors of the interface. This example effectively does
+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. It explains how the handler functions are
called, so that if you do need to extend their functionality, you'll understand
@@ -1242,8 +1242,8 @@ Object Comparison
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 :cfunc:`PyObject_RichCompare` and
-:cfunc:`PyObject_RichCompareBool`.
+:meth:`__lt__`, and also called by :c:func:`PyObject_RichCompare` and
+:c:func:`PyObject_RichCompareBool`.
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``,
@@ -1306,8 +1306,8 @@ to indicate the presence of a slot, but a slot may still be unfilled.) ::
If you wish your object to be able to act like a number, a sequence, or a
mapping object, then you place the address of a structure that implements the C
-type :ctype:`PyNumberMethods`, :ctype:`PySequenceMethods`, or
-:ctype:`PyMappingMethods`, respectively. It is up to you to fill in this
+type :c:type:`PyNumberMethods`, :c:type:`PySequenceMethods`, or
+:c:type:`PyMappingMethods`, respectively. It is up to you to fill in this
structure with appropriate values. You can find examples of the use of each of
these in the :file:`Objects` directory of the Python source distribution. ::
@@ -1339,11 +1339,11 @@ This function takes three arguments:
the call is ``obj1('hello')``, then *arg1* is ``obj1``.
#. *arg2* is a tuple containing the arguments to the call. You can use
- :cfunc:`PyArg_ParseTuple` to extract the arguments.
+ :c:func:`PyArg_ParseTuple` to extract the arguments.
#. *arg3* is a dictionary of keyword arguments that were passed. If this is
non-*NULL* and you support keyword arguments, use
- :cfunc:`PyArg_ParseTupleAndKeywords` to extract the arguments. If you do not
+ :c:func:`PyArg_ParseTupleAndKeywords` to extract the arguments. If you do not
want to support keyword arguments and this is non-*NULL*, raise a
:exc:`TypeError` with a message saying that keyword arguments are not supported.
@@ -1417,7 +1417,7 @@ to participate in the weak reference mechanism without incurring the overhead on
those objects which do not benefit by weak referencing (such as numbers).
For an object to be weakly referencable, the extension must include a
-:ctype:`PyObject\*` field in the instance structure for the use of the weak
+:c:type:`PyObject\*` field in the instance structure for the use of the weak
reference mechanism; it must be initialized to *NULL* by the object's
constructor. It must also set the :attr:`tp_weaklistoffset` field of the
corresponding type object to the offset of the field. For example, the instance
@@ -1493,7 +1493,7 @@ 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 :cfunc:`PyObject_TypeCheck` function. A sample of its use
+implementing, use the :c:func:`PyObject_TypeCheck` function. A sample of its use
might be something like the following::
if (! PyObject_TypeCheck(some_object, &MyType)) {
diff --git a/Doc/extending/windows.rst b/Doc/extending/windows.rst
index d1d0cf7..3fd5e57 100644
--- a/Doc/extending/windows.rst
+++ b/Doc/extending/windows.rst
@@ -98,8 +98,8 @@ described here are distributed with the Python sources in the
it. Copy your C sources into it. Note that the module source file name does
not necessarily have to match the module name, but the name of the
initialization function should match the module name --- you can only import a
- module :mod:`spam` if its initialization function is called :cfunc:`initspam`,
- and it should call :cfunc:`Py_InitModule` with the string ``"spam"`` as its
+ module :mod:`spam` if its initialization function is called :c:func:`initspam`,
+ and it should call :c:func:`Py_InitModule` with the string ``"spam"`` as its
first argument (use the minimal :file:`example.c` in this directory as a guide).
By convention, it lives in a file called :file:`spam.c` or :file:`spammodule.c`.
The output file should be called :file:`spam.pyd` (in Release mode) or
@@ -259,7 +259,7 @@ use these commands::
The first command created three files: :file:`spam.obj`, :file:`spam.dll` and
:file:`spam.lib`. :file:`Spam.dll` does not contain any Python functions (such
-as :cfunc:`PyArg_ParseTuple`), but it does know how to find the Python code
+as :c:func:`PyArg_ParseTuple`), but it does know how to find the Python code
thanks to :file:`pythonXY.lib`.
The second command created :file:`ni.dll` (and :file:`.obj` and :file:`.lib`),
diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst
index 3889774..b9faf57 100644
--- a/Doc/faq/design.rst
+++ b/Doc/faq/design.rst
@@ -418,11 +418,9 @@ 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
+code in various ways to increase performance. See, for example, `Cython
+<http://cython.org/>`_, `Pyrex
+<http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/>`_ and `Weave
<http://www.scipy.org/Weave>`_.
@@ -649,9 +647,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 builtin -- :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::
+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::
for key in sorted(mydict):
... # do whatever with mydict[key]...
diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst
index 6527ff1..fa8e6e7 100644
--- a/Doc/faq/extending.rst
+++ b/Doc/faq/extending.rst
@@ -45,10 +45,11 @@ 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.
-`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
@@ -56,47 +57,48 @@ with a tool such as `SWIG <http://www.swig.org>`_. `SIP
<http://www.riverbankcomputing.co.uk/software/sip/>`__, `CXX
<http://cxx.sourceforge.net/>`_ `Boost
<http://www.boost.org/libs/python/doc/index.html>`_, or `Weave
-<http://www.scipy.org/Weave>`_ are also alternatives for wrapping C++ libraries.
+<http://www.scipy.org/Weave>`_ are also alternatives for wrapping
+C++ libraries.
How can I execute arbitrary Python statements from C?
-----------------------------------------------------
-The highest-level function to do this is :cfunc:`PyRun_SimpleString` which takes
+The highest-level function to do this is :c:func:`PyRun_SimpleString` which takes
a single string argument to be executed in the context of the module
``__main__`` and returns 0 for success and -1 when an exception occurred
(including ``SyntaxError``). If you want more control, use
-:cfunc:`PyRun_String`; see the source for :cfunc:`PyRun_SimpleString` in
+:c:func:`PyRun_String`; see the source for :c:func:`PyRun_SimpleString` in
``Python/pythonrun.c``.
How can I evaluate an arbitrary Python expression from C?
---------------------------------------------------------
-Call the function :cfunc:`PyRun_String` from the previous question with the
-start symbol :cdata:`Py_eval_input`; it parses an expression, evaluates it and
+Call the function :c:func:`PyRun_String` from the previous question with the
+start symbol :c:data:`Py_eval_input`; it parses an expression, evaluates it and
returns its value.
How do I extract C values from a Python object?
-----------------------------------------------
-That depends on the object's type. If it's a tuple, :cfunc:`PyTuple_Size`
-returns its length and :cfunc:`PyTuple_GetItem` returns the item at a specified
-index. Lists have similar functions, :cfunc:`PyListSize` and
-:cfunc:`PyList_GetItem`.
+That depends on the object's type. If it's a tuple, :c:func:`PyTuple_Size`
+returns its length and :c:func:`PyTuple_GetItem` returns the item at a specified
+index. Lists have similar functions, :c:func:`PyListSize` and
+:c:func:`PyList_GetItem`.
-For strings, :cfunc:`PyString_Size` returns its length and
-:cfunc:`PyString_AsString` a pointer to its value. Note that Python strings may
-contain null bytes so C's :cfunc:`strlen` should not be used.
+For strings, :c:func:`PyString_Size` returns its length and
+:c:func:`PyString_AsString` a pointer to its value. Note that Python strings may
+contain null bytes so C's :c:func:`strlen` should not be used.
To test the type of an object, first make sure it isn't *NULL*, and then use
-:cfunc:`PyString_Check`, :cfunc:`PyTuple_Check`, :cfunc:`PyList_Check`, etc.
+:c:func:`PyString_Check`, :c:func:`PyTuple_Check`, :c:func:`PyList_Check`, etc.
There is also a high-level API to Python objects which is provided by the
so-called 'abstract' interface -- read ``Include/abstract.h`` for further
details. It allows interfacing with any kind of Python sequence using calls
-like :cfunc:`PySequence_Length`, :cfunc:`PySequence_GetItem`, etc.) as well as
+like :c:func:`PySequence_Length`, :c:func:`PySequence_GetItem`, etc.) as well as
many other useful protocols.
@@ -105,7 +107,7 @@ 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 :cfunc:`Py_INCREF` it. Lists have similar functions
+``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.
@@ -114,9 +116,9 @@ the tuple items to some value before you pass the tuple to Python code --
How do I call an object's method from C?
----------------------------------------
-The :cfunc:`PyObject_CallMethod` function can be used to call an arbitrary
+The :c:func:`PyObject_CallMethod` function can be used to call an arbitrary
method of an object. The parameters are the object, the name of the method to
-call, a format string like that used with :cfunc:`Py_BuildValue`, and the
+call, a format string like that used with :c:func:`Py_BuildValue`, and the
argument values::
PyObject *
@@ -124,7 +126,7 @@ argument values::
char *arg_format, ...);
This works for any object that has methods -- whether built-in or user-defined.
-You are responsible for eventually :cfunc:`Py_DECREF`\ 'ing the return value.
+You are responsible for eventually :c:func:`Py_DECREF`\ 'ing the return value.
To call, e.g., a file object's "seek" method with arguments 10, 0 (assuming the
file object pointer is "f")::
@@ -137,7 +139,7 @@ file object pointer is "f")::
Py_DECREF(res);
}
-Note that since :cfunc:`PyObject_CallObject` *always* wants a tuple for the
+Note that since :c:func:`PyObject_CallObject` *always* wants a tuple for the
argument list, to call a function without arguments, pass "()" for the format,
and to call a function with one argument, surround the argument in parentheses,
e.g. "(i)".
@@ -188,7 +190,7 @@ module) as follows::
attr = PyObject_GetAttrString(module, "<attrname>");
-Calling :cfunc:`PyObject_SetAttrString` to assign to variables in the module
+Calling :c:func:`PyObject_SetAttrString` to assign to variables in the module
also works.
@@ -201,11 +203,7 @@ begin by reading :ref:`the "Extending and Embedding" document
whole lot of difference between C and C++ -- so the strategy of building a new
Python type around a C structure (pointer) type will also work for C++ objects.
-For C++ libraries, you can look at `SIP
-<http://www.riverbankcomputing.co.uk/sip/>`_, `CXX
-<http://cxx.sourceforge.net/>`_, `Boost
-<http://www.boost.org/libs/python/doc/index.html>`_, `Weave
-<http://www.scipy.org/Weave>`_ or `SWIG <http://www.swig.org>`_
+For C++ libraries, see :ref:`c-wrapper-software`.
I added a module using the Setup file and the make fails; why?
@@ -273,16 +271,16 @@ the input is invalid.
In Python you can use the :mod:`codeop` module, which approximates the parser's
behavior sufficiently. IDLE uses this, for example.
-The easiest way to do it in C is to call :cfunc:`PyRun_InteractiveLoop` (perhaps
+The easiest way to do it in C is to call :c:func:`PyRun_InteractiveLoop` (perhaps
in a separate thread) and let the Python interpreter handle the input for
-you. You can also set the :cfunc:`PyOS_ReadlineFunctionPointer` to point at your
+you. You can also set the :c:func:`PyOS_ReadlineFunctionPointer` to point at your
custom input function. See ``Modules/readline.c`` and ``Parser/myreadline.c``
for more hints.
However sometimes you have to run the embedded Python interpreter in the same
thread as your rest application and you can't allow the
-:cfunc:`PyRun_InteractiveLoop` to stop while waiting for user input. The one
-solution then is to call :cfunc:`PyParser_ParseString` and test for ``e.error``
+:c:func:`PyRun_InteractiveLoop` to stop while waiting for user input. The one
+solution then is to call :c:func:`PyParser_ParseString` and test for ``e.error``
equal to ``E_EOF``, which means the input is incomplete). Here's a sample code
fragment, untested, inspired by code from Alex Farber::
@@ -313,8 +311,8 @@ fragment, untested, inspired by code from Alex Farber::
}
Another solution is trying to compile the received string with
-:cfunc:`Py_CompileString`. If it compiles without errors, try to execute the
-returned code object by calling :cfunc:`PyEval_EvalCode`. Otherwise save the
+:c:func:`Py_CompileString`. If it compiles without errors, try to execute the
+returned code object by calling :c:func:`PyEval_EvalCode`. Otherwise save the
input for later. If the compilation fails, find out if it's an error or just
more input is required - by extracting the message string from the exception
tuple and comparing it to the string "unexpected EOF while parsing". Here is a
@@ -382,7 +380,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);
@@ -443,7 +441,7 @@ extension module using g++ (e.g., ``g++ -shared -o mymodule.so mymodule.o``).
Can I create an object class with some methods implemented in C and others in Python (e.g. through inheritance)?
----------------------------------------------------------------------------------------------------------------
-In Python 2.2, you can inherit from builtin classes such as :class:`int`,
+In Python 2.2, you can inherit from built-in classes such as :class:`int`,
:class:`list`, :class:`dict`, etc.
The Boost Python Library (BPL, http://www.boost.org/libs/python/doc/index.html)
@@ -466,8 +464,8 @@ This can easily occur when using pre-built extension packages. RedHat Linux
7.x, in particular, provided a "python2" binary that is compiled with 4-byte
Unicode. This only causes the link failure if the extension uses any of the
``PyUnicode_*()`` functions. It is also a problem if an extension uses any of
-the Unicode-related format specifiers for :cfunc:`Py_BuildValue` (or similar) or
-parameter specifications for :cfunc:`PyArg_ParseTuple`.
+the Unicode-related format specifiers for :c:func:`Py_BuildValue` (or similar) or
+parameter specifications for :c:func:`PyArg_ParseTuple`.
You can check the size of the Unicode character a Python interpreter is using by
checking the value of sys.maxunicode:
diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst
index 03177c9..e502ef8 100644
--- a/Doc/faq/gui.rst
+++ b/Doc/faq/gui.rst
@@ -15,7 +15,9 @@ 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
@@ -23,12 +25,14 @@ 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.
-
-wxWindows
+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
---------
wxWidgets (http://www.wxwidgets.org) is a free, portable GUI class
@@ -47,22 +51,25 @@ Both wxWidgets and wxPython are free, open source, software with
permissive licences that allow their use in commercial products as
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). 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 by James Henstridge; see ftp://ftp.gtk.org/pub/gtk/python/.
+implemented by James Henstridge; see <http://www.pygtk.org>.
FLTK
----
@@ -91,14 +98,15 @@ What platform-specific GUI toolkits exist for Python?
`The Mac port <http://python.org/download/mac>`_ by Jack Jansen has a rich and
ever-growing set of modules that support the native Mac toolbox calls. The port
-includes support for MacOS9 and MacOS X's Carbon libraries. By installing the
-`PyObjc Objective-C bridge <http://pyobjc.sourceforge.net>`_, Python programs
-can use MacOS X's Cocoa libraries. See the documentation that comes with the Mac
-port.
+supports MacOS X's Carbon libraries.
+
+By installing the `PyObjc Objective-C bridge
+<http://pyobjc.sourceforge.net>`_, Python programs can use MacOS X's
+Cocoa libraries. See the documentation that comes with the Mac port.
:ref:`Pythonwin <windows-faq>` by Mark Hammond includes an interface to the
-Microsoft Foundation Classes and a Python programming environment using it
-that's written mostly in Python.
+Microsoft Foundation Classes and a Python programming environment
+that's written mostly in Python using the MFC classes.
Tkinter questions
@@ -111,23 +119,26 @@ Freeze is a tool to create stand-alone applications. When freezing Tkinter
applications, the applications will not be truly stand-alone, as the application
will still need the Tcl and Tk libraries.
-One solution is to ship the application with the tcl and tk libraries, and point
+One solution is to ship the application with the Tcl and Tk libraries, and point
to them at run-time using the :envvar:`TCL_LIBRARY` and :envvar:`TK_LIBRARY`
environment variables.
To get truly stand-alone applications, the Tcl scripts that form the library
have to be integrated into the application as well. One tool supporting that is
SAM (stand-alone modules), which is part of the Tix distribution
-(http://tix.mne.com). Build Tix with SAM enabled, perform the appropriate call
-to Tclsam_init etc inside Python's Modules/tkappinit.c, and link with libtclsam
-and libtksam (you might include the Tix libraries as well).
+(http://tix.sourceforge.net/).
+
+Build Tix with SAM enabled, perform the appropriate call to
+:c:func:`Tclsam_init`, etc. inside Python's
+:file:`Modules/tkappinit.c`, and link with libtclsam and libtksam (you
+might include the Tix libraries as well).
Can I have Tk events handled while waiting for I/O?
---------------------------------------------------
Yes, and you don't even need threads! But you'll have to restructure your I/O
-code a bit. Tk has the equivalent of Xt's XtAddInput() call, which allows you
+code a bit. Tk has the equivalent of Xt's :c:func:`XtAddInput()` call, which allows you
to register a callback function which will be called from the Tk mainloop when
I/O is possible on a file descriptor. Here's what you need::
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 180bd39..ee099cf 100644
--- a/Doc/faq/library.rst
+++ b/Doc/faq/library.rst
@@ -25,10 +25,10 @@ your topic of interest will usually find something helpful.
Where is the math.py (socket.py, regex.py, etc.) source file?
-------------------------------------------------------------
-If you can't find a source file for a module it may be a builtin or dynamically
-loaded module implemented in C, C++ or other compiled language. In this case
-you may not have the source file or it may be something like mathmodule.c,
-somewhere in a C source directory (not on the Python Path).
+If you can't find a source file for a module it may be a built-in or
+dynamically loaded module implemented in C, C++ or other compiled language.
+In this case you may not have the source file or it may be something like
+mathmodule.c, somewhere in a C source directory (not on the Python Path).
There are (at least) three kinds of modules in Python:
@@ -285,11 +285,15 @@ 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 with ``.put(obj)`` to
-add an item to the queue and ``.get()`` to return an item. 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 with ``.put(obj)`` to add an item to the queue and ``.get()``
+to return an item. The class will take care of the locking necessary to
+ensure that each job is handed out exactly once.
Here's a trivial example::
@@ -352,7 +356,7 @@ provides a featureful interface.
What kinds of global value mutation are thread-safe?
----------------------------------------------------
-A global interpreter lock (GIL) is used internally to ensure that only one
+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.setswitchinterval`. Each bytecode instruction and
@@ -361,7 +365,7 @@ therefore atomic from the point of view of a Python program.
In theory, this means an exact accounting requires an exact understanding of the
PVM bytecode implementation. In practice, it means that operations on shared
-variables of builtin data types (ints, lists, dicts, etc) that "look atomic"
+variables of built-in data types (ints, lists, dicts, etc) that "look atomic"
really are.
For example, the following operations are all atomic (L, L1, L2 are lists, D,
@@ -395,32 +399,34 @@ 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 Global Interpreter Lock (GIL) is often seen as a hindrance to Python's
+The :term:`global interpreter lock` (GIL) is often seen as a hindrance to Python's
deployment on high-end multiprocessor server machines, because a multi-threaded
Python program effectively only uses one CPU, due to the insistence that
(almost) all Python code can only run while the GIL is held.
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 at 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.
@@ -511,9 +517,9 @@ I can't seem to use os.read() on a pipe created with os.popen(); why?
:func:`os.read` is a low-level function which takes a file descriptor, a small
integer representing the opened file. :func:`os.popen` creates a high-level
-file object, the same type returned by the builtin :func:`open` function. Thus,
-to read n bytes from a pipe p created with :func:`os.popen`, you need to use
-``p.read(n)``.
+file object, the same type returned by the built-in :func:`open` function.
+Thus, to read n bytes from a pipe p created with :func:`os.popen`, you need to
+use ``p.read(n)``.
.. XXX update to use subprocess. See the :ref:`subprocess-replacements` section.
@@ -751,7 +757,8 @@ some sample code::
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
@@ -765,6 +772,12 @@ 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
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
=========
diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst
index 7226e70..07e6818 100644
--- a/Doc/faq/programming.rst
+++ b/Doc/faq/programming.rst
@@ -127,9 +127,9 @@ 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.
+`Cython <http://cython.org>`_ and `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
@@ -178,9 +178,10 @@ 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 builtins 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::
+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::
>>> list(zip([1, 2, 3], [4, 5, 6]))
[(1, 4), (2, 5), (3, 6)]
@@ -203,7 +204,7 @@ 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.
-Be sure to use the :meth:`list.sort` builtin method to do sorting, and see the
+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.
@@ -361,7 +362,7 @@ Though a bit surprising at first, a moment's consideration explains this. On
one hand, requiring :keyword:`global` for assigned variables provides a bar
against unintended side-effects. On the other hand, if ``global`` was required
for all global references, you'd be using ``global`` all the time. You'd have
-to declare as global every reference to a builtin function or to a component of
+to declare as global every reference to a built-in function or to a component of
an imported module. This clutter would defeat the usefulness of the ``global``
declaration for identifying side-effects.
@@ -987,8 +988,8 @@ and then convert decimal strings to numeric values using :func:`int` or
:func:`float`. ``split()`` supports an optional "sep" parameter which is useful
if the line uses something other than whitespace as a separator.
-For more complicated input parsing, regular expressions more powerful than C's
-:cfunc:`sscanf` and better suited for the task.
+For more complicated input parsing, regular expressions are more powerful
+than C's :c:func:`sscanf` and better suited for the task.
What does 'UnicodeDecodeError' or 'UnicodeEncodeError' error mean?
@@ -1033,7 +1034,7 @@ trailing newline from a string.
How do I iterate over a sequence in reverse order?
--------------------------------------------------
-Use the :func:`reversed` builtin function, which is new in Python 2.4::
+Use the :func:`reversed` built-in function, which is new in Python 2.4::
for x in reversed(sequence):
... # do something with x...
diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst
index 7cd16b0..8a20950 100644
--- a/Doc/faq/windows.rst
+++ b/Doc/faq/windows.rst
@@ -445,7 +445,7 @@ present, and ``getch()`` which gets one character without echoing it.
How do I emulate os.kill() in Windows?
--------------------------------------
-To terminate a process, you can use ctypes::
+Prior to Python 2.7 and 3.2, to terminate a process, you can use :mod:`ctypes`::
import ctypes
@@ -455,6 +455,11 @@ To terminate a process, you can use ctypes::
handle = kernel32.OpenProcess(1, 0, pid)
return (0 != kernel32.TerminateProcess(handle, 0))
+In 2.7 and 3.2, :func:`os.kill` is implemented similar to the above function,
+with the additional feature of being able to send CTRL+C and CTRL+BREAK
+to console subprocesses which are designed to handle those signals. See
+:func:`os.kill` for further details.
+
Why does os.path.isdir() fail on NT shared directories?
-------------------------------------------------------
@@ -536,7 +541,7 @@ assumed by the Python interpreter it won't work.
The Python 1.5.* DLLs (``python15.dll``) are all compiled with MS VC++ 5.0 and
with multithreading-DLL options (``/MD``).
-If you can't change compilers or flags, try using :cfunc:`Py_RunSimpleString`.
+If you can't change compilers or flags, try using :c:func:`Py_RunSimpleString`.
A trick to get it to run an arbitrary file is to construct a call to
:func:`execfile` with the name of your file as argument.
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index 7431545..ec8af62 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -27,7 +27,7 @@ Glossary
:ref:`2to3-reference`.
abstract base class
- Abstract Base Classes (abbreviated ABCs) complement :term:`duck-typing` by
+ :ref:`abstract-base-classes` complement :term:`duck-typing` by
providing a way to define interfaces when other techniques like
:func:`hasattr` would be clumsy. Python comes with many built-in ABCs for
data structures (in the :mod:`collections` module), numbers (in the
@@ -57,11 +57,14 @@ Glossary
bytecode
Python source code is compiled into bytecode, the internal representation
- of a Python program in the interpreter. The bytecode is also cached in
- ``.pyc`` and ``.pyo`` files so that executing the same file is faster the
- second time (recompilation from source to bytecode can be avoided). This
- "intermediate language" is said to run on a :term:`virtual machine`
- that executes the machine code corresponding to each bytecode.
+ of a Python program in the CPython interpreter. The bytecode is also
+ cached in ``.pyc`` and ``.pyo`` files so that executing the same file is
+ faster the second time (recompilation from source to bytecode can be
+ avoided). This "intermediate language" is said to run on a
+ :term:`virtual machine` that executes the machine code corresponding to
+ each bytecode. Do note that bytecodes are not expected to work between
+ different Python virtual machines, nor to be stable between Python
+ releases.
A list of bytecode instructions can be found in the documentation for
:ref:`the dis module <bytecodes>`.
@@ -234,6 +237,8 @@ Glossary
performs garbage collection via reference counting and a cyclic garbage
collector that is able to detect and break reference cycles.
+ .. index:: single: generator
+
generator
A function which returns an iterator. It looks like a normal function
except that it contains :keyword:`yield` statements for producing a series
@@ -247,7 +252,7 @@ Glossary
.. index:: single: generator expression
generator expression
- An expression that returns a generator. It looks like a normal expression
+ An expression that returns an iterator. It looks like a normal expression
followed by a :keyword:`for` expression defining a loop variable, range,
and an optional :keyword:`if` expression. The combined expression
generates values for an enclosing function::
@@ -327,7 +332,7 @@ Glossary
slowly. See also :term:`interactive`.
iterable
- A container object capable of returning its members one at a
+ An object capable of returning its members one at a
time. Examples of iterables include all sequence types (such as
:class:`list`, :class:`str`, and :class:`tuple`) and some non-sequence
types like :class:`dict` and :class:`file` and objects of any classes you
@@ -397,6 +402,12 @@ Glossary
the :term:`EAFP` approach and is characterized by the presence of many
:keyword:`if` statements.
+ In a multi-threaded environment, the LBYL approach can risk introducing a
+ race condition between "the looking" and "the leaping". For example, the
+ code, ``if key in mapping: return mapping[key]`` can fail if another
+ thread removes *key* from *mapping* after the test, but before the lookup.
+ This issue can be solved with locks or by using the EAFP approach.
+
list
A built-in Python :term:`sequence`. Despite its name it is more akin
to an array in other languages than to a linked list since access to
@@ -417,9 +428,11 @@ Glossary
:class:`importlib.abc.Loader` for an :term:`abstract base class`.
mapping
- A container object (such as :class:`dict`) which supports arbitrary key
- lookups using the special method :meth:`__getitem__`. Mappings also
- support :meth:`__len__`, :meth:`__iter__`, and :meth:`__contains__`.
+ A container object that supports arbitrary key lookups and implements the
+ methods specified in the :class:`Mapping` or :class:`MutableMapping`
+ :ref:`abstract base classes <abstract-base-classes>`. Examples include
+ :class:`dict`, :class:`collections.defaultdict`,
+ :class:`collections.OrderedDict` and :class:`collections.Counter`.
metaclass
The class of a class. Class definitions create a class name, a class
@@ -440,6 +453,14 @@ Glossary
its first :term:`argument` (which is usually called ``self``).
See :term:`function` and :term:`nested scope`.
+ method resolution order
+ Method Resolution Order is the order in which base classes are searched
+ for a member during lookup. See `The Python 2.3 Method Resolution Order
+ <http://www.python.org/download/releases/2.3/mro/>`_.
+
+ MRO
+ See :term:`method resolution order`.
+
mutable
Mutable objects can change their value but keep their :func:`id`. See
also :term:`immutable`.
diff --git a/Doc/howto/cporting.rst b/Doc/howto/cporting.rst
index d20e4a6..7184496 100644
--- a/Doc/howto/cporting.rst
+++ b/Doc/howto/cporting.rst
@@ -22,7 +22,7 @@ Conditional compilation
=======================
The easiest way to compile only some code for 3.0 is to check if
-:cmacro:`PY_MAJOR_VERSION` is greater than or equal to 3. ::
+:c:macro:`PY_MAJOR_VERSION` is greater than or equal to 3. ::
#if PY_MAJOR_VERSION >= 3
#define IS_PY3K
@@ -47,12 +47,12 @@ Python 3.0's :func:`str` (``PyString_*`` functions in C) type is equivalent to
2.x's :func:`unicode` (``PyUnicode_*``). The old 8-bit string type has become
:func:`bytes`. Python 2.6 and later provide a compatibility header,
:file:`bytesobject.h`, mapping ``PyBytes`` names to ``PyString`` ones. For best
-compatibility with 3.0, :ctype:`PyUnicode` should be used for textual data and
-:ctype:`PyBytes` for binary data. It's also important to remember that
-:ctype:`PyBytes` and :ctype:`PyUnicode` in 3.0 are not interchangeable like
-:ctype:`PyString` and :ctype:`PyUnicode` are in 2.x. The following example
-shows best practices with regards to :ctype:`PyUnicode`, :ctype:`PyString`,
-and :ctype:`PyBytes`. ::
+compatibility with 3.0, :c:type:`PyUnicode` should be used for textual data and
+:c:type:`PyBytes` for binary data. It's also important to remember that
+:c:type:`PyBytes` and :c:type:`PyUnicode` in 3.0 are not interchangeable like
+:c:type:`PyString` and :c:type:`PyUnicode` are in 2.x. The following example
+shows best practices with regards to :c:type:`PyUnicode`, :c:type:`PyString`,
+and :c:type:`PyBytes`. ::
#include "stdlib.h"
#include "Python.h"
@@ -120,7 +120,7 @@ can also be used in some cases. ::
Module initialization and state
===============================
-Python 3.0 has a revamped extension module initialization system. (See PEP
+Python 3.0 has a revamped extension module initialization system. (See
:pep:`3121`.) Instead of storing module state in globals, they should be stored
in an interpreter specific structure. Creating modules that act correctly in
both 2.x and 3.0 is tricky. The following simple example demonstrates how. ::
diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst
index cdb6a8e..81bb8ca 100644
--- a/Doc/howto/descriptor.rst
+++ b/Doc/howto/descriptor.rst
@@ -97,7 +97,7 @@ transforms ``b.x`` into ``type(b).__dict__['x'].__get__(b, type(b))``. The
implementation works through a precedence chain that gives data descriptors
priority over instance variables, instance variables priority over non-data
descriptors, and assigns lowest priority to :meth:`__getattr__` if provided. The
-full C implementation can be found in :cfunc:`PyObject_GenericGetAttr()` in
+full C implementation can be found in :c:func:`PyObject_GenericGetAttr()` in
`Objects/object.c <http://svn.python.org/view/python/trunk/Objects/object.c?view=markup>`_\.
For classes, the machinery is in :meth:`type.__getattribute__` which transforms
@@ -131,7 +131,7 @@ search using :meth:`object.__getattribute__`.
Note, in Python 2.2, ``super(B, obj).m()`` would only invoke :meth:`__get__` if
``m`` was a data descriptor. In Python 2.3, non-data descriptors also get
invoked unless an old-style class is involved. The implementation details are
-in :cfunc:`super_getattro()` in
+in :c:func:`super_getattro()` in
`Objects/typeobject.c <http://svn.python.org/view/python/trunk/Objects/typeobject.c?view=markup>`_
and a pure Python equivalent can be found in `Guido's Tutorial`_.
@@ -297,7 +297,7 @@ Running the interpreter shows how the function descriptor works in practice::
The output suggests that bound and unbound methods are two different types.
While they could have been implemented that way, the actual C implementation of
-:ctype:`PyMethod_Type` in
+:c:type:`PyMethod_Type` in
`Objects/classobject.c <http://svn.python.org/view/python/trunk/Objects/classobject.c?view=markup>`_
is a single object with two different representations depending on whether the
:attr:`im_self` field is set or is *NULL* (the C equivalent of *None*).
diff --git a/Doc/howto/doanddont.rst b/Doc/howto/doanddont.rst
deleted file mode 100644
index 365a6209d..0000000
--- a/Doc/howto/doanddont.rst
+++ /dev/null
@@ -1,290 +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 are
-local and which are 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 question 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 builtins 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.
-
-
-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 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`.
-
-
-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:`functools.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, functools
- >>> functools.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/index.rst b/Doc/howto/index.rst
index 417ae00..11fe108 100644
--- a/Doc/howto/index.rst
+++ b/Doc/howto/index.rst
@@ -14,11 +14,13 @@ Currently, the HOWTOs are:
:maxdepth: 1
advocacy.rst
+ pyporting.rst
cporting.rst
curses.rst
descriptor.rst
- doanddont.rst
functional.rst
+ logging.rst
+ logging-cookbook.rst
regex.rst
sockets.rst
sorting.rst
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
new file mode 100644
index 0000000..198d892
--- /dev/null
+++ b/Doc/howto/logging-cookbook.rst
@@ -0,0 +1,1039 @@
+.. _logging-cookbook:
+
+================
+Logging Cookbook
+================
+
+:Author: Vinay Sajip <vinay_sajip at red-dove dot com>
+
+This page contains a number of recipes related to logging, which have been found
+useful in the past.
+
+.. currentmodule:: logging
+
+Using logging in multiple modules
+---------------------------------
+
+Multiple calls to ``logging.getLogger('someLogger')`` return a reference to the
+same logger object. This is true not only within the same module, but also
+across modules as long as it is in the same Python interpreter process. It is
+true for references to the same object; additionally, application code can
+define and configure a parent logger in one module and create (but not
+configure) a child logger in a separate module, and all logger calls to the
+child will pass up to the parent. Here is a main module::
+
+ import logging
+ import auxiliary_module
+
+ # create logger with 'spam_application'
+ logger = logging.getLogger('spam_application')
+ logger.setLevel(logging.DEBUG)
+ # create file handler which logs even debug messages
+ fh = logging.FileHandler('spam.log')
+ fh.setLevel(logging.DEBUG)
+ # create console handler with a higher log level
+ ch = logging.StreamHandler()
+ ch.setLevel(logging.ERROR)
+ # create formatter and add it to the handlers
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ fh.setFormatter(formatter)
+ ch.setFormatter(formatter)
+ # add the handlers to the logger
+ logger.addHandler(fh)
+ logger.addHandler(ch)
+
+ logger.info('creating an instance of auxiliary_module.Auxiliary')
+ a = auxiliary_module.Auxiliary()
+ logger.info('created an instance of auxiliary_module.Auxiliary')
+ logger.info('calling auxiliary_module.Auxiliary.do_something')
+ a.do_something()
+ logger.info('finished auxiliary_module.Auxiliary.do_something')
+ logger.info('calling auxiliary_module.some_function()')
+ auxiliary_module.some_function()
+ logger.info('done with auxiliary_module.some_function()')
+
+Here is the auxiliary module::
+
+ import logging
+
+ # create logger
+ module_logger = logging.getLogger('spam_application.auxiliary')
+
+ class Auxiliary:
+ def __init__(self):
+ self.logger = logging.getLogger('spam_application.auxiliary.Auxiliary')
+ self.logger.info('creating an instance of Auxiliary')
+ def do_something(self):
+ self.logger.info('doing something')
+ a = 1 + 1
+ self.logger.info('done doing something')
+
+ def some_function():
+ module_logger.info('received a call to "some_function"')
+
+The output looks like this::
+
+ 2005-03-23 23:47:11,663 - spam_application - INFO -
+ creating an instance of auxiliary_module.Auxiliary
+ 2005-03-23 23:47:11,665 - spam_application.auxiliary.Auxiliary - INFO -
+ creating an instance of Auxiliary
+ 2005-03-23 23:47:11,665 - spam_application - INFO -
+ created an instance of auxiliary_module.Auxiliary
+ 2005-03-23 23:47:11,668 - spam_application - INFO -
+ calling auxiliary_module.Auxiliary.do_something
+ 2005-03-23 23:47:11,668 - spam_application.auxiliary.Auxiliary - INFO -
+ doing something
+ 2005-03-23 23:47:11,669 - spam_application.auxiliary.Auxiliary - INFO -
+ done doing something
+ 2005-03-23 23:47:11,670 - spam_application - INFO -
+ finished auxiliary_module.Auxiliary.do_something
+ 2005-03-23 23:47:11,671 - spam_application - INFO -
+ calling auxiliary_module.some_function()
+ 2005-03-23 23:47:11,672 - spam_application.auxiliary - INFO -
+ received a call to 'some_function'
+ 2005-03-23 23:47:11,673 - spam_application - INFO -
+ done with auxiliary_module.some_function()
+
+Multiple handlers and formatters
+--------------------------------
+
+Loggers are plain Python objects. The :func:`addHandler` method has no minimum
+or maximum quota for the number of handlers you may add. Sometimes it will be
+beneficial for an application to log all messages of all severities to a text
+file while simultaneously logging errors or above to the console. To set this
+up, simply configure the appropriate handlers. The logging calls in the
+application code will remain unchanged. Here is a slight modification to the
+previous simple module-based configuration example::
+
+ import logging
+
+ logger = logging.getLogger('simple_example')
+ logger.setLevel(logging.DEBUG)
+ # create file handler which logs even debug messages
+ fh = logging.FileHandler('spam.log')
+ fh.setLevel(logging.DEBUG)
+ # create console handler with a higher log level
+ ch = logging.StreamHandler()
+ ch.setLevel(logging.ERROR)
+ # create formatter and add it to the handlers
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ ch.setFormatter(formatter)
+ fh.setFormatter(formatter)
+ # add the handlers to logger
+ logger.addHandler(ch)
+ logger.addHandler(fh)
+
+ # 'application' code
+ logger.debug('debug message')
+ logger.info('info message')
+ logger.warn('warn message')
+ logger.error('error message')
+ logger.critical('critical message')
+
+Notice that the 'application' code does not care about multiple handlers. All
+that changed was the addition and configuration of a new handler named *fh*.
+
+The ability to create new handlers with higher- or lower-severity filters can be
+very helpful when writing and testing an application. Instead of using many
+``print`` statements for debugging, use ``logger.debug``: Unlike the print
+statements, which you will have to delete or comment out later, the logger.debug
+statements can remain intact in the source code and remain dormant until you
+need them again. At that time, the only change that needs to happen is to
+modify the severity level of the logger and/or handler to debug.
+
+.. _multiple-destinations:
+
+Logging to multiple destinations
+--------------------------------
+
+Let's say you want to log to console and file with different message formats and
+in differing circumstances. Say you want to log messages with levels of DEBUG
+and higher to file, and those messages at level INFO and higher to the console.
+Let's also assume that the file should contain timestamps, but the console
+messages should not. Here's how you can achieve this::
+
+ import logging
+
+ # set up logging to file - see previous section for more details
+ logging.basicConfig(level=logging.DEBUG,
+ format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
+ datefmt='%m-%d %H:%M',
+ filename='/temp/myapp.log',
+ filemode='w')
+ # define a Handler which writes INFO messages or higher to the sys.stderr
+ console = logging.StreamHandler()
+ console.setLevel(logging.INFO)
+ # set a format which is simpler for console use
+ formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
+ # tell the handler to use this format
+ console.setFormatter(formatter)
+ # add the handler to the root logger
+ logging.getLogger('').addHandler(console)
+
+ # Now, we can log to the root logger, or any other logger. First the root...
+ logging.info('Jackdaws love my big sphinx of quartz.')
+
+ # Now, define a couple of other loggers which might represent areas in your
+ # application:
+
+ logger1 = logging.getLogger('myapp.area1')
+ logger2 = logging.getLogger('myapp.area2')
+
+ logger1.debug('Quick zephyrs blow, vexing daft Jim.')
+ logger1.info('How quickly daft jumping zebras vex.')
+ logger2.warning('Jail zesty vixen who grabbed pay from quack.')
+ logger2.error('The five boxing wizards jump quickly.')
+
+When you run this, on the console you will see ::
+
+ root : INFO Jackdaws love my big sphinx of quartz.
+ myapp.area1 : INFO How quickly daft jumping zebras vex.
+ myapp.area2 : WARNING Jail zesty vixen who grabbed pay from quack.
+ myapp.area2 : ERROR The five boxing wizards jump quickly.
+
+and in the file you will see something like ::
+
+ 10-22 22:19 root INFO Jackdaws love my big sphinx of quartz.
+ 10-22 22:19 myapp.area1 DEBUG Quick zephyrs blow, vexing daft Jim.
+ 10-22 22:19 myapp.area1 INFO How quickly daft jumping zebras vex.
+ 10-22 22:19 myapp.area2 WARNING Jail zesty vixen who grabbed pay from quack.
+ 10-22 22:19 myapp.area2 ERROR The five boxing wizards jump quickly.
+
+As you can see, the DEBUG message only shows up in the file. The other messages
+are sent to both destinations.
+
+This example uses console and file handlers, but you can use any number and
+combination of handlers you choose.
+
+
+Configuration server example
+----------------------------
+
+Here is an example of a module using the logging configuration server::
+
+ import logging
+ import logging.config
+ import time
+ import os
+
+ # read initial config file
+ logging.config.fileConfig('logging.conf')
+
+ # create and start listener on port 9999
+ t = logging.config.listen(9999)
+ t.start()
+
+ logger = logging.getLogger('simpleExample')
+
+ try:
+ # loop through logging calls to see the difference
+ # new configurations make, until Ctrl+C is pressed
+ while True:
+ logger.debug('debug message')
+ logger.info('info message')
+ logger.warn('warn message')
+ logger.error('error message')
+ logger.critical('critical message')
+ time.sleep(5)
+ except KeyboardInterrupt:
+ # cleanup
+ logging.config.stopListening()
+ t.join()
+
+And here is a script that takes a filename and sends that file to the server,
+properly preceded with the binary-encoded length, as the new logging
+configuration::
+
+ #!/usr/bin/env python
+ import socket, sys, struct
+
+ with open(sys.argv[1], 'rb') as f:
+ data_to_send = f.read()
+
+ HOST = 'localhost'
+ PORT = 9999
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ print('connecting...')
+ s.connect((HOST, PORT))
+ print('sending config...')
+ s.send(struct.pack('>L', len(data_to_send)))
+ s.send(data_to_send)
+ s.close()
+ 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
+-----------------------------------------------------
+
+Let's say you want to send logging events across a network, and handle them at
+the receiving end. A simple way of doing this is attaching a
+:class:`SocketHandler` instance to the root logger at the sending end::
+
+ import logging, logging.handlers
+
+ rootLogger = logging.getLogger('')
+ rootLogger.setLevel(logging.DEBUG)
+ socketHandler = logging.handlers.SocketHandler('localhost',
+ logging.handlers.DEFAULT_TCP_LOGGING_PORT)
+ # don't bother with a formatter, since a socket handler sends the event as
+ # an unformatted pickle
+ rootLogger.addHandler(socketHandler)
+
+ # Now, we can log to the root logger, or any other logger. First the root...
+ logging.info('Jackdaws love my big sphinx of quartz.')
+
+ # Now, define a couple of other loggers which might represent areas in your
+ # application:
+
+ logger1 = logging.getLogger('myapp.area1')
+ logger2 = logging.getLogger('myapp.area2')
+
+ logger1.debug('Quick zephyrs blow, vexing daft Jim.')
+ logger1.info('How quickly daft jumping zebras vex.')
+ 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`
+module. Here is a basic working example::
+
+ import pickle
+ import logging
+ import logging.handlers
+ import socketserver
+ import struct
+
+
+ class LogRecordStreamHandler(socketserver.StreamRequestHandler):
+ """Handler for a streaming logging request.
+
+ This basically logs the record using whatever logging policy is
+ configured locally.
+ """
+
+ def handle(self):
+ """
+ Handle multiple requests - each expected to be a 4-byte length,
+ followed by the LogRecord in pickle format. Logs the record
+ according to whatever policy is configured locally.
+ """
+ while True:
+ chunk = self.connection.recv(4)
+ if len(chunk) < 4:
+ break
+ slen = struct.unpack('>L', chunk)[0]
+ chunk = self.connection.recv(slen)
+ while len(chunk) < slen:
+ chunk = chunk + self.connection.recv(slen - len(chunk))
+ obj = self.unPickle(chunk)
+ record = logging.makeLogRecord(obj)
+ self.handleLogRecord(record)
+
+ def unPickle(self, data):
+ return pickle.loads(data)
+
+ def handleLogRecord(self, record):
+ # if a name is specified, we use the named logger rather than the one
+ # implied by the record.
+ if self.server.logname is not None:
+ name = self.server.logname
+ else:
+ name = record.name
+ logger = logging.getLogger(name)
+ # N.B. EVERY record gets logged. This is because Logger.handle
+ # is normally called AFTER logger-level filtering. If you want
+ # to do filtering, do it at the client end to save wasting
+ # cycles and network bandwidth!
+ logger.handle(record)
+
+ class LogRecordSocketReceiver(socketserver.ThreadingTCPServer):
+ """
+ Simple TCP socket-based logging receiver suitable for testing.
+ """
+
+ allow_reuse_address = 1
+
+ def __init__(self, host='localhost',
+ port=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
+ handler=LogRecordStreamHandler):
+ socketserver.ThreadingTCPServer.__init__(self, (host, port), handler)
+ self.abort = 0
+ self.timeout = 1
+ self.logname = None
+
+ def serve_until_stopped(self):
+ import select
+ abort = 0
+ while not abort:
+ rd, wr, ex = select.select([self.socket.fileno()],
+ [], [],
+ self.timeout)
+ if rd:
+ self.handle_request()
+ abort = self.abort
+
+ def main():
+ logging.basicConfig(
+ format='%(relativeCreated)5d %(name)-15s %(levelname)-8s %(message)s')
+ tcpserver = LogRecordSocketReceiver()
+ print('About to start TCP server...')
+ tcpserver.serve_until_stopped()
+
+ if __name__ == '__main__':
+ main()
+
+First run the server, and then the client. On the client side, nothing is
+printed on the console; on the server side, you should see something like::
+
+ About to start TCP server...
+ 59 root INFO Jackdaws love my big sphinx of quartz.
+ 59 myapp.area1 DEBUG Quick zephyrs blow, vexing daft Jim.
+ 69 myapp.area1 INFO How quickly daft jumping zebras vex.
+ 69 myapp.area2 WARNING Jail zesty vixen who grabbed pay from quack.
+ 69 myapp.area2 ERROR The five boxing wizards jump quickly.
+
+Note that there are some security issues with pickle in some scenarios. If
+these affect you, you can use an alternative serialization scheme by overriding
+the :meth:`makePickle` method and implementing your alternative there, as
+well as adapting the above script to use your alternative serialization.
+
+
+.. _context-info:
+
+Adding contextual information to your logging output
+----------------------------------------------------
+
+Sometimes you want logging output to contain contextual information in
+addition to the parameters passed to the logging call. For example, in a
+networked application, it may be desirable to log client-specific information
+in the log (e.g. remote client's username, or IP address). Although you could
+use the *extra* parameter to achieve this, it's not always convenient to pass
+the information in this way. While it might be tempting to create
+:class:`Logger` instances on a per-connection basis, this is not a good idea
+because these instances are not garbage collected. While this is not a problem
+in practice, when the number of :class:`Logger` instances is dependent on the
+level of granularity you want to use in logging an application, it could
+be hard to manage if the number of :class:`Logger` instances becomes
+effectively unbounded.
+
+
+Using LoggerAdapters to impart contextual information
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+An easy way in which you can pass contextual information to be output along
+with logging event information is to use the :class:`LoggerAdapter` class.
+This class is designed to look like a :class:`Logger`, so that you can call
+:meth:`debug`, :meth:`info`, :meth:`warning`, :meth:`error`,
+:meth:`exception`, :meth:`critical` and :meth:`log`. These methods have the
+same signatures as their counterparts in :class:`Logger`, so you can use the
+two types of instances interchangeably.
+
+When you create an instance of :class:`LoggerAdapter`, you pass it a
+:class:`Logger` instance and a dict-like object which contains your contextual
+information. When you call one of the logging methods on an instance of
+:class:`LoggerAdapter`, it delegates the call to the underlying instance of
+:class:`Logger` passed to its constructor, and arranges to pass the contextual
+information in the delegated call. Here's a snippet from the code of
+:class:`LoggerAdapter`::
+
+ def debug(self, msg, *args, **kwargs):
+ """
+ Delegate a debug call to the underlying logger, after adding
+ contextual information from this adapter instance.
+ """
+ msg, kwargs = self.process(msg, kwargs)
+ self.logger.debug(msg, *args, **kwargs)
+
+The :meth:`process` method of :class:`LoggerAdapter` is where the contextual
+information is added to the logging output. It's passed the message and
+keyword arguments of the logging call, and it passes back (potentially)
+modified versions of these to use in the call to the underlying logger. The
+default implementation of this method leaves the message alone, but inserts
+an 'extra' key in the keyword argument whose value is the dict-like object
+passed to the constructor. Of course, if you had passed an 'extra' keyword
+argument in the call to the adapter, it will be silently overwritten.
+
+The advantage of using 'extra' is that the values in the dict-like object are
+merged into the :class:`LogRecord` instance's __dict__, allowing you to use
+customized strings with your :class:`Formatter` instances which know about
+the keys of the dict-like object. If you need a different method, e.g. if you
+want to prepend or append the contextual information to the message string,
+you just need to subclass :class:`LoggerAdapter` and override :meth:`process`
+to do what you need. Here's an example script which uses this class, which
+also illustrates what dict-like behaviour is needed from an arbitrary
+'dict-like' object for use in the constructor::
+
+ import logging
+
+ class ConnInfo:
+ """
+ An example class which shows how an arbitrary class can be used as
+ the 'extra' context information repository passed to a LoggerAdapter.
+ """
+
+ def __getitem__(self, name):
+ """
+ To allow this instance to look like a dict.
+ """
+ from random import choice
+ if name == 'ip':
+ result = choice(['127.0.0.1', '192.168.0.1'])
+ elif name == 'user':
+ result = choice(['jim', 'fred', 'sheila'])
+ else:
+ result = self.__dict__.get(name, '?')
+ return result
+
+ def __iter__(self):
+ """
+ To allow iteration over keys, which will be merged into
+ the LogRecord dict before formatting and output.
+ """
+ keys = ['ip', 'user']
+ keys.extend(self.__dict__.keys())
+ return keys.__iter__()
+
+ if __name__ == '__main__':
+ from random import choice
+ levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
+ a1 = logging.LoggerAdapter(logging.getLogger('a.b.c'),
+ { 'ip' : '123.231.231.123', 'user' : 'sheila' })
+ logging.basicConfig(level=logging.DEBUG,
+ format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s')
+ a1.debug('A debug message')
+ a1.info('An info message with %s', 'some parameters')
+ a2 = logging.LoggerAdapter(logging.getLogger('d.e.f'), ConnInfo())
+ for x in range(10):
+ lvl = choice(levels)
+ lvlname = logging.getLevelName(lvl)
+ a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')
+
+When this script is run, the output should look something like this::
+
+ 2008-01-18 14:49:54,023 a.b.c DEBUG IP: 123.231.231.123 User: sheila A debug message
+ 2008-01-18 14:49:54,023 a.b.c INFO IP: 123.231.231.123 User: sheila An info message with some parameters
+ 2008-01-18 14:49:54,023 d.e.f CRITICAL IP: 192.168.0.1 User: jim A message at CRITICAL level with 2 parameters
+ 2008-01-18 14:49:54,033 d.e.f INFO IP: 192.168.0.1 User: jim A message at INFO level with 2 parameters
+ 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters
+ 2008-01-18 14:49:54,033 d.e.f ERROR IP: 127.0.0.1 User: fred A message at ERROR level with 2 parameters
+ 2008-01-18 14:49:54,033 d.e.f ERROR IP: 127.0.0.1 User: sheila A message at ERROR level with 2 parameters
+ 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters
+ 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: jim A message at WARNING level with 2 parameters
+ 2008-01-18 14:49:54,033 d.e.f INFO IP: 192.168.0.1 User: fred A message at INFO level with 2 parameters
+ 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters
+ 2008-01-18 14:49:54,033 d.e.f WARNING IP: 127.0.0.1 User: jim A message at WARNING level with 2 parameters
+
+
+.. _filters-contextual:
+
+Using Filters to impart contextual information
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can also add contextual information to log output using a user-defined
+:class:`Filter`. ``Filter`` instances are allowed to modify the ``LogRecords``
+passed to them, including adding additional attributes which can then be output
+using a suitable format string, or if needed a custom :class:`Formatter`.
+
+For example in a web application, the request being processed (or at least,
+the interesting parts of it) can be stored in a threadlocal
+(:class:`threading.local`) variable, and then accessed from a ``Filter`` to
+add, say, information from the request - say, the remote IP address and remote
+user's username - to the ``LogRecord``, using the attribute names 'ip' and
+'user' as in the ``LoggerAdapter`` example above. In that case, the same format
+string can be used to get similar output to that shown above. Here's an example
+script::
+
+ import logging
+ from random import choice
+
+ class ContextFilter(logging.Filter):
+ """
+ This is a filter which injects contextual information into the log.
+
+ Rather than use actual contextual information, we just use random
+ data in this demo.
+ """
+
+ USERS = ['jim', 'fred', 'sheila']
+ IPS = ['123.231.231.123', '127.0.0.1', '192.168.0.1']
+
+ def filter(self, record):
+
+ record.ip = choice(ContextFilter.IPS)
+ record.user = choice(ContextFilter.USERS)
+ return True
+
+ if __name__ == '__main__':
+ levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
+ logging.basicConfig(level=logging.DEBUG,
+ format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s')
+ a1 = logging.getLogger('a.b.c')
+ a2 = logging.getLogger('d.e.f')
+
+ f = ContextFilter()
+ a1.addFilter(f)
+ a2.addFilter(f)
+ a1.debug('A debug message')
+ a1.info('An info message with %s', 'some parameters')
+ for x in range(10):
+ lvl = choice(levels)
+ lvlname = logging.getLevelName(lvl)
+ a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')
+
+which, when run, produces something like::
+
+ 2010-09-06 22:38:15,292 a.b.c DEBUG IP: 123.231.231.123 User: fred A debug message
+ 2010-09-06 22:38:15,300 a.b.c INFO IP: 192.168.0.1 User: sheila An info message with some parameters
+ 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 127.0.0.1 User: sheila A message at CRITICAL level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f ERROR IP: 127.0.0.1 User: jim A message at ERROR level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f DEBUG IP: 127.0.0.1 User: sheila A message at DEBUG level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f ERROR IP: 123.231.231.123 User: fred A message at ERROR level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 192.168.0.1 User: jim A message at CRITICAL level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 127.0.0.1 User: sheila A message at CRITICAL level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f DEBUG IP: 192.168.0.1 User: jim A message at DEBUG level with 2 parameters
+ 2010-09-06 22:38:15,301 d.e.f ERROR IP: 127.0.0.1 User: sheila A message at ERROR level with 2 parameters
+ 2010-09-06 22:38:15,301 d.e.f DEBUG IP: 123.231.231.123 User: fred A message at DEBUG level with 2 parameters
+ 2010-09-06 22:38:15,301 d.e.f INFO IP: 123.231.231.123 User: fred A message at INFO level with 2 parameters
+
+
+.. _multiple-processes:
+
+Logging to a single file from multiple processes
+------------------------------------------------
+
+Although logging is thread-safe, and logging to a single file from multiple
+threads in a single process *is* supported, logging to a single file from
+*multiple processes* is *not* supported, because there is no standard way to
+serialize access to a single file across multiple processes in Python. If you
+need to log to a single file from multiple processes, one way of doing this is
+to have all the processes log to a :class:`SocketHandler`, and have a separate
+process which implements a socket server which reads from the socket and logs
+to file. (If you prefer, you can dedicate one thread in one of the existing
+processes to perform this function.) The following section documents this
+approach in more detail and includes a working socket receiver which can be
+used as a starting point for you to adapt in your own applications.
+
+If you are using a recent version of Python which includes the
+:mod:`multiprocessing` module, you could write your own handler which uses the
+:class:`Lock` class from this module to serialize access to the file from
+your processes. The existing :class:`FileHandler` and subclasses do not make
+use of :mod:`multiprocessing` at present, though they may do so in the future.
+Note that at present, the :mod:`multiprocessing` module does not provide
+working lock functionality on all platforms (see
+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('/tmp/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 >> sys.stderr, 'Whoops! Problem:'
+ 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
+-------------------
+
+.. sectionauthor:: Doug Hellmann, Vinay Sajip (changes)
+.. (see <http://blog.doughellmann.com/2007/05/pymotw-logging.html>)
+
+Sometimes you want to let a log file grow to a certain size, then open a new
+file and log to that. You may want to keep a certain number of these files, and
+when that many files have been created, rotate the files so that the number of
+files and the size of the files both remain bounded. For this usage pattern, the
+logging package provides a :class:`RotatingFileHandler`::
+
+ import glob
+ import logging
+ import logging.handlers
+
+ LOG_FILENAME = 'logging_rotatingfile_example.out'
+
+ # Set up a specific logger with our desired output level
+ my_logger = logging.getLogger('MyLogger')
+ my_logger.setLevel(logging.DEBUG)
+
+ # Add the log message handler to the logger
+ handler = logging.handlers.RotatingFileHandler(
+ LOG_FILENAME, maxBytes=20, backupCount=5)
+
+ my_logger.addHandler(handler)
+
+ # Log some messages
+ for i in range(20):
+ my_logger.debug('i = %d' % i)
+
+ # See what files are created
+ logfiles = glob.glob('%s*' % LOG_FILENAME)
+
+ for filename in logfiles:
+ print(filename)
+
+The result should be 6 separate files, each with part of the log history for the
+application::
+
+ logging_rotatingfile_example.out
+ logging_rotatingfile_example.out.1
+ logging_rotatingfile_example.out.2
+ logging_rotatingfile_example.out.3
+ logging_rotatingfile_example.out.4
+ logging_rotatingfile_example.out.5
+
+The most current file is always :file:`logging_rotatingfile_example.out`,
+and each time it reaches the size limit it is renamed with the suffix
+``.1``. Each of the existing backup files is renamed to increment the suffix
+(``.1`` becomes ``.2``, etc.) and the ``.6`` file is erased.
+
+Obviously this example sets the log length much much too small as an extreme
+example. You would want to set *maxBytes* to an appropriate value.
+
+.. _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>`
diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst
new file mode 100644
index 0000000..a7d6024
--- /dev/null
+++ b/Doc/howto/logging.rst
@@ -0,0 +1,1026 @@
+=============
+Logging HOWTO
+=============
+
+:Author: Vinay Sajip <vinay_sajip at red-dove dot com>
+
+.. _logging-basic-tutorial:
+
+.. currentmodule:: logging
+
+Basic Logging Tutorial
+----------------------
+
+Logging is a means of tracking events that happen when some software runs. The
+software's developer adds logging calls to their code to indicate that certain
+events have occurred. An event is described by a descriptive message which can
+optionally contain variable data (i.e. data that is potentially different for
+each occurrence of the event). Events also have an importance which the
+developer ascribes to the event; the importance can also be called the *level*
+or *severity*.
+
+When to use logging
+^^^^^^^^^^^^^^^^^^^
+
+Logging provides a set of convenience functions for simple logging usage. These
+are :func:`debug`, :func:`info`, :func:`warning`, :func:`error` and
+:func:`critical`. To determine when to use logging, see the table below, which
+states, for each of a set of common tasks, the best tool to use for it.
+
++-------------------------------------+--------------------------------------+
+| Task you want to perform | The best tool for the task |
++=====================================+======================================+
+| Display console output for ordinary | :func:`print` |
+| usage of a command line script or | |
+| program | |
++-------------------------------------+--------------------------------------+
+| Report events that occur during | :func:`logging.info` (or |
+| normal operation of a program (e.g. | :func:`logging.debug` for very |
+| for status monitoring or fault | detailed output for diagnostic |
+| investigation) | purposes) |
++-------------------------------------+--------------------------------------+
+| Issue a warning regarding a | :func:`warnings.warn` in library |
+| particular runtime event | code if the issue is avoidable and |
+| | the client application should be |
+| | modified to eliminate the warning |
+| | |
+| | :func:`logging.warning` if there is |
+| | nothing the client application can do|
+| | about the situation, but the event |
+| | should still be noted |
++-------------------------------------+--------------------------------------+
+| Report an error regarding a | Raise an exception |
+| particular runtime event | |
++-------------------------------------+--------------------------------------+
+| Report suppression of an error | :func:`logging.error`, |
+| without raising an exception (e.g. | :func:`logging.exception` or |
+| error handler in a long-running | :func:`logging.critical` as |
+| server process) | appropriate for the specific error |
+| | and application domain |
++-------------------------------------+--------------------------------------+
+
+The logging functions are named after the level or severity of the events
+they are used to track. The standard levels and their applicability are
+described below (in increasing order of severity):
+
++--------------+---------------------------------------------+
+| Level | When it's used |
++==============+=============================================+
+| ``DEBUG`` | Detailed information, typically of interest |
+| | only when diagnosing problems. |
++--------------+---------------------------------------------+
+| ``INFO`` | Confirmation that things are working as |
+| | expected. |
++--------------+---------------------------------------------+
+| ``WARNING`` | An indication that something unexpected |
+| | happened, or indicative of some problem in |
+| | the near future (e.g. 'disk space low'). |
+| | The software is still working as expected. |
++--------------+---------------------------------------------+
+| ``ERROR`` | Due to a more serious problem, the software |
+| | has not been able to perform some function. |
++--------------+---------------------------------------------+
+| ``CRITICAL`` | A serious error, indicating that the program|
+| | itself may be unable to continue running. |
++--------------+---------------------------------------------+
+
+The default level is ``WARNING``, which means that only events of this level
+and above will be tracked, unless the logging package is configured to do
+otherwise.
+
+Events that are tracked can be handled in different ways. The simplest way of
+handling tracked events is to print them to the console. Another common way
+is to write them to a disk file.
+
+
+.. _howto-minimal-example:
+
+A simple example
+^^^^^^^^^^^^^^^^
+
+A very simple example is::
+
+ import logging
+ logging.warning('Watch out!') # will print a message to the console
+ logging.info('I told you so') # will not print anything
+
+If you type these lines into a script and run it, you'll see::
+
+ WARNING:root:Watch out!
+
+printed out on the console. The ``INFO`` message doesn't appear because the
+default level is ``WARNING``. The printed message includes the indication of
+the level and the description of the event provided in the logging call, i.e.
+'Watch out!'. Don't worry about the 'root' part for now: it will be explained
+later. The actual output can be formatted quite flexibly if you need that;
+formatting options will also be explained later.
+
+
+Logging to a file
+^^^^^^^^^^^^^^^^^
+
+A very common situation is that of recording logging events in a file, so let's
+look at that next::
+
+ import logging
+ logging.basicConfig(filename='example.log',level=logging.DEBUG)
+ logging.debug('This message should go to the log file')
+ logging.info('So should this')
+ logging.warning('And this, too')
+
+And now if we open the file and look at what we have, we should find the log
+messages::
+
+ DEBUG:root:This message should go to the log file
+ INFO:root:So should this
+ WARNING:root:And this, too
+
+This example also shows how you can set the logging level which acts as the
+threshold for tracking. In this case, because we set the threshold to
+``DEBUG``, all of the messages were printed.
+
+If you want to set the logging level from a command-line option such as::
+
+ --log=INFO
+
+and you have the value of the parameter passed for ``--log`` in some variable
+*loglevel*, you can use::
+
+ getattr(logging, loglevel.upper())
+
+to get the value which you'll pass to :func:`basicConfig` via the *level*
+argument. You may want to error check any user input value, perhaps as in the
+following example::
+
+ # assuming loglevel is bound to the string value obtained from the
+ # command line argument. Convert to upper case to allow the user to
+ # specify --log=DEBUG or --log=debug
+ numeric_level = getattr(logging, loglevel.upper(), None)
+ if not isinstance(numeric_level, int):
+ raise ValueError('Invalid log level: %s' % loglevel)
+ logging.basicConfig(level=numeric_level, ...)
+
+The call to :func:`basicConfig` should come *before* any calls to :func:`debug`,
+:func:`info` etc. As it's intended as a one-off simple configuration facility,
+only the first call will actually do anything: subsequent calls are effectively
+no-ops.
+
+If you run the above script several times, the messages from successive runs
+are appended to the file *example.log*. If you want each run to start afresh,
+not remembering the messages from earlier runs, you can specify the *filemode*
+argument, by changing the call in the above example to::
+
+ logging.basicConfig(filename='example.log', filemode='w', level=logging.DEBUG)
+
+The output will be the same as before, but the log file is no longer appended
+to, so the messages from earlier runs are lost.
+
+
+Logging from multiple modules
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If your program consists of multiple modules, here's an example of how you
+could organize logging in it::
+
+ # myapp.py
+ import logging
+ import mylib
+
+ def main():
+ logging.basicConfig(filename='myapp.log', level=logging.INFO)
+ logging.info('Started')
+ mylib.do_something()
+ logging.info('Finished')
+
+ if __name__ == '__main__':
+ main()
+
+::
+
+ # mylib.py
+ import logging
+
+ def do_something():
+ logging.info('Doing something')
+
+If you run *myapp.py*, you should see this in *myapp.log*::
+
+ INFO:root:Started
+ INFO:root:Doing something
+ INFO:root:Finished
+
+which is hopefully what you were expecting to see. You can generalize this to
+multiple modules, using the pattern in *mylib.py*. Note that for this simple
+usage pattern, you won't know, by looking in the log file, *where* in your
+application your messages came from, apart from looking at the event
+description. If you want to track the location of your messages, you'll need
+to refer to the documentation beyond the tutorial level -- see
+:ref:`logging-advanced-tutorial`.
+
+
+Logging variable data
+^^^^^^^^^^^^^^^^^^^^^
+
+To log variable data, use a format string for the event description message and
+append the variable data as arguments. For example::
+
+ import logging
+ logging.warning('%s before you %s', 'Look', 'leap!')
+
+will display::
+
+ WARNING:root:Look before you leap!
+
+As you can see, merging of variable data into the event description message
+uses the old, %-style of string formatting. This is for backwards
+compatibility: the logging package pre-dates newer formatting options such as
+:meth:`str.format` and :class:`string.Template`. These newer formatting
+options *are* supported, but exploring them is outside the scope of this
+tutorial.
+
+
+Changing the format of displayed messages
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To change the format which is used to display messages, you need to
+specify the format you want to use::
+
+ import logging
+ logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
+ logging.debug('This message should appear on the console')
+ logging.info('So should this')
+ logging.warning('And this, too')
+
+which would print::
+
+ DEBUG:This message should appear on the console
+ INFO:So should this
+ WARNING:And this, too
+
+Notice that the 'root' which appeared in earlier examples has disappeared. For
+a full set of things that can appear in format strings, you can refer to the
+documentation for :ref:`logrecord-attributes`, but for simple usage, you just
+need the *levelname* (severity), *message* (event description, including
+variable data) and perhaps to display when the event occurred. This is
+described in the next section.
+
+
+Displaying the date/time in messages
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To display the date and time of an event, you would place '%(asctime)s' in
+your format string::
+
+ import logging
+ logging.basicConfig(format='%(asctime)s %(message)s')
+ logging.warning('is when this event was logged.')
+
+which should print something like this::
+
+ 2010-12-12 11:41:42,612 is when this event was logged.
+
+The default format for date/time display (shown above) is ISO8601. If you need
+more control over the formatting of the date/time, provide a *datefmt*
+argument to ``basicConfig``, as in this example::
+
+ import logging
+ logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
+ logging.warning('is when this event was logged.')
+
+which would display something like this::
+
+ 12/12/2010 11:46:36 AM is when this event was logged.
+
+The format of the *datefmt* argument is the same as supported by
+:func:`time.strftime`.
+
+
+Next Steps
+^^^^^^^^^^
+
+That concludes the basic tutorial. It should be enough to get you up and
+running with logging. There's a lot more that the logging package offers, but
+to get the best out of it, you'll need to invest a little more of your time in
+reading the following sections. If you're ready for that, grab some of your
+favourite beverage and carry on.
+
+If your logging needs are simple, then use the above examples to incorporate
+logging into your own scripts, and if you run into problems or don't
+understand something, please post a question on the comp.lang.python Usenet
+group (available at http://groups.google.com/group/comp.lang.python) and you
+should receive help before too long.
+
+Still here? You can carry on reading the next few sections, which provide a
+slightly more advanced/in-depth tutorial than the basic one above. After that,
+you can take a look at the :ref:`logging-cookbook`.
+
+.. _logging-advanced-tutorial:
+
+
+Advanced Logging Tutorial
+-------------------------
+
+The logging library takes a modular approach and offers several categories
+of components: loggers, handlers, filters, and formatters.
+
+* Loggers expose the interface that application code directly uses.
+* Handlers send the log records (created by loggers) to the appropriate
+ destination.
+* Filters provide a finer grained facility for determining which log records
+ to output.
+* Formatters specify the layout of log records in the final output.
+
+Logging is performed by calling methods on instances of the :class:`Logger`
+class (hereafter called :dfn:`loggers`). Each instance has a name, and they are
+conceptually arranged in a namespace hierarchy using dots (periods) as
+separators. For example, a logger named 'scan' is the parent of loggers
+'scan.text', 'scan.html' and 'scan.pdf'. Logger names can be anything you want,
+and indicate the area of an application in which a logged message originates.
+
+A good convention to use when naming loggers is to use a module-level logger,
+in each module which uses logging, named as follows::
+
+ logger = logging.getLogger(__name__)
+
+This means that logger names track the package/module hierarchy, and it's
+intuitively obvious where events are logged just from the logger name.
+
+The root of the hierarchy of loggers is called the root logger. That's the
+logger used by the functions :func:`debug`, :func:`info`, :func:`warning`,
+:func:`error` and :func:`critical`, which just call the same-named method of
+the root logger. The functions and the methods have the same signatures. The
+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, 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
+tutorial examples. If you call the functions :func:`debug`, :func:`info`,
+:func:`warning`, :func:`error` and :func:`critical`, they will check to see
+if no destination is set; and if one is not set, they will set a destination
+of the console (``sys.stderr``) and a default format for the displayed
+message before delegating to the root logger to do the actual message output.
+
+The default format set by :func:`basicConfig` for messages is::
+
+ severity:logger name:message
+
+You can change this by passing a format string to :func:`basicConfig` with the
+*format* keyword argument. For all options regarding how a format string is
+constructed, see :ref:`formatter-objects`.
+
+
+Loggers
+^^^^^^^
+
+:class:`Logger` objects have a threefold job. First, they expose several
+methods to application code so that applications can log messages at runtime.
+Second, logger objects determine which log messages to act upon based upon
+severity (the default filtering facility) or filter objects. Third, logger
+objects pass along relevant log messages to all interested log handlers.
+
+The most widely used methods on logger objects fall into two categories:
+configuration and message sending.
+
+These are the most common configuration methods:
+
+* :meth:`Logger.setLevel` specifies the lowest-severity log message a logger
+ will handle, where debug is the lowest built-in severity level and critical
+ is the highest built-in severity. For example, if the severity level is
+ INFO, the logger will handle only INFO, WARNING, ERROR, and CRITICAL messages
+ and will ignore DEBUG messages.
+
+* :meth:`Logger.addHandler` and :meth:`Logger.removeHandler` add and remove
+ handler objects from the logger object. Handlers are covered in more detail
+ in :ref:`handler-basic`.
+
+* :meth:`Logger.addFilter` and :meth:`Logger.removeFilter` add and remove filter
+ objects from the logger object. Filters are covered in more detail in
+ :ref:`filter`.
+
+You don't need to always call these methods on every logger you create. See the
+last two paragraphs in this section.
+
+With the logger object configured, the following methods create log messages:
+
+* :meth:`Logger.debug`, :meth:`Logger.info`, :meth:`Logger.warning`,
+ :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
+ 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
+ determine whether to log exception information.
+
+* :meth:`Logger.exception` creates a log message similar to
+ :meth:`Logger.error`. The difference is that :meth:`Logger.exception` dumps a
+ stack trace along with it. Call this method only from an exception handler.
+
+* :meth:`Logger.log` takes a log level as an explicit argument. This is a
+ little more verbose for logging messages than using the log level convenience
+ methods listed above, but this is how to log at custom log levels.
+
+:func:`getLogger` returns a reference to a logger instance with the specified
+name if it is provided, or ``root`` if not. The names are period-separated
+hierarchical structures. Multiple calls to :func:`getLogger` with the same name
+will return a reference to the same logger object. Loggers that are further
+down in the hierarchical list are children of loggers higher up in the list.
+For example, given a logger with a name of ``foo``, loggers with names of
+``foo.bar``, ``foo.bar.baz``, and ``foo.bam`` are all descendants of ``foo``.
+
+Loggers have a concept of *effective level*. If a level is not explicitly set
+on a logger, the level of its parent is used instead as its effective level.
+If the parent has no explicit level set, *its* parent is examined, and so on -
+all ancestors are searched until an explicitly set level is found. The root
+logger always has an explicit level set (``WARNING`` by default). When deciding
+whether to process an event, the effective level of the logger is used to
+determine whether the event is passed to the logger's handlers.
+
+Child loggers propagate messages up to the handlers associated with their
+ancestor loggers. Because of this, it is unnecessary to define and configure
+handlers for all the loggers an application uses. It is sufficient to
+configure handlers for a top-level logger and create child loggers as needed.
+(You can, however, turn off propagation by setting the *propagate*
+attribute of a logger to *False*.)
+
+
+.. _handler-basic:
+
+Handlers
+^^^^^^^^
+
+:class:`~logging.Handler` objects are responsible for dispatching the
+appropriate log messages (based on the log messages' severity) to the handler's
+specified destination. Logger objects can add zero or more handler objects to
+themselves with an :func:`addHandler` method. As an example scenario, an
+application may want to send all log messages to a log file, all log messages
+of error or higher to stdout, and all messages of critical to an email address.
+This scenario requires three individual handlers where each handler is
+responsible for sending messages of a specific severity to a specific location.
+
+The standard library includes quite a few handler types (see
+:ref:`useful-handlers`); the tutorials use mainly :class:`StreamHandler` and
+:class:`FileHandler` in its examples.
+
+There are very few methods in a handler for application developers to concern
+themselves with. The only handler methods that seem relevant for application
+developers who are using the built-in handler objects (that is, not creating
+custom handlers) are the following configuration methods:
+
+* The :meth:`Handler.setLevel` method, just as in logger objects, specifies the
+ lowest severity that will be dispatched to the appropriate destination. Why
+ are there two :func:`setLevel` methods? The level set in the logger
+ determines which severity of messages it will pass to its handlers. The level
+ set in each handler determines which messages that handler will send on.
+
+* :func:`setFormatter` selects a Formatter object for this handler to use.
+
+* :func:`addFilter` and :func:`removeFilter` respectively configure and
+ deconfigure filter objects on handlers.
+
+Application code should not directly instantiate and use instances of
+:class:`Handler`. Instead, the :class:`Handler` class is a base class that
+defines the interface that all handlers should have and establishes some
+default behavior that child classes can use (or override).
+
+
+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 three
+optional arguments -- a message format string, a date format string and a style
+indicator.
+
+.. 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. The ``style`` is one of `%`, '{'
+or '$'. If one of these is not specified, then '%' will be used.
+
+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
+order::
+
+ '%(asctime)s - %(levelname)s - %(message)s'
+
+Formatters use a user-configurable function to convert the creation time of a
+record to a tuple. By default, :func:`time.localtime` is used; to change this
+for a particular formatter instance, set the ``converter`` attribute of the
+instance to a function with the same signature as :func:`time.localtime` or
+:func:`time.gmtime`. To change it for all formatters, for example if you want
+all logging times to be shown in GMT, set the ``converter`` attribute in the
+Formatter class (to ``time.gmtime`` for GMT display).
+
+
+Configuring Logging
+^^^^^^^^^^^^^^^^^^^
+
+.. currentmodule:: logging.config
+
+Programmers can configure logging in three ways:
+
+1. Creating loggers, handlers, and formatters explicitly using Python
+ code that calls the configuration methods listed above.
+2. Creating a logging config file and reading it using the :func:`fileConfig`
+ function.
+3. Creating a dictionary of configuration information and passing it
+ to the :func:`dictConfig` function.
+
+For the reference documentation on the last two options, see
+:ref:`logging-config-api`. The following example configures a very simple
+logger, a console handler, and a simple formatter using Python code::
+
+ import logging
+
+ # create logger
+ logger = logging.getLogger('simple_example')
+ logger.setLevel(logging.DEBUG)
+
+ # create console handler and set level to debug
+ ch = logging.StreamHandler()
+ ch.setLevel(logging.DEBUG)
+
+ # create formatter
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+
+ # add formatter to ch
+ ch.setFormatter(formatter)
+
+ # add ch to logger
+ logger.addHandler(ch)
+
+ # 'application' code
+ logger.debug('debug message')
+ logger.info('info message')
+ logger.warn('warn message')
+ logger.error('error message')
+ logger.critical('critical message')
+
+Running this module from the command line produces the following output::
+
+ $ python simple_logging_module.py
+ 2005-03-19 15:10:26,618 - simple_example - DEBUG - debug message
+ 2005-03-19 15:10:26,620 - simple_example - INFO - info message
+ 2005-03-19 15:10:26,695 - simple_example - WARNING - warn message
+ 2005-03-19 15:10:26,697 - simple_example - ERROR - error message
+ 2005-03-19 15:10:26,773 - simple_example - CRITICAL - critical message
+
+The following Python module creates a logger, handler, and formatter nearly
+identical to those in the example listed above, with the only difference being
+the names of the objects::
+
+ import logging
+ import logging.config
+
+ logging.config.fileConfig('logging.conf')
+
+ # create logger
+ logger = logging.getLogger('simpleExample')
+
+ # 'application' code
+ logger.debug('debug message')
+ logger.info('info message')
+ logger.warn('warn message')
+ logger.error('error message')
+ logger.critical('critical message')
+
+Here is the logging.conf file::
+
+ [loggers]
+ keys=root,simpleExample
+
+ [handlers]
+ keys=consoleHandler
+
+ [formatters]
+ keys=simpleFormatter
+
+ [logger_root]
+ level=DEBUG
+ handlers=consoleHandler
+
+ [logger_simpleExample]
+ level=DEBUG
+ handlers=consoleHandler
+ qualname=simpleExample
+ propagate=0
+
+ [handler_consoleHandler]
+ class=StreamHandler
+ level=DEBUG
+ formatter=simpleFormatter
+ args=(sys.stdout,)
+
+ [formatter_simpleFormatter]
+ format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
+ datefmt=
+
+The output is nearly identical to that of the non-config-file-based example::
+
+ $ python simple_logging_config.py
+ 2005-03-19 15:38:55,977 - simpleExample - DEBUG - debug message
+ 2005-03-19 15:38:55,979 - simpleExample - INFO - info message
+ 2005-03-19 15:38:56,054 - simpleExample - WARNING - warn message
+ 2005-03-19 15:38:56,055 - simpleExample - ERROR - error message
+ 2005-03-19 15:38:56,130 - simpleExample - CRITICAL - critical message
+
+You can see that the config file approach has a few advantages over the Python
+code approach, mainly separation of configuration and code and the ability of
+noncoders to easily modify the logging properties.
+
+.. currentmodule:: logging
+
+Note that the class names referenced in config files need to be either relative
+to the logging module, or absolute values which can be resolved using normal
+import mechanisms. Thus, you could use either
+:class:`~logging.handlers.WatchedFileHandler` (relative to the logging module) or
+``mypackage.mymodule.MyHandler`` (for a class defined in package ``mypackage``
+and module ``mymodule``, where ``mypackage`` is available on the Python import
+path).
+
+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
+a Python dictionary is used to hold configuration information, and since you
+can populate that dictionary using different means, you have more options for
+configuration. For example, you can use a configuration file in JSON format,
+or, if you have access to YAML processing functionality, a file in YAML
+format, to populate the configuration dictionary. Or, of course, you can
+construct the dictionary in Python code, receive it in pickled form over a
+socket, or use whatever approach makes sense for your application.
+
+Here's an example of the same configuration as above, in YAML format for
+the new dictionary-based approach::
+
+ version: 1
+ formatters:
+ simple:
+ format: format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
+ handlers:
+ console:
+ class: logging.StreamHandler
+ level: DEBUG
+ formatter: simple
+ stream: ext://sys.stdout
+ loggers:
+ simpleExample:
+ level: DEBUG
+ handlers: [console]
+ propagate: no
+ root:
+ level: DEBUG
+ handlers: [console]
+
+For more information about logging using a dictionary, see
+:ref:`logging-config-api`.
+
+What happens if no configuration is provided
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If no logging configuration is provided, it is possible to have a situation
+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 versions of Python prior to 3.2, the behaviour is as follows:
+
+* If *logging.raiseExceptions* is *False* (production mode), the event is
+ silently dropped.
+
+* 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
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When developing a library which uses logging, you should take care to
+document how the library uses logging - for example, the names of loggers
+used. Some consideration also needs to be given to its logging configuration.
+If the using application does not use logging, and library code makes logging
+calls, then (as described in the previous section) events of severity
+``WARNING`` and greater will be printed to ``sys.stderr``. This is regarded as
+the best default behaviour.
+
+If for some reason you *don't* want these messages printed in the absence of
+any logging configuration, you can attach a do-nothing handler to the top-level
+logger for your library. This avoids the message being printed, since a handler
+will be always be found for the library's events: it just doesn't produce any
+output. If the library user configures logging for application use, presumably
+that configuration will add some handlers, and if levels are suitably
+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 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
+library *foo* is done using loggers with names matching 'foo.x', 'foo.x.y',
+etc. then the code::
+
+ import logging
+ logging.getLogger('foo').addHandler(logging.NullHandler())
+
+should have the desired effect. If an organisation produces a number of
+libraries, then the logger name specified can be 'orgname.foo' rather than
+just 'foo'.
+
+**PLEASE NOTE:** It is strongly advised that you *do not add any handlers other
+than* :class:`~logging.NullHandler` *to your library's loggers*. This is
+because the configuration of handlers is the prerogative of the application
+developer who uses your library. The application developer knows their target
+audience and what handlers are most appropriate for their application: if you
+add handlers 'under the hood', you might well interfere with their ability to
+carry out unit tests and deliver logs which suit their requirements.
+
+
+Logging Levels
+--------------
+
+The numeric values of logging levels are given in the following table. These are
+primarily of interest if you want to define your own levels, and need them to
+have specific values relative to the predefined levels. If you define a level
+with the same numeric value, it overwrites the predefined value; the predefined
+name is lost.
+
++--------------+---------------+
+| Level | Numeric value |
++==============+===============+
+| ``CRITICAL`` | 50 |
++--------------+---------------+
+| ``ERROR`` | 40 |
++--------------+---------------+
+| ``WARNING`` | 30 |
++--------------+---------------+
+| ``INFO`` | 20 |
++--------------+---------------+
+| ``DEBUG`` | 10 |
++--------------+---------------+
+| ``NOTSET`` | 0 |
++--------------+---------------+
+
+Levels can also be associated with loggers, being set either by the developer or
+through loading a saved logging configuration. When a logging method is called
+on a logger, the logger compares its own level with the level associated with
+the method call. If the logger's level is higher than the method call's, no
+logging message is actually generated. This is the basic mechanism controlling
+the verbosity of logging output.
+
+Logging messages are encoded as instances of the :class:`~logging.LogRecord`
+class. When a logger decides to actually log an event, a
+:class:`~logging.LogRecord` instance is created from the logging message.
+
+Logging messages are subjected to a dispatch mechanism through the use of
+:dfn:`handlers`, which are instances of subclasses of the :class:`Handler`
+class. Handlers are responsible for ensuring that a logged message (in the form
+of a :class:`LogRecord`) ends up in a particular location (or set of locations)
+which is useful for the target audience for that message (such as end users,
+support desk staff, system administrators, developers). Handlers are passed
+:class:`LogRecord` instances intended for particular destinations. Each logger
+can have zero, one or more handlers associated with it (via the
+:meth:`~Logger.addHandler` method of :class:`Logger`). In addition to any
+handlers directly associated with a logger, *all handlers associated with all
+ancestors of the logger* are called to dispatch the message (unless the
+*propagate* flag for a logger is set to a false value, at which point the
+passing to ancestor handlers stops).
+
+Just as for loggers, handlers can have levels associated with them. A handler's
+level acts as a filter in the same way as a logger's level does. If a handler
+decides to actually dispatch an event, the :meth:`~Handler.emit` method is used
+to send the message to its destination. Most user-defined subclasses of
+:class:`Handler` will need to override this :meth:`~Handler.emit`.
+
+.. _custom-levels:
+
+Custom Levels
+^^^^^^^^^^^^^
+
+Defining your own levels is possible, but should not be necessary, as the
+existing levels have been chosen on the basis of practical experience.
+However, if you are convinced that you need custom levels, great care should
+be exercised when doing this, and it is possibly *a very bad idea to define
+custom levels if you are developing a library*. That's because if multiple
+library authors all define their own custom levels, there is a chance that
+the logging output from such multiple libraries used together will be
+difficult for the using developer to control and/or interpret, because a
+given numeric value might mean different things for different libraries.
+
+.. _useful-handlers:
+
+Useful Handlers
+---------------
+
+In addition to the base :class:`Handler` class, many useful subclasses are
+provided:
+
+#. :class:`StreamHandler` instances send messages to streams (file-like
+ objects).
+
+#. :class:`FileHandler` instances send messages to disk files.
+
+#. :class:`~handlers.BaseRotatingHandler` is the base class for handlers that
+ rotate log files at a certain point. It is not meant to be instantiated
+ directly. Instead, use :class:`~handlers.RotatingFileHandler` or
+ :class:`~handlers.TimedRotatingFileHandler`.
+
+#. :class:`~handlers.RotatingFileHandler` instances send messages to disk
+ files, with support for maximum log file sizes and log file rotation.
+
+#. :class:`~handlers.TimedRotatingFileHandler` instances send messages to
+ disk files, rotating the log file at certain timed intervals.
+
+#. :class:`~handlers.SocketHandler` instances send messages to TCP/IP
+ sockets.
+
+#. :class:`~handlers.DatagramHandler` instances send messages to UDP
+ sockets.
+
+#. :class:`~handlers.SMTPHandler` instances send messages to a designated
+ email address.
+
+#. :class:`~handlers.SysLogHandler` instances send messages to a Unix
+ syslog daemon, possibly on a remote machine.
+
+#. :class:`~handlers.NTEventLogHandler` instances send messages to a
+ Windows NT/2000/XP event log.
+
+#. :class:`~handlers.MemoryHandler` instances send messages to a buffer
+ in memory, which is flushed whenever specific criteria are met.
+
+#. :class:`~handlers.HTTPHandler` instances send messages to an HTTP
+ server using either ``GET`` or ``POST`` semantics.
+
+#. :class:`~handlers.WatchedFileHandler` instances watch the file they are
+ logging to. If the file changes, it is closed and reopened using the file
+ 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:: 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
+sub-module, :mod:`logging.config`, for configuration functionality.)
+
+Logged messages are formatted for presentation through instances of the
+:class:`Formatter` class. They are initialized with a format string suitable for
+use with the % operator and a dictionary.
+
+For formatting multiple messages in a batch, instances of
+:class:`BufferingFormatter` can be used. In addition to the format string (which
+is applied to each message in the batch), there is provision for header and
+trailer format strings.
+
+When filtering based on logger level and/or handler level is not enough,
+instances of :class:`Filter` can be added to both :class:`Logger` and
+:class:`Handler` instances (through their :meth:`addFilter` method). Before
+deciding to process a message further, both loggers and handlers consult all
+their filters for permission. If any filter returns a false value, the message
+is not processed further.
+
+The basic :class:`Filter` functionality allows filtering by specific logger
+name. If this feature is used, messages sent to the named logger and its
+children are allowed through the filter, and all others dropped.
+
+
+.. _logging-exceptions:
+
+Exceptions raised during logging
+--------------------------------
+
+The logging package is designed to swallow exceptions which occur while logging
+in production. This is so that errors which occur while handling logging events
+- such as logging misconfiguration, network or other similar errors - do not
+cause the application using logging to terminate prematurely.
+
+:class:`SystemExit` and :class:`KeyboardInterrupt` exceptions are never
+swallowed. Other exceptions which occur during the :meth:`emit` method of a
+:class:`Handler` subclass are passed to its :meth:`handleError` method.
+
+The default implementation of :meth:`handleError` in :class:`Handler` checks
+to see if a module-level variable, :data:`raiseExceptions`, is set. If set, a
+traceback is printed to :data:`sys.stderr`. If not set, the exception is swallowed.
+
+**Note:** The default value of :data:`raiseExceptions` is ``True``. This is because
+during development, you typically want to be notified of any exceptions that
+occur. It's advised that you set :data:`raiseExceptions` to ``False`` for production
+usage.
+
+.. currentmodule:: logging
+
+.. _arbitrary-object-messages:
+
+Using arbitrary objects as messages
+-----------------------------------
+
+In the preceding sections and examples, it has been assumed that the message
+passed when logging the event is a string. However, this is not the only
+possibility. You can pass an arbitrary object as a message, and its
+:meth:`__str__` method will be called when the logging system needs to convert
+it to a string representation. In fact, if you want to, you can avoid
+computing a string representation altogether - for example, the
+:class:`SocketHandler` emits an event by pickling it and sending it over the
+wire.
+
+
+Optimization
+------------
+
+Formatting of message arguments is deferred until it cannot be avoided.
+However, computing the arguments passed to the logging method can also be
+expensive, and you may want to avoid doing it if the logger will just throw
+away your event. To decide what to do, you can call the :meth:`isEnabledFor`
+method which takes a level argument and returns true if the event would be
+created by the Logger for that level of call. You can write code like this::
+
+ if logger.isEnabledFor(logging.DEBUG):
+ logger.debug('Message with %s, %s', expensive_func1(),
+ expensive_func2())
+
+so that if the logger's threshold is set above ``DEBUG``, the calls to
+:func:`expensive_func1` and :func:`expensive_func2` are never made.
+
+There are other optimizations which can be made for specific applications which
+need more precise control over what logging information is collected. Here's a
+list of things you can do to avoid processing during logging which you don't
+need:
+
++-----------------------------------------------+----------------------------------------+
+| What you don't want to collect | How to avoid collecting it |
++===============================================+========================================+
+| Information about where calls were made from. | Set ``logging._srcfile`` to ``None``. |
++-----------------------------------------------+----------------------------------------+
+| Threading information. | Set ``logging.logThreads`` to ``0``. |
++-----------------------------------------------+----------------------------------------+
+| Process information. | Set ``logging.logProcesses`` to ``0``. |
++-----------------------------------------------+----------------------------------------+
+
+Also note that the core logging module only includes the basic handlers. If
+you don't import :mod:`logging.handlers` and :mod:`logging.config`, they won't
+take up any memory.
+
+.. 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 logging cookbook <logging-cookbook>`
+
diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst
new file mode 100644
index 0000000..124ef33
--- /dev/null
+++ b/Doc/howto/pyporting.rst
@@ -0,0 +1,703 @@
+.. _pyporting-howto:
+
+*********************************
+Porting Python 2 Code to Python 3
+*********************************
+
+:author: Brett Cannon
+
+.. topic:: Abstract
+
+ With Python 3 being the future of Python while Python 2 is still in active
+ use, it is good to have your project available for both major releases of
+ Python. This guide is meant to help you choose which strategy works best
+ for your project to support both Python 2 & 3 along with how to execute
+ that strategy.
+
+ If you are looking to port an extension module instead of pure Python code,
+ please see :ref:`cporting-howto`.
+
+
+Choosing a Strategy
+===================
+
+When a project makes the decision that it's time to support both Python 2 & 3,
+a decision needs to be made as to how to go about accomplishing that goal.
+The chosen strategy will depend on how large the project's existing
+codebase is and how much divergence you want from your Python 2 codebase from
+your Python 3 one (e.g., starting a new version with Python 3).
+
+If your project is brand-new or does not have a large codebase, then you may
+want to consider writing/porting :ref:`all of your code for Python 3
+and use 3to2 <use_3to2>` to port your code for Python 2.
+
+If you would prefer to maintain a codebase which is semantically **and**
+syntactically compatible with Python 2 & 3 simultaneously, you can write
+:ref:`use_same_source`. While this tends to lead to somewhat non-idiomatic
+code, it does mean you keep a rapid development process for you, the developer.
+
+Finally, you do have the option of :ref:`using 2to3 <use_2to3>` to translate
+Python 2 code into Python 3 code (with some manual help). This can take the
+form of branching your code and using 2to3 to start a Python 3 branch. You can
+also have users perform the translation as installation time automatically so
+that you only have to maintain a Python 2 codebase.
+
+Regardless of which approach you choose, porting is not as hard or
+time-consuming as you might initially think. You can also tackle the problem
+piece-meal as a good portion of porting is simply updating your code to follow
+current best practices in a Python 2/3 compatible way.
+
+
+Universal Bits of Advice
+------------------------
+
+Regardless of what strategy you pick, there are a few things you should
+consider.
+
+One is make sure you have a robust test suite. You need to make sure everything
+continues to work, just like when you support a new minor version of Python.
+This means making sure your test suite is thorough and is ported properly
+between Python 2 & 3. You will also most likely want to use something like tox_
+to automate testing between both a Python 2 and Python 3 VM.
+
+Two, once your project has Python 3 support, make sure to add the proper
+classifier on the Cheeseshop_ (PyPI_). To have your project listed as Python 3
+compatible it must have the
+`Python 3 classifier <http://pypi.python.org/pypi?:action=browse&c=533>`_
+(from
+http://techspot.zzzeek.org/2011/01/24/zzzeek-s-guide-to-python-3-porting/)::
+
+ setup(
+ name='Your Library',
+ version='1.0',
+ classifiers=[
+ # make sure to use :: Python *and* :: Python :: 3 so
+ # that pypi can list the package on the python 3 page
+ 'Programming Language :: Python',
+ 'Programming Language :: Python :: 3'
+ ],
+ packages=['yourlibrary'],
+ # make sure to add custom_fixers to the MANIFEST.in
+ include_package_data=True,
+ # ...
+ )
+
+
+Doing so will cause your project to show up in the
+`Python 3 packages list
+<http://pypi.python.org/pypi?:action=browse&c=533&show=all>`_. You will know
+you set the classifier properly as visiting your project page on the Cheeseshop
+will show a Python 3 logo in the upper-left corner of the page.
+
+Three, the six_ project provides a library which helps iron out differences
+between Python 2 & 3. If you find there is a sticky point that is a continual
+point of contention in your translation or maintenance of code, consider using
+a source-compatible solution relying on six. If you have to create your own
+Python 2/3 compatible solution, you can use ``sys.version_info[0] >= 3`` as a
+guard.
+
+Four, read all the approaches. Just because some bit of advice applies to one
+approach more than another doesn't mean that some advice doesn't apply to other
+strategies.
+
+Five, drop support for older Python versions if possible. `Python 2.5`_
+introduced a lot of useful syntax and libraries which have become idiomatic
+in Python 3. `Python 2.6`_ introduced future statements which makes
+compatibility much easier if you are going from Python 2 to 3.
+`Python 2.7`_ continues the trend in the stdlib. So choose the newest version
+of Python which you believe can be your minimum support version
+and work from there.
+
+
+.. _tox: http://codespeak.net/tox/
+.. _Cheeseshop:
+.. _PyPI: http://pypi.python.org/
+.. _six: http://packages.python.org/six
+.. _Python 2.7: http://www.python.org/2.7.x
+.. _Python 2.6: http://www.python.org/2.6.x
+.. _Python 2.5: http://www.python.org/2.5.x
+.. _Python 2.4: http://www.python.org/2.4.x
+.. _Python 2.3: http://www.python.org/2.3.x
+.. _Python 2.2: http://www.python.org/2.2.x
+
+
+.. _use_3to2:
+
+Python 3 and 3to2
+=================
+
+If you are starting a new project or your codebase is small enough, you may
+want to consider writing your code for Python 3 and backporting to Python 2
+using 3to2_. Thanks to Python 3 being more strict about things than Python 2
+(e.g., bytes vs. strings), the source translation can be easier and more
+straightforward than from Python 2 to 3. Plus it gives you more direct
+experience developing in Python 3 which, since it is the future of Python, is a
+good thing long-term.
+
+A drawback of this approach is that 3to2 is a third-party project. This means
+that the Python core developers (and thus this guide) can make no promises
+about how well 3to2 works at any time. There is nothing to suggest, though,
+that 3to2 is not a high-quality project.
+
+
+.. _3to2: https://bitbucket.org/amentajo/lib3to2/overview
+
+
+.. _use_2to3:
+
+Python 2 and 2to3
+=================
+
+Included with Python since 2.6, the 2to3_ tool (and :mod:`lib2to3` module)
+helps with porting Python 2 to Python 3 by performing various source
+translations. This is a perfect solution for projects which wish to branch
+their Python 3 code from their Python 2 codebase and maintain them as
+independent codebases. You can even begin preparing to use this approach
+today by writing future-compatible Python code which works cleanly in
+Python 2 in conjunction with 2to3; all steps outlined below will work
+with Python 2 code up to the point when the actual use of 2to3 occurs.
+
+Use of 2to3 as an on-demand translation step at install time is also possible,
+preventing the need to maintain a separate Python 3 codebase, but this approach
+does come with some drawbacks. While users will only have to pay the
+translation cost once at installation, you as a developer will need to pay the
+cost regularly during development. If your codebase is sufficiently large
+enough then the translation step ends up acting like a compilation step,
+robbing you of the rapid development process you are used to with Python.
+Obviously the time required to translate a project will vary, so do an
+experimental translation just to see how long it takes to evaluate whether you
+prefer this approach compared to using :ref:`use_same_source` or simply keeping
+a separate Python 3 codebase.
+
+Below are the typical steps taken by a project which uses a 2to3-based approach
+to supporting Python 2 & 3.
+
+
+Support Python 2.7
+------------------
+
+As a first step, make sure that your project is compatible with `Python 2.7`_.
+This is just good to do as Python 2.7 is the last release of Python 2 and thus
+will be used for a rather long time. It also allows for use of the ``-3`` flag
+to Python to help discover places in your code which 2to3 cannot handle but are
+known to cause issues.
+
+Try to Support `Python 2.6`_ and Newer Only
+-------------------------------------------
+
+While not possible for all projects, if you can support `Python 2.6`_ and newer
+**only**, your life will be much easier. Various future statements, stdlib
+additions, etc. exist only in Python 2.6 and later which greatly assist in
+porting to Python 3. But if you project must keep support for `Python 2.5`_ (or
+even `Python 2.4`_) then it is still possible to port to Python 3.
+
+Below are the benefits you gain if you only have to support Python 2.6 and
+newer. Some of these options are personal choice while others are
+**strongly** recommended (the ones that are more for personal choice are
+labeled as such). If you continue to support older versions of Python then you
+at least need to watch out for situations that these solutions fix.
+
+
+``from __future__ import print_function``
+'''''''''''''''''''''''''''''''''''''''''
+
+This is a personal choice. 2to3 handles the translation from the print
+statement to the print function rather well so this is an optional step. This
+future statement does help, though, with getting used to typing
+``print('Hello, World')`` instead of ``print 'Hello, World'``.
+
+
+``from __future__ import unicode_literals``
+'''''''''''''''''''''''''''''''''''''''''''
+
+Another personal choice. You can always mark what you want to be a (unicode)
+string with a ``u`` prefix to get the same effect. But regardless of whether
+you use this future statement or not, you **must** make sure you know exactly
+which Python 2 strings you want to be bytes, and which are to be strings. This
+means you should, **at minimum** mark all strings that are meant to be text
+strings with a ``u`` prefix if you do not use this future statement.
+
+
+Bytes literals
+''''''''''''''
+
+This is a **very** important one. The ability to prefix Python 2 strings that
+are meant to contain bytes with a ``b`` prefix help to very clearly delineate
+what is and is not a Python 3 string. When you run 2to3 on code, all Python 2
+strings become Python 3 strings **unless** they are prefixed with ``b``.
+
+There are some differences between byte literals in Python 2 and those in
+Python 3 thanks to the bytes type just being an alias to ``str`` in Python 2.
+Probably the biggest "gotcha" is that indexing results in different values. In
+Python 2, the value of ``b'py'[1]`` is ``'y'``, while in Python 3 it's ``121``.
+You can avoid this disparity by always slicing at the size of a single element:
+``b'py'[1:2]`` is ``'y'`` in Python 2 and ``b'y'`` in Python 3 (i.e., close
+enough).
+
+You cannot concatenate bytes and strings in Python 3. But since in Python
+2 has bytes aliased to ``str``, it will succeed: ``b'a' + u'b'`` works in
+Python 2, but ``b'a' + 'b'`` in Python 3 is a :exc:`TypeError`. A similar issue
+also comes about when doing comparisons between bytes and strings.
+
+
+Supporting `Python 2.5`_ and Newer Only
+---------------------------------------
+
+If you are supporting `Python 2.5`_ and newer there are still some features of
+Python that you can utilize.
+
+
+``from __future__ import absolute_import``
+''''''''''''''''''''''''''''''''''''''''''
+
+Implicit relative imports (e.g., importing ``spam.bacon`` from within
+``spam.eggs`` with the statement ``import bacon``) does not work in Python 3.
+This future statement moves away from that and allows the use of explicit
+relative imports (e.g., ``from . import bacon``).
+
+In `Python 2.5`_ you must use
+the __future__ statement to get to use explicit relative imports and prevent
+implicit ones. In `Python 2.6`_ explicit relative imports are available without
+the statement, but you still want the __future__ statement to prevent implicit
+relative imports. In `Python 2.7`_ the __future__ statement is not needed. In
+other words, unless you are only supporting Python 2.7 or a version earlier
+than Python 2.5, use the __future__ statement.
+
+
+
+Handle Common "Gotchas"
+-----------------------
+
+There are a few things that just consistently come up as sticking points for
+people which 2to3 cannot handle automatically or can easily be done in Python 2
+to help modernize your code.
+
+
+``from __future__ import division``
+'''''''''''''''''''''''''''''''''''
+
+While the exact same outcome can be had by using the ``-Qnew`` argument to
+Python, using this future statement lifts the requirement that your users use
+the flag to get the expected behavior of division in Python 3
+(e.g., ``1/2 == 0.5; 1//2 == 0``).
+
+
+
+Specify when opening a file as binary
+'''''''''''''''''''''''''''''''''''''
+
+Unless you have been working on Windows, there is a chance you have not always
+bothered to add the ``b`` mode when opening a binary file (e.g., ``rb`` for
+binary reading). Under Python 3, binary files and text files are clearly
+distinct and mutually incompatible; see the :mod:`io` module for details.
+Therefore, you **must** make a decision of whether a file will be used for
+binary access (allowing to read and/or write bytes data) or text access
+(allowing to read and/or write unicode data).
+
+Text files
+''''''''''
+
+Text files created using ``open()`` under Python 2 return byte strings,
+while under Python 3 they return unicode strings. Depending on your porting
+strategy, this can be an issue.
+
+If you want text files to return unicode strings in Python 2, you have two
+possibilities:
+
+* Under Python 2.6 and higher, use :func:`io.open`. Since :func:`io.open`
+ is essentially the same function in both Python 2 and Python 3, it will
+ help iron out any issues that might arise.
+
+* If pre-2.6 compatibility is needed, then you should use :func:`codecs.open`
+ instead. This will make sure that you get back unicode strings in Python 2.
+
+Subclass ``object``
+'''''''''''''''''''
+
+New-style classes have been around since `Python 2.2`_. You need to make sure
+you are subclassing from ``object`` to avoid odd edge cases involving method
+resolution order, etc. This continues to be totally valid in Python 3 (although
+unneeded as all classes implicitly inherit from ``object``).
+
+
+Deal With the Bytes/String Dichotomy
+''''''''''''''''''''''''''''''''''''
+
+One of the biggest issues people have when porting code to Python 3 is handling
+the bytes/string dichotomy. Because Python 2 allowed the ``str`` type to hold
+textual data, people have over the years been rather loose in their delineation
+of what ``str`` instances held text compared to bytes. In Python 3 you cannot
+be so care-free anymore and need to properly handle the difference. The key
+handling this issue to to make sure that **every** string literal in your
+Python 2 code is either syntactically of functionally marked as either bytes or
+text data. After this is done you then need to make sure your APIs are designed
+to either handle a specific type or made to be properly polymorphic.
+
+
+Mark Up Python 2 String Literals
+********************************
+
+First thing you must do is designate every single string literal in Python 2
+as either textual or bytes data. If you are only supporting Python 2.6 or
+newer, this can be accomplished by marking bytes literals with a ``b`` prefix
+and then designating textual data with a ``u`` prefix or using the
+``unicode_literals`` future statement.
+
+If your project supports versions of Python pre-dating 2.6, then you should use
+the six_ project and its ``b()`` function to denote bytes literals. For text
+literals you can either use six's ``u()`` function or use a ``u`` prefix.
+
+
+Decide what APIs Will Accept
+****************************
+
+In Python 2 it was very easy to accidentally create an API that accepted both
+bytes and textual data. But in Python 3, thanks to the more strict handling of
+disparate types, this loose usage of bytes and text together tends to fail.
+
+Take the dict ``{b'a': 'bytes', u'a': 'text'}`` in Python 2.6. It creates the
+dict ``{u'a': 'text'}`` since ``b'a' == u'a'``. But in Python 3 the equivalent
+dict creates ``{b'a': 'bytes', 'a': 'text'}``, i.e., no lost data. Similar
+issues can crop up when transitioning Python 2 code to Python 3.
+
+This means you need to choose what an API is going to accept and create and
+consistently stick to that API in both Python 2 and 3.
+
+
+Bytes / Unicode Comparison
+**************************
+
+In Python 3, mixing bytes and unicode is forbidden in most situations; it
+will raise a :class:`TypeError` where Python 2 would have attempted an implicit
+coercion between types. However, there is one case where it doesn't and
+it can be very misleading::
+
+ >>> b"" == ""
+ False
+
+This is because an equality comparison is required by the language to always
+succeed (and return ``False`` for incompatible types). However, this also
+means that code incorrectly ported to Python 3 can display buggy behaviour
+if such comparisons are silently executed. To detect such situations,
+Python 3 has a ``-b`` flag that will display a warning::
+
+ $ python3 -b
+ >>> b"" == ""
+ __main__:1: BytesWarning: Comparison between bytes and string
+ False
+
+To turn the warning into an exception, use the ``-bb`` flag instead::
+
+ $ python3 -bb
+ >>> b"" == ""
+ Traceback (most recent call last):
+ File "<stdin>", line 1, in <module>
+ BytesWarning: Comparison between bytes and string
+
+
+Indexing bytes objects
+''''''''''''''''''''''
+
+Another potentially surprising change is the indexing behaviour of bytes
+objects in Python 3::
+
+ >>> b"xyz"[0]
+ 120
+
+Indeed, Python 3 bytes objects (as well as :class:`bytearray` objects)
+are sequences of integers. But code converted from Python 2 will often
+assume that indexing a bytestring produces another bytestring, not an
+integer. To reconcile both behaviours, use slicing::
+
+ >>> b"xyz"[0:1]
+ b'x'
+ >>> n = 1
+ >>> b"xyz"[n:n+1]
+ b'y'
+
+The only remaining gotcha is that an out-of-bounds slice returns an empty
+bytes object instead of raising ``IndexError``:
+
+ >>> b"xyz"[3]
+ Traceback (most recent call last):
+ File "<stdin>", line 1, in <module>
+ IndexError: index out of range
+ >>> b"xyz"[3:4]
+ b''
+
+
+``__str__()``/``__unicode__()``
+'''''''''''''''''''''''''''''''
+
+In Python 2, objects can specify both a string and unicode representation of
+themselves. In Python 3, though, there is only a string representation. This
+becomes an issue as people can inadvertently do things in their ``__str__()``
+methods which have unpredictable results (e.g., infinite recursion if you
+happen to use the ``unicode(self).encode('utf8')`` idiom as the body of your
+``__str__()`` method).
+
+There are two ways to solve this issue. One is to use a custom 2to3 fixer. The
+blog post at http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/
+specifies how to do this. That will allow 2to3 to change all instances of ``def
+__unicode(self): ...`` to ``def __str__(self): ...``. This does require you
+define your ``__str__()`` method in Python 2 before your ``__unicode__()``
+method.
+
+The other option is to use a mixin class. This allows you to only define a
+``__unicode__()`` method for your class and let the mixin derive
+``__str__()`` for you (code from
+http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/)::
+
+ import sys
+
+ class UnicodeMixin(object):
+
+ """Mixin class to handle defining the proper __str__/__unicode__
+ methods in Python 2 or 3."""
+
+ if sys.version_info[0] >= 3: # Python 3
+ def __str__(self):
+ return self.__unicode__()
+ else: # Python 2
+ def __str__(self):
+ return self.__unicode__().encode('utf8')
+
+
+ class Spam(UnicodeMixin):
+
+ def __unicode__(self):
+ return u'spam-spam-bacon-spam' # 2to3 will remove the 'u' prefix
+
+
+Don't Index on Exceptions
+'''''''''''''''''''''''''
+
+In Python 2, the following worked::
+
+ >>> exc = Exception(1, 2, 3)
+ >>> exc.args[1]
+ 2
+ >>> exc[1] # Python 2 only!
+ 2
+
+But in Python 3, indexing directly on an exception is an error. You need to
+make sure to only index on the :attr:`BaseException.args` attribute which is a
+sequence containing all arguments passed to the :meth:`__init__` method.
+
+Even better is to use the documented attributes the exception provides.
+
+Don't use ``__getslice__`` & Friends
+''''''''''''''''''''''''''''''''''''
+
+Been deprecated for a while, but Python 3 finally drops support for
+``__getslice__()``, etc. Move completely over to :meth:`__getitem__` and
+friends.
+
+
+Updating doctests
+'''''''''''''''''
+
+2to3_ will attempt to generate fixes for doctests that it comes across. It's
+not perfect, though. If you wrote a monolithic set of doctests (e.g., a single
+docstring containing all of your doctests), you should at least consider
+breaking the doctests up into smaller pieces to make it more manageable to fix.
+Otherwise it might very well be worth your time and effort to port your tests
+to :mod:`unittest`.
+
+
+Eliminate ``-3`` Warnings
+-------------------------
+
+When you run your application's test suite, run it using the ``-3`` flag passed
+to Python. This will cause various warnings to be raised during execution about
+things that 2to3 cannot handle automatically (e.g., modules that have been
+removed). Try to eliminate those warnings to make your code even more portable
+to Python 3.
+
+
+Run 2to3
+--------
+
+Once you have made your Python 2 code future-compatible with Python 3, it's
+time to use 2to3_ to actually port your code.
+
+
+Manually
+''''''''
+
+To manually convert source code using 2to3_, you use the ``2to3`` script that
+is installed with Python 2.6 and later.::
+
+ 2to3 <directory or file to convert>
+
+This will cause 2to3 to write out a diff with all of the fixers applied for the
+converted source code. If you would like 2to3 to go ahead and apply the changes
+you can pass it the ``-w`` flag::
+
+ 2to3 -w <stuff to convert>
+
+There are other flags available to control exactly which fixers are applied,
+etc.
+
+
+During Installation
+'''''''''''''''''''
+
+When a user installs your project for Python 3, you can have either
+:mod:`distutils` or Distribute_ run 2to3_ on your behalf.
+For distutils, use the following idiom::
+
+ try: # Python 3
+ from distutils.command.build_py import build_py_2to3 as build_py
+ except ImportError: # Python 2
+ from distutils.command.build_py import build_py
+
+ setup(cmdclass = {'build_py': build_py},
+ # ...
+ )
+
+For Distribute::
+
+ setup(use_2to3=True,
+ # ...
+ )
+
+This will allow you to not have to distribute a separate Python 3 version of
+your project. It does require, though, that when you perform development that
+you at least build your project and use the built Python 3 source for testing.
+
+
+Verify & Test
+-------------
+
+At this point you should (hopefully) have your project converted in such a way
+that it works in Python 3. Verify it by running your unit tests and making sure
+nothing has gone awry. If you miss something then figure out how to fix it in
+Python 3, backport to your Python 2 code, and run your code through 2to3 again
+to verify the fix transforms properly.
+
+
+.. _2to3: http://docs.python.org/py3k/library/2to3.html
+.. _Distribute: http://packages.python.org/distribute/
+
+
+.. _use_same_source:
+
+Python 2/3 Compatible Source
+============================
+
+While it may seem counter-intuitive, you can write Python code which is
+source-compatible between Python 2 & 3. It does lead to code that is not
+entirely idiomatic Python (e.g., having to extract the currently raised
+exception from ``sys.exc_info()[1]``), but it can be run under Python 2
+**and** Python 3 without using 2to3_ as a translation step (although the tool
+should be used to help find potential portability problems). This allows you to
+continue to have a rapid development process regardless of whether you are
+developing under Python 2 or Python 3. Whether this approach or using
+:ref:`use_2to3` works best for you will be a per-project decision.
+
+To get a complete idea of what issues you will need to deal with, see the
+`What's New in Python 3.0`_. Others have reorganized the data in other formats
+such as http://docs.pythonsprints.com/python3_porting/py-porting.html .
+
+The following are some steps to take to try to support both Python 2 & 3 from
+the same source code.
+
+
+.. _What's New in Python 3.0: http://docs.python.org/release/3.0/whatsnew/3.0.html
+
+
+Follow The Steps for Using 2to3_
+--------------------------------
+
+All of the steps outlined in how to
+:ref:`port Python 2 code with 2to3 <use_2to3>` apply
+to creating a Python 2/3 codebase. This includes trying only support Python 2.6
+or newer (the :mod:`__future__` statements work in Python 3 without issue),
+eliminating warnings that are triggered by ``-3``, etc.
+
+You should even consider running 2to3_ over your code (without committing the
+changes). This will let you know where potential pain points are within your
+code so that you can fix them properly before they become an issue.
+
+
+Use six_
+--------
+
+The six_ project contains many things to help you write portable Python code.
+You should make sure to read its documentation from beginning to end and use
+any and all features it provides. That way you will minimize any mistakes you
+might make in writing cross-version code.
+
+
+Capturing the Currently Raised Exception
+----------------------------------------
+
+One change between Python 2 and 3 that will require changing how you code (if
+you support `Python 2.5`_ and earlier) is
+accessing the currently raised exception. In Python 2.5 and earlier the syntax
+to access the current exception is::
+
+ try:
+ raise Exception()
+ except Exception, exc:
+ # Current exception is 'exc'
+ pass
+
+This syntax changed in Python 3 (and backported to `Python 2.6`_ and later)
+to::
+
+ try:
+ raise Exception()
+ except Exception as exc:
+ # Current exception is 'exc'
+ # In Python 3, 'exc' is restricted to the block; Python 2.6 will "leak"
+ pass
+
+Because of this syntax change you must change to capturing the current
+exception to::
+
+ try:
+ raise Exception()
+ except Exception:
+ import sys
+ exc = sys.exc_info()[1]
+ # Current exception is 'exc'
+ pass
+
+You can get more information about the raised exception from
+:func:`sys.exc_info` than simply the current exception instance, but you most
+likely don't need it.
+
+.. note::
+ In Python 3, the traceback is attached to the exception instance
+ through the ``__traceback__`` attribute. If the instance is saved in
+ a local variable that persists outside of the ``except`` block, the
+ traceback will create a reference cycle with the current frame and its
+ dictionary of local variables. This will delay reclaiming dead
+ resources until the next cyclic :term:`garbage collection` pass.
+
+ In Python 2, this problem only occurs if you save the traceback itself
+ (e.g. the third element of the tuple returned by :func:`sys.exc_info`)
+ in a variable.
+
+
+Other Resources
+===============
+
+The authors of the following blog posts, wiki pages, and books deserve special
+thanks for making public their tips for porting Python 2 code to Python 3 (and
+thus helping provide information for this document):
+
+* http://python3porting.com/
+* http://docs.pythonsprints.com/python3_porting/py-porting.html
+* http://techspot.zzzeek.org/2011/01/24/zzzeek-s-guide-to-python-3-porting/
+* http://dabeaz.blogspot.com/2011/01/porting-py65-and-my-superboard-to.html
+* http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/
+* http://lucumr.pocoo.org/2010/2/11/porting-to-python-3-a-guide/
+* http://wiki.python.org/moin/PortingPythonToPy3k
+
+If you feel there is something missing from this document that should be added,
+please email the python-porting_ mailing list.
+
+.. _python-porting: http://mail.python.org/mailman/listinfo/python-porting
diff --git a/Doc/howto/sorting.rst b/Doc/howto/sorting.rst
index 351713f..d9c70e2 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.
@@ -87,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
-an :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 an :func:`~operator.methodcaller` function.
Using those functions, the above examples become simpler and faster:
@@ -247,6 +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 3.2, the :func:`functools.cmp_to_key` function was added to the
+:mod:`functools` module in the standard library.
Odd and Ends
============
@@ -254,7 +256,7 @@ Odd and Ends
* For locale aware sorting, use :func:`locale.strxfrm` for a key function or
:func:`locale.strcoll` for a comparison function.
-* The *reverse* parameter still maintains sort stability (i.e. records with
+* The *reverse* parameter still maintains sort stability (so that records with
equal keys retain the original order). Interestingly, that effect can be
simulated without the parameter by using the builtin :func:`reversed` function
twice:
diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst
index 13efa76..77fcd26 100644
--- a/Doc/howto/unicode.rst
+++ b/Doc/howto/unicode.rst
@@ -4,13 +4,11 @@
Unicode HOWTO
*****************
-:Release: 1.11
+: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. (This HOWTO has not yet been updated to cover the 3.x
-versions of Python.)
-
+with Unicode.
Introduction to Unicode
=======================
@@ -44,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
@@ -64,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
@@ -90,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
@@ -117,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::
@@ -164,7 +162,7 @@ encoding, for example, are 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.
@@ -226,8 +224,8 @@ 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.
@@ -284,10 +282,10 @@ 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::
- >>> chr(40960)
- '\ua000'
- >>> ord('\ua000')
- 40960
+ >>> chr(57344)
+ '\ue000'
+ >>> ord('\ue000')
+ 57344
Converting to Bytes
-------------------
@@ -329,7 +327,8 @@ Unicode Literals in Python Source Code
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 8 hex digits, not 4::
+point. The ``\U`` escape sequence is similar, but expects eight hex digits,
+not four::
>>> s = "a\xac\u1234\u20ac\U00008000"
^^^^ two-digit hex escape
@@ -409,7 +408,7 @@ These are grouped into categories such as "Letter", "Number", "Punctuation", or
from the above output, ``'Ll'`` means 'Letter, lowercase', ``'No'`` means
"Number, other", ``'Mn'`` is "Mark, nonspacing", and ``'So'`` is "Symbol,
other". See
-<http://unicode.org/Public/5.1.0/ucd/UCD.html#General_Category_Values> for a
+<http://www.unicode.org/reports/tr44/#General_Category_Values> for a
list of category codes.
References
@@ -468,18 +467,17 @@ like those in string objects' :meth:`encode` and :meth:`decode` methods.
Reading Unicode from a file is therefore simple::
- f = 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 = open('test', encoding='utf-8', mode='w+')
- f.write('\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]))
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
@@ -516,14 +514,13 @@ usually just provide the Unicode string as the filename, and it will be
automatically converted to the right encoding for you::
filename = 'filename\u4500abc'
- f = open(filename, 'w')
- f.write('blah\n')
- f.close()
+ 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
+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 a byte string or a Unicode string. If you pass a
@@ -572,14 +569,6 @@ strings, you will find your program vulnerable to bugs wherever you combine the
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.
-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.
-
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
@@ -597,8 +586,8 @@ this code::
if '/' in filename:
raise ValueError("'/' not allowed in filenames")
unicode_name = filename.decode(encoding)
- f = open(unicode_name, 'r')
- # ... return contents of file ...
+ with open(unicode_name, 'r') as f:
+ # ... 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
@@ -613,27 +602,30 @@ 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.1: Feb-Nov 2008. Updates the document with respect to Python 3 changes.
+ 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.
+ 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
diff --git a/Doc/howto/webservers.rst b/Doc/howto/webservers.rst
index caf0ad6..c4ac2b2 100644
--- a/Doc/howto/webservers.rst
+++ b/Doc/howto/webservers.rst
@@ -293,7 +293,7 @@ following WSGI-application::
# -*- coding: UTF-8 -*-
import sys, os
- from cgi import escape
+ from html import escape
from flup.server.fcgi import WSGIServer
def app(environ, start_response):
diff --git a/Doc/includes/dbpickle.py b/Doc/includes/dbpickle.py
index c021eac..b88ee87 100644
--- a/Doc/includes/dbpickle.py
+++ b/Doc/includes/dbpickle.py
@@ -47,7 +47,8 @@ class DBUnpickler(pickle.Unpickler):
def main():
- import io, pprint
+ import io
+ import pprint
# Initialize and populate our database.
conn = sqlite3.connect(":memory:")
diff --git a/Doc/includes/email-alternative.py b/Doc/includes/email-alternative.py
index 82e3ffa..33c430a 100644
--- a/Doc/includes/email-alternative.py
+++ b/Doc/includes/email-alternative.py
@@ -1,4 +1,4 @@
-#! /usr/bin/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
new file mode 100644
index 0000000..a53317d
--- /dev/null
+++ b/Doc/includes/email-headers.py
@@ -0,0 +1,17 @@
+# Import the email modules we'll need
+from email.parser import Parser
+
+# If the e-mail headers are in a file, uncomment this line:
+#headers = Parser().parse(open(messagefile, 'r'))
+
+# Or for parsing headers in a string, use:
+headers = Parser().parsestr('From: <user@example.com>\n'
+ 'To: <someone_else@example.com>\n'
+ 'Subject: Test message\n'
+ '\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'])
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 88048c0..5ee7682 100644
--- a/Doc/includes/minidom-example.py
+++ b/Doc/includes/minidom-example.py
@@ -19,11 +19,11 @@ document = """\
dom = xml.dom.minidom.parseString(document)
def getText(nodelist):
- rc = ""
+ rc = []
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
- rc = rc + node.data
- return rc
+ rc.append(node.data)
+ return ''.join(rc)
def handleSlideshow(slideshow):
print("<html>")
diff --git a/Doc/includes/mp_benchmarks.py b/Doc/includes/mp_benchmarks.py
index 72d4426..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
@@ -111,7 +116,7 @@ def test_seqspeed(seq):
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)
@@ -132,7 +137,7 @@ def test_lockspeed(l):
l.acquire()
l.release()
- elapsed = _timer()-t
+ elapsed = _timer() - t
print(iterations, 'iterations in', elapsed, 'seconds')
print('average number/sec:', iterations/elapsed)
@@ -169,7 +174,7 @@ def test_conditionspeed(Process, c):
c.notify()
c.wait()
- elapsed = _timer()-t
+ elapsed = _timer() - t
c.release()
p.join()
diff --git a/Doc/includes/mp_pool.py b/Doc/includes/mp_pool.py
index e360703..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
diff --git a/Doc/includes/mp_synchronize.py b/Doc/includes/mp_synchronize.py
index fd393f2..81dbc38 100644
--- a/Doc/includes/mp_synchronize.py
+++ b/Doc/includes/mp_synchronize.py
@@ -5,7 +5,9 @@
# All rights reserved.
#
-import time, sys, random
+import time
+import sys
+import random
from queue import Empty
import multiprocessing # may get overwritten
@@ -237,9 +239,9 @@ 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__)
func()
diff --git a/Doc/includes/mp_webserver.py b/Doc/includes/mp_webserver.py
index 0878de1..651024d 100644
--- a/Doc/includes/mp_webserver.py
+++ b/Doc/includes/mp_webserver.py
@@ -24,7 +24,7 @@ if sys.platform == 'win32':
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
diff --git a/Doc/includes/sqlite3/adapter_datetime.py b/Doc/includes/sqlite3/adapter_datetime.py
index 5869e22..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())
diff --git a/Doc/includes/sqlite3/load_extension.py b/Doc/includes/sqlite3/load_extension.py
new file mode 100644
index 0000000..015aa0d
--- /dev/null
+++ b/Doc/includes/sqlite3/load_extension.py
@@ -0,0 +1,26 @@
+import sqlite3
+
+con = sqlite3.connect(":memory:")
+
+# enable extension loading
+con.enable_load_extension(True)
+
+# Load the fulltext search extension
+con.execute("select load_extension('./fts3.so')")
+
+# alternatively you can load the extension using an API call:
+# con.load_extension("./fts3.so")
+
+# disable extension laoding again
+con.enable_load_extension(False)
+
+# example from SQLite wiki
+con.execute("create virtual table recipe using fts3(name, ingredients)")
+con.executescript("""
+ insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes');
+ insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery');
+ insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour');
+ 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)
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/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 6a11c5a..31c1d7f 100644
--- a/Doc/install/index.rst
+++ b/Doc/install/index.rst
@@ -691,6 +691,9 @@ And on Windows, the configuration files are:
| local | :file:`setup.cfg` | \(3) |
+--------------+-------------------------------------------------+-------+
+On all platforms, the "personal" file can be temporarily disabled by
+passing the `--no-user-cfg` option.
+
Notes:
(1)
diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst
index de31251..b3efeab 100644
--- a/Doc/library/2to3.rst
+++ b/Doc/library/2to3.rst
@@ -141,7 +141,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
@@ -267,6 +267,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
@@ -274,7 +293,7 @@ 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
diff --git a/Doc/library/__future__.rst b/Doc/library/__future__.rst
index 2348217..0acccc5 100644
--- a/Doc/library/__future__.rst
+++ b/Doc/library/__future__.rst
@@ -4,6 +4,9 @@
.. module:: __future__
:synopsis: Future statement definitions
+**Source code:** :source:`Lib/__future__.py`
+
+--------------
:mod:`__future__` is a real module, and serves three purposes:
diff --git a/Doc/library/_dummy_thread.rst b/Doc/library/_dummy_thread.rst
index 62e5708..83aec12 100644
--- a/Doc/library/_dummy_thread.rst
+++ b/Doc/library/_dummy_thread.rst
@@ -4,6 +4,9 @@
.. 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
diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst
index cb62407..369e9cd 100644
--- a/Doc/library/_thread.rst
+++ b/Doc/library/_thread.rst
@@ -28,7 +28,7 @@ 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 constant and functions:
+It defines the following constants and functions:
.. exception:: error
@@ -103,18 +103,42 @@ It defines the following constant and functions:
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])
+.. method:: lock.acquire(waitflag=1, timeout=-1)
- Without the optional argument, this method acquires the lock unconditionally, if
+ 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 before. The
- return value is ``True`` if the lock is acquired successfully, ``False`` if not.
+ 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()
@@ -156,12 +180,10 @@ In addition to these methods, lock objects can also be used via the
* 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.
- .. index:: pair: threads; IRIX
-
* When the main thread exits, it is system defined whether the other threads
- survive. On SGI IRIX using the native thread implementation, they survive. On
- most other systems, they are killed without executing :keyword:`try` ...
- :keyword:`finally` clauses or executing object destructors.
+ 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
diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst
index aa1cc78..9fadbd2 100644
--- a/Doc/library/abc.rst
+++ b/Doc/library/abc.rst
@@ -7,6 +7,10 @@
.. sectionauthor:: Georg Brandl
.. much of the content adapted from docstrings
+**Source code:** :source:`Lib/abc.py`
+
+--------------
+
This module provides the infrastructure for defining an :term:`abstract base
class` (ABCs) in Python, as outlined in :pep:`3119`; see the PEP for why this
was added to Python. (See also :pep:`3141` and the :mod:`numbers` module
@@ -122,7 +126,7 @@ This module provides the following class:
It also provides the following decorators:
-.. function:: abstractmethod(function)
+.. decorator:: abstractmethod(function)
A decorator indicating abstract methods.
@@ -157,6 +161,36 @@ It also provides the following decorators:
multiple-inheritance.
+.. decorator:: abstractclassmethod(function)
+
+ 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(function)
+
+ 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.
diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst
index 304437d..999bad8 100644
--- a/Doc/library/aifc.rst
+++ b/Doc/library/aifc.rst
@@ -10,6 +10,10 @@
single: AIFF
single: AIFF-C
+**Source code:** :source:`Lib/aifc.py`
+
+--------------
+
This module provides support for reading and writing AIFF and AIFF-C files.
AIFF is Audio Interchange File Format, a format for storing digital audio
samples in a file. AIFF-C is a newer version of the format that includes the
diff --git a/Doc/library/allos.rst b/Doc/library/allos.rst
index f25c3b8..bf91717 100644
--- a/Doc/library/allos.rst
+++ b/Doc/library/allos.rst
@@ -15,9 +15,12 @@ but they are available on most other systems as well. Here's an overview:
os.rst
io.rst
time.rst
+ argparse.rst
optparse.rst
getopt.rst
logging.rst
+ logging.config.rst
+ logging.handlers.rst
getpass.rst
curses.rst
curses.ascii.rst
diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst
new file mode 100644
index 0000000..61e1786
--- /dev/null
+++ b/Doc/library/argparse.rst
@@ -0,0 +1,1816 @@
+:mod:`argparse` --- Parser for command-line options, arguments and sub-commands
+===============================================================================
+
+.. module:: argparse
+ :synopsis: Command-line option and argument-parsing library.
+.. moduleauthor:: Steven Bethard <steven.bethard@gmail.com>
+.. sectionauthor:: Steven Bethard <steven.bethard@gmail.com>
+
+**Source code:** :source:`Lib/argparse.py`
+
+.. versionadded:: 3.2
+
+--------------
+
+The :mod:`argparse` module makes it easy to write user-friendly command-line
+interfaces. The program defines what arguments it requires, and :mod:`argparse`
+will figure out how to parse those out of :data:`sys.argv`. The :mod:`argparse`
+module also automatically generates help and usage messages and issues errors
+when users give the program invalid arguments.
+
+
+Example
+-------
+
+The following code is a Python program that takes a list of integers and
+produces either the sum or the max::
+
+ import argparse
+
+ parser = argparse.ArgumentParser(description='Process some integers.')
+ parser.add_argument('integers', metavar='N', type=int, nargs='+',
+ help='an integer for the accumulator')
+ parser.add_argument('--sum', dest='accumulate', action='store_const',
+ const=sum, default=max,
+ help='sum the integers (default: find the max)')
+
+ args = parser.parse_args()
+ 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::
+
+ $ prog.py -h
+ usage: prog.py [-h] [--sum] N [N ...]
+
+ Process some integers.
+
+ positional arguments:
+ N an integer for the accumulator
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --sum sum the integers (default: find the max)
+
+When run with the appropriate arguments, it prints either the sum or the max of
+the command-line integers::
+
+ $ prog.py 1 2 3 4
+ 4
+
+ $ prog.py 1 2 3 4 --sum
+ 10
+
+If invalid arguments are passed in, it will issue an error::
+
+ $ prog.py a b c
+ usage: prog.py [-h] [--sum] N [N ...]
+ prog.py: error: argument N: invalid int value: 'a'
+
+The following sections walk you through this example.
+
+
+Creating a parser
+^^^^^^^^^^^^^^^^^
+
+The first step in using the :mod:`argparse` is creating an
+:class:`ArgumentParser` object::
+
+ >>> parser = argparse.ArgumentParser(description='Process some integers.')
+
+The :class:`ArgumentParser` object will hold all the information necessary to
+parse the command line into Python data types.
+
+
+Adding arguments
+^^^^^^^^^^^^^^^^
+
+Filling an :class:`ArgumentParser` with information about program arguments is
+done by making calls to the :meth:`~ArgumentParser.add_argument` method.
+Generally, these calls tell the :class:`ArgumentParser` how to take the strings
+on the command line and turn them into objects. This information is stored and
+used when :meth:`~ArgumentParser.parse_args` is called. For example::
+
+ >>> parser.add_argument('integers', metavar='N', type=int, nargs='+',
+ ... help='an integer for the accumulator')
+ >>> parser.add_argument('--sum', dest='accumulate', action='store_const',
+ ... const=sum, default=max,
+ ... help='sum the integers (default: find the max)')
+
+Later, calling :meth:`~ArgumentParser.parse_args` will return an object with
+two attributes, ``integers`` and ``accumulate``. The ``integers`` attribute
+will be a list of one or more ints, and the ``accumulate`` attribute will be
+either the :func:`sum` function, if ``--sum`` was specified at the command line,
+or the :func:`max` function if it was not.
+
+
+Parsing arguments
+^^^^^^^^^^^^^^^^^
+
+:class:`ArgumentParser` parses args through the
+:meth:`~ArgumentParser.parse_args` method. This will inspect the command line,
+convert each arg to the appropriate type and then invoke the appropriate action.
+In most cases, this means a simple namespace object will be built up from
+attributes parsed out of the command line::
+
+ >>> parser.parse_args(['--sum', '7', '-1', '42'])
+ Namespace(accumulate=<built-in function sum>, integers=[7, -1, 42])
+
+In a script, :meth:`~ArgumentParser.parse_args` will typically be called with no
+arguments, and the :class:`ArgumentParser` will automatically determine the
+command-line args from :data:`sys.argv`.
+
+
+ArgumentParser objects
+----------------------
+
+.. class:: ArgumentParser([description], [epilog], [prog], [usage], [add_help], \
+ [argument_default], [parents], [prefix_chars], \
+ [conflict_handler], [formatter_class])
+
+ Create a new :class:`ArgumentParser` object. Each parameter has its own more
+ detailed description below, but in short they are:
+
+ * description_ - Text to display before the argument help.
+
+ * epilog_ - Text to display after the argument help.
+
+ * add_help_ - Add a -h/--help option to the parser. (default: ``True``)
+
+ * argument_default_ - Set the global default value for arguments.
+ (default: ``None``)
+
+ * parents_ - A list of :class:`ArgumentParser` objects whose arguments should
+ also be included.
+
+ * prefix_chars_ - The set of characters that prefix optional arguments.
+ (default: '-')
+
+ * fromfile_prefix_chars_ - The set of characters that prefix files from
+ which additional arguments should be read. (default: ``None``)
+
+ * formatter_class_ - A class for customizing the help output.
+
+ * conflict_handler_ - Usually unnecessary, defines strategy for resolving
+ conflicting optionals.
+
+ * prog_ - The name of the program (default:
+ :data:`sys.argv[0]`)
+
+ * usage_ - The string describing the program usage (default: generated)
+
+The following sections describe how each of these are used.
+
+
+description
+^^^^^^^^^^^
+
+Most calls to the :class:`ArgumentParser` constructor will use the
+``description=`` keyword argument. This argument gives a brief description of
+what the program does and how it works. In help messages, the description is
+displayed between the command-line usage string and the help messages for the
+various arguments::
+
+ >>> parser = argparse.ArgumentParser(description='A foo that bars')
+ >>> parser.print_help()
+ usage: argparse.py [-h]
+
+ A foo that bars
+
+ optional arguments:
+ -h, --help show this help message and exit
+
+By default, the description will be line-wrapped so that it fits within the
+given space. To change this behavior, see the formatter_class_ argument.
+
+
+epilog
+^^^^^^
+
+Some programs like to display additional description of the program after the
+description of the arguments. Such text can be specified using the ``epilog=``
+argument to :class:`ArgumentParser`::
+
+ >>> parser = argparse.ArgumentParser(
+ ... description='A foo that bars',
+ ... epilog="And that's how you'd foo a bar")
+ >>> parser.print_help()
+ usage: argparse.py [-h]
+
+ A foo that bars
+
+ optional arguments:
+ -h, --help show this help message and exit
+
+ And that's how you'd foo a bar
+
+As with the description_ argument, the ``epilog=`` text is by default
+line-wrapped, but this behavior can be adjusted with the formatter_class_
+argument to :class:`ArgumentParser`.
+
+
+add_help
+^^^^^^^^
+
+By default, ArgumentParser objects add an option which simply displays
+the parser's help message. For example, consider a file named
+``myprogram.py`` containing the following code::
+
+ import argparse
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--foo', help='foo help')
+ args = parser.parse_args()
+
+If ``-h`` or ``--help`` is supplied at the command line, the ArgumentParser
+help will be printed::
+
+ $ python myprogram.py --help
+ usage: myprogram.py [-h] [--foo FOO]
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --foo FOO foo help
+
+Occasionally, it may be useful to disable the addition of this help option.
+This can be achieved by passing ``False`` as the ``add_help=`` argument to
+:class:`ArgumentParser`::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
+ >>> parser.add_argument('--foo', help='foo help')
+ >>> parser.print_help()
+ usage: PROG [--foo FOO]
+
+ optional arguments:
+ --foo FOO foo help
+
+The help option is typically ``-h/--help``. The exception to this is
+if the ``prefix_chars=`` is specified and does not include ``'-'``, in
+which case ``-h`` and ``--help`` are not valid options. In
+this case, the first character in ``prefix_chars`` is used to prefix
+the help options::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='+/')
+ >>> parser.print_help()
+ usage: PROG [+h]
+
+ optional arguments:
+ +h, ++help show this help message and exit
+
+
+prefix_chars
+^^^^^^^^^^^^
+
+Most command-line options will use ``'-'`` as the prefix, e.g. ``-f/--foo``.
+Parsers that need to support different or additional prefix
+characters, e.g. for options
+like ``+f`` or ``/foo``, may specify them using the ``prefix_chars=`` argument
+to the ArgumentParser constructor::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='-+')
+ >>> parser.add_argument('+f')
+ >>> parser.add_argument('++bar')
+ >>> parser.parse_args('+f X ++bar Y'.split())
+ Namespace(bar='Y', f='X')
+
+The ``prefix_chars=`` argument defaults to ``'-'``. Supplying a set of
+characters that does not include ``'-'`` will cause ``-f/--foo`` options to be
+disallowed.
+
+
+fromfile_prefix_chars
+^^^^^^^^^^^^^^^^^^^^^
+
+Sometimes, for example when dealing with a particularly long argument lists, it
+may make sense to keep the list of arguments in a file rather than typing it out
+at the command line. If the ``fromfile_prefix_chars=`` argument is given to the
+:class:`ArgumentParser` constructor, then arguments that start with any of the
+specified characters will be treated as files, and will be replaced by the
+arguments they contain. For example::
+
+ >>> with open('args.txt', 'w') as fp:
+ ... fp.write('-f\nbar')
+ >>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
+ >>> parser.add_argument('-f')
+ >>> parser.parse_args(['-f', 'foo', '@args.txt'])
+ Namespace(f='bar')
+
+Arguments read from a file must by default be one per line (but see also
+:meth:`~ArgumentParser.convert_arg_line_to_args`) and are treated as if they
+were in the same place as the original file referencing argument on the command
+line. So in the example above, the expression ``['-f', 'foo', '@args.txt']``
+is considered equivalent to the expression ``['-f', 'foo', '-f', 'bar']``.
+
+The ``fromfile_prefix_chars=`` argument defaults to ``None``, meaning that
+arguments will never be treated as file references.
+
+
+argument_default
+^^^^^^^^^^^^^^^^
+
+Generally, argument defaults are specified either by passing a default to
+:meth:`~ArgumentParser.add_argument` or by calling the
+:meth:`~ArgumentParser.set_defaults` methods with a specific set of name-value
+pairs. Sometimes however, it may be useful to specify a single parser-wide
+default for arguments. This can be accomplished by passing the
+``argument_default=`` keyword argument to :class:`ArgumentParser`. For example,
+to globally suppress attribute creation on :meth:`~ArgumentParser.parse_args`
+calls, we supply ``argument_default=SUPPRESS``::
+
+ >>> parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
+ >>> parser.add_argument('--foo')
+ >>> parser.add_argument('bar', nargs='?')
+ >>> parser.parse_args(['--foo', '1', 'BAR'])
+ Namespace(bar='BAR', foo='1')
+ >>> parser.parse_args([])
+ Namespace()
+
+
+parents
+^^^^^^^
+
+Sometimes, several parsers share a common set of arguments. Rather than
+repeating the definitions of these arguments, a single parser with all the
+shared arguments and passed to ``parents=`` argument to :class:`ArgumentParser`
+can be used. The ``parents=`` argument takes a list of :class:`ArgumentParser`
+objects, collects all the positional and optional actions from them, and adds
+these actions to the :class:`ArgumentParser` object being constructed::
+
+ >>> parent_parser = argparse.ArgumentParser(add_help=False)
+ >>> parent_parser.add_argument('--parent', type=int)
+
+ >>> foo_parser = argparse.ArgumentParser(parents=[parent_parser])
+ >>> foo_parser.add_argument('foo')
+ >>> foo_parser.parse_args(['--parent', '2', 'XXX'])
+ Namespace(foo='XXX', parent=2)
+
+ >>> bar_parser = argparse.ArgumentParser(parents=[parent_parser])
+ >>> bar_parser.add_argument('--bar')
+ >>> bar_parser.parse_args(['--bar', 'YYY'])
+ Namespace(bar='YYY', parent=None)
+
+Note that most parent parsers will specify ``add_help=False``. Otherwise, the
+:class:`ArgumentParser` will see two ``-h/--help`` options (one in the parent
+and one in the child) and raise an error.
+
+.. note::
+ You must fully initialize the parsers before passing them via ``parents=``.
+ If you change the parent parsers after the child parser, those changes will
+ not be reflected in the child.
+
+
+formatter_class
+^^^^^^^^^^^^^^^
+
+:class:`ArgumentParser` objects allow the help formatting to be customized by
+specifying an alternate formatting class. Currently, there are three such
+classes:
+
+.. class:: RawDescriptionHelpFormatter
+ RawTextHelpFormatter
+ ArgumentDefaultsHelpFormatter
+
+The first two allow more control over how textual descriptions are displayed,
+while the last automatically adds information about argument default values.
+
+By default, :class:`ArgumentParser` objects line-wrap the description_ and
+epilog_ texts in command-line help messages::
+
+ >>> parser = argparse.ArgumentParser(
+ ... prog='PROG',
+ ... description='''this description
+ ... was indented weird
+ ... but that is okay''',
+ ... epilog='''
+ ... likewise for this epilog whose whitespace will
+ ... be cleaned up and whose words will be wrapped
+ ... across a couple lines''')
+ >>> parser.print_help()
+ usage: PROG [-h]
+
+ this description was indented weird but that is okay
+
+ optional arguments:
+ -h, --help show this help message and exit
+
+ likewise for this epilog whose whitespace will be cleaned up and whose words
+ will be wrapped across a couple lines
+
+Passing :class:`~argparse.RawDescriptionHelpFormatter` as ``formatter_class=``
+indicates that description_ and epilog_ are already correctly formatted and
+should not be line-wrapped::
+
+ >>> parser = argparse.ArgumentParser(
+ ... prog='PROG',
+ ... formatter_class=argparse.RawDescriptionHelpFormatter,
+ ... description=textwrap.dedent('''\
+ ... Please do not mess up this text!
+ ... --------------------------------
+ ... I have indented it
+ ... exactly the way
+ ... I want it
+ ... '''))
+ >>> parser.print_help()
+ usage: PROG [-h]
+
+ Please do not mess up this text!
+ --------------------------------
+ I have indented it
+ exactly the way
+ I want it
+
+ optional arguments:
+ -h, --help show this help message and exit
+
+:class:`RawTextHelpFormatter` maintains whitespace for all sorts of help text
+including argument descriptions.
+
+The other formatter class available, :class:`ArgumentDefaultsHelpFormatter`,
+will add information about the default value of each of the arguments::
+
+ >>> parser = argparse.ArgumentParser(
+ ... prog='PROG',
+ ... formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+ >>> parser.add_argument('--foo', type=int, default=42, help='FOO!')
+ >>> parser.add_argument('bar', nargs='*', default=[1, 2, 3], help='BAR!')
+ >>> parser.print_help()
+ usage: PROG [-h] [--foo FOO] [bar [bar ...]]
+
+ positional arguments:
+ bar BAR! (default: [1, 2, 3])
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --foo FOO FOO! (default: 42)
+
+
+conflict_handler
+^^^^^^^^^^^^^^^^
+
+:class:`ArgumentParser` objects do not allow two actions with the same option
+string. By default, :class:`ArgumentParser` objects raises an exception if an
+attempt is made to create an argument with an option string that is already in
+use::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('-f', '--foo', help='old foo help')
+ >>> parser.add_argument('--foo', help='new foo help')
+ Traceback (most recent call last):
+ ..
+ ArgumentError: argument --foo: conflicting option string(s): --foo
+
+Sometimes (e.g. when using parents_) it may be useful to simply override any
+older arguments with the same option string. To get this behavior, the value
+``'resolve'`` can be supplied to the ``conflict_handler=`` argument of
+:class:`ArgumentParser`::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG', conflict_handler='resolve')
+ >>> parser.add_argument('-f', '--foo', help='old foo help')
+ >>> parser.add_argument('--foo', help='new foo help')
+ >>> parser.print_help()
+ usage: PROG [-h] [-f FOO] [--foo FOO]
+
+ optional arguments:
+ -h, --help show this help message and exit
+ -f FOO old foo help
+ --foo FOO new foo help
+
+Note that :class:`ArgumentParser` objects only remove an action if all of its
+option strings are overridden. So, in the example above, the old ``-f/--foo``
+action is retained as the ``-f`` action, because only the ``--foo`` option
+string was overridden.
+
+
+prog
+^^^^
+
+By default, :class:`ArgumentParser` objects uses ``sys.argv[0]`` to determine
+how to display the name of the program in help messages. This default is almost
+always desirable because it will make the help messages match how the program was
+invoked on the command line. For example, consider a file named
+``myprogram.py`` with the following code::
+
+ import argparse
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--foo', help='foo help')
+ args = parser.parse_args()
+
+The help for this program will display ``myprogram.py`` as the program name
+(regardless of where the program was invoked from)::
+
+ $ python myprogram.py --help
+ usage: myprogram.py [-h] [--foo FOO]
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --foo FOO foo help
+ $ cd ..
+ $ python subdir\myprogram.py --help
+ usage: myprogram.py [-h] [--foo FOO]
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --foo FOO foo help
+
+To change this default behavior, another value can be supplied using the
+``prog=`` argument to :class:`ArgumentParser`::
+
+ >>> parser = argparse.ArgumentParser(prog='myprogram')
+ >>> parser.print_help()
+ usage: myprogram [-h]
+
+ optional arguments:
+ -h, --help show this help message and exit
+
+Note that the program name, whether determined from ``sys.argv[0]`` or from the
+``prog=`` argument, is available to help messages using the ``%(prog)s`` format
+specifier.
+
+::
+
+ >>> parser = argparse.ArgumentParser(prog='myprogram')
+ >>> parser.add_argument('--foo', help='foo of the %(prog)s program')
+ >>> parser.print_help()
+ usage: myprogram [-h] [--foo FOO]
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --foo FOO foo of the myprogram program
+
+
+usage
+^^^^^
+
+By default, :class:`ArgumentParser` calculates the usage message from the
+arguments it contains::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('--foo', nargs='?', help='foo help')
+ >>> parser.add_argument('bar', nargs='+', help='bar help')
+ >>> parser.print_help()
+ usage: PROG [-h] [--foo [FOO]] bar [bar ...]
+
+ positional arguments:
+ bar bar help
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --foo [FOO] foo help
+
+The default message can be overridden with the ``usage=`` keyword argument::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG', usage='%(prog)s [options]')
+ >>> parser.add_argument('--foo', nargs='?', help='foo help')
+ >>> parser.add_argument('bar', nargs='+', help='bar help')
+ >>> parser.print_help()
+ usage: PROG [options]
+
+ positional arguments:
+ bar bar help
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --foo [FOO] foo help
+
+The ``%(prog)s`` format specifier is available to fill in the program name in
+your usage messages.
+
+
+The add_argument() method
+-------------------------
+
+.. method:: ArgumentParser.add_argument(name or flags..., [action], [nargs], \
+ [const], [default], [type], [choices], [required], \
+ [help], [metavar], [dest])
+
+ Define how a single command-line argument should be parsed. Each parameter
+ has its own more detailed description below, but in short they are:
+
+ * `name or flags`_ - Either a name or a list of option strings, e.g. ``foo``
+ or ``-f, --foo``.
+
+ * action_ - The basic type of action to be taken when this argument is
+ encountered at the command line.
+
+ * nargs_ - The number of command-line arguments that should be consumed.
+
+ * const_ - A constant value required by some action_ and nargs_ selections.
+
+ * default_ - The value produced if the argument is absent from the
+ command line.
+
+ * type_ - The type to which the command-line argument should be converted.
+
+ * choices_ - A container of the allowable values for the argument.
+
+ * required_ - Whether or not the command-line option may be omitted
+ (optionals only).
+
+ * help_ - A brief description of what the argument does.
+
+ * metavar_ - A name for the argument in usage messages.
+
+ * dest_ - The name of the attribute to be added to the object returned by
+ :meth:`parse_args`.
+
+The following sections describe how each of these are used.
+
+
+name or flags
+^^^^^^^^^^^^^
+
+The :meth:`~ArgumentParser.add_argument` method must know whether an optional
+argument, like ``-f`` or ``--foo``, or a positional argument, like a list of
+filenames, is expected. The first arguments passed to
+:meth:`~ArgumentParser.add_argument` must therefore be either a series of
+flags, or a simple argument name. For example, an optional argument could
+be created like::
+
+ >>> parser.add_argument('-f', '--foo')
+
+while a positional argument could be created like::
+
+ >>> parser.add_argument('bar')
+
+When :meth:`~ArgumentParser.parse_args` is called, optional arguments will be
+identified by the ``-`` prefix, and the remaining arguments will be assumed to
+be positional::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('-f', '--foo')
+ >>> parser.add_argument('bar')
+ >>> parser.parse_args(['BAR'])
+ Namespace(bar='BAR', foo=None)
+ >>> parser.parse_args(['BAR', '--foo', 'FOO'])
+ Namespace(bar='BAR', foo='FOO')
+ >>> parser.parse_args(['--foo', 'FOO'])
+ usage: PROG [-h] [-f FOO] bar
+ PROG: error: too few arguments
+
+
+action
+^^^^^^
+
+:class:`ArgumentParser` objects associate command-line args with actions. These
+actions can do just about anything with the command-line args associated with
+them, though most actions simply add an attribute to the object returned by
+:meth:`~ArgumentParser.parse_args`. The ``action`` keyword argument specifies
+how the command-line args should be handled. The supported actions are:
+
+* ``'store'`` - This just stores the argument's value. This is the default
+ action. For example::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo')
+ >>> parser.parse_args('--foo 1'.split())
+ Namespace(foo='1')
+
+* ``'store_const'`` - This stores the value specified by the const_ keyword
+ argument. (Note that the const_ keyword argument defaults to the rather
+ unhelpful ``None``.) The ``'store_const'`` action is most commonly used with
+ optional arguments that specify some sort of flag. For example::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo', action='store_const', const=42)
+ >>> parser.parse_args('--foo'.split())
+ Namespace(foo=42)
+
+* ``'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.parse_args('--foo --bar'.split())
+ 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.
+ Example usage::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo', action='append')
+ >>> parser.parse_args('--foo 1 --foo 2'.split())
+ Namespace(foo=['1', '2'])
+
+* ``'append_const'`` - This stores a list, and appends the value specified by
+ the const_ keyword argument to the list. (Note that the const_ keyword
+ argument defaults to ``None``.) The ``'append_const'`` action is typically
+ useful when multiple arguments need to store constants to the same list. For
+ example::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> 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'>])
+
+* ``'version'`` - This expects a ``version=`` keyword argument in the
+ :meth:`~ArgumentParser.add_argument` call, and prints version information
+ and exits when invoked.
+
+ >>> import argparse
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('--version', action='version', version='%(prog)s 2.0')
+ >>> parser.parse_args(['--version'])
+ PROG 2.0
+
+You can also specify an arbitrary action by passing an object that implements
+the Action API. The easiest way to do this is to extend
+:class:`argparse.Action`, supplying an appropriate ``__call__`` method. The
+``__call__`` method should accept four parameters:
+
+* ``parser`` - The ArgumentParser object which contains this action.
+
+* ``namespace`` - The namespace object that will be returned by
+ :meth:`~ArgumentParser.parse_args`. Most actions add an attribute to this
+ object.
+
+* ``values`` - The associated command-line args, with any type-conversions
+ applied. (Type-conversions are specified with the type_ keyword argument to
+ :meth:`~ArgumentParser.add_argument`.
+
+* ``option_string`` - The option string that was used to invoke this action.
+ The ``option_string`` argument is optional, and will be absent if the action
+ is associated with a positional argument.
+
+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))
+ ... setattr(namespace, self.dest, values)
+ ...
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo', action=FooAction)
+ >>> parser.add_argument('bar', action=FooAction)
+ >>> args = parser.parse_args('1 --foo 2'.split())
+ Namespace(bar=None, foo=None) '1' None
+ Namespace(bar='1', foo=None) '2' '--foo'
+ >>> args
+ Namespace(bar='1', foo='2')
+
+
+nargs
+^^^^^
+
+ArgumentParser objects usually associate a single command-line argument with a
+single action to be taken. The ``nargs`` keyword argument associates a
+different number of command-line arguments with a single action. The supported
+values are:
+
+* N (an integer). N args from the command line will be gathered together into a
+ list. For example::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo', nargs=2)
+ >>> parser.add_argument('bar', nargs=1)
+ >>> parser.parse_args('c --foo a b'.split())
+ Namespace(bar=['c'], foo=['a', 'b'])
+
+ Note that ``nargs=1`` produces a list of one item. This is different from
+ the default, in which the item is produced by itself.
+
+* ``'?'``. One arg will be consumed from the command line if possible, and
+ produced as a single item. If no command-line arg is present, the value from
+ default_ will be produced. Note that for optional arguments, there is an
+ additional case - the option string is present but not followed by a
+ command-line arg. In this case the value from const_ will be produced. Some
+ examples to illustrate this::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo', nargs='?', const='c', default='d')
+ >>> parser.add_argument('bar', nargs='?', default='d')
+ >>> parser.parse_args('XX --foo YY'.split())
+ Namespace(bar='XX', foo='YY')
+ >>> parser.parse_args('XX --foo'.split())
+ Namespace(bar='XX', foo='c')
+ >>> parser.parse_args(''.split())
+ Namespace(bar='d', foo='d')
+
+ One of the more common uses of ``nargs='?'`` is to allow optional input and
+ output files::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('infile', nargs='?', type=argparse.FileType('r'),
+ ... default=sys.stdin)
+ >>> parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'),
+ ... default=sys.stdout)
+ >>> parser.parse_args(['input.txt', 'output.txt'])
+ Namespace(infile=<_io.TextIOWrapper name='input.txt' encoding='UTF-8'>,
+ outfile=<_io.TextIOWrapper name='output.txt' encoding='UTF-8'>)
+ >>> parser.parse_args([])
+ Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>,
+ outfile=<_io.TextIOWrapper name='<stdout>' encoding='UTF-8'>)
+
+* ``'*'``. All command-line args present are gathered into a list. Note that
+ it generally doesn't make much sense to have more than one positional argument
+ with ``nargs='*'``, but multiple optional arguments with ``nargs='*'`` is
+ possible. For example::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo', nargs='*')
+ >>> parser.add_argument('--bar', nargs='*')
+ >>> parser.add_argument('baz', nargs='*')
+ >>> parser.parse_args('a b --foo x y --bar 1 2'.split())
+ Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
+
+* ``'+'``. Just like ``'*'``, all command-line args present are gathered into a
+ list. Additionally, an error message will be generated if there wasn't at
+ least one command-line arg present. For example::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('foo', nargs='+')
+ >>> parser.parse_args('a b'.split())
+ Namespace(foo=['a', 'b'])
+ >>> parser.parse_args(''.split())
+ usage: PROG [-h] foo [foo ...]
+ PROG: error: too few arguments
+
+If the ``nargs`` keyword argument is not provided, the number of args consumed
+is determined by the action_. Generally this means a single command-line arg
+will be consumed and a single item (not a list) will be produced.
+
+
+const
+^^^^^
+
+The ``const`` argument of :meth:`~ArgumentParser.add_argument` is used to hold
+constant values that are not read from the command line but are required for
+the various :class:`ArgumentParser` actions. The two most common uses of it are:
+
+* When :meth:`~ArgumentParser.add_argument` is called with
+ ``action='store_const'`` or ``action='append_const'``. These actions add the
+ ``const`` value to one of the attributes of the object returned by :meth:`~ArgumentParser.parse_args`. See the action_ description for examples.
+
+* When :meth:`~ArgumentParser.add_argument` is called with option strings
+ (like ``-f`` or ``--foo``) and ``nargs='?'``. This creates an optional
+ argument that can be followed by zero or one command-line args.
+ When parsing the command line, if the option string is encountered with no
+ command-line arg following it, the value of ``const`` will be assumed instead.
+ See the nargs_ description for examples.
+
+The ``const`` keyword argument defaults to ``None``.
+
+
+default
+^^^^^^^
+
+All optional arguments and some positional arguments may be omitted at the
+command line. The ``default`` keyword argument of
+:meth:`~ArgumentParser.add_argument`, whose value defaults to ``None``,
+specifies what value should be used if the command-line arg is not present.
+For optional arguments, the ``default`` value is used when the option string
+was not present at the command line::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo', default=42)
+ >>> parser.parse_args('--foo 2'.split())
+ Namespace(foo='2')
+ >>> parser.parse_args(''.split())
+ Namespace(foo=42)
+
+For positional arguments with nargs_ ``='?'`` or ``'*'``, the ``default`` value
+is used when no command-line arg was present::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('foo', nargs='?', default=42)
+ >>> parser.parse_args('a'.split())
+ Namespace(foo='a')
+ >>> parser.parse_args(''.split())
+ Namespace(foo=42)
+
+
+Providing ``default=argparse.SUPPRESS`` causes no attribute to be added if the
+command-line argument was not present.::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo', default=argparse.SUPPRESS)
+ >>> parser.parse_args([])
+ Namespace()
+ >>> parser.parse_args(['--foo', '1'])
+ Namespace(foo='1')
+
+
+type
+^^^^
+
+By default, :class:`ArgumentParser` objects read command-line args in as simple
+strings. However, quite often the command-line string should instead be
+interpreted as another type, like a :class:`float` or :class:`int`. The
+``type`` keyword argument of :meth:`~ArgumentParser.add_argument` allows any
+necessary type-checking and type-conversions to be performed. Common built-in
+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=open)
+ >>> parser.parse_args('2 temp.txt'.split())
+ Namespace(bar=<_io.TextIOWrapper name='temp.txt' encoding='UTF-8'>, foo=2)
+
+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
+: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=<_io.TextIOWrapper name='out.txt' encoding='UTF-8'>)
+
+``type=`` can take any callable that takes a single string argument and returns
+the type-converted value::
+
+ >>> def perfect_square(string):
+ ... value = int(string)
+ ... sqrt = math.sqrt(value)
+ ... if sqrt != int(sqrt):
+ ... msg = "%r is not a perfect square" % string
+ ... raise argparse.ArgumentTypeError(msg)
+ ... return value
+ ...
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('foo', type=perfect_square)
+ >>> parser.parse_args('9'.split())
+ Namespace(foo=9)
+ >>> parser.parse_args('7'.split())
+ usage: PROG [-h] foo
+ PROG: error: argument foo: '7' is not a perfect square
+
+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=range(5, 10))
+ >>> parser.parse_args('7'.split())
+ Namespace(foo=7)
+ >>> parser.parse_args('11'.split())
+ usage: PROG [-h] {5,6,7,8,9}
+ PROG: error: argument foo: invalid choice: 11 (choose from 5, 6, 7, 8, 9)
+
+See the choices_ section for more details.
+
+
+choices
+^^^^^^^
+
+Some command-line args should be selected from a restricted set of values.
+These can be handled by passing a container object as the ``choices`` keyword
+argument to :meth:`~ArgumentParser.add_argument`. When the command line is
+parsed, arg values will be checked, and an error message will be displayed if
+the arg was not one of the acceptable values::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('foo', choices='abc')
+ >>> parser.parse_args('c'.split())
+ Namespace(foo='c')
+ >>> parser.parse_args('X'.split())
+ usage: PROG [-h] {a,b,c}
+ PROG: error: argument foo: invalid choice: 'X' (choose from 'a', 'b', 'c')
+
+Note that inclusion in the ``choices`` container is checked after any type_
+conversions have been performed, so the type of the objects in the ``choices``
+container should match the type_ specified::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('foo', type=complex, choices=[1, 1j])
+ >>> parser.parse_args('1j'.split())
+ Namespace(foo=1j)
+ >>> parser.parse_args('-- -4'.split())
+ usage: PROG [-h] {1,1j}
+ PROG: error: argument foo: invalid choice: (-4+0j) (choose from 1, 1j)
+
+Any object that supports the ``in`` operator can be passed as the ``choices``
+value, so :class:`dict` objects, :class:`set` objects, custom containers,
+etc. are all supported.
+
+
+required
+^^^^^^^^
+
+In general, the :mod:`argparse` module assumes that flags like ``-f`` and ``--bar``
+indicate *optional* arguments, which can always be omitted at the command line.
+To make an option *required*, ``True`` can be specified for the ``required=``
+keyword argument to :meth:`~ArgumentParser.add_argument`::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo', required=True)
+ >>> parser.parse_args(['--foo', 'BAR'])
+ Namespace(foo='BAR')
+ >>> parser.parse_args([])
+ usage: argparse.py [-h] [--foo FOO]
+ argparse.py: error: option --foo is required
+
+As the example shows, if an option is marked as ``required``,
+:meth:`~ArgumentParser.parse_args` will report an error if that option is not
+present at the command line.
+
+.. note::
+
+ Required options are generally considered bad form because users expect
+ *options* to be *optional*, and thus they should be avoided when possible.
+
+
+help
+^^^^
+
+The ``help`` value is a string containing a brief description of the argument.
+When a user requests help (usually by using ``-h`` or ``--help`` at the
+command line), these ``help`` descriptions will be displayed with each
+argument::
+
+ >>> parser = argparse.ArgumentParser(prog='frobble')
+ >>> parser.add_argument('--foo', action='store_true',
+ ... help='foo the bars before frobbling')
+ >>> parser.add_argument('bar', nargs='+',
+ ... help='one of the bars to be frobbled')
+ >>> parser.parse_args('-h'.split())
+ usage: frobble [-h] [--foo] bar [bar ...]
+
+ positional arguments:
+ bar one of the bars to be frobbled
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --foo foo the bars before frobbling
+
+The ``help`` strings can include various format specifiers to avoid repetition
+of things like the program name or the argument default_. The available
+specifiers include the program name, ``%(prog)s`` and most keyword arguments to
+:meth:`~ArgumentParser.add_argument`, e.g. ``%(default)s``, ``%(type)s``, etc.::
+
+ >>> parser = argparse.ArgumentParser(prog='frobble')
+ >>> parser.add_argument('bar', nargs='?', type=int, default=42,
+ ... help='the bar to %(prog)s (default: %(default)s)')
+ >>> parser.print_help()
+ usage: frobble [-h] [bar]
+
+ positional arguments:
+ bar the bar to frobble (default: 42)
+
+ optional arguments:
+ -h, --help show this help message and exit
+
+
+metavar
+^^^^^^^
+
+When :class:`ArgumentParser` generates help messages, it need some way to refer
+to each expected argument. By default, ArgumentParser objects use the dest_
+value as the "name" of each object. By default, for positional argument
+actions, the dest_ value is used directly, and for optional argument actions,
+the dest_ value is uppercased. So, a single positional argument with
+``dest='bar'`` will that argument will be referred to as ``bar``. A single
+optional argument ``--foo`` that should be followed by a single command-line arg
+will be referred to as ``FOO``. An example::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo')
+ >>> parser.add_argument('bar')
+ >>> parser.parse_args('X --foo Y'.split())
+ Namespace(bar='X', foo='Y')
+ >>> parser.print_help()
+ usage: [-h] [--foo FOO] bar
+
+ positional arguments:
+ bar
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --foo FOO
+
+An alternative name can be specified with ``metavar``::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo', metavar='YYY')
+ >>> parser.add_argument('bar', metavar='XXX')
+ >>> parser.parse_args('X --foo Y'.split())
+ Namespace(bar='X', foo='Y')
+ >>> parser.print_help()
+ usage: [-h] [--foo YYY] XXX
+
+ positional arguments:
+ XXX
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --foo YYY
+
+Note that ``metavar`` only changes the *displayed* name - the name of the
+attribute on the :meth:`~ArgumentParser.parse_args` object is still determined
+by the dest_ value.
+
+Different values of ``nargs`` may cause the metavar to be used multiple times.
+Providing a tuple to ``metavar`` specifies a different display for each of the
+arguments::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('-x', nargs=2)
+ >>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz'))
+ >>> parser.print_help()
+ usage: PROG [-h] [-x X X] [--foo bar baz]
+
+ optional arguments:
+ -h, --help show this help message and exit
+ -x X X
+ --foo bar baz
+
+
+dest
+^^^^
+
+Most :class:`ArgumentParser` actions add some value as an attribute of the
+object returned by :meth:`~ArgumentParser.parse_args`. The name of this
+attribute is determined by the ``dest`` keyword argument of
+:meth:`~ArgumentParser.add_argument`. For positional argument actions,
+``dest`` is normally supplied as the first argument to
+:meth:`~ArgumentParser.add_argument`::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('bar')
+ >>> parser.parse_args('XXX'.split())
+ Namespace(bar='XXX')
+
+For optional argument actions, the value of ``dest`` is normally inferred from
+the option strings. :class:`ArgumentParser` generates the value of ``dest`` by
+taking the first long option string and stripping away the initial ``'--'``
+string. If no long option strings were supplied, ``dest`` will be derived from
+the first short option string by stripping the initial ``'-'`` character. Any
+internal ``'-'`` characters will be converted to ``'_'`` characters to make sure
+the string is a valid attribute name. The examples below illustrate this
+behavior::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('-f', '--foo-bar', '--foo')
+ >>> parser.add_argument('-x', '-y')
+ >>> parser.parse_args('-f 1 -x 2'.split())
+ Namespace(foo_bar='1', x='2')
+ >>> parser.parse_args('--foo 1 -y 2'.split())
+ Namespace(foo_bar='1', x='2')
+
+``dest`` allows a custom attribute name to be provided::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo', dest='bar')
+ >>> parser.parse_args('--foo XXX'.split())
+ Namespace(bar='XXX')
+
+
+The parse_args() method
+-----------------------
+
+.. method:: ArgumentParser.parse_args(args=None, namespace=None)
+
+ Convert argument strings to objects and assign them as attributes of the
+ namespace. Return the populated namespace.
+
+ Previous calls to :meth:`add_argument` determine exactly what objects are
+ created and how they are assigned. See the documentation for
+ :meth:`add_argument` for details.
+
+ By default, the arg strings are taken from :data:`sys.argv`, and a new empty
+ :class:`Namespace` object is created for the attributes.
+
+
+Option value syntax
+^^^^^^^^^^^^^^^^^^^
+
+The :meth:`~ArgumentParser.parse_args` method supports several ways of
+specifying the value of an option (if it takes one). In the simplest case, the
+option and its value are passed as two separate arguments::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('-x')
+ >>> parser.add_argument('--foo')
+ >>> parser.parse_args('-x X'.split())
+ Namespace(foo=None, x='X')
+ >>> parser.parse_args('--foo FOO'.split())
+ Namespace(foo='FOO', x=None)
+
+For long options (options with names longer than a single character), the option
+and value can also be passed as a single command-line argument, using ``=`` to
+separate them::
+
+ >>> parser.parse_args('--foo=FOO'.split())
+ Namespace(foo='FOO', x=None)
+
+For short options (options only one character long), the option and its value
+can be concatenated::
+
+ >>> parser.parse_args('-xX'.split())
+ Namespace(foo=None, x='X')
+
+Several short options can be joined together, using only a single ``-`` prefix,
+as long as only the last option (or none of them) requires a value::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('-x', action='store_true')
+ >>> parser.add_argument('-y', action='store_true')
+ >>> parser.add_argument('-z')
+ >>> parser.parse_args('-xyzZ'.split())
+ Namespace(x=True, y=True, z='Z')
+
+
+Invalid arguments
+^^^^^^^^^^^^^^^^^
+
+While parsing the command line, :meth:`~ArgumentParser.parse_args` checks for a
+variety of errors, including ambiguous options, invalid types, invalid options,
+wrong number of positional arguments, etc. When it encounters such an error,
+it exits and prints the error along with a usage message::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('--foo', type=int)
+ >>> parser.add_argument('bar', nargs='?')
+
+ >>> # invalid type
+ >>> parser.parse_args(['--foo', 'spam'])
+ usage: PROG [-h] [--foo FOO] [bar]
+ PROG: error: argument --foo: invalid int value: 'spam'
+
+ >>> # invalid option
+ >>> parser.parse_args(['--bar'])
+ usage: PROG [-h] [--foo FOO] [bar]
+ PROG: error: no such option: --bar
+
+ >>> # wrong number of arguments
+ >>> parser.parse_args(['spam', 'badger'])
+ usage: PROG [-h] [--foo FOO] [bar]
+ PROG: error: extra arguments found: badger
+
+
+Arguments containing ``"-"``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The :meth:`~ArgumentParser.parse_args` method attempts to give errors whenever
+the user has clearly made a mistake, but some situations are inherently
+ambiguous. For example, the command-line arg ``'-1'`` could either be an
+attempt to specify an option or an attempt to provide a positional argument.
+The :meth:`~ArgumentParser.parse_args` method is cautious here: positional
+arguments may only begin with ``'-'`` if they look like negative numbers and
+there are no options in the parser that look like negative numbers::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('-x')
+ >>> parser.add_argument('foo', nargs='?')
+
+ >>> # no negative number options, so -1 is a positional argument
+ >>> parser.parse_args(['-x', '-1'])
+ Namespace(foo=None, x='-1')
+
+ >>> # no negative number options, so -1 and -5 are positional arguments
+ >>> parser.parse_args(['-x', '-1', '-5'])
+ Namespace(foo='-5', x='-1')
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('-1', dest='one')
+ >>> parser.add_argument('foo', nargs='?')
+
+ >>> # negative number options present, so -1 is an option
+ >>> parser.parse_args(['-1', 'X'])
+ Namespace(foo=None, one='X')
+
+ >>> # negative number options present, so -2 is an option
+ >>> parser.parse_args(['-2'])
+ usage: PROG [-h] [-1 ONE] [foo]
+ PROG: error: no such option: -2
+
+ >>> # negative number options present, so both -1s are options
+ >>> parser.parse_args(['-1', '-1'])
+ usage: PROG [-h] [-1 ONE] [foo]
+ PROG: error: argument -1: expected one argument
+
+If you have positional arguments that must begin with ``'-'`` and don't look
+like negative numbers, you can insert the pseudo-argument ``'--'`` which tells
+:meth:`~ArgumentParser.parse_args` that everything after that is a positional
+argument::
+
+ >>> parser.parse_args(['--', '-f'])
+ Namespace(foo='-f', one=None)
+
+
+Argument abbreviations
+^^^^^^^^^^^^^^^^^^^^^^
+
+The :meth:`~ArgumentParser.parse_args` method allows long options to be
+abbreviated if the abbreviation is unambiguous::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('-bacon')
+ >>> parser.add_argument('-badger')
+ >>> parser.parse_args('-bac MMM'.split())
+ Namespace(bacon='MMM', badger=None)
+ >>> parser.parse_args('-bad WOOD'.split())
+ Namespace(bacon=None, badger='WOOD')
+ >>> parser.parse_args('-ba BA'.split())
+ usage: PROG [-h] [-bacon BACON] [-badger BADGER]
+ PROG: error: ambiguous option: -ba could match -badger, -bacon
+
+An error is produced for arguments that could produce more than one options.
+
+
+Beyond ``sys.argv``
+^^^^^^^^^^^^^^^^^^^
+
+Sometimes it may be useful to have an ArgumentParser parse args other than those
+of :data:`sys.argv`. This can be accomplished by passing a list of strings to
+:meth:`~ArgumentParser.parse_args`. This is useful for testing at the
+interactive prompt::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument(
+ ... '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,
+ ... default=max, help='sum the integers (default: find the max)')
+ >>> parser.parse_args(['1', '2', '3', '4'])
+ Namespace(accumulate=<built-in function max>, integers=[1, 2, 3, 4])
+ >>> parser.parse_args('1 2 3 4 --sum'.split())
+ Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])
+
+
+The Namespace object
+^^^^^^^^^^^^^^^^^^^^
+
+By default, :meth:`~ArgumentParser.parse_args` will return a new object of type
+:class:`Namespace` where the necessary attributes have been set. This class is
+deliberately simple, just an :class:`object` subclass with a readable string
+representation. If you prefer to have dict-like view of the attributes, you
+can use the standard Python idiom via :func:`vars`::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo')
+ >>> args = parser.parse_args(['--foo', 'BAR'])
+ >>> vars(args)
+ {'foo': 'BAR'}
+
+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:
+ ... pass
+ ...
+ >>> c = C()
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo')
+ >>> parser.parse_args(args=['--foo', 'BAR'], namespace=c)
+ >>> c.foo
+ 'BAR'
+
+
+Other utilities
+---------------
+
+Sub-commands
+^^^^^^^^^^^^
+
+.. method:: ArgumentParser.add_subparsers()
+
+ Many programs split up their functionality into a number of sub-commands,
+ for example, the ``svn`` program can invoke sub-commands like ``svn
+ checkout``, ``svn update``, and ``svn commit``. Splitting up functionality
+ this way can be a particularly good idea when a program performs several
+ different functions which require different kinds of command-line arguments.
+ :class:`ArgumentParser` supports the creation of such sub-commands with the
+ :meth:`add_subparsers` method. The :meth:`add_subparsers` method is normally
+ called with no arguments and returns an special action object. This object
+ has a single method, :meth:`~ArgumentParser.add_parser`, which takes a
+ command name and any :class:`ArgumentParser` constructor arguments, and
+ returns an :class:`ArgumentParser` object that can be modified as usual.
+
+ Some example usage::
+
+ >>> # create the top-level parser
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> parser.add_argument('--foo', action='store_true', help='foo help')
+ >>> subparsers = parser.add_subparsers(help='sub-command help')
+ >>>
+ >>> # create the parser for the "a" command
+ >>> parser_a = subparsers.add_parser('a', help='a help')
+ >>> parser_a.add_argument('bar', type=int, help='bar help')
+ >>>
+ >>> # create the parser for the "b" command
+ >>> parser_b = subparsers.add_parser('b', help='b help')
+ >>> parser_b.add_argument('--baz', choices='XYZ', help='baz help')
+ >>>
+ >>> # parse some arg lists
+ >>> parser.parse_args(['a', '12'])
+ Namespace(bar=12, foo=False)
+ >>> parser.parse_args(['--foo', 'b', '--baz', 'Z'])
+ Namespace(baz='Z', foo=True)
+
+ Note that the object returned by :meth:`parse_args` will only contain
+ attributes for the main parser and the subparser that was selected by the
+ command line (and not any other subparsers). So in the example above, when
+ the ``"a"`` command is specified, only the ``foo`` and ``bar`` attributes are
+ present, and when the ``"b"`` command is specified, only the ``foo`` and
+ ``baz`` attributes are present.
+
+ Similarly, when a help message is requested from a subparser, only the help
+ for that particular parser will be printed. The help message will not
+ include parent parser or sibling parser messages. (A help message for each
+ subparser command, however, can be given by supplying the ``help=`` argument
+ to :meth:`add_parser` as above.)
+
+ ::
+
+ >>> parser.parse_args(['--help'])
+ usage: PROG [-h] [--foo] {a,b} ...
+
+ positional arguments:
+ {a,b} sub-command help
+ a a help
+ b b help
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --foo foo help
+
+ >>> parser.parse_args(['a', '--help'])
+ usage: PROG a [-h] bar
+
+ positional arguments:
+ bar bar help
+
+ optional arguments:
+ -h, --help show this help message and exit
+
+ >>> parser.parse_args(['b', '--help'])
+ usage: PROG b [-h] [--baz {X,Y,Z}]
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --baz {X,Y,Z} baz help
+
+ The :meth:`add_subparsers` method also supports ``title`` and ``description``
+ keyword arguments. When either is present, the subparser's commands will
+ appear in their own group in the help output. For example::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> subparsers = parser.add_subparsers(title='subcommands',
+ ... description='valid subcommands',
+ ... help='additional help')
+ >>> subparsers.add_parser('foo')
+ >>> subparsers.add_parser('bar')
+ >>> parser.parse_args(['-h'])
+ usage: [-h] {foo,bar} ...
+
+ optional arguments:
+ -h, --help show this help message and exit
+
+ subcommands:
+ valid subcommands
+
+ {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
+ that each subparser knows which Python function it should execute. For
+ example::
+
+ >>> # sub-command functions
+ >>> def foo(args):
+ ... print(args.x * args.y)
+ ...
+ >>> def bar(args):
+ ... print('((%s))' % args.z)
+ ...
+ >>> # create the top-level parser
+ >>> parser = argparse.ArgumentParser()
+ >>> subparsers = parser.add_subparsers()
+ >>>
+ >>> # create the parser for the "foo" command
+ >>> parser_foo = subparsers.add_parser('foo')
+ >>> parser_foo.add_argument('-x', type=int, default=1)
+ >>> parser_foo.add_argument('y', type=float)
+ >>> parser_foo.set_defaults(func=foo)
+ >>>
+ >>> # create the parser for the "bar" command
+ >>> parser_bar = subparsers.add_parser('bar')
+ >>> parser_bar.add_argument('z')
+ >>> parser_bar.set_defaults(func=bar)
+ >>>
+ >>> # parse the args and call whatever function was selected
+ >>> args = parser.parse_args('foo 1 -x 2'.split())
+ >>> args.func(args)
+ 2.0
+ >>>
+ >>> # parse the args and call whatever function was selected
+ >>> args = parser.parse_args('bar XYZYX'.split())
+ >>> args.func(args)
+ ((XYZYX))
+
+ This way, you can let :meth:`parse_args` do the job of calling the
+ appropriate function after argument parsing is complete. Associating
+ functions with actions like this is typically the easiest way to handle the
+ different actions for each of your subparsers. However, if it is necessary
+ to check the name of the subparser that was invoked, the ``dest`` keyword
+ argument to the :meth:`add_subparsers` call will work::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> subparsers = parser.add_subparsers(dest='subparser_name')
+ >>> subparser1 = subparsers.add_parser('1')
+ >>> subparser1.add_argument('-x')
+ >>> subparser2 = subparsers.add_parser('2')
+ >>> subparser2.add_argument('y')
+ >>> parser.parse_args(['2', 'frobble'])
+ Namespace(subparser_name='2', y='frobble')
+
+
+FileType objects
+^^^^^^^^^^^^^^^^
+
+.. class:: FileType(mode='r', bufsize=None)
+
+ The :class:`FileType` factory creates objects that can be passed to the type
+ argument of :meth:`ArgumentParser.add_argument`. Arguments that have
+ :class:`FileType` objects as their type will open command-line args as files
+ with the requested modes and buffer sizes:
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--output', type=argparse.FileType('wb', 0))
+ >>> parser.parse_args(['--output', 'out'])
+ 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
+ ``sys.stdout`` for writable :class:`FileType` objects:
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('infile', type=argparse.FileType('r'))
+ >>> parser.parse_args(['-'])
+ Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>)
+
+
+Argument groups
+^^^^^^^^^^^^^^^
+
+.. method:: ArgumentParser.add_argument_group(title=None, description=None)
+
+ By default, :class:`ArgumentParser` groups command-line arguments into
+ "positional arguments" and "optional arguments" when displaying help
+ messages. When there is a better conceptual grouping of arguments than this
+ default one, appropriate groups can be created using the
+ :meth:`add_argument_group` method::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
+ >>> group = parser.add_argument_group('group')
+ >>> group.add_argument('--foo', help='foo help')
+ >>> group.add_argument('bar', help='bar help')
+ >>> parser.print_help()
+ usage: PROG [--foo FOO] bar
+
+ group:
+ bar bar help
+ --foo FOO foo help
+
+ The :meth:`add_argument_group` method returns an argument group object which
+ has an :meth:`~ArgumentParser.add_argument` method just like a regular
+ :class:`ArgumentParser`. When an argument is added to the group, the parser
+ treats it just like a normal argument, but displays the argument in a
+ separate group for help messages. The :meth:`add_argument_group` method
+ accepts *title* and *description* arguments which can be used to
+ customize this display::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
+ >>> group1 = parser.add_argument_group('group1', 'group1 description')
+ >>> group1.add_argument('foo', help='foo help')
+ >>> group2 = parser.add_argument_group('group2', 'group2 description')
+ >>> group2.add_argument('--bar', help='bar help')
+ >>> parser.print_help()
+ usage: PROG [--bar BAR] foo
+
+ group1:
+ group1 description
+
+ foo foo help
+
+ group2:
+ group2 description
+
+ --bar BAR bar help
+
+ Note that any arguments not your user defined groups will end up back in the
+ usual "positional arguments" and "optional arguments" sections.
+
+
+Mutual exclusion
+^^^^^^^^^^^^^^^^
+
+.. method:: add_mutually_exclusive_group(required=False)
+
+ Create a mutually exclusive group. :mod:`argparse` will make sure that only
+ one of the arguments in the mutually exclusive group was present on the
+ command line::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> group = parser.add_mutually_exclusive_group()
+ >>> group.add_argument('--foo', action='store_true')
+ >>> group.add_argument('--bar', action='store_false')
+ >>> parser.parse_args(['--foo'])
+ Namespace(bar=True, foo=True)
+ >>> parser.parse_args(['--bar'])
+ Namespace(bar=False, foo=False)
+ >>> parser.parse_args(['--foo', '--bar'])
+ usage: PROG [-h] [--foo | --bar]
+ PROG: error: argument --bar: not allowed with argument --foo
+
+ The :meth:`add_mutually_exclusive_group` method also accepts a *required*
+ argument, to indicate that at least one of the mutually exclusive arguments
+ is required::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG')
+ >>> group = parser.add_mutually_exclusive_group(required=True)
+ >>> group.add_argument('--foo', action='store_true')
+ >>> group.add_argument('--bar', action='store_false')
+ >>> parser.parse_args([])
+ usage: PROG [-h] (--foo | --bar)
+ PROG: error: one of the arguments --foo --bar is required
+
+ Note that currently mutually exclusive argument groups do not support the
+ *title* and *description* arguments of
+ :meth:`~ArgumentParser.add_argument_group`.
+
+
+Parser defaults
+^^^^^^^^^^^^^^^
+
+.. method:: ArgumentParser.set_defaults(**kwargs)
+
+ Most of the time, the attributes of the object returned by :meth:`parse_args`
+ will be fully determined by inspecting the command-line args and the argument
+ actions. :meth:`set_defaults` allows some additional
+ attributes that are determined without any inspection of the command line to
+ be added::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('foo', type=int)
+ >>> parser.set_defaults(bar=42, baz='badger')
+ >>> parser.parse_args(['736'])
+ Namespace(bar=42, baz='badger', foo=736)
+
+ Note that parser-level defaults always override argument-level defaults::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo', default='bar')
+ >>> parser.set_defaults(foo='spam')
+ >>> parser.parse_args([])
+ Namespace(foo='spam')
+
+ Parser-level defaults can be particularly useful when working with multiple
+ parsers. See the :meth:`~ArgumentParser.add_subparsers` method for an
+ example of this type.
+
+.. method:: ArgumentParser.get_default(dest)
+
+ Get the default value for a namespace attribute, as set by either
+ :meth:`~ArgumentParser.add_argument` or by
+ :meth:`~ArgumentParser.set_defaults`::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo', default='badger')
+ >>> parser.get_default('foo')
+ 'badger'
+
+
+Printing help
+^^^^^^^^^^^^^
+
+In most typical applications, :meth:`~ArgumentParser.parse_args` will take
+care of formatting and printing any usage or error messages. However, several
+formatting methods are available:
+
+.. method:: ArgumentParser.print_usage(file=None)
+
+ Print a brief description of how the :class:`ArgumentParser` should be
+ invoked on the command line. If *file* is ``None``, :data:`sys.stdout` is
+ assumed.
+
+.. method:: ArgumentParser.print_help(file=None)
+
+ Print a help message, including the program usage and information about the
+ arguments registered with the :class:`ArgumentParser`. If *file* is
+ ``None``, :data:`sys.stdout` is assumed.
+
+There are also variants of these methods that simply return a string instead of
+printing it:
+
+.. method:: ArgumentParser.format_usage()
+
+ Return a string containing a brief description of how the
+ :class:`ArgumentParser` should be invoked on the command line.
+
+.. method:: ArgumentParser.format_help()
+
+ Return a string containing a help message, including the program usage and
+ information about the arguments registered with the :class:`ArgumentParser`.
+
+
+Partial parsing
+^^^^^^^^^^^^^^^
+
+.. method:: ArgumentParser.parse_known_args(args=None, namespace=None)
+
+Sometimes a script may only parse a few of the command-line arguments, passing
+the remaining arguments on to another script or program. In these cases, the
+:meth:`~ArgumentParser.parse_known_args` method can be useful. It works much like
+:meth:`~ArgumentParser.parse_args` except that it does not produce an error when
+extra arguments are present. Instead, it returns a two item tuple containing
+the populated namespace and the list of remaining argument strings.
+
+::
+
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--foo', action='store_true')
+ >>> parser.add_argument('bar')
+ >>> parser.parse_known_args(['--foo', '--badger', 'BAR', 'spam'])
+ (Namespace(bar='BAR', foo=True), ['--badger', 'spam'])
+
+
+Customizing file parsing
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. method:: ArgumentParser.convert_arg_line_to_args(arg_line)
+
+ Arguments that are read from a file (see the *fromfile_prefix_chars*
+ keyword argument to the :class:`ArgumentParser` constructor) are read one
+ argument per line. :meth:`convert_arg_line_to_args` can be overriden for
+ fancier reading.
+
+ This method takes a single argument *arg_line* which is a string read from
+ the argument file. It returns a list of arguments parsed from this string.
+ The method is called once per line read from the argument file, in order.
+
+ A useful override of this method is one that treats each space-separated word
+ as an argument::
+
+ def convert_arg_line_to_args(self, arg_line):
+ for arg in arg_line.split():
+ if not arg.strip():
+ continue
+ yield arg
+
+
+Exiting methods
+^^^^^^^^^^^^^^^
+
+.. method:: ArgumentParser.exit(status=0, message=None)
+
+ This method terminates the program, exiting with the specified *status*
+ and, if given, it prints a *message* before that.
+
+.. method:: ArgumentParser.error(message)
+
+ This method prints a usage message including the *message* to the
+ standard output and terminates the program with a status code of 2.
+
+.. _upgrading-optparse-code:
+
+Upgrading optparse code
+-----------------------
+
+Originally, the :mod:`argparse` module had attempted to maintain compatibility
+with :mod:`optparse`. However, :mod:`optparse` was difficult to extend
+transparently, particularly with the changes required to support the new
+``nargs=`` specifiers and better usage messages. When most everything in
+:mod:`optparse` had either been copy-pasted over or monkey-patched, it no
+longer seemed practical to try to maintain the backwards compatibility.
+
+A partial upgrade path from :mod:`optparse` to :mod:`argparse`:
+
+* Replace all :meth:`optparse.OptionParser.add_option` calls with
+ :meth:`ArgumentParser.add_argument` calls.
+
+* Replace ``options, args = parser.parse_args()`` with ``args =
+ parser.parse_args()`` and add additional :meth:`ArgumentParser.add_argument`
+ calls for the positional arguments.
+
+* Replace callback actions and the ``callback_*`` keyword arguments with
+ ``type`` or ``action`` arguments.
+
+* Replace string names for ``type`` keyword arguments with the corresponding
+ type objects (e.g. int, float, complex, etc).
+
+* Replace :class:`optparse.Values` with :class:`Namespace` and
+ :exc:`optparse.OptionError` and :exc:`optparse.OptionValueError` with
+ :exc:`ArgumentError`.
+
+* Replace strings with implicit arguments such as ``%default`` or ``%prog`` with
+ the standard Python syntax to use dictionaries to format strings, that is,
+ ``%(default)s`` and ``%(prog)s``.
+
+* Replace the OptionParser constructor ``version`` argument with a call to
+ ``parser.add_argument('--version', action='version', version='<the version>')``
diff --git a/Doc/library/array.rst b/Doc/library/array.rst
index 3ffc64d..d563cce 100644
--- a/Doc/library/array.rst
+++ b/Doc/library/array.rst
@@ -60,7 +60,7 @@ The module defines the following type:
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.
@@ -99,7 +99,7 @@ The following data items and methods are also supported:
memory buffer in bytes can be computed as ``array.buffer_info()[1] *
array.itemsize``. This is occasionally useful when working with low-level (and
inherently unsafe) I/O interfaces that require memory addresses, such as certain
- :cfunc:`ioctl` operations. The returned numbers are valid as long as the array
+ :c:func:`ioctl` operations. The returned numbers are valid as long as the array
exists and no length-changing operations are applied to it.
.. note::
@@ -132,6 +132,15 @@ The following data items and methods are also supported:
must be the right type to be appended to the 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 :term:`file object` *f* and append
@@ -147,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.
@@ -190,6 +198,16 @@ 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 :term:`file object` *f*.
@@ -202,15 +220,13 @@ 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.
diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst
index 08ee714..e2c0b6d 100644
--- a/Doc/library/ast.rst
+++ b/Doc/library/ast.rst
@@ -7,6 +7,9 @@
.. sectionauthor:: Martin v. Löwis <martin@v.loewis.de>
.. sectionauthor:: Georg Brandl <georg@python.org>
+**Source code:** :source:`Lib/ast.py`
+
+--------------
The :mod:`ast` module helps Python applications to process trees of the Python
abstract syntax grammar. The abstract syntax itself might change with each
@@ -117,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 3b8eb12..75b3cda 100644
--- a/Doc/library/asynchat.rst
+++ b/Doc/library/asynchat.rst
@@ -6,6 +6,9 @@
.. moduleauthor:: Sam Rushing <rushing@nightmare.com>
.. sectionauthor:: Steve Holden <sholden@holdenweb.com>
+**Source code:** :source:`Lib/asynchat.py`
+
+--------------
This module builds on the :mod:`asyncore` infrastructure, simplifying
asynchronous clients and servers and making it easier to handle protocols
@@ -31,7 +34,7 @@ connection requests.
Like :class:`asyncore.dispatcher`, :class:`async_chat` defines a set of
events that are generated by an analysis of socket conditions after a
- :cfunc:`select` call. Once the polling loop has been started the
+ :c:func:`select` call. Once the polling loop has been started the
:class:`async_chat` object's methods are called by the event-processing
framework with no action on the part of the programmer.
diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst
index b6fe2bb..5f95d41 100644
--- a/Doc/library/asyncore.rst
+++ b/Doc/library/asyncore.rst
@@ -9,6 +9,9 @@
.. sectionauthor:: Steve Holden <sholden@holdenweb.com>
.. heavily adapted from original documentation by Sam Rushing
+**Source code:** :source:`Lib/asyncore.py`
+
+--------------
This module provides the basic infrastructure for writing asynchronous socket
service clients and servers.
@@ -22,7 +25,7 @@ bound. If your program is processor bound, then pre-emptive scheduled threads
are probably what you really need. Network servers are rarely processor
bound, however.
-If your operating system supports the :cfunc:`select` system call in its I/O
+If your operating system supports the :c:func:`select` system call in its I/O
library (and nearly all do), then you can use it to juggle multiple
communication channels at once; doing other work while your I/O is taking
place in the "background." Although this strategy can seem strange and
@@ -86,14 +89,14 @@ 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 |
+----------------------+----------------------------------------+
During asynchronous processing, each mapped channel's :meth:`readable` and
:meth:`writable` methods are used to determine whether the channel's socket
- should be added to the list of channels :cfunc:`select`\ ed or
- :cfunc:`poll`\ ed for read and write events.
+ should be added to the list of channels :c:func:`select`\ ed or
+ :c:func:`poll`\ ed for read and write events.
Thus, the set of channel events is larger than the basic socket events. The
full set of methods that can be overridden in your subclass follows:
@@ -144,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. *conn* is a *new* socket object usable to
+ send and receive data on the connection, and *address* is the address
+ bound to the socket on the other end of the connection.
+
+ .. versionadded:: 3.2
.. method:: readable()
@@ -201,7 +218,8 @@ any that have been added to the map during asynchronous service) is closed.
.. method:: bind(address)
Bind the socket to *address*. The socket must not already be bound. (The
- format of *address* depends on the address family --- see above.) To mark
+ format of *address* depends on the address family --- refer to the
+ :mod:`socket` documentation for more information.) To mark
the socket as re-usable (setting the :const:`SO_REUSEADDR` option), call
the :class:`dispatcher` object's :meth:`set_reuse_addr` method.
@@ -225,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,
@@ -234,9 +253,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 :term:`file object` along
- with an optional map argument and wraps it for use with the :cfunc:`poll`
- or :cfunc:`loop` functions. If provided a file object or anything with a
- :cfunc:`fileno` method, that method will be called and passed to the
+ 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.
.. class:: file_wrapper()
@@ -283,15 +302,15 @@ 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:
asyncore Example basic echo server
----------------------------------
-Here is abasic echo server that uses the :class:`dispatcher` class to accept
+Here is a basic echo server that uses the :class:`dispatcher` class to accept
connections and dispatches the incoming connections to a handler::
import asyncore
@@ -301,7 +320,8 @@ connections and dispatches the incoming connections to a handler::
def handle_read(self):
data = self.recv(8192)
- self.send(data)
+ if data:
+ self.send(data)
class EchoServer(asyncore.dispatcher):
@@ -312,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:
- return
- 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 104c730..cc1051b 100644
--- a/Doc/library/atexit.rst
+++ b/Doc/library/atexit.rst
@@ -98,3 +98,4 @@ Usage as a :term:`decorator`::
This obviously only works with functions that don't take arguments.
+
diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst
index c10a74a..2401ae7 100644
--- a/Doc/library/base64.rst
+++ b/Doc/library/base64.rst
@@ -37,7 +37,7 @@ The modern interface provides:
The encoded byte string is returned.
-.. function:: b64decode(s, altchars=None)
+.. function:: b64decode(s, altchars=None, validate=False)
Decode a Base64 encoded byte string.
@@ -45,9 +45,13 @@ The modern interface provides:
at least length 2 (additional characters are ignored) which specifies the
alternative alphabet used instead of the ``+`` and ``/`` characters.
- 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 decoded string is returned. A `binascii.Error` 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)
diff --git a/Doc/library/bdb.rst b/Doc/library/bdb.rst
index 4795ec9..0737602 100644
--- a/Doc/library/bdb.rst
+++ b/Doc/library/bdb.rst
@@ -4,6 +4,10 @@
.. module:: bdb
:synopsis: Debugger framework.
+**Source code:** :source:`Lib/bdb.py`
+
+--------------
+
The :mod:`bdb` module handles basic debugger functions, like setting breakpoints
or managing execution via the debugger.
@@ -50,9 +54,10 @@ The :mod:`bdb` module also defines two classes:
Mark the breakpoint as disabled.
- .. method:: bpprint(out=None)
+ .. 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.
@@ -61,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)
@@ -267,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*.
diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst
index 2f7851a..2aa3702 100644
--- a/Doc/library/binascii.rst
+++ b/Doc/library/binascii.rst
@@ -18,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:
@@ -54,6 +59,9 @@ The :mod:`binascii` module defines the following functions:
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=False, istext=True, header=False)
@@ -83,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)
@@ -139,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
@@ -164,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/bisect.rst b/Doc/library/bisect.rst
index eb23159..13b0147 100644
--- a/Doc/library/bisect.rst
+++ b/Doc/library/bisect.rst
@@ -7,6 +7,10 @@
.. sectionauthor:: Raymond Hettinger <python at rcn.com>
.. example based on the PyModules FAQ entry by Aaron Watters <arw@pythonpros.com>
+**Source code:** :source:`Lib/bisect.py`
+
+--------------
+
This module provides support for maintaining a list in sorted order without
having to sort the list after each insertion. For long lists of items with
expensive comparison operations, this can be an improvement over the more common
diff --git a/Doc/library/builtins.rst b/Doc/library/builtins.rst
index f0d2a60..c495728 100644
--- a/Doc/library/builtins.rst
+++ b/Doc/library/builtins.rst
@@ -7,7 +7,7 @@
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 chapter :ref:`builtin`.
+:func:`open`.
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,
diff --git a/Doc/library/calendar.rst b/Doc/library/calendar.rst
index c8dac49..f495271 100644
--- a/Doc/library/calendar.rst
+++ b/Doc/library/calendar.rst
@@ -6,6 +6,9 @@
of the Unix cal program.
.. sectionauthor:: Drew Csillag <drew_csillag@geocities.com>
+**Source code:** :source:`Lib/calendar.py`
+
+--------------
This module allows you to output calendars like the Unix :program:`cal` program,
and provides additional useful functions related to the calendar. By default,
@@ -16,7 +19,7 @@ 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.
@@ -309,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/cgi.rst b/Doc/library/cgi.rst
index 734031d..1e2498d 100644
--- a/Doc/library/cgi.rst
+++ b/Doc/library/cgi.rst
@@ -13,6 +13,10 @@
single: URL
single: Common Gateway Interface
+**Source code:** :source:`Lib/cgi.py`
+
+--------------
+
Support module for Common Gateway Interface (CGI) scripts.
This module defines a number of utilities for use by CGI scripts written in
@@ -324,15 +328,13 @@ algorithms implemented in this module in other circumstances.
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 quotation mark
- character (``'"'``) is also translated; this helps for inclusion in an HTML
- attribute value, as in ``<A HREF="...">``. 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.
+ character (``"``) is also translated; this helps for inclusion in an HTML
+ 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:`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:
@@ -510,8 +512,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/cmath.rst b/Doc/library/cmath.rst
index 14b909b..d7778df 100644
--- a/Doc/library/cmath.rst
+++ b/Doc/library/cmath.rst
@@ -187,15 +187,24 @@ Hyperbolic functions
Classification functions
------------------------
+.. function:: isfinite(x)
+
+ Return ``True`` if both the real and imaginary parts of *x* are finite, and
+ ``False`` otherwise.
+
+ .. versionadded:: 3.2
+
+
.. function:: isinf(x)
- Return *True* if the real or the imaginary part of x is positive
- or negative infinity.
+ Return ``True`` if either the real or the imaginary part of *x* is an
+ infinity, and ``False`` otherwise.
.. function:: isnan(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 a NaN,
+ and ``False`` otherwise.
Constants
diff --git a/Doc/library/cmd.rst b/Doc/library/cmd.rst
index d789270..464764d 100644
--- a/Doc/library/cmd.rst
+++ b/Doc/library/cmd.rst
@@ -5,13 +5,15 @@
:synopsis: Build line-oriented command interpreters.
.. sectionauthor:: Eric S. Raymond <esr@snark.thyrsus.com>
+**Source code:** :source:`Lib/cmd.py`
+
+--------------
The :class:`Cmd` class provides a simple framework for writing line-oriented
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='tab', stdin=None, stdout=None)
A :class:`Cmd` instance or subclass instance is a line-oriented interpreter
@@ -203,3 +205,161 @@ Instances of :class:`Cmd` subclasses have some public instance variables:
:mod:`readline`, on systems that support it, the interpreter will automatically
support :program:`Emacs`\ -like line editing and command-history keystrokes.)
+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'
+ right(*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()
+ sys.exit(0)
+
+ # ----- 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/codecs.rst b/Doc/library/codecs.rst
index d07dafa..922bcf4 100644
--- a/Doc/library/codecs.rst
+++ b/Doc/library/codecs.rst
@@ -787,9 +787,9 @@ Encodings and Unicode
---------------------
Strings are stored internally as sequences of codepoints (to be precise
-as :ctype:`Py_UNICODE` arrays). Depending on the way Python is compiled (either
+as :c:type:`Py_UNICODE` arrays). Depending on the way Python is compiled (either
via ``--without-wide-unicode`` or ``--with-wide-unicode``, with the
-former being the default) :ctype:`Py_UNICODE` is either a 16-bit or 32-bit data
+former being the default) :c:type:`Py_UNICODE` is either a 16-bit or 32-bit data
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
string object into a sequence of bytes is called encoding and recreating the
@@ -936,6 +936,8 @@ particular, the following variants typically exist:
| cp500 | EBCDIC-CP-BE, EBCDIC-CP-CH, | Western Europe |
| | IBM500 | |
+-----------------+--------------------------------+--------------------------------+
+| cp720 | | Arabic |
++-----------------+--------------------------------+--------------------------------+
| cp737 | | Greek |
+-----------------+--------------------------------+--------------------------------+
| cp775 | IBM775 | Baltic languages |
@@ -951,6 +953,8 @@ particular, the following variants typically exist:
+-----------------+--------------------------------+--------------------------------+
| cp857 | 857, IBM857 | Turkish |
+-----------------+--------------------------------+--------------------------------+
+| cp858 | 858, IBM858 | Western Europe |
++-----------------+--------------------------------+--------------------------------+
| cp860 | 860, IBM860 | Portuguese |
+-----------------+--------------------------------+--------------------------------+
| cp861 | 861, CP-IS, IBM861 | Icelandic |
@@ -1086,7 +1090,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 |
+-----------------+--------------------------------+--------------------------------+
@@ -1110,9 +1114,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 |
+-----------------+--------------------------------+--------------------------------+
@@ -1161,6 +1165,44 @@ particular, the following variants typically exist:
| | | 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
------------------------------------------------------------------------
@@ -1227,6 +1269,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
-------------------------------------------------------------
diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst
index 68a79f1..d29bc17 100644
--- a/Doc/library/collections.rst
+++ b/Doc/library/collections.rst
@@ -13,6 +13,10 @@
import itertools
__name__ = '<doctest>'
+**Source code:** :source:`Lib/collections.py` and :source:`Lib/_abcoll.py`
+
+--------------
+
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`.
@@ -29,7 +33,7 @@ Python's general purpose built-in containers, :class:`dict`, :class:`list`,
===================== ====================================================================
In addition to the concrete container classes, the collections module provides
-ABCs (abstract base classes) that can be used to test whether a class provides a
+:ref:`abstract-base-classes` that can be used to test whether a class provides a
particular interface, for example, whether it is hashable or a mapping.
@@ -85,7 +89,7 @@ For example::
.. versionadded:: 3.1
- Counter objects support two methods beyond those available for all
+ Counter objects support three methods beyond those available for all
dictionaries:
.. method:: elements()
@@ -108,6 +112,19 @@ For example::
>>> Counter('abracadabra').most_common(3)
[('a', 5), ('r', 2), ('b', 2)]
+ .. method:: subtract([iterable-or-mapping])
+
+ Elements are subtracted from an *iterable* or from another *mapping*
+ (or counter). Like :meth:`dict.update` but subtracts counts instead
+ of replacing them. Both inputs and outputs may be zero or negative.
+
+ >>> c = Counter(a=4, b=2, c=0, d=-2)
+ >>> d = Counter(a=1, b=2, c=3, d=4)
+ >>> c.subtract(d)
+ 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.
@@ -188,14 +205,14 @@ counts, but the output will exclude results with counts of zero or less.
* `Bag class <http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html>`_
in Smalltalk.
- * Wikipedia entry for `Multisets <http://en.wikipedia.org/wiki/Multiset>`_\.
+ * Wikipedia entry for `Multisets <http://en.wikipedia.org/wiki/Multiset>`_.
* `C++ multisets <http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm>`_
tutorial with examples.
* For mathematical operations on multisets and their use cases, see
*Knuth, Donald. The Art of Computer Programming Volume II,
- Section 4.6.3, Exercise 19*\.
+ Section 4.6.3, Exercise 19*.
* To enumerate all distinct multisets of a given size over a given set of
elements, see :func:`itertools.combinations_with_replacement`.
@@ -248,6 +265,13 @@ counts, but the output will exclude results with counts of zero or less.
Remove all elements from the deque leaving it with length 0.
+ .. method:: count(x)
+
+ Count the number of deque elements equal to *x*.
+
+ .. versionadded:: 3.2
+
+
.. method:: extend(iterable)
Extend the right side of the deque by appending elements from the iterable
@@ -279,6 +303,13 @@ counts, but the output will exclude results with counts of zero or less.
:exc:`ValueError`.
+ .. method:: reverse()
+
+ Reverse the elements of the deque in-place and then return ``None``.
+
+ .. versionadded:: 3.2
+
+
.. method:: rotate(n)
Rotate the deque *n* steps to the right. If *n* is negative, rotate to
@@ -555,11 +586,15 @@ they add the ability to access fields by name instead of position index.
.. versionchanged:: 3.1
Added support for *rename*.
-Example:
.. doctest::
:options: +NORMALIZE_WHITESPACE
+ >>> # 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)'
@@ -569,6 +604,7 @@ Example:
_fields = ('x', 'y')
<BLANKLINE>
def __new__(_cls, x, y):
+ 'Create a new instance of Point(x, y)'
return _tuple.__new__(_cls, (x, y))
<BLANKLINE>
@classmethod
@@ -580,7 +616,8 @@ Example:
return result
<BLANKLINE>
def __repr__(self):
- return 'Point(x=%r, y=%r)' % self
+ 'Return a nicely formatted representation string'
+ return self.__class__.__name__ + '(x=%r, y=%r)' % self
<BLANKLINE>
def _asdict(self):
'Return a new OrderedDict which maps field names to their values'
@@ -594,10 +631,11 @@ Example:
return result
<BLANKLINE>
def __getnewargs__(self):
+ 'Return self as a plain tuple. Used by copy and pickle.'
return tuple(self)
<BLANKLINE>
- x = _property(_itemgetter(0))
- y = _property(_itemgetter(1))
+ 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)
@@ -698,15 +736,15 @@ functionality with a subclass. Here is how to add a calculated field and
a fixed-width print format:
>>> class Point(namedtuple('Point', 'x y')):
- ... __slots__ = ()
- ... @property
- ... def hypot(self):
- ... return (self.x ** 2 + self.y ** 2) ** 0.5
- ... def __str__(self):
- ... return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
+ __slots__ = ()
+ @property
+ def hypot(self):
+ return (self.x ** 2 + self.y ** 2) ** 0.5
+ 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)
+ print(p)
Point: x= 3.000 y= 4.000 hypot= 5.000
Point: x=14.000 y= 0.714 hypot=14.018
@@ -733,12 +771,19 @@ and more efficient to use a simple class declaration:
>>> Status.open, Status.pending, Status.closed
(0, 1, 2)
>>> class Status:
- ... open, pending, closed = range(3)
+ open, pending, closed = range(3)
.. 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
@@ -764,6 +809,23 @@ the items are returned in the order their keys were first added.
(key, value) pair. The pairs are returned in LIFO order if *last* is true
or FIFO order if false.
+ .. method:: move_to_end(key, last=True)
+
+ 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`.
@@ -864,6 +926,7 @@ attribute.
class.
+
:class:`UserList` objects
-------------------------
@@ -923,6 +986,7 @@ attribute.
subclass) or an arbitrary sequence which can be converted into a string using
the built-in :func:`str` function.
+.. _abstract-base-classes:
ABCs - abstract base classes
----------------------------
@@ -939,7 +1003,7 @@ ABC Inherits from Abstract Methods Mixin
:class:`Sized` ``__len__``
:class:`Callable` ``__call__``
-:class:`Sequence` :class:`Sized`, ``__getitem__`` ``__contains__``. ``__iter__``, ``__reversed__``,
+:class:`Sequence` :class:`Sized`, ``__getitem__`` ``__contains__``, ``__iter__``, ``__reversed__``,
:class:`Iterable`, ``index``, and ``count``
:class:`Container`
@@ -1074,6 +1138,9 @@ Notes on using :class:`Set` and :class:`MutableSet` as a mixin:
.. seealso::
+ * Latest version of the :source:`Python source code for the collections
+ abstract base classes <Lib/_abcoll.py>`
+
* `OrderedSet recipe <http://code.activestate.com/recipes/576694/>`_ for an
example built on :class:`MutableSet`.
diff --git a/Doc/library/colorsys.rst b/Doc/library/colorsys.rst
index 2cbc704..dbab706 100644
--- a/Doc/library/colorsys.rst
+++ b/Doc/library/colorsys.rst
@@ -5,6 +5,9 @@
:synopsis: Conversion functions between RGB and other color systems.
.. sectionauthor:: David Ascher <da@python.net>
+**Source code:** :source:`Lib/colorsys.py`
+
+--------------
The :mod:`colorsys` module defines bidirectional conversions of color values
between colors expressed in the RGB (Red Green Blue) color space used in
diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst
index 8a93f9b..cb7a09c 100644
--- a/Doc/library/compileall.rst
+++ b/Doc/library/compileall.rst
@@ -52,11 +52,30 @@ compile Python sources.
regex is used to search the full path to each file considered for
compilation, and if the regex produces a match, the file is skipped.
+.. cmdoption:: -i list
+
+ Read the file ``list`` and add each line that it contains to the list of
+ files and directories to compile. If ``list`` is ``-``, read lines from
+ ``stdin``.
+
+.. 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=10, ddir=None, force=False, rx=None, quiet=False)
+.. 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.
@@ -80,7 +99,49 @@ Public functions
If *quiet* is true, nothing is printed to the standard output unless errors
occur.
-.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False)
+ 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=None, force=False, rx=None, quiet=False, legacy=False, optimize=-1)
+
+ Compile the file with path *fullname*.
+
+ If *ddir* is given, it is prepended to the path to the file being compiled
+ for use in compilation time tracebacks, and is also compiled in to the
+ byte-code file, where it will be used in tracebacks and other messages in
+ cases where the source file does not exist at the time the byte-code file is
+ executed.
+
+ If *rx* is given, its search method is passed the full path name to the
+ file being compiled, and if it returns a true value, the file is not
+ compiled and ``True`` is returned.
+
+ 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.
+
+ .. 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
@@ -88,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/concurrent.futures.rst b/Doc/library/concurrent.futures.rst
new file mode 100644
index 0000000..e5d13f3
--- /dev/null
+++ b/Doc/library/concurrent.futures.rst
@@ -0,0 +1,371 @@
+:mod:`concurrent.futures` --- Launching parallel tasks
+======================================================
+
+.. module:: concurrent.futures
+ :synopsis: Execute computations concurrently using threads or processes.
+
+**Source code:** :source:`Lib/concurrent/futures/thread.py`
+and :source:`Lib/concurrent/futures/process.py`
+
+.. versionadded:: 3.2
+
+--------------
+
+The :mod:`concurrent.futures` module provides a high-level interface for
+asynchronously executing callables.
+
+The asynchronous execution can be 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:`__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:`__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 2cef232..1a88bbd 100644
--- a/Doc/library/configparser.rst
+++ b/Doc/library/configparser.rst
@@ -7,7 +7,9 @@
.. 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>
+.. sectionauthor:: Łukasz Langa <lukasz@langa.pl>
.. index::
pair: .ini; file
@@ -15,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::
@@ -36,444 +37,1234 @@ 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
+-----------
+
+Let's take a very basic configuration file that looks like this:
+
+.. code-block:: ini
+
+ [DEFAULT]
+ ServerAliveInterval = 45
+ Compression = yes
+ CompressionLevel = 9
+ ForwardX11 = yes
+
+ [bitbucket.org]
+ User = hg
+
+ [topsecret.server.com]
+ Port = 50022
+ ForwardX11 = no
+
+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::
+
+ >>> 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.
+
+.. doctest::
+
+ >>> 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:
+
+.. doctest::
+
+ >>> int(topsecret['Port'])
+ 50022
+ >>> float(topsecret['CompressionLevel'])
+ 9.0
+
+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:
+
+.. doctest::
+
+ >>> topsecret.getboolean('ForwardX11')
+ False
+ >>> config['bitbucket.org'].getboolean('ForwardX11')
+ True
+ >>> config.getboolean('bitbucket.org', 'Compression')
+ True
+
+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.
+
+
+Fallback Values
+---------------
+
+As with a dictionary, you can use a section's :meth:`get` method to
+provide fallback values:
+
+.. doctest::
+
+ >>> 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:
+
+.. doctest::
+
+ >>> topsecret.get('CompressionLevel', '3')
+ '9'
+
+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:
+
+.. doctest::
+
+ >>> config.get('bitbucket.org', 'monster',
+ ... fallback='No such things as monsters')
+ 'No such things as monsters'
+
+The same ``fallback`` argument can be used with the :meth:`getint`,
+:meth:`getfloat` and :meth:`getboolean` methods, for example:
+
+.. doctest::
+
+ >>> '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 =
-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.
+ [You can use comments]
+ # like this
+ ; or this
-For example::
+ # 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
+-----------------------
- [My Section]
- foodir: %(dir)s/whatever
- dir=frob
- long: this value continues
- in the next line
+On top of the core functionality, :class:`ConfigParser` supports
+interpolation. This means values can be preprocessed before returning them
+from ``get()`` calls.
-would resolve the ``%(dir)s`` to the value of ``dir`` (``frob`` in this case).
-All reference expansions are done on demand.
+.. class:: BasicInterpolation()
-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.
+ 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.
-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.
+ For example:
+ .. code-block:: ini
-.. class:: RawConfigParser(defaults=None, dict_type=collections.OrderedDict)
+ [Paths]
+ home_dir: /Users
+ my_dir: %(home_dir)s/lumberjack
+ my_pictures: %(my_dir)s/Pictures
- 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. This class does not
- support the magical interpolation behavior.
- .. versionchanged:: 3.1
- The default *dict_type* is :class:`collections.OrderedDict`.
+ 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.
+ 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``.
-.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict)
+.. class:: ExtendedInterpolation()
- 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*.
+ 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).
- 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.
+ For example, the configuration specified above with basic interpolation,
+ would look like this with extended interpolation:
- .. versionchanged:: 3.1
- The default *dict_type* is :class:`collections.OrderedDict`.
+ .. code-block:: ini
+
+ [Paths]
+ home_dir: /Users
+ my_dir: ${home_dir}/lumberjack
+ my_pictures: ${my_dir}/Pictures
+
+ Values from other sections can be fetched as well:
+
+ .. code-block:: ini
+
+ [Common]
+ home_dir: /Users
+ library_dir: /Library
+ system_dir: /System
+ macports_dir: /opt/local
+ [Frameworks]
+ Python: 3.2
+ path: ${Common:system_dir}/Library/Frameworks/
-.. class:: SafeConfigParser(defaults=None, dict_type=collections.OrderedDict)
+ [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}
- 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.
+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
+
+ Other typical Boolean pairs include ``accept``/``reject`` or
+ ``enabled``/``disabled``.
+
+.. method:: optionxform(option)
+
+ 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::
+
+ >>> 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.
+
+An example of writing to a configuration file::
+
+ import configparser
- .. XXX Need to explain what's safer/more predictable about it.
+ config = configparser.RawConfigParser()
+
+ # 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', 'int', '15')
+ config.set('Section1', 'bool', 'true')
+ config.set('Section1', '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)
+
+An example of reading the configuration file again::
+
+ import configparser
+
+ config = configparser.RawConfigParser()
+ config.read('example.cfg')
+
+ # getfloat() raises an exception if the value is not a float
+ # getint() and getboolean() also do this for their respective types
+ float = config.getfloat('Section1', 'float')
+ int = config.getint('Section1', 'int')
+ print(float + int)
+
+ # 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', 'bool'):
+ print(config.get('Section1', 'foo'))
+
+To get interpolation, use :class:`ConfigParser`::
+
+ import configparser
+
+ cfg = configparser.ConfigParser()
+ cfg.read('example.cfg')
+
+ # 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'}))
+
+ # The optional `fallback` argument can be used to provide a fallback value
+ print(cfg.get('Section1', 'foo'))
+ # -> "Python is fun!"
+
+ 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."
+
+ # A bare print(cfg.get('Section1', 'monster')) would raise NoOptionError
+ # but we can also use:
+
+ 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. ::
+
+ import configparser
+
+ # New instance with 'bar' and 'baz' defaulting to 'Life' and 'hard' each
+ config = configparser.ConfigParser({'bar': 'Life', 'baz': 'hard'})
+ config.read('example.cfg')
+
+ 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!"
+
+
+.. _configparser-objects:
+
+ConfigParser Objects
+--------------------
+
+.. 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.
+
+ line and inline comments. For backwards compatibility, the default value for
+ *comment_prefixes* is a special value that indicates that ``;`` and ``#`` can
+ start whole line comments while only ``;`` can start inline comments.
+
+ 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.
.. versionchanged:: 3.1
The default *dict_type* is :class:`collections.OrderedDict`.
+ .. versionchanged:: 3.2
+ *allow_no_value*, *delimiters*, *comment_prefixes*, *strict*,
+ *empty_lines_in_values*, *default_section* and *interpolation* were
+ added.
-.. exception:: Error
- Base class for all other configparser exceptions.
+ .. method:: defaults()
+ Return a dictionary containing the instance-wide defaults.
-.. exception:: NoSectionError
- Exception raised when a specified section is not found.
+ .. method:: sections()
+ Return a list of the sections available; the *default section* is not
+ included in the list.
-.. exception:: DuplicateSectionError
- Exception raised if :meth:`add_section` is called with the name of a section
- that is already present.
+ .. 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. The name
+ of the section must be a string; if not, :exc:`TypeError` is raised.
-.. exception:: NoOptionError
+ .. versionchanged:: 3.2
+ Non-string section names raise :exc:`TypeError`.
- Exception raised when a specified option is not found in the specified section.
+ .. method:: has_section(section)
-.. exception:: InterpolationError
+ Indicates whether the named *section* is present in the configuration.
+ The *default section* is not acknowledged.
- Base class for exceptions raised when problems occur performing string
- interpolation.
+ .. method:: options(section)
-.. exception:: InterpolationDepthError
+ Return a list of options available in the specified *section*.
- Exception raised when string interpolation cannot be completed because the
- number of iterations exceeds :const:`MAX_INTERPOLATION_DEPTH`. Subclass of
- :exc:`InterpolationError`.
+ .. method:: has_option(section, option)
-.. exception:: InterpolationMissingOptionError
+ 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.
- Exception raised when an option referenced from a value does not exist. Subclass
- of :exc:`InterpolationError`.
+ .. method:: read(filenames, encoding=None)
-.. exception:: InterpolationSyntaxError
+ 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::
- Exception raised when the source text into which substitutions are made does not
- conform to the required syntax. Subclass of :exc:`InterpolationError`.
+ import configparser, os
+ config = configparser.ConfigParser()
+ config.read_file(open('defaults.cfg'))
+ config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')],
+ encoding='cp1250')
-.. exception:: MissingSectionHeaderError
+ .. versionadded:: 3.2
+ The *encoding* parameter. Previously, all files were read using the
+ default encoding for :func:`open`.
- Exception raised when attempting to parse a file which has no section headers.
+ .. method:: read_file(f, source=None)
-.. exception:: ParsingError
+ Read and parse configuration data from *f* which must be an iterable
+ yielding Unicode strings (for example files opened in text mode).
- Exception raised when errors occur attempting to parse a file.
+ 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`.
-.. data:: MAX_INTERPOLATION_DEPTH
+ .. method:: read_string(string, source='<string>')
- The maximum depth for recursive interpolation for :meth:`get` when the *raw*
- parameter is false. This is relevant only for the :class:`ConfigParser` class.
+ Parse configuration data from a string.
+ 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.
-.. seealso::
+ .. versionadded:: 3.2
- Module :mod:`shlex`
- Support for a creating Unix shell-like mini-languages which can be used as an
- alternate format for application configuration files.
+ .. method:: read_dict(dictionary, source='<dict>')
-.. _rawconfigparser-objects:
+ 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.
-RawConfigParser Objects
------------------------
+ Optional argument *source* specifies a context-specific name of the
+ dictionary passed. If not given, ``<dict>`` is used.
-:class:`RawConfigParser` instances have the following methods:
+ This method can be used to copy state between parsers.
+ .. versionadded:: 3.2
-.. method:: RawConfigParser.defaults()
- Return a dictionary containing the instance-wide defaults.
+ .. method:: get(section, option, raw=False, [vars, fallback])
+ 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.
-.. method:: RawConfigParser.sections()
+ 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.
- Return a list of the sections available; ``DEFAULT`` is not included in the
- list.
+ .. 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).
-.. method:: RawConfigParser.add_section(section)
+ .. method:: getint(section, option, raw=False, [vars, fallback])
- 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.
+ A convenience method which coerces the *option* in the specified *section*
+ to an integer. See :meth:`get` for explanation of *raw*, *vars* and
+ *fallback*.
-.. method:: RawConfigParser.has_section(section)
- Indicates whether the named section is present in the configuration. The
- ``DEFAULT`` section is not acknowledged.
+ .. method:: getfloat(section, option, raw=False, [vars, 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:: RawConfigParser.options(section)
- Returns a list of options available in the specified *section*.
+ .. method:: getboolean(section, option, raw=False, [vars, fallback])
+ 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:: RawConfigParser.has_option(section, option)
- If the given section exists, and contains the given option, return
- :const:`True`; otherwise return :const:`False`.
+ .. method:: items([section], raw=False, vars=None)
+ When *section* is not given, return a list of *section_name*,
+ *section_proxy* pairs, including DEFAULTSECT.
-.. method:: RawConfigParser.read(filenames)
+ 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.
- 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:`readfp` before calling :meth:`read`
- for any optional files::
- import configparser, os
+ .. method:: set(section, option, value)
- config = configparser.ConfigParser()
- config.readfp(open('defaults.cfg'))
- config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')])
+ 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:: RawConfigParser.readfp(fp, filename=None)
+ .. method:: write(fileobject, space_around_delimiters=True)
- Read and parse configuration data from the file or file-like object in *fp*
- (only the :meth:`readline` method is used). The file-like object must
- operate in text mode, i.e. return strings from :meth:`readline`.
+ 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.
- If *filename* is omitted and *fp* has a :attr:`name` attribute, that is used
- for *filename*; the default is ``<???>``.
+ .. method:: remove_option(section, option)
-.. method:: RawConfigParser.get(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`.
- Get an *option* value for the named *section*.
+ .. method:: remove_section(section)
-.. method:: RawConfigParser.getint(section, option)
+ Remove the specified *section* from the configuration. If the section in
+ fact existed, return ``True``. Otherwise return ``False``.
- A convenience method which coerces the *option* in the specified *section* to an
- integer.
+ .. method:: optionxform(option)
-.. method:: RawConfigParser.getfloat(section, option)
+ 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.
- A convenience method which coerces the *option* in the specified *section* to a
- floating point number.
+ 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::
+ cfgparser = ConfigParser()
+ cfgparser.optionxform = str
-.. method:: RawConfigParser.getboolean(section, option)
+ Note that when reading configuration files, whitespace around the option
+ names is stripped before :meth:`optionxform` is called.
- 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`.
+ .. method:: readfp(fp, filename=None)
-.. method:: RawConfigParser.items(section)
+ .. deprecated:: 3.2
+ Use :meth:`read_file` instead.
- Return a list of ``(name, value)`` pairs for each option in the given *section*.
+ .. versionchanged:: 3.2
+ :meth:`readfp` now iterates on *f* instead of calling ``f.readline()``.
+ 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::
-.. method:: RawConfigParser.set(section, option, value)
+ def readline_generator(f):
+ line = f.readline()
+ while line:
+ yield line
+ line = f.readline()
- 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.
+ Instead of ``parser.readfp(f)`` use
+ ``parser.read_file(readline_generator(f))``.
-.. method:: RawConfigParser.write(fileobject)
+.. data:: MAX_INTERPOLATION_DEPTH
- 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.
+ 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.
-.. method:: RawConfigParser.remove_option(section, option)
+.. _rawconfigparser-objects:
- 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`.
+RawConfigParser Objects
+-----------------------
+.. 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=configaparser.DEFAULTSECT, interpolation=None)
-.. method:: RawConfigParser.remove_section(section)
+ Legacy variant of the :class:`ConfigParser` with interpolation disabled
+ by default and unsafe ``add_section`` and ``set`` methods.
- Remove the specified *section* from the configuration. If the section in fact
- existed, return ``True``. Otherwise return ``False``.
+ .. 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:: RawConfigParser.optionxform(option)
+ .. method:: add_section(section)
- 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.
+ 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.
- 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::
+ Type of *section* is not checked which lets users create non-string named
+ sections. This behaviour is unsupported and may cause internal errors.
- cfgparser = ConfigParser()
- ...
- cfgparser.optionxform = str
- Note that when reading configuration files, whitespace around the
- option names are stripped before :meth:`optionxform` is called.
+ .. 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.
-.. _configparser-objects:
+ 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.
-ConfigParser Objects
---------------------
-The :class:`ConfigParser` class extends some methods of the
-:class:`RawConfigParser` interface, adding some optional arguments.
+Exceptions
+----------
+.. exception:: Error
-.. method:: ConfigParser.get(section, option, raw=False, vars=None)
+ Base class for all other :mod:`configparser` exceptions.
- 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.
- 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.
+.. exception:: NoSectionError
+ Exception raised when a specified section is not found.
-.. method:: ConfigParser.items(section, raw=False, vars=None)
- 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.
+.. 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.
-.. _safeconfigparser-objects:
+ .. versionadded:: 3.2
+ Optional ``source`` and ``lineno`` attributes and arguments to
+ :meth:`__init__` were added.
-SafeConfigParser Objects
-------------------------
-The :class:`SafeConfigParser` class implements the same extended interface as
-:class:`ConfigParser`, with the following addition:
+.. 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.
-.. method:: SafeConfigParser.set(section, option, value)
- If the given section exists, set the given option to the specified value;
- otherwise raise :exc:`NoSectionError`. *value* must be a string; if it is
- not, :exc:`TypeError` is raised.
+.. exception:: NoOptionError
+ Exception raised when a specified option is not found in the specified
+ section.
-Examples
---------
-An example of writing to a configuration file::
+.. exception:: InterpolationError
- import configparser
+ Base class for exceptions raised when problems occur performing string
+ interpolation.
- config = configparser.RawConfigParser()
- # 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', 'int', '15')
- config.set('Section1', 'bool', 'true')
- config.set('Section1', 'float', '3.1415')
- config.set('Section1', 'baz', 'fun')
- config.set('Section1', 'bar', 'Python')
- config.set('Section1', 'foo', '%(bar)s is %(baz)s!')
+.. exception:: InterpolationDepthError
- # Writing our configuration file to 'example.cfg'
- with open('example.cfg', 'w') as configfile:
- config.write(configfile)
+ Exception raised when string interpolation cannot be completed because the
+ number of iterations exceeds :const:`MAX_INTERPOLATION_DEPTH`. Subclass of
+ :exc:`InterpolationError`.
-An example of reading the configuration file again::
- import configparser
+.. exception:: InterpolationMissingOptionError
- config = configparser.RawConfigParser()
- config.read('example.cfg')
+ Exception raised when an option referenced from a value does not exist.
+ Subclass of :exc:`InterpolationError`.
- # getfloat() raises an exception if the value is not a float
- # getint() and getboolean() also do this for their respective types
- float = config.getfloat('Section1', 'float')
- int = config.getint('Section1', 'int')
- print(float + int)
- # 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', 'bool'):
- print(config.get('Section1', 'foo'))
+.. exception:: InterpolationSyntaxError
-To get interpolation, you will need to use a :class:`ConfigParser` or
-:class:`SafeConfigParser`::
+ Exception raised when the source text into which substitutions are made does
+ not conform to the required syntax. Subclass of :exc:`InterpolationError`.
- import configparser
- config = configparser.ConfigParser()
- config.read('example.cfg')
+.. exception:: MissingSectionHeaderError
- # 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!"
+ Exception raised when attempting to parse a file which has no section
+ headers.
- # 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'}))
-Defaults are available in all three types of ConfigParsers. They are used in
-interpolation if an option used is not defined elsewhere. ::
+.. exception:: ParsingError
- import configparser
+ Exception raised when errors occur attempting to parse a file.
- # New instance with 'bar' and 'baz' defaulting to 'Life' and 'hard' each
- config = configparser.SafeConfigParser({'bar': 'Life', 'baz': 'hard'})
- config.read('example.cfg')
+ .. versionchanged:: 3.2
+ The ``filename`` attribute and :meth:`__init__` argument were renamed to
+ ``source`` for consistency.
- 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 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)
+.. 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/contextlib.rst b/Doc/library/contextlib.rst
index ca37f0f..e8dc17f 100644
--- a/Doc/library/contextlib.rst
+++ b/Doc/library/contextlib.rst
@@ -4,6 +4,9 @@
.. module:: contextlib
:synopsis: Utilities for with-statement contexts.
+**Source code:** :source:`Lib/contextlib.py`
+
+--------------
This module provides utilities for common tasks involving the :keyword:`with`
statement. For more information see also :ref:`typecontextmanager` and
@@ -12,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
@@ -51,54 +54,15 @@ 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.
-
- 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:: 3.1
- The with-statement now supports this functionality directly (without the
- confusing error prone quirks).
+ .. versionchanged:: 3.2
+ Use of :class:`ContextDecorator`.
.. function:: closing(thing)
@@ -128,6 +92,82 @@ Functions provided:
``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/csv.rst b/Doc/library/csv.rst
index 92ba6da..edbe726 100644
--- a/Doc/library/csv.rst
+++ b/Doc/library/csv.rst
@@ -188,6 +188,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.
@@ -393,6 +402,16 @@ Writer objects have the following public attribute:
A read-only description of the dialect in use by the writer.
+DictWriter objects have the following public method:
+
+
+.. method:: DictWriter.writeheader()
+
+ Write a row with the field names (as specified in the constructor).
+
+ .. versionadded:: 3.2
+
+
.. _csv-examples:
Examples
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
index d1d025b..33d1f7e 100644
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -38,7 +38,7 @@ You load libraries by accessing them as attributes of these objects. *cdll*
loads libraries which export functions using the standard ``cdecl`` calling
convention, while *windll* libraries call functions using the ``stdcall``
calling convention. *oledll* also uses the ``stdcall`` calling convention, and
-assumes the functions return a Windows :ctype:`HRESULT` error code. The error
+assumes the functions return a Windows :c:type:`HRESULT` error code. The error
code is used to automatically raise a :class:`WindowsError` exception when the
function call fails.
@@ -198,9 +198,9 @@ should be careful anyway.
``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, bytes objects and strings are passed
-as pointer to the memory block that contains their data (:ctype:`char *` or
-:ctype:`wchar_t *`). Python integers are passed as the platforms default C
-:ctype:`int` type, their value is masked to fit into the C type.
+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.
@@ -213,48 +213,48 @@ Fundamental data types
:mod:`ctypes` defines a number of primitive C compatible data types :
-+----------------------+----------------------------------------+----------------------------+
-| ctypes type | C type | Python type |
-+======================+========================================+============================+
-| :class:`c_bool` | :ctype:`_Bool` | bool (1) |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_char` | :ctype:`char` | 1-character bytes object |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_wchar` | :ctype:`wchar_t` | 1-character string |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_byte` | :ctype:`char` | int |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_ubyte` | :ctype:`unsigned char` | int |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_short` | :ctype:`short` | int |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_ushort` | :ctype:`unsigned short` | int |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_int` | :ctype:`int` | int |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_uint` | :ctype:`unsigned int` | int |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_long` | :ctype:`long` | int |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_ulong` | :ctype:`unsigned long` | int |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_longlong` | :ctype:`__int64` or :ctype:`long long` | int |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_ulonglong` | :ctype:`unsigned __int64` or | int |
-| | :ctype:`unsigned long long` | |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_float` | :ctype:`float` | float |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_double` | :ctype:`double` | float |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_longdouble`| :ctype:`long double` | float |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_char_p` | :ctype:`char *` (NUL terminated) | bytes object or ``None`` |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_wchar_p` | :ctype:`wchar_t *` (NUL terminated) | string or ``None`` |
-+----------------------+----------------------------------------+----------------------------+
-| :class:`c_void_p` | :ctype:`void *` | int or ``None`` |
-+----------------------+----------------------------------------+----------------------------+
++----------------------+------------------------------------------+----------------------------+
+| ctypes type | C type | Python type |
++======================+==========================================+============================+
+| :class:`c_bool` | :c:type:`_Bool` | bool (1) |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_char` | :c:type:`char` | 1-character bytes object |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_wchar` | :c:type:`wchar_t` | 1-character string |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_byte` | :c:type:`char` | int |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_ubyte` | :c:type:`unsigned char` | int |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_short` | :c:type:`short` | int |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_ushort` | :c:type:`unsigned short` | int |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_int` | :c:type:`int` | int |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_uint` | :c:type:`unsigned int` | int |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_long` | :c:type:`long` | int |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_ulong` | :c:type:`unsigned long` | int |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_longlong` | :c:type:`__int64` or :c:type:`long long` | int |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_ulonglong` | :c:type:`unsigned __int64` or | int |
+| | :c:type:`unsigned long long` | |
++----------------------+------------------------------------------+----------------------------+
+| :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) | bytes object or ``None`` |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_wchar_p` | :c:type:`wchar_t *` (NUL terminated) | string or ``None`` |
++----------------------+------------------------------------------+----------------------------+
+| :class:`c_void_p` | :c:type:`void *` | int or ``None`` |
++----------------------+------------------------------------------+----------------------------+
(1)
The constructor accepts any object with a truth value.
@@ -325,7 +325,7 @@ property::
The :func:`create_string_buffer` function replaces the :func:`c_buffer` function
(which is still available as an alias), as well as the :func:`c_string` function
from earlier ctypes releases. To create a mutable memory block containing
-unicode characters of the C type :ctype:`wchar_t` use the
+unicode characters of the C type :c:type:`wchar_t` use the
:func:`create_unicode_buffer` function.
@@ -436,7 +436,7 @@ integer, string, bytes, a :mod:`ctypes` instance, or an object with an
Return types
^^^^^^^^^^^^
-By default functions are assumed to return the C :ctype:`int` type. Other
+By default functions are assumed to return the C :c:type:`int` type. Other
return types can be specified by setting the :attr:`restype` attribute of the
function object.
@@ -935,8 +935,8 @@ 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
-:cfunc:`qsort` function, this is used to sort items with the help of a callback
-function. :cfunc:`qsort` will be used to sort an array of integers::
+: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)
@@ -1077,7 +1077,7 @@ 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 :cdata:`Py_OptimizeFlag`, an integer
+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.
@@ -1095,11 +1095,11 @@ 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
-:cdata:`PyImport_FrozenModules` pointer exported by Python.
+:c:data:`PyImport_FrozenModules` pointer exported by Python.
Quoting the docs for that value:
- This pointer is initialized to point to an array of :ctype:`struct _frozen`
+ 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.
@@ -1116,7 +1116,7 @@ size, we show only how this table can be read with :mod:`ctypes`::
...
>>>
-We have defined the :ctype:`struct _frozen` data type, so we can get the pointer
+We have defined the :c:type:`struct _frozen` data type, so we can get the pointer
to the table::
>>> FrozenTable = POINTER(struct_frozen)
@@ -1335,7 +1335,7 @@ way is to instantiate one of the following classes:
Instances of this class represent loaded shared libraries. Functions in these
libraries use the standard C calling convention, and are assumed to return
- :ctype:`int`.
+ :c:type:`int`.
.. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)
@@ -1352,7 +1352,7 @@ way is to instantiate one of the following classes:
Windows only: Instances of this class represent loaded shared libraries,
functions in these libraries use the ``stdcall`` calling convention, and are
- assumed to return :ctype:`int` by default.
+ assumed to return :c:type:`int` by default.
On Windows CE only the standard calling convention is used, for convenience the
:class:`WinDLL` and :class:`OleDLL` use the standard calling convention on this
@@ -1493,7 +1493,7 @@ object is available:
An instance of :class:`PyDLL` that exposes Python C API functions as
attributes. Note that all these functions are assumed to return C
- :ctype:`int`, which is of course not always the truth, so you have to assign
+ :c:type:`int`, which is of course not always the truth, so you have to assign
the correct :attr:`restype` attribute to use these functions.
@@ -1522,10 +1522,10 @@ They are instances of a private class:
.. attribute:: restype
Assign a ctypes type to specify the result type of the foreign function.
- Use ``None`` for :ctype:`void`, a function not returning anything.
+ Use ``None`` for :c:type:`void`, a function not returning anything.
It is possible to assign a callable Python object that is not a ctypes
- type, in this case the function is assumed to return a C :ctype:`int`, and
+ type, in this case the function is assumed to return a C :c:type:`int`, and
the callable will be called with this integer, allowing to do further
processing or error checking. Using this is deprecated, for more flexible
post processing or error checking use a ctypes data type as
@@ -1935,22 +1935,6 @@ 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
- bytes objects 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')``.
-
- You can set the *encoding* to ``'undefined'`` to completely disable automatic
- conversions.
-
-
.. function:: set_errno(value)
Set the current value of the ctypes-private copy of the system :data:`errno`
@@ -2120,21 +2104,21 @@ These are the fundamental ctypes data types:
.. class:: c_byte
- Represents the C :ctype:`signed char` datatype, and interprets the value as
+ Represents the C :c:type:`signed char` datatype, and interprets the value as
small integer. The constructor accepts an optional integer initializer; no
overflow checking is done.
.. class:: c_char
- Represents the C :ctype:`char` datatype, and interprets the value as a single
+ Represents the C :c:type:`char` datatype, and interprets the value as a single
character. The constructor accepts an optional string initializer, the
length of the string must be exactly one character.
.. class:: c_char_p
- Represents the C :ctype:`char *` datatype when it points to a zero-terminated
+ 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 bytes object.
@@ -2142,173 +2126,180 @@ These are the fundamental ctypes data types:
.. class:: c_double
- Represents the C :ctype:`double` datatype. The constructor accepts an
+ Represents the C :c:type:`double` datatype. The constructor accepts an
optional float initializer.
.. class:: c_longdouble
- Represents the C :ctype:`long double` datatype. The constructor accepts an
+ Represents the C :c:type:`long double` datatype. The constructor accepts an
optional float initializer. On platforms where ``sizeof(long double) ==
sizeof(double)`` it is an alias to :class:`c_double`.
.. class:: c_float
- Represents the C :ctype:`float` datatype. The constructor accepts an
+ Represents the C :c:type:`float` datatype. The constructor accepts an
optional float initializer.
.. class:: c_int
- Represents the C :ctype:`signed int` datatype. The constructor accepts an
+ Represents the C :c:type:`signed int` datatype. The constructor accepts an
optional integer initializer; no overflow checking is done. On platforms
where ``sizeof(int) == sizeof(long)`` it is an alias to :class:`c_long`.
.. class:: c_int8
- Represents the C 8-bit :ctype:`signed int` datatype. Usually an alias for
+ Represents the C 8-bit :c:type:`signed int` datatype. Usually an alias for
:class:`c_byte`.
.. class:: c_int16
- Represents the C 16-bit :ctype:`signed int` datatype. Usually an alias for
+ Represents the C 16-bit :c:type:`signed int` datatype. Usually an alias for
:class:`c_short`.
.. class:: c_int32
- Represents the C 32-bit :ctype:`signed int` datatype. Usually an alias for
+ Represents the C 32-bit :c:type:`signed int` datatype. Usually an alias for
:class:`c_int`.
.. class:: c_int64
- Represents the C 64-bit :ctype:`signed int` datatype. Usually an alias for
+ Represents the C 64-bit :c:type:`signed int` datatype. Usually an alias for
:class:`c_longlong`.
.. class:: c_long
- Represents the C :ctype:`signed long` datatype. The constructor accepts an
+ Represents the C :c:type:`signed long` datatype. The constructor accepts an
optional integer initializer; no overflow checking is done.
.. class:: c_longlong
- Represents the C :ctype:`signed long long` datatype. The constructor accepts
+ Represents the C :c:type:`signed long long` datatype. The constructor accepts
an optional integer initializer; no overflow checking is done.
.. class:: c_short
- Represents the C :ctype:`signed short` datatype. The constructor accepts an
+ Represents the C :c:type:`signed short` datatype. The constructor accepts an
optional integer initializer; no overflow checking is done.
.. class:: c_size_t
- Represents the C :ctype:`size_t` datatype.
+ Represents the C :c:type:`size_t` datatype.
+
+
+.. class:: c_ssize_t
+
+ Represents the C :c:type:`ssize_t` datatype.
+
+ .. versionadded:: 3.2
.. class:: c_ubyte
- Represents the C :ctype:`unsigned char` datatype, it interprets the value as
+ Represents the C :c:type:`unsigned char` datatype, it interprets the value as
small integer. The constructor accepts an optional integer initializer; no
overflow checking is done.
.. class:: c_uint
- Represents the C :ctype:`unsigned int` datatype. The constructor accepts an
+ Represents the C :c:type:`unsigned int` datatype. The constructor accepts an
optional integer initializer; no overflow checking is done. On platforms
where ``sizeof(int) == sizeof(long)`` it is an alias for :class:`c_ulong`.
.. class:: c_uint8
- Represents the C 8-bit :ctype:`unsigned int` datatype. Usually an alias for
+ Represents the C 8-bit :c:type:`unsigned int` datatype. Usually an alias for
:class:`c_ubyte`.
.. class:: c_uint16
- Represents the C 16-bit :ctype:`unsigned int` datatype. Usually an alias for
+ Represents the C 16-bit :c:type:`unsigned int` datatype. Usually an alias for
:class:`c_ushort`.
.. class:: c_uint32
- Represents the C 32-bit :ctype:`unsigned int` datatype. Usually an alias for
+ Represents the C 32-bit :c:type:`unsigned int` datatype. Usually an alias for
:class:`c_uint`.
.. class:: c_uint64
- Represents the C 64-bit :ctype:`unsigned int` datatype. Usually an alias for
+ Represents the C 64-bit :c:type:`unsigned int` datatype. Usually an alias for
:class:`c_ulonglong`.
.. class:: c_ulong
- Represents the C :ctype:`unsigned long` datatype. The constructor accepts an
+ Represents the C :c:type:`unsigned long` datatype. The constructor accepts an
optional integer initializer; no overflow checking is done.
.. class:: c_ulonglong
- Represents the C :ctype:`unsigned long long` datatype. The constructor
+ Represents the C :c:type:`unsigned long long` datatype. The constructor
accepts an optional integer initializer; no overflow checking is done.
.. class:: c_ushort
- Represents the C :ctype:`unsigned short` datatype. The constructor accepts
+ Represents the C :c:type:`unsigned short` datatype. The constructor accepts
an optional integer initializer; no overflow checking is done.
.. class:: c_void_p
- Represents the C :ctype:`void *` type. The value is represented as integer.
+ Represents the C :c:type:`void *` type. The value is represented as integer.
The constructor accepts an optional integer initializer.
.. class:: c_wchar
- Represents the C :ctype:`wchar_t` datatype, and interprets the value as a
+ Represents the C :c:type:`wchar_t` datatype, and interprets the value as a
single character unicode string. The constructor accepts an optional string
initializer, the length of the string must be exactly one character.
.. class:: c_wchar_p
- Represents the C :ctype:`wchar_t *` datatype, which must be a pointer to a
+ Represents the C :c:type:`wchar_t *` datatype, which must be a pointer to a
zero-terminated wide character string. The constructor accepts an integer
address, or a string.
.. class:: c_bool
- Represent the C :ctype:`bool` datatype (more accurately, :ctype:`_Bool` from
+ Represent the C :c:type:`bool` datatype (more accurately, :c:type:`_Bool` from
C99). Its value can be True or False, and the constructor accepts any object
that has a truth value.
.. class:: HRESULT
- Windows only: Represents a :ctype:`HRESULT` value, which contains success or
+ Windows only: Represents a :c:type:`HRESULT` value, which contains success or
error information for a function or method call.
.. class:: py_object
- Represents the C :ctype:`PyObject *` datatype. Calling this without an
- argument creates a ``NULL`` :ctype:`PyObject *` pointer.
+ Represents the C :c:type:`PyObject *` datatype. Calling this without an
+ argument creates a ``NULL`` :c:type:`PyObject *` pointer.
The :mod:`ctypes.wintypes` module provides quite some other Windows specific
-data types, for example :ctype:`HWND`, :ctype:`WPARAM`, or :ctype:`DWORD`. Some
-useful structures like :ctype:`MSG` or :ctype:`RECT` are also defined.
+data types, for example :c:type:`HWND`, :c:type:`WPARAM`, or :c:type:`DWORD`. Some
+useful structures like :c:type:`MSG` or :c:type:`RECT` are also defined.
.. _ctypes-structured-data-types:
diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst
index 6d2baa0..1ca22c8 100644
--- a/Doc/library/curses.rst
+++ b/Doc/library/curses.rst
@@ -49,7 +49,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.
diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst
index 26d9946..de9ad44 100644
--- a/Doc/library/datetime.rst
+++ b/Doc/library/datetime.rst
@@ -28,11 +28,14 @@ For applications requiring more, :class:`datetime` and :class:`time` objects
have an optional time zone information member, :attr:`tzinfo`, that can contain
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.
+time zone name, and whether Daylight Saving Time is in effect. Note that only
+one concrete :class:`tzinfo` class, the :class:`timezone` class, is supplied by the
+:mod:`datetime` module. The :class:`timezone` class can reprsent simple
+timezones with fixed offset from UTC such as UTC itself or North American EST and
+EDT timezones. 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, change frequently, and there is no
+standard suitable for every application aside from UTC.
The :mod:`datetime` module exports the following constants:
@@ -99,6 +102,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.
@@ -116,6 +127,7 @@ Subclass relationships::
object
timedelta
tzinfo
+ timezone
time
date
datetime
@@ -220,8 +232,28 @@ Supported operations:
| | 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) |
@@ -270,6 +302,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
@@ -282,12 +321,27 @@ comparison is ``==`` or ``!=``. The latter cases return :const:`False` or
efficient pickling, and in Boolean contexts, a :class:`timedelta` object is
considered to be true if and only if it isn't equal to ``timedelta(0)``.
+Instance methods:
+
+.. method:: timedelta.total_seconds()
+
+ 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:: 3.2
+
+
Example usage:
>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> another_year = timedelta(weeks=40, days=84, hours=23,
... minutes=50, seconds=600) # adds up to 365 days
+ >>> year.total_seconds()
+ 31536000.0
>>> year == another_year
True
>>> ten_years = 10 * year
@@ -342,7 +396,7 @@ Other constructors, all class methods:
Return the local date corresponding to the POSIX timestamp, such as is returned
by :func:`time.time`. This may raise :exc:`ValueError`, if the timestamp is out
- of the range of values supported by the platform C :cfunc:`localtime` function.
+ of the range of values supported by the platform C :c:func:`localtime` function.
It's common for this to be restricted to years from 1970 through 2038. Note
that on non-POSIX systems that include leap seconds in their notion of a
timestamp, leap seconds are ignored by :meth:`fromtimestamp`.
@@ -516,7 +570,7 @@ Instance methods:
Return a string representing the date, for example ``date(2002, 12,
4).ctime() == 'Wed Dec 4 00:00:00 2002'``. ``d.ctime()`` is equivalent to
``time.ctime(time.mktime(d.timetuple()))`` on platforms where the native C
- :cfunc:`ctime` function (which :func:`time.ctime` invokes, but which
+ :c:func:`ctime` function (which :func:`time.ctime` invokes, but which
:meth:`date.ctime` does not invoke) conforms to the C standard.
@@ -623,7 +677,7 @@ Other constructors, all class methods:
or not specified, this is like :meth:`today`, but, if possible, supplies more
precision than can be gotten from going through a :func:`time.time` timestamp
(for example, this may be possible on platforms supplying the C
- :cfunc:`gettimeofday` function).
+ :c:func:`gettimeofday` function).
Else *tz* must be an instance of a class :class:`tzinfo` subclass, and the
current date and time are converted to *tz*'s time zone. In this case the
@@ -635,8 +689,8 @@ 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=None)
@@ -651,8 +705,8 @@ Other constructors, all class methods:
``tz.fromutc(datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz))``.
:meth:`fromtimestamp` may raise :exc:`ValueError`, if the timestamp is out of
- the range of values supported by the platform C :cfunc:`localtime` or
- :cfunc:`gmtime` functions. It's common for this to be restricted to years in
+ the range of values supported by the platform C :c:func:`localtime` or
+ :c:func:`gmtime` functions. It's common for this to be restricted to years in
1970 through 2038. Note that on non-POSIX systems that include leap seconds in
their notion of a timestamp, leap seconds are ignored by :meth:`fromtimestamp`,
and then it's possible to have two timestamps differing by a second that yield
@@ -663,7 +717,7 @@ Other constructors, all class methods:
Return the UTC :class:`datetime` corresponding to the POSIX timestamp, with
:attr:`tzinfo` ``None``. This may raise :exc:`ValueError`, if the timestamp is
- out of the range of values supported by the platform C :cfunc:`gmtime` function.
+ out of the range of values supported by the platform C :c:func:`gmtime` function.
It's common for this to be restricted to years in 1970 through 2038. See also
:meth:`fromtimestamp`.
@@ -927,7 +981,7 @@ Instance methods:
of the result is set according to the :meth:`dst` method: :attr:`tzinfo` is
``None`` or :meth:`dst` returns ``None``, :attr:`tm_isdst` is set to ``-1``;
else if :meth:`dst` returns a non-zero value, :attr:`tm_isdst` is set to ``1``;
- else ``tm_isdst`` is set to ``0``.
+ else :attr:`tm_isdst` is set to ``0``.
.. method:: datetime.utctimetuple()
@@ -937,10 +991,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.
@@ -1002,7 +1056,7 @@ Instance methods:
Return a string representing the date and time, for example ``datetime(2002, 12,
4, 20, 30, 40).ctime() == 'Wed Dec 4 20:30:40 2002'``. ``d.ctime()`` is
equivalent to ``time.ctime(time.mktime(d.timetuple()))`` on platforms where the
- native C :cfunc:`ctime` function (which :func:`time.ctime` invokes, but which
+ native C :c:func:`ctime` function (which :func:`time.ctime` invokes, but which
:meth:`datetime.ctime` does not invoke) conforms to the C standard.
@@ -1293,8 +1347,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 reprsent
+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
@@ -1312,7 +1368,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
@@ -1334,7 +1390,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
@@ -1382,7 +1438,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,
@@ -1418,7 +1474,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 date and time members
@@ -1495,9 +1551,65 @@ 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)).
+
+
+.. _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:
@@ -1549,9 +1661,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 |
+===========+================================+=======+
@@ -1594,7 +1703,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 | |
@@ -1624,10 +1733,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). | |
+-----------+--------------------------------+-------+
@@ -1651,17 +1761,30 @@ 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.
diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst
index cbefc1a..e3d50b9 100644
--- a/Doc/library/dbm.rst
+++ b/Doc/library/dbm.rst
@@ -61,10 +61,15 @@ the Oracle Berkeley DB.
modified by the prevailing umask).
-The object returned by :func:`.open` supports most of the same functionality as
+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. Key and values are always stored as bytes. This means that when
+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.
diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst
index 758dcce..9d5b32f 100644
--- a/Doc/library/decimal.rst
+++ b/Doc/library/decimal.rst
@@ -123,15 +123,14 @@ 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
-Decimal instances can be constructed from integers, strings, or tuples. To
-create a Decimal from a :class:`float`, first convert it to a string. This
-serves as an explicit reminder of the details of the conversion (including
-representation error). Decimal numbers include special values such as
+Decimal instances can be constructed from integers, strings, floats, or tuples.
+Construction from an integer or a float performs an exact conversion of the
+value of that integer or float. Decimal numbers include special values such as
:const:`NaN` which stands for "Not a number", positive and negative
:const:`Infinity`, and :const:`-0`.
@@ -140,10 +139,12 @@ representation error). Decimal numbers include special values such as
Decimal('10')
>>> Decimal('3.14')
Decimal('3.14')
+ >>> Decimal(3.14)
+ Decimal('3.140000000000000124344978758017532527446746826171875')
>>> 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')
@@ -244,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')
@@ -269,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=[Inexact, Rounded], 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
@@ -309,7 +310,7 @@ Decimal objects
Construct a new :class:`Decimal` object based from *value*.
- *value* can be an integer, string, tuple, or another :class:`Decimal`
+ *value* can be an integer, string, tuple, :class:`float`, or another :class:`Decimal`
object. If no *value* is given, returns ``Decimal('0')``. If *value* is a
string, it should conform to the decimal numeric string syntax after leading
and trailing whitespace characters are removed::
@@ -335,6 +336,12 @@ Decimal objects
digits, and an integer exponent. For example, ``Decimal((0, (1, 4, 1, 4), -3))``
returns ``Decimal('1.414')``.
+ If *value* is a :class:`float`, the binary floating point value is losslessly
+ converted to its exact decimal equivalent. This conversion can often require
+ 53 or more digits of precision. For example, ``Decimal(float('1.1'))``
+ converts to
+ ``Decimal('1.100000000000000088817841970012523233890533447265625')``.
+
The *context* precision does not affect how many digits are stored. That is
determined exclusively by the number of digits in *value*. For example,
``Decimal('3.00000')`` records all five zeros even if the context precision is
@@ -347,6 +354,10 @@ Decimal objects
Once constructed, :class:`Decimal` objects are immutable.
+ .. 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
@@ -354,6 +365,18 @@ Decimal objects
compared, sorted, and coerced to another type (such as :class:`float` or
:class:`int`).
+ 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:
@@ -468,6 +491,9 @@ Decimal objects
`0x1.999999999999ap-4`. That equivalent value in decimal is
`0.1000000000000000055511151231257827021181583404541015625`.
+ .. note:: From Python 3.2 onwards, a :class:`Decimal` instance
+ can also be constructed directly from a :class:`float`.
+
.. doctest::
>>> Decimal.from_float(0.1)
@@ -861,7 +887,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*
@@ -892,13 +918,33 @@ 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')`.
+ 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.
In addition, for each of the :class:`Decimal` methods described above (with
the exception of the :meth:`adjusted` and :meth:`as_tuple` methods) there is
- a corresponding :class:`Context` method. For example, ``C.exp(x)`` is
- equivalent to ``x.exp(context=C)``.
+ 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`) anywhere that a
+ Decimal instance is accepted.
.. method:: clear_flags()
@@ -963,7 +1009,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``.
@@ -1612,7 +1657,8 @@ to work with the :class:`Decimal` class::
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
@@ -1672,6 +1718,9 @@ to work with the :class:`Decimal` class::
def cos(x):
"""Return the cosine of x as measured in radians.
+ 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))
@@ -1695,6 +1744,9 @@ to work with the :class:`Decimal` class::
def sin(x):
"""Return the sine of x as measured in radians.
+ 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))
@@ -1821,37 +1873,15 @@ value unchanged:
Q. Is there a way to convert a regular float to a :class:`Decimal`?
-A. Yes, all binary floating point numbers can be exactly expressed as a
-Decimal. An exact conversion may take more precision than intuition would
-suggest, so we trap :const:`Inexact` to signal a need for more precision:
-
-.. testcode::
-
- def float_to_decimal(f):
- "Convert a floating point number to a Decimal with no loss of information"
- n, d = f.as_integer_ratio()
- with localcontext() as ctx:
- ctx.traps[Inexact] = True
- while True:
- try:
- return Decimal(n) / Decimal(d)
- except Inexact:
- ctx.prec += 1
+A. Yes, any binary floating point number can be exactly expressed as a
+Decimal though an exact conversion may take more precision than intuition would
+suggest:
.. doctest::
- >>> float_to_decimal(math.pi)
+ >>> Decimal(math.pi)
Decimal('3.141592653589793115997963468544185161590576171875')
-Q. Why isn't the :func:`float_to_decimal` routine included in the module?
-
-A. There is some question about whether it is advisable to mix binary and
-decimal floating point. Also, its use requires some care to avoid the
-representation issues associated with binary floating point:
-
- >>> float_to_decimal(1.1)
- Decimal('1.100000000000000088817841970012523233890533447265625')
-
Q. Within a complex calculation, how can I make sure that I haven't gotten a
spurious result because of insufficient precision or rounding anomalies.
diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst
index 6dea8c1..bdc37b3 100644
--- a/Doc/library/difflib.rst
+++ b/Doc/library/difflib.rst
@@ -17,6 +17,7 @@ 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
@@ -35,11 +36,17 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
complicated way on how many elements the sequences have in common; best case
time is linear.
- **Heuristic:** To speed-up matching, items whose duplicates appear more than 1% of
- the time in sequences of at least 200 items are treated as junk. This has the
- unfortunate side-effect of giving bad results for sequences constructed from
- a small set of items. An option to turn off the heuristic will be added to
- Python 3.2.
+ **Automatic junk heuristic:** :class:`SequenceMatcher` supports a heuristic that
+ automatically treats certain sequence items as junk. The heuristic counts how many
+ times each individual item appears in the sequence. If an item's duplicates (after
+ the first one) account for more than 1% of the sequence and the sequence is at least
+ 200 items long, this item is marked as "popular" and is treated as junk for
+ the purpose of sequence matching. This heuristic can be turned off by setting
+ the ``autojunk`` argument to ``False`` when creating the :class:`SequenceMatcher`.
+
+ .. versionadded:: 3.2
+ The *autojunk* parameter.
+
.. class:: Differ
@@ -145,8 +152,8 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
The context diff format normally has a header for filenames and modification
times. Any or all of these may be specified using strings for *fromfile*,
- *tofile*, *fromfiledate*, and *tofiledate*. The modification times are normally
- expressed in the format returned by :func:`time.ctime`. If not specified, the
+ *tofile*, *fromfiledate*, and *tofiledate*. The modification times are normally
+ expressed in the ISO 8601 format. If not specified, the
strings default to blanks.
>>> s1 = ['bacon\n', 'eggs\n', 'ham\n', 'guido\n']
@@ -277,8 +284,8 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
The context diff format normally has a header for filenames and modification
times. Any or all of these may be specified using strings for *fromfile*,
- *tofile*, *fromfiledate*, and *tofiledate*. The modification times are normally
- expressed in the format returned by :func:`time.ctime`. If not specified, the
+ *tofile*, *fromfiledate*, and *tofiledate*. The modification times are normally
+ expressed in the ISO 8601 format. If not specified, the
strings default to blanks.
@@ -329,7 +336,7 @@ SequenceMatcher Objects
The :class:`SequenceMatcher` class has this constructor:
-.. class:: SequenceMatcher(isjunk=None, a='', b='')
+.. class:: SequenceMatcher(isjunk=None, a='', b='', autojunk=True)
Optional argument *isjunk* must be ``None`` (the default) or a one-argument
function that takes a sequence element and returns true if and only if the
@@ -345,6 +352,22 @@ The :class:`SequenceMatcher` class has this constructor:
The optional arguments *a* and *b* are sequences to be compared; both default to
empty strings. The elements of both sequences must be :term:`hashable`.
+ The optional argument *autojunk* can be used to disable the automatic junk
+ heuristic.
+
+ .. 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)
@@ -460,13 +483,15 @@ The :class:`SequenceMatcher` class has this constructor:
>>> 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)
+ 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=3)
@@ -524,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;",
diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index 4aae06b..79cc583 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -4,6 +4,9 @@
.. module:: dis
:synopsis: Disassembler for Python bytecode.
+**Source code:** :source:`Lib/dis.py`
+
+--------------
The :mod:`dis` module supports the analysis of CPython :term:`bytecode` by
disassembling it. The CPython bytecode which this module takes as an
@@ -12,7 +15,7 @@ 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.
@@ -36,6 +39,28 @@ the following command can be used to get the disassembly of :func:`myfunc`::
The :mod:`dis` module defines the following functions and constants:
+.. 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.
+
+ This is a convenient shorthand for ``print(code_info(x))``, intended for
+ interactive exploration at the interpreter prompt.
+
+ .. versionadded:: 3.2
+
.. function:: dis(x=None)
Disassemble the *x* object. *x* can denote either a module, a class, a
@@ -172,15 +197,15 @@ The Python compiler currently generates the following bytecode instructions.
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**
@@ -445,6 +470,18 @@ the stack so that it is available for further iterations of the loop.
by ``CALL_FUNCTION`` to construct a class.
+.. opcode:: SETUP_WITH (delta)
+
+ This opcode performs several operations before a with block starts. First,
+ it loads :meth:`~object.__exit__` from the context manager and pushes it onto
+ the stack for later use by :opcode:`WITH_CLEANUP`. Then,
+ :meth:`~object.__enter__` is called, and a finally block pointing to *delta*
+ is pushed. Finally, the result of calling the enter method is pushed onto
+ the stack. The next opcode will either ignore it (:opcode:`POP_TOP`), or
+ store it in (a) variable(s) (:opcode:`STORE_FAST`, :opcode:`STORE_NAME`, or
+ :opcode:`UNPACK_SEQUENCE`).
+
+
.. opcode:: WITH_CLEANUP
Cleans up the stack when a :keyword:`with` statement block exits. TOS is
@@ -507,12 +544,6 @@ the more significant byte last.
are put onto the stack right-to-left.
-.. opcode:: DUP_TOPX (count)
-
- Duplicate *count* items, keeping them in the same order. Due to implementation
- limits, *count* should be between 1 and 5 inclusive.
-
-
.. opcode:: STORE_ATTR (namei)
Implements ``TOS.name = TOS1``, where *namei* is the index of name in
@@ -695,6 +726,12 @@ the more significant byte last.
storage.
+.. opcode:: DELETE_DEREF (i)
+
+ Empties the cell contained in slot *i* of the cell and free variable storage.
+ Used by the :keyword:`del` statement.
+
+
.. opcode:: RAISE_VARARGS (argc)
Raises an exception. *argc* indicates the number of parameters to the raise
diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst
index 5f40432..29fbd64 100644
--- a/Doc/library/doctest.rst
+++ b/Doc/library/doctest.rst
@@ -452,8 +452,9 @@ Some details you should read once, but won't need to remember:
with an alphanumeric is taken to be the start of the exception detail. Of
course this does the right thing for genuine tracebacks.
-* When the :const:`IGNORE_EXCEPTION_DETAIL` doctest option is is specified,
- everything following the leftmost colon is ignored.
+* When the :const:`IGNORE_EXCEPTION_DETAIL` doctest option is specified,
+ everything following the leftmost colon and any module information in the
+ exception name is ignored.
* The interactive shell omits the traceback header line for some
:exc:`SyntaxError`\ s. But doctest uses the traceback header line to
@@ -543,20 +544,38 @@ doctest decides whether actual output matches an example's expected output:
exception raised is ``ValueError: 3*14``, but will fail, e.g., if
:exc:`TypeError` is raised.
- Note that a similar effect can be obtained using :const:`ELLIPSIS`, and
- :const:`IGNORE_EXCEPTION_DETAIL` may go away when Python releases prior to 2.4
- become uninteresting. Until then, :const:`IGNORE_EXCEPTION_DETAIL` is the only
- clear way to write a doctest that doesn't care about the exception detail yet
- continues to pass under Python releases prior to 2.4 (doctest directives appear
- to be comments to them). For example, ::
+ It will also ignore the module name used in Python 3 doctest reports. Hence
+ 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') #doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ CustomError: message
+
+ >>> raise CustomError('message') #doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ my_module.CustomError: message
+
+ Note that :const:`ELLIPSIS` can also be used to ignore the
+ details of the exception message, but such a test may still fail based
+ on whether or not the module details are printed as part of the
+ 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 doctest directives and ignore them
+ as irrelevant comments). For example, ::
>>> (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.4 and Python 2.3. The detail changed in 2.4, to say "does
- not" instead of "doesn't".
+ 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:: 3.2
+ :const:`IGNORE_EXCEPTION_DETAIL` now also ignores any information relating
+ to the module containing the exception under test.
.. data:: SKIP
@@ -671,7 +690,6 @@ 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.
-
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:
@@ -895,18 +913,16 @@ Unittest API
As your collection of doctest'ed modules grows, you'll want a way to run all
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. These test suites can then be run using :mod:`unittest`
-test runners::
+containing doctests. To integrate with :mod:`unittest` test discovery, include
+a :func:`load_tests` function in your test module::
import unittest
import doctest
- import my_module_with_doctests, and_another
+ import my_module_with_doctests
- suite = unittest.TestSuite()
- for mod in my_module_with_doctests, and_another:
- suite.addTest(doctest.DocTestSuite(mod))
- runner = unittest.TextTestRunner()
- runner.run(suite)
+ def load_tests(loader, tests, ignore):
+ tests.addTests(doctest.DocTestSuite(my_module_with_doctests))
+ return tests
There are two main functions for creating :class:`unittest.TestSuite` instances
from text files and modules with doctests:
diff --git a/Doc/library/dummy_threading.rst b/Doc/library/dummy_threading.rst
index 0658df2..b578324 100644
--- a/Doc/library/dummy_threading.rst
+++ b/Doc/library/dummy_threading.rst
@@ -4,6 +4,9 @@
.. module:: dummy_threading
:synopsis: Drop-in replacement for the threading module.
+**Source code:** :source:`Lib/dummy_threading.py`
+
+--------------
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
diff --git a/Doc/library/email-examples.rst b/Doc/library/email-examples.rst
index c1b16da..32cecf3 100644
--- a/Doc/library/email-examples.rst
+++ b/Doc/library/email-examples.rst
@@ -11,6 +11,12 @@ First, let's see how to create and send a simple text message:
.. literalinclude:: ../includes/email-simple.py
+And parsing RFC822 headers can easily be done by the parse(filename) or
+parsestr(message_as_string) methods of the Parser() class:
+
+.. literalinclude:: ../includes/email-headers.py
+
+
Here's an example of how to send a MIME message containing a bunch of family
pictures that may be residing in a directory:
diff --git a/Doc/library/email.generator.rst b/Doc/library/email.generator.rst
index 930905a..85b32fe 100644
--- a/Doc/library/email.generator.rst
+++ b/Doc/library/email.generator.rst
@@ -22,6 +22,12 @@ 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:
@@ -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=False)
+ .. 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,6 +71,21 @@ Here are the public methods of the :class:`Generator` class, imported from the
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.
+
+ 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
@@ -76,11 +97,81 @@ Here are the public methods of the :class:`Generator` class, imported from the
:class:`Generator`'s constructor. This provides just enough file-like API
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
diff --git a/Doc/library/email.header.rst b/Doc/library/email.header.rst
index 2202637..c385cf3 100644
--- a/Doc/library/email.header.rst
+++ b/Doc/library/email.header.rst
@@ -104,25 +104,48 @@ Here is the :class:`Header` class description:
Optional *errors* is passed as the errors argument to the decode call
if *s* is a byte string.
- .. method:: encode(splitchars=';, \\t', maxlinelen=None)
+
+ .. 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.
+
+ 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.
+ *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.
+
+ .. versionchanged:: 3.2
+ Added the *linesep* argument.
+
The :class:`Header` class also provides a number of methods to support
standard operators and built-in functions.
.. method:: __str__()
- A helper for :class:`str`'s :func:`encode` method. Returns the header as
- a Unicode string.
+ 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.
+
+ .. versionchanged:: 3.2
+ Added handling for the `unknown-8bit` charset.
.. method:: __eq__(other)
diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst
index 4b23f6a..1e6a485 100644
--- a/Doc/library/email.message.rst
+++ b/Doc/library/email.message.rst
@@ -112,9 +112,18 @@ 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=None)
@@ -168,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__()
@@ -263,10 +277,10 @@ Here are the methods of the :class:`Message` class:
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),
+ 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``
+ it is automatically encoded in :rfc:`2231` format using a ``CHARSET``
of ``utf-8`` and a ``LANGUAGE`` of ``None``.
Here's an example::
diff --git a/Doc/library/email.parser.rst b/Doc/library/email.parser.rst
index 32f4ff1..77a0b69 100644
--- a/Doc/library/email.parser.rst
+++ b/Doc/library/email.parser.rst
@@ -80,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
^^^^^^^^^^^^^^^^
@@ -131,7 +139,7 @@ class.
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 a flag specifying whether to stop parsing after
@@ -139,25 +147,78 @@ class.
the entire contents of the file.
+.. 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.
+.. 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][, strict])
+.. 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_binary_file(fp, _class=email.message.Message, strict=None)
+
+ 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.
+
+ .. versionadded:: 3.2
+
Here's an example of how you might use this at an interactive Python prompt::
>>> import email
diff --git a/Doc/library/email.rst b/Doc/library/email.rst
index d3f1908..4530b95 100644
--- a/Doc/library/email.rst
+++ b/Doc/library/email.rst
@@ -6,7 +6,7 @@
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
The :mod:`email` package is a library for managing email messages, including
@@ -92,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 a1ce301..f7b777a 100644
--- a/Doc/library/email.util.rst
+++ b/Doc/library/email.util.rst
@@ -105,11 +105,17 @@ There are several useful utilities provided in the :mod:`email.utils` module:
``False``. The default is ``False``.
-.. function:: make_msgid(idstring=None)
+.. 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.
+ 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)
diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst
index 4159287..528febd 100644
--- a/Doc/library/exceptions.rst
+++ b/Doc/library/exceptions.rst
@@ -197,7 +197,7 @@ The following exceptions are the exceptions that are usually raised.
Raised when an operation runs out of memory but the situation may still be
rescued (by deleting some objects). The associated value is a string indicating
what kind of (internal) operation ran out of memory. Note that because of the
- underlying memory management architecture (C's :cfunc:`malloc` function), the
+ underlying memory management architecture (C's :c:func:`malloc` function), the
interpreter may not always be able to completely recover from this situation; it
nevertheless raises an exception so that a stack traceback can be printed, in
case a run-away program was the cause.
@@ -224,8 +224,8 @@ The following exceptions are the exceptions that are usually raised.
This exception is derived from :exc:`EnvironmentError`. It is raised when a
function returns a system-related error (not for illegal argument types or
other incidental errors). The :attr:`errno` attribute is a numeric error
- code from :cdata:`errno`, and the :attr:`strerror` attribute is the
- corresponding string, as would be printed by the C function :cfunc:`perror`.
+ code from :c:data:`errno`, and the :attr:`strerror` attribute is the
+ corresponding string, as would be printed by the C function :c:func:`perror`.
See the module :mod:`errno`, which contains names for the error codes defined
by the underlying operating system.
@@ -261,8 +261,8 @@ The following exceptions are the exceptions that are usually raised.
.. exception:: StopIteration
- Raised by builtin :func:`next` and an :term:`iterator`\'s :meth:`__next__`
- method to signal that there are no further values.
+ Raised by built-in function :func:`next` and an :term:`iterator`\'s
+ :meth:`__next__` method to signal that there are no further values.
.. exception:: SyntaxError
@@ -307,7 +307,7 @@ The following exceptions are the exceptions that are usually 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 an integer, it specifies the system exit status (passed
- to C's :cfunc:`exit` function); if it is ``None``, the exit status is zero;
+ 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.
@@ -380,9 +380,9 @@ The following exceptions are the exceptions that are usually raised.
.. exception:: WindowsError
Raised when a Windows-specific error occurs or when the error number does not
- correspond to an :cdata:`errno` value. The :attr:`winerror` and
+ correspond to an :c:data:`errno` value. The :attr:`winerror` and
:attr:`strerror` values are created from the return values of the
- :cfunc:`GetLastError` and :cfunc:`FormatMessage` functions from the Windows
+ :c:func:`GetLastError` and :c:func:`FormatMessage` functions from the Windows
Platform API. The :attr:`errno` value maps the :attr:`winerror` value to
corresponding ``errno.h`` values. This is a subclass of :exc:`OSError`.
@@ -442,10 +442,20 @@ module for more information.
Base class for warnings related to Unicode.
+
.. 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 dd76d65..6192400 100644
--- a/Doc/library/fcntl.rst
+++ b/Doc/library/fcntl.rst
@@ -12,7 +12,7 @@
pair: UNIX; I/O control
This module performs file control and I/O control on file descriptors. It is an
-interface to the :cfunc:`fcntl` and :cfunc:`ioctl` Unix routines.
+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
@@ -30,17 +30,17 @@ The module defines the following functions:
:mod:`fcntl` module. The argument *arg* is optional, and defaults to the integer
value ``0``. When present, it can either be an integer value, or a string.
With the argument missing or an integer value, the return value of this function
- is the integer return value of the C :cfunc:`fcntl` call. When the argument is
+ is the integer return value of the C :c:func:`fcntl` call. When the argument is
a string it represents a binary structure, e.g. created by :func:`struct.pack`.
The binary data is copied to a buffer whose address is passed to the C
- :cfunc:`fcntl` call. The return value after a successful call is the contents
+ :c:func:`fcntl` call. The return value after a successful call is the contents
of the buffer, converted to a string object. The length of the returned string
will be the same as the length of the *arg* argument. This is limited to 1024
bytes. If the information returned in the buffer by the operating system is
larger than 1024 bytes, this is most likely to result in a segmentation
violation or a more subtle data corruption.
- If the :cfunc:`fcntl` fails, an :exc:`IOError` is raised.
+ If the :c:func:`fcntl` fails, an :exc:`IOError` is raised.
.. function:: ioctl(fd, op[, arg[, mutate_flag]])
@@ -91,7 +91,7 @@ The module defines the following functions:
Perform the lock operation *op* on file descriptor *fd* (file objects providing
a :meth:`fileno` method are accepted as well). See the Unix manual
:manpage:`flock(2)` for details. (On some systems, this function is emulated
- using :cfunc:`fcntl`.)
+ using :c:func:`fcntl`.)
.. function:: lockf(fd, operation, [length, [start, [whence]]])
diff --git a/Doc/library/filecmp.rst b/Doc/library/filecmp.rst
index f57dcce..e0ffff7 100644
--- a/Doc/library/filecmp.rst
+++ b/Doc/library/filecmp.rst
@@ -5,6 +5,9 @@
:synopsis: Compare files efficiently.
.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
+**Source code:** :source:`Lib/filecmp.py`
+
+--------------
The :mod:`filecmp` module defines functions to compare files and directories,
with various optional time/correctness trade-offs. For comparing files,
diff --git a/Doc/library/fileformats.rst b/Doc/library/fileformats.rst
index 980d4f5..e9c2e1f 100644
--- a/Doc/library/fileformats.rst
+++ b/Doc/library/fileformats.rst
@@ -5,7 +5,7 @@ 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::
diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst
index d98a198..ac44311 100644
--- a/Doc/library/fileinput.rst
+++ b/Doc/library/fileinput.rst
@@ -6,6 +6,9 @@
.. moduleauthor:: Guido van Rossum <guido@python.org>
.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
+**Source code:** :source:`Lib/fileinput.py`
+
+--------------
This module implements a helper class and functions to quickly write a
loop over standard input or a list of files. If you just want to read or
@@ -24,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
@@ -54,6 +57,17 @@ The following function is the primary interface of this module:
during iteration. The parameters to this function will be passed along to the
constructor of the :class:`FileInput` class.
+ 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.
@@ -132,13 +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.
+ 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
diff --git a/Doc/library/fnmatch.rst b/Doc/library/fnmatch.rst
index 7fa6148..4ba6b77 100644
--- a/Doc/library/fnmatch.rst
+++ b/Doc/library/fnmatch.rst
@@ -9,6 +9,10 @@
.. index:: module: re
+**Source code:** :source:`Lib/fnmatch.py`
+
+--------------
+
This module provides support for Unix shell-style wildcards, which are *not* the
same as regular expressions (which are documented in the :mod:`re` module). The
special characters used in shell-style wildcards are:
@@ -70,6 +74,8 @@ patterns.
Return the shell-style *pattern* converted to a regular expression.
+ Be aware there is no way to quote meta-characters.
+
Example:
>>> import fnmatch, re
@@ -86,4 +92,3 @@ patterns.
Module :mod:`glob`
Unix shell-style path expansion.
-
diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst
index 7960026..a3ad44a 100644
--- a/Doc/library/fractions.rst
+++ b/Doc/library/fractions.rst
@@ -6,6 +6,9 @@
.. moduleauthor:: Jeffrey Yasskin <jyasskin at gmail.com>
.. sectionauthor:: Jeffrey Yasskin <jyasskin at gmail.com>
+**Source code:** :source:`Lib/fractions.py`
+
+--------------
The :mod:`fractions` module provides support for rational number arithmetic.
@@ -15,17 +18,24 @@ another rational number, or from a string.
.. class:: Fraction(numerator=0, denominator=1)
Fraction(other_fraction)
+ Fraction(float)
+ Fraction(decimal)
Fraction(string)
- The first version requires that *numerator* and *denominator* are
- instances of :class:`numbers.Rational` and returns a new
- :class:`Fraction` instance with value ``numerator/denominator``. If
- *denominator* is :const:`0`, it raises a
- :exc:`ZeroDivisionError`. The second version requires that
- *other_fraction* is an instance of :class:`numbers.Rational` and
- returns an :class:`Fraction` instance with the same value. The
- last version of the constructor expects a string instance. The
- usual form for this string is::
+ The first version requires that *numerator* and *denominator* are instances
+ of :class:`numbers.Rational` and returns a new :class:`Fraction` instance
+ with value ``numerator/denominator``. If *denominator* is :const:`0`, it
+ raises a :exc:`ZeroDivisionError`. The second version requires that
+ *other_fraction* is an instance of :class:`numbers.Rational` and returns a
+ :class:`Fraction` instance with the same value. The next two versions accept
+ either a :class:`float` or a :class:`decimal.Decimal` instance, and return a
+ :class:`Fraction` instance with exactly the same value. Note that due to the
+ usual issues with binary floating-point (see :ref:`tut-fp-issues`), the
+ argument to ``Fraction(1.1)`` is not exactly equal to 11/10, and so
+ ``Fraction(1.1)`` does *not* return ``Fraction(11, 10)`` as one might expect.
+ (But see the documentation for the :meth:`limit_denominator` method below.)
+ The last version of the constructor expects a string or unicode instance.
+ The usual form for this instance is::
[sign] numerator ['/' denominator]
@@ -55,6 +65,13 @@ another rational number, or from a string.
Fraction(-1, 8)
>>> Fraction('7e-6')
Fraction(7, 1000000)
+ >>> Fraction(2.25)
+ Fraction(9, 4)
+ >>> Fraction(1.1)
+ Fraction(2476979795053773, 2251799813685248)
+ >>> from decimal import Decimal
+ >>> Fraction(Decimal('1.1'))
+ Fraction(11, 10)
The :class:`Fraction` class inherits from the abstract base class
@@ -63,6 +80,10 @@ another rational number, or from a string.
and should be treated as immutable. In addition,
:class:`Fraction` has the following methods:
+ .. versionchanged:: 3.2
+ The :class:`Fraction` constructor now accepts :class:`float` and
+ :class:`decimal.Decimal` instances.
+
.. method:: from_float(flt)
@@ -70,12 +91,19 @@ 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 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` instance.
+ .. note:: From Python 3.2 onwards, you can also construct a
+ :class:`Fraction` instance directly from a :class:`decimal.Decimal`
+ instance.
+
.. method:: limit_denominator(max_denominator=1000000)
@@ -90,10 +118,12 @@ another rational number, or from a string.
or for recovering a rational number that's represented as a float:
>>> from math import pi, cos
- >>> Fraction.from_float(cos(pi/3))
+ >>> Fraction(cos(pi/3))
Fraction(4503599627370497, 9007199254740992)
- >>> Fraction.from_float(cos(pi/3)).limit_denominator()
+ >>> Fraction(cos(pi/3)).limit_denominator()
Fraction(1, 2)
+ >>> Fraction(1.1).limit_denominator()
+ Fraction(11, 10)
.. method:: __floor__()
diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst
index 5545505..5bbef4f 100644
--- a/Doc/library/ftplib.rst
+++ b/Doc/library/ftplib.rst
@@ -9,6 +9,10 @@
pair: FTP; protocol
single: FTP; ftplib (standard module)
+**Source code:** :source:`Lib/ftplib.py`
+
+--------------
+
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
@@ -33,8 +37,8 @@ Here's a sample session using the :mod:`ftplib` module::
'226 Transfer complete.'
>>> ftp.quit()
-The module defines the following items:
+The module defines the following items:
.. class:: FTP(host='', user='', passwd='', acct=''[, timeout])
@@ -46,6 +50,61 @@ The module defines the following items:
connection attempt (if is not specified, the global default timeout setting
will be used).
+ :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
+ >>>
+
+ .. 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`.
+ Connect as usual to port 21 implicitly securing the FTP control connection
+ before authenticating. Securing the data connection requires the user to
+ 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:: 3.2
+
+ Here's a sample session using the :class:`FTP_TLS` class:
+
+ >>> from ftplib import FTP_TLS
+ >>> ftps = FTP_TLS('ftp.python.org')
+ >>> ftps.login() # login anonymously before securing control channel
+ >>> ftps.prot_p() # switch to secure data connection
+ >>> ftps.retrlines('LIST') # list directory content securely
+ total 9
+ drwxr-xr-x 8 root wheel 1024 Jan 3 1994 .
+ drwxr-xr-x 8 root wheel 1024 Jan 3 1994 ..
+ drwxr-xr-x 2 root wheel 1024 Jan 3 1994 bin
+ drwxr-xr-x 2 root wheel 1024 Jan 3 1994 etc
+ d-wxrwxr-x 2 ftp wheel 1024 Sep 5 13:43 incoming
+ drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib
+ drwxr-xr-x 6 1094 wheel 1024 Sep 13 19:07 pub
+ drwxr-xr-x 3 root wheel 1024 Jan 3 1994 usr
+ -rw-r--r-- 1 root root 312 Aug 1 1994 welcome.msg
+ '226 Transfer complete.'
+ >>> ftps.quit()
+ >>>
+
.. exception:: error_reply
@@ -197,14 +256,18 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
Passive mode is on by default.
-.. method:: FTP.storbinary(cmd, file, blocksize=8192, callback=None)
+.. method:: FTP.storbinary(cmd, file, blocksize=8192, callback=None, rest=None)
Store a file in binary transfer mode. *cmd* should be an appropriate
``STOR`` command: ``"STOR filename"``. *file* is an open :term:`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.
+ is called on each block of data after it is sent. *rest* means the same thing
+ as in the :meth:`transfercmd` method.
+
+ .. versionchanged:: 3.2
+ *rest* parameter added.
.. method:: FTP.storlines(cmd, file, callback=None)
@@ -319,3 +382,26 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
:meth:`close` or :meth:`quit` you cannot reopen the connection by issuing
another :meth:`login` method).
+
+FTP_TLS Objects
+---------------
+
+:class:`FTP_TLS` class inherits from :class:`FTP`, defining these additional objects:
+
+.. attribute:: FTP_TLS.ssl_version
+
+ The SSL version to use (defaults to *TLSv1*).
+
+.. method:: FTP_TLS.auth()
+
+ Set up secure control connection by using TLS or SSL, depending on what specified in :meth:`ssl_version` attribute.
+
+.. method:: FTP_TLS.prot_p()
+
+ Set up secure data connection.
+
+.. method:: FTP_TLS.prot_c()
+
+ Set up clear text data connection.
+
+
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 1547f6d..3020128 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -10,20 +10,20 @@ are always available. They are listed here in alphabetical order.
=================== ================= ================== ================ ====================
.. .. Built-in Functions .. ..
=================== ================= ================== ================ ====================
-:func:`abs` :func:`dir` :func:`hex` :func:`next` :func:`slice`
-:func:`all` :func:`divmod` :func:`id` :func:`object` :func:`sorted`
-:func:`any` :func:`enumerate` :func:`input` :func:`oct` :func:`staticmethod`
-:func:`ascii` :func:`eval` :func:`int` :func:`open` :func:`str`
-:func:`bin` :func:`exec` :func:`isinstance` :func:`ord` :func:`sum`
-:func:`bool` :func:`filter` :func:`issubclass` :func:`pow` :func:`super`
-:func:`bytearray` :func:`float` :func:`iter` :func:`print` :func:`tuple`
-:func:`bytes` :func:`format` :func:`len` :func:`property` :func:`type`
+: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`
-:func:`dict` :func:`help` :func:`min` :func:`setattr`
=================== ================= ================== ================ ====================
.. function:: abs(x)
@@ -121,6 +121,19 @@ are always available. They are listed here in alphabetical order.
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);
+ 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 the string representing a character whose Unicode codepoint is the integer
@@ -161,7 +174,7 @@ are always available. They are listed here in alphabetical order.
type hierarchy in :ref:`types`.
-.. function:: compile(source, filename, mode, flags=0, dont_inherit=False)
+.. 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 :func:`exec` or :func:`eval`. *source* can either be a string or an AST
@@ -193,16 +206,25 @@ are always 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.
.. note::
- When compiling a string with multi-line statements, line endings must be
- represented by a single newline character (``'\n'``), and the input must
- be terminated by at least one newline character. If line endings are
- represented by ``'\r\n'``, use :meth:`str.replace` to change them into
- ``'\n'``.
+ When compiling a string with multi-line code in ``'single'`` or
+ ``'eval'`` mode, input must be terminated by at least one newline
+ character. This is to facilitate detection of incomplete and complete
+ statements in the :mod:`code` module.
+
+ .. versionchanged:: 3.2
+ Allowed use of Windows and Mac newlines. Also input in ``'exec'`` mode
+ does not have to end in a newline anymore. Added the *optimize* parameter.
.. function:: complex([real[, imag]])
@@ -346,7 +368,7 @@ are always available. They are listed here in alphabetical order.
This function can also be used to execute arbitrary code objects (such as
those created by :func:`compile`). In this case pass a code object instead
of a string. If the code object has been compiled with ``'exec'`` as the
- *kind* argument, :func:`eval`\'s return value will be ``None``.
+ *mode* argument, :func:`eval`\'s return value will be ``None``.
Hints: dynamic execution of statements is supported by the :func:`exec`
function. The :func:`globals` and :func:`locals` functions
@@ -414,26 +436,54 @@ are always available. They are listed here in alphabetical order.
.. 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 an 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,
- ``0.0`` is returned.
-
- .. 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`.
@@ -482,10 +532,10 @@ are always 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)
@@ -653,6 +703,10 @@ are always available. They are listed here in alphabetical order.
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)``.
.. function:: memoryview(obj)
:noindex:
@@ -670,6 +724,10 @@ are always available. They are listed here in alphabetical order.
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])
@@ -971,6 +1029,35 @@ are always available. They are listed here in alphabetical order.
>>> 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:
+
+ >>> 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
+
+ Ranges containing absolute values larger than :data:`sys.maxsize` are permitted
+ but some features (such as :func:`len`) will raise :exc:`OverflowError`.
+
+ .. 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)
@@ -1050,14 +1137,14 @@ are always available. They are listed here in alphabetical order.
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``.
+ key from each list element: ``key=str.lower``. The default value is ``None``
+ (compare the elements directly).
*reverse* is a boolean value. If set to ``True``, then the list elements are
sorted as if each comparison were reversed.
- To convert an old-style *cmp* function to a *key* function, see the
- `CmpToKey recipe in the ASPN cookbook
- <http://code.activestate.com/recipes/576653/>`_\.
+ 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/>`_\.
diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst
index 570f4d2..2316e80 100644
--- a/Doc/library/functools.rst
+++ b/Doc/library/functools.rst
@@ -8,6 +8,9 @@
.. moduleauthor:: Nick Coghlan <ncoghlan@gmail.com>
.. sectionauthor:: Peter Harris <scav@blueyonder.co.uk>
+**Source code:** :source:`Lib/functools.py`
+
+--------------
The :mod:`functools` module is for higher-order functions: functions that act on
or return other functions. In general, any callable object can be treated as a
@@ -15,6 +18,123 @@ function for the purposes of this module.
The :mod:`functools` module defines the following functions:
+.. 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 from Py2.x which supported the use of
+ comparison functions.
+
+ A compare 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 indicating the position in the desired
+ collation sequence.
+
+ Example::
+
+ sorted(iterable, key=cmp_to_key(locale.strcoll)) # locale-aware sort order
+
+ .. 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)
+
+ >>> 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
+ in specifying all of the possible rich comparison operations:
+
+ The class must define one of :meth:`__lt__`, :meth:`__le__`,
+ :meth:`__gt__`, or :meth:`__ge__`.
+ In addition, the class should supply an :meth:`__eq__` method.
+
+ For example::
+
+ @total_ordering
+ class Student:
+ def __eq__(self, other):
+ return ((self.lastname.lower(), self.firstname.lower()) ==
+ (other.lastname.lower(), other.firstname.lower()))
+ def __lt__(self, other):
+ return ((self.lastname.lower(), self.firstname.lower()) <
+ (other.lastname.lower(), other.firstname.lower()))
+
+ .. versionadded:: 3.2
+
+
.. function:: partial(func, *args, **keywords)
Return a new :class:`partial` object which when called will behave like *func*
@@ -70,14 +190,34 @@ The :mod:`functools` module defines the following functions:
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
not updated, the metadata of the returned function will reflect the wrapper
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=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
+.. 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
diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst
index 34aba65..0281bb7 100644
--- a/Doc/library/gc.rst
+++ b/Doc/library/gc.rst
@@ -43,7 +43,7 @@ The :mod:`gc` module provides the following functions:
:exc:`ValueError` is raised if the generation number is invalid. The number of
unreachable objects found is returned.
- The free lists maintained for a number of builtin types are cleared
+ 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`.
@@ -174,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`:
@@ -194,9 +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.
+ 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
diff --git a/Doc/library/getopt.rst b/Doc/library/getopt.rst
index 6a95142..bcfc4b5 100644
--- a/Doc/library/getopt.rst
+++ b/Doc/library/getopt.rst
@@ -1,13 +1,23 @@
-:mod:`getopt` --- Parser for command line options
-=================================================
+:mod:`getopt` --- C-style parser for command line options
+=========================================================
.. module:: getopt
:synopsis: Portable parser for command line options; support both short and
long option names.
+**Source code:** :source:`Lib/getopt.py`
+
+--------------
+
+.. note::
+ The :mod:`getopt` module is a parser for command line options whose API is
+ designed to be familiar to users of the C :c:func:`getopt` function. Users who
+ are unfamiliar with the C :c:func:`getopt` function or who would like to write
+ less code and get better help and error messages should consider using the
+ :mod:`argparse` module instead.
This module helps scripts to parse the command line arguments in ``sys.argv``.
-It supports the same conventions as the Unix :cfunc:`getopt` function (including
+It supports the same conventions as the Unix :c:func:`getopt` function (including
the special meanings of arguments of the form '``-``' and '``--``'). Long
options similar to those supported by GNU software may be used as well via an
optional third argument.
@@ -25,11 +35,11 @@ exception:
be parsed, without the leading reference to the running program. Typically, this
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 :cfunc:`getopt` uses).
+ colon (``':'``; i.e., the same format that Unix :c:func:`getopt` uses).
.. note::
- Unlike GNU :cfunc:`getopt`, after a non-option argument, all further
+ Unlike GNU :c:func:`getopt`, after a non-option argument, all further
arguments are considered also non-options. This is similar to the way
non-GNU Unix systems work.
@@ -136,9 +146,21 @@ In a script, typical usage is something like this::
if __name__ == "__main__":
main()
+Note that an equivalent command line interface could be produced with less code
+and more informative help and error messages by using the :mod:`argparse` module::
+
+ import argparse
+
+ if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-o', '--output')
+ parser.add_argument('-v', dest='verbose', action='store_true')
+ args = parser.parse_args()
+ # ... do something with args.output ...
+ # ... do something with args.verbose ..
.. seealso::
- Module :mod:`optparse`
- More object-oriented command line option parsing.
+ Module :mod:`argparse`
+ Alternative command line option and argument parsing library.
diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst
index 9e1528b..bc825cc 100644
--- a/Doc/library/gettext.rst
+++ b/Doc/library/gettext.rst
@@ -6,6 +6,9 @@
.. moduleauthor:: Barry A. Warsaw <barry@zope.com>
.. sectionauthor:: Barry A. Warsaw <barry@zope.com>
+**Source code:** :source:`Lib/gettext.py`
+
+--------------
The :mod:`gettext` module provides internationalization (I18N) and localization
(L10N) services for your Python modules and applications. It supports both the
diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst
index 3e0322d..3d31c11 100644
--- a/Doc/library/glob.rst
+++ b/Doc/library/glob.rst
@@ -7,6 +7,10 @@
.. index:: single: filenames; pathname expansion
+**Source code:** :source:`Lib/glob.py`
+
+--------------
+
The :mod:`glob` module finds all the pathnames matching a specified pattern
according to the rules used by the Unix shell. No tilde expansion is done, but
``*``, ``?``, and character ranges expressed with ``[]`` will be correctly
diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst
index fdd8590..659a027 100644
--- a/Doc/library/gzip.rst
+++ b/Doc/library/gzip.rst
@@ -4,6 +4,10 @@
.. module:: gzip
:synopsis: Interfaces for gzip compression and decompression using file objects.
+**Source code:** :source:`Lib/gzip.py`
+
+--------------
+
This module provides a simple interface to compress and decompress files just
like the GNU programs :program:`gzip` and :program:`gunzip` would.
@@ -25,10 +29,10 @@ The module defines the following items:
.. 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 :term:`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
@@ -62,15 +66,34 @@ 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:
- :class:`GzipFile` supports the :keyword:`with` statement.
+ .. method:: peek([n])
+
+ 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.
+
+ .. versionadded:: 3.2
.. versionchanged:: 3.1
Support for the :keyword:`with` statement was added.
+ .. versionchanged:: 3.2
+ Support for zero-padded files was added.
+
+ .. versionchanged:: 3.2
+ Support for unseekable files was added.
+
.. function:: open(filename, mode='rb', compresslevel=9)
@@ -78,6 +101,21 @@ The module defines the following items:
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:
@@ -104,6 +142,11 @@ Example of how to GZIP compress an existing file::
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 b73d753..bc8ab2c 100644
--- a/Doc/library/hashlib.rst
+++ b/Doc/library/hashlib.rst
@@ -11,6 +11,10 @@
single: message digest, MD5
single: secure hash algorithm, SHA1, SHA224, SHA256, SHA384, SHA512
+**Source code:** :source:`Lib/hashlib.py`
+
+--------------
+
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
@@ -70,10 +74,13 @@ More condensed:
>>> 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:
@@ -82,6 +89,25 @@ Using :func:`new` with an algorithm provided by OpenSSL:
>>> h.hexdigest()
'cc4a5ce1b3df48aec5d22d1f16b894a0b894eccc'
+Hashlib provides the following constant attributes:
+
+.. data:: algorithms_guaranteed
+
+ Contains the names of the hash algorithms guaranteed to be supported
+ by this module on all platforms.
+
+ .. versionadded:: 3.2
+
+.. 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:
diff --git a/Doc/library/heapq.rst b/Doc/library/heapq.rst
index 7735365..c8634ba 100644
--- a/Doc/library/heapq.rst
+++ b/Doc/library/heapq.rst
@@ -8,6 +8,10 @@
.. sectionauthor:: François Pinard
.. sectionauthor:: Raymond Hettinger
+**Source code:** :source:`Lib/heapq.py`
+
+--------------
+
This module provides an implementation of the heap queue algorithm, also known
as the priority queue algorithm.
diff --git a/Doc/library/hmac.rst b/Doc/library/hmac.rst
index b2bd98d..0ca3eda 100644
--- a/Doc/library/hmac.rst
+++ b/Doc/library/hmac.rst
@@ -7,6 +7,9 @@
.. moduleauthor:: Gerhard Häring <ghaering@users.sourceforge.net>
.. sectionauthor:: Gerhard Häring <ghaering@users.sourceforge.net>
+**Source code:** :source:`Lib/hmac.py`
+
+--------------
This module implements the HMAC algorithm as described by :rfc:`2104`.
diff --git a/Doc/library/html.entities.rst b/Doc/library/html.entities.rst
index aa67bae..239ae50 100644
--- a/Doc/library/html.entities.rst
+++ b/Doc/library/html.entities.rst
@@ -5,6 +5,9 @@
: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`
diff --git a/Doc/library/html.parser.rst b/Doc/library/html.parser.rst
index 1fa11a2..06a3b1a 100644
--- a/Doc/library/html.parser.rst
+++ b/Doc/library/html.parser.rst
@@ -9,12 +9,20 @@
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()
+.. class:: HTMLParser(strict=True)
- The :class:`HTMLParser` class is instantiated without arguments.
+ 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.
An :class:`HTMLParser` instance is fed HTML data and calls handler functions when tags
begin and end. The :class:`HTMLParser` class is meant to be overridden by the
@@ -23,6 +31,8 @@ parsing text files formatted in HTML (HyperText Mark-up Language) and XHTML.
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:
@@ -191,3 +201,8 @@ As a basic example, below is a very basic HTML parser that uses the
Encountered a html end tag
+.. 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..0063db6
--- /dev/null
+++ b/Doc/library/html.rst
@@ -0,0 +1,21 @@
+:mod:`html` --- HyperText Markup Language support
+=================================================
+
+.. module:: html
+ :synopsis: Helpers for manipulating HTML.
+
+.. versionadded:: 3.2
+
+**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="...">``.
diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst
index cbe4f05..704585b 100644
--- a/Doc/library/http.client.rst
+++ b/Doc/library/http.client.rst
@@ -11,30 +11,33 @@
.. 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 the :mod:`socket` module was compiled with
- SSL support.
+ 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=None[, timeout])
+.. class:: HTTPConnection(host, port=None[, 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
+ 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::
@@ -44,24 +47,58 @@ The module provides the following classes:
>>> 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=None[, timeout])
+
+.. class:: HTTPSConnection(host, port=None, key_file=None, cert_file=None[, strict[, timeout[, source_address]]], *, context=None, check_hostname=None)
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, and *cert_file* is a PEM
- formatted certificate chain file; both can be used for authenticating
- yourself against the server.
+ 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).
- .. warning::
- This does not do any verification of the server's certificate.
+ .. versionchanged:: 3.2
+ The *strict* parameter is deprecated. HTTP 0.9-style "Simple Responses"
+ are not supported anymore.
-.. class:: HTTPResponse(sock, debuglevel=0, strict=0, method=None, url=None)
+.. 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:
@@ -360,14 +397,18 @@ HTTPConnection Objects
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.
+ 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.
@@ -389,6 +430,17 @@ HTTPConnection Objects
.. 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 to sent
+ with the CONNECT request.
+
+ .. versionadded:: 3.2
+
+
.. method:: HTTPConnection.connect()
Connect to the server specified when the object was created.
@@ -511,9 +563,8 @@ Here is an example session that uses the ``GET`` method::
>>> data2 = r2.read()
>>> conn.close()
-Here is an example session that uses ``HEAD`` method. Note that ``HEAD`` method
-never returns any data. ::
-
+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")
diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst
index 74d8d16..9771496 100644
--- a/Doc/library/http.cookiejar.rst
+++ b/Doc/library/http.cookiejar.rst
@@ -6,6 +6,9 @@
.. 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
diff --git a/Doc/library/http.cookies.rst b/Doc/library/http.cookies.rst
index 472ddcf..d8a437b 100644
--- a/Doc/library/http.cookies.rst
+++ b/Doc/library/http.cookies.rst
@@ -6,6 +6,9 @@
.. 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
diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst
index 1ca1620..e3a3a10 100644
--- a/Doc/library/http.server.rst
+++ b/Doc/library/http.server.rst
@@ -11,6 +11,10 @@
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.
@@ -155,6 +159,17 @@ of which this module provides three different variants:
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*
@@ -171,13 +186,29 @@ of which this module provides three different variants:
.. 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.
+ 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()
- Sends a blank line, indicating the end of the HTTP headers in the
- response.
+ 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='-')
diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst
index 04088ac..1d92fe5 100644
--- a/Doc/library/imaplib.rst
+++ b/Doc/library/imaplib.rst
@@ -16,6 +16,10 @@
pair: IMAP4_SSL; protocol
pair: IMAP4_stream; protocol
+**Source code:** :source:`Lib/imaplib.py`
+
+--------------
+
This module defines three classes, :class:`IMAP4`, :class:`IMAP4_SSL` and
:class:`IMAP4_stream`, which encapsulate a connection to an IMAP4 server and
implement a large subset of the IMAP4rev1 client protocol as defined in
@@ -56,6 +60,7 @@ 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:
@@ -68,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:
@@ -83,9 +89,9 @@ The following utility functions are defined:
.. function:: Internaldate2tuple(datestr)
- Converts an IMAP4 INTERNALDATE string to Coordinated Universal Time. Returns a
- :mod:`time` module tuple.
-
+ Parse an IMAP4 ``INTERNALDATE`` string and return corresponding local
+ time. The return value is a :class:`time.struct_time` tuple or
+ None if the string has wrong format.
.. function:: Int2AP(num)
@@ -100,9 +106,13 @@ The following utility functions are defined:
.. function:: Time2Internaldate(date_time)
- Converts a :mod:`time` module tuple to an IMAP4 ``INTERNALDATE`` representation.
- Returns a string in the form: ``"DD-Mmm-YYYY HH:MM:SS +HHMM"`` (including
- double-quotes).
+ Convert *date_time* to an IMAP4 ``INTERNALDATE`` representation. The
+ return value is a string in the form: ``"DD-Mmm-YYYY HH:MM:SS
+ +HHMM"`` (including double-quotes). The *date_time* argument can be a
+ number (int or float) represening seconds since epoch (as returned
+ by :func:`time.time`), a 9-tuple representing local time (as returned by
+ :func:`time.localtime`), or a double-quoted string. In the last case, it
+ is assumed to already be in the correct format.
Note that IMAP4 message numbers change as the mailbox changes; in particular,
after an ``EXPUNGE`` command performs deletions the remaining messages are
@@ -408,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*.
diff --git a/Doc/library/imghdr.rst b/Doc/library/imghdr.rst
index 0c0722d..32ec9cf 100644
--- a/Doc/library/imghdr.rst
+++ b/Doc/library/imghdr.rst
@@ -4,6 +4,9 @@
.. module:: imghdr
:synopsis: Determine the type of image contained in a file or byte stream.
+**Source code:** :source:`Lib/imghdr.py`
+
+--------------
The :mod:`imghdr` module determines the type of image contained in a file or
byte stream.
diff --git a/Doc/library/imp.rst b/Doc/library/imp.rst
index 2d83893..6e9845e 100644
--- a/Doc/library/imp.rst
+++ b/Doc/library/imp.rst
@@ -190,8 +190,43 @@ This module provides an interface to the mechanisms used to implement the
continue to use the old class definition. The same is true for derived classes.
-The following constants with integer values, defined in this module, are used to
-indicate the search result of :func:`find_module`.
+The following functions are conveniences for handling :pep:`3147` byte-compiled
+file paths.
+
+.. versionadded:: 3.2
+
+.. function:: cache_from_source(path, debug_override=None)
+
+ 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.
+
+
+.. 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:: get_tag()
+
+ Return the :pep:`3147` magic tag string matching this version of Python's
+ magic number, as returned by :func:`get_magic`.
+
+
+The following constants with integer values, defined in this module, are used
+to indicate the search result of :func:`find_module`.
.. data:: PY_SOURCE
@@ -273,10 +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:: 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 cf13ba3..c9f742a 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -18,12 +18,12 @@ 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 in a programming language other than Python.
+comprehend than one implemented in a programming language other than Python.
-Two, the components to implement :keyword:`import` can be exposed in this
+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 providing custom importers can be found in :pep:`302`.
+Details on custom importers can be found in :pep:`302`.
.. seealso::
@@ -32,12 +32,11 @@ Details on providing custom importers can be found in :pep:`302`.
`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 :keyword:`None`
+ the writing of this document (e.g. redirecting based on ``None``
in :data:`sys.modules`).
The :func:`.__import__` function
- The built-in function for which the :keyword:`import` statement is
- syntactic sugar.
+ The :keyword:`import` statement is syntactic sugar for this function.
:pep:`235`
Import on Case-Insensitive Platforms
@@ -46,7 +45,7 @@ Details on providing custom importers can be found in :pep:`302`.
Defining Python Source Code Encodings
:pep:`302`
- New Import Hooks.
+ New Import Hooks
:pep:`328`
Imports: Multi-Line and Absolute/Relative
@@ -57,14 +56,16 @@ Details on providing custom importers can be found in :pep:`302`.
: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. See the
- built-in function's documentation for usage instructions.
+ An implementation of the built-in :func:`__import__` function.
.. function:: import_module(name, package=None)
@@ -108,7 +109,7 @@ are also provided to help in implementing the core ABCs.
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, :keyword:`None` is returned.
+ cannot be found, ``None`` is returned.
.. class:: Loader
@@ -184,14 +185,14 @@ are also provided to help in implementing the core ABCs.
.. method:: get_code(fullname)
An abstract method to return the :class:`code` object for a module.
- :keyword:`None` is returned if the module does not have a code object
+ ``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.
.. method:: get_source(fullname)
An abstract method to return the source of a module. It is returned as
- a text string with universal newlines. Returns :keyword:`None` if no
+ a text string with universal newlines. Returns ``None`` if no
source is available (e.g. a built-in module). Raises :exc:`ImportError`
if the loader cannot find the module specified.
@@ -202,21 +203,133 @@ are also provided to help in implementing the core ABCs.
: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:`importlib.abc.InspectLoader`
- and :class:`importlib.abc.ResourceLoader` designed to ease the loading of
+ 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:`importlib.abc.PyPycLoader` for a source/bytecode ABC). A subclass
+ :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 :keyword:`None` if there is no source code.
- :exc:`ImportError` if the module cannot be found.
+ 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)
@@ -231,43 +344,62 @@ are also provided to help in implementing the core ABCs.
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`), converting it to standard
- newlines, and compiling it with the built-in :func:`compile` function.
+ :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
+ :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:`importlib.abc.PyLoader`.
+ 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 :keyword:`None`. If the
+ 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 :keyword:`None`
+ specified module, if it exists. It returns ``None``
if no bytecode exists (yet).
- Raises :exc:`ImportError` if the module is not found.
+ 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 :keyword:`True`. Return
- :keyword:`False` if the bytecode could not be written. This method
+ 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.
@@ -311,7 +443,7 @@ find and load modules.
terms of :data:`sys.path`. No implicit path hooks are assumed for
simplification of the class and its semantics.
- Only class method are defined by this class to alleviate the need for
+ Only class methods are defined by this class to alleviate the need for
instantiation.
.. classmethod:: find_module(fullname, path=None)
@@ -325,7 +457,7 @@ find and load modules.
: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 :keyword:`None` is returned.
+ module. If no finder is ever found then ``None`` is returned.
:mod:`importlib.util` -- Utility code for importers
@@ -337,7 +469,7 @@ find and load modules.
This module contains the various objects that help in the construction of
an :term:`importer`.
-.. function:: module_for_loader(method)
+.. decorator:: module_for_loader
A :term:`decorator` for a :term:`loader` method,
to handle selecting the proper
@@ -362,7 +494,7 @@ an :term:`importer`.
Use of this decorator handles all the details of which module object a
loader should initialize as specified by :pep:`302`.
-.. function:: set_loader(fxn)
+.. decorator:: set_loader
A :term:`decorator` for a :term:`loader` method,
to set the :attr:`__loader__`
@@ -370,11 +502,11 @@ an :term:`importer`.
does nothing. It is assumed that the first positional argument to the
wrapped method is what :attr:`__loader__` should be set to.
-.. function:: set_package(fxn)
+.. 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 :keyword:`None` it will not be changed.
+ 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`.
@@ -384,100 +516,3 @@ an :term:`importer`.
attribute to be used at the global level of the module during
initialization.
-
-Example
--------
-
-Below is an example meta path importer that uses a dict for back-end storage
-for source code. While not an optimal solution -- manipulations of
-:attr:`__path__` on packages does not influence import -- it does illustrate
-what little is required to implement an importer.
-
-.. testcode::
-
- """An importer where source is stored in a dict."""
- from importlib import abc
-
-
- class DictImporter(abc.Finder, abc.PyLoader):
-
- """A meta path importer that stores source code in a dict.
-
- The keys are the module names -- packages must end in ``.__init__``.
- The values must be something that can be passed to 'bytes'.
-
- """
-
- def __init__(self, memory):
- """Store the dict."""
- self.memory = memory
-
- def contains(self, name):
- """See if a module or package is in the dict."""
- if name in self.memory:
- return name
- package_name = '{}.__init__'.format(name)
- if package_name in self.memory:
- return package_name
- return False
-
- __contains__ = contains # Convenience.
-
- def find_module(self, fullname, path=None):
- """Find the module in the dict."""
- if fullname in self:
- return self
- return None
-
- def source_path(self, fullname):
- """Return the module name if the module is in the dict."""
- if not fullname in self:
- raise ImportError
- return fullname
-
- def get_data(self, path):
- """Return the bytes for the source.
-
- The value found in the dict is passed through 'bytes' before being
- returned.
-
- """
- name = self.contains(path)
- if not name:
- raise IOError
- return bytes(self.memory[name])
-
- def is_package(self, fullname):
- """Tell if module is a package based on whether the dict contains the
- name with ``.__init__`` appended to it."""
- if fullname not in self:
- raise ImportError
- if fullname in self.memory:
- return False
- # If name is in this importer but not as it is then it must end in
- # ``__init__``.
- else:
- return True
-
-.. testcode::
- :hide:
-
- import importlib
- import sys
-
-
- # Build the dict; keys of name, value of __package__.
- names = {'_top_level': '', '_pkg.__init__': '_pkg', '_pkg.mod': '_pkg'}
- source = {name: "name = {!r}".format(name).encode() for name in names}
-
- # Register the meta path importer.
- importer = DictImporter(source)
- sys.meta_path.append(importer)
-
- # Sanity check.
- for name in names:
- module = importlib.import_module(name)
- assert module.__name__ == name
- assert getattr(module, 'name') == name
- assert module.__loader__ is importer
- assert module.__package__ == names[name]
diff --git a/Doc/library/index.rst b/Doc/library/index.rst
index aa582de..9ac688c 100644
--- a/Doc/library/index.rst
+++ b/Doc/library/index.rst