[Python-checkins] r63654 - sandbox/trunk/ttk-gsoc/src/idlelib_ttk.diff
guilherme.polo
python-checkins at python.org
Mon May 26 02:45:10 CEST 2008
Author: guilherme.polo
Date: Mon May 26 02:45:09 2008
New Revision: 63654
Log:
In case ttk is not present, idlelib reacts better now (a lot more to improve here tho)
Modified:
sandbox/trunk/ttk-gsoc/src/idlelib_ttk.diff
Modified: sandbox/trunk/ttk-gsoc/src/idlelib_ttk.diff
==============================================================================
--- sandbox/trunk/ttk-gsoc/src/idlelib_ttk.diff (original)
+++ sandbox/trunk/ttk-gsoc/src/idlelib_ttk.diff Mon May 26 02:45:09 2008
@@ -1,18 +1,22 @@
Index: Lib/idlelib/AutoCompleteWindow.py
===================================================================
---- Lib/idlelib/AutoCompleteWindow.py (revision 63649)
+--- Lib/idlelib/AutoCompleteWindow.py (revision 63650)
+++ Lib/idlelib/AutoCompleteWindow.py (working copy)
-@@ -2,6 +2,7 @@
- An auto-completion window for IDLE, used by the AutoComplete extension
- """
+@@ -4,7 +4,11 @@
from Tkinter import *
-+from ttk import *
from MultiCall import MC_SHIFT
import AutoComplete
++from idlelib.configHandler import idleConf
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
++
+ HIDE_VIRTUAL_EVENT_NAME = "<<autocompletewindow-hide>>"
+ HIDE_SEQUENCES = ("<FocusOut>", "<ButtonPress>")
+ KEYPRESS_VIRTUAL_EVENT_NAME = "<<autocompletewindow-keypress>>"
Index: Lib/idlelib/ToolTip.py
===================================================================
---- Lib/idlelib/ToolTip.py (revision 63649)
+--- Lib/idlelib/ToolTip.py (revision 63650)
+++ Lib/idlelib/ToolTip.py (working copy)
@@ -3,7 +3,8 @@
# may be useful for some purposes in (or almost in ;) the current project scope
@@ -26,17 +30,21 @@
Index: Lib/idlelib/configSectionNameDialog.py
===================================================================
---- Lib/idlelib/configSectionNameDialog.py (revision 63649)
+--- Lib/idlelib/configSectionNameDialog.py (revision 63650)
+++ Lib/idlelib/configSectionNameDialog.py (working copy)
-@@ -3,6 +3,7 @@
- Used to get new highlight theme and keybinding set names.
+@@ -4,7 +4,11 @@
"""
from Tkinter import *
-+from ttk import *
import tkMessageBox
++from idlelib.configHandler import idleConf
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
++
class GetCfgSectionNameDialog(Toplevel):
-@@ -46,7 +47,7 @@
+ def __init__(self,parent,title,message,usedNames):
+ """
+@@ -46,7 +50,7 @@
entryName.focus_set()
self.messageInfo.pack(padx=5,pady=5)#,expand=TRUE,fill=BOTH)
entryName.pack(padx=5,pady=5)
@@ -47,65 +55,93 @@
width=8,command=self.Ok)
Index: Lib/idlelib/PyShell.py
===================================================================
---- Lib/idlelib/PyShell.py (revision 63649)
+--- Lib/idlelib/PyShell.py (revision 63650)
+++ Lib/idlelib/PyShell.py (working copy)
-@@ -18,6 +18,7 @@
-
- try:
- from Tkinter import *
-+ from ttk import *
- except ImportError:
+@@ -22,14 +22,25 @@
print>>sys.__stderr__, "** IDLE can't import Tkinter. " \
"Your Python may not be configured for Tk. **"
-@@ -1381,6 +1382,23 @@
+ sys.exit(1)
++try:
++ from ttk import *
++ TTK = 1
++except ImportError:
++ print >> sys.stderr, "** IDLE can't import ttk."
++ TTK = 0
++
+ import tkMessageBox
+
++from configHandler import idleConf
++
++# store ttk availability
++idleConf.SetOption('main', 'General', 'use-ttk', str(TTK))
++
+ from EditorWindow import EditorWindow, fixwordbreaks
+ from FileList import FileList
+ from ColorDelegator import ColorDelegator
+ from UndoDelegator import UndoDelegator
+ from OutputWindow import OutputWindow
+-from configHandler import idleConf
+ import idlever
+
+ import rpc
+@@ -1381,6 +1392,19 @@
# start editor and/or shell windows:
root = Tk(className="Idle")
-+ # create base styles used along idle files
-+ style = Style()
-+ #if root.tk.eval("tk windowingsystem") == 'x11':
-+ # try:
-+ # style.theme_use("clam")
-+ # except TclError:
-+ # pass
-+
-+ x = style.map('.')
-+ r = {'background': []}
-+ for sspec in x['background']:
-+ if 'active' in sspec[:-1]:
-+ r['background'].append(('!disabled', sspec[-1]))
-+ break
-+ style.map('RootColor.TFrame', **r)
-+ # end styles
++ if TTK:
++ # create base styles used along idle files
++ style = Style()
++
++ x = style.map('.')
++ r = {'background': []}
++ for sspec in x['background']:
++ if 'active' in sspec[:-1]:
++ r['background'].append(('!disabled', sspec[-1]))
++ break
++ style.map('RootColor.TFrame', **r)
++ # end styles
+
fixwordbreaks(root)
root.withdraw()
flist = PyShellFileList(root)
Index: Lib/idlelib/Debugger.py
===================================================================
---- Lib/idlelib/Debugger.py (revision 63649)
+--- Lib/idlelib/Debugger.py (revision 63650)
+++ Lib/idlelib/Debugger.py (working copy)
-@@ -2,6 +2,7 @@
- import bdb
- import types
- from Tkinter import *
-+from ttk import *
+@@ -5,7 +5,10 @@
from WindowList import ListedToplevel
from ScrolledList import ScrolledList
import macosxSupport
++from idlelib.configHandler import idleConf
+
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
+
+ class Idb(bdb.Bdb):
+
Index: Lib/idlelib/configDialog.py
===================================================================
---- Lib/idlelib/configDialog.py (revision 63649)
+--- Lib/idlelib/configDialog.py (revision 63650)
+++ Lib/idlelib/configDialog.py (working copy)
-@@ -10,6 +10,7 @@
+@@ -7,7 +7,6 @@
+ Note that tab width in IDLE is currently fixed at eight due to Tk issues.
+ Refer to comments in EditorWindow autoindent code for details.
+-
"""
from Tkinter import *
-+from ttk import *
import tkMessageBox, tkColorChooser, tkFont
- import string
+@@ -20,6 +19,9 @@
+ from configSectionNameDialog import GetCfgSectionNameDialog
+ from configHelpSourceEdit import GetHelpSourceDialog
+
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
++
+ class ConfigDialog(Toplevel):
-@@ -47,6 +48,7 @@
+ def __init__(self,parent,title):
+@@ -47,6 +49,7 @@
'Shell Stderr Text':('stderr','12'),
}
self.ResetChangedItems() #load initial values in changed items dict
@@ -113,13 +149,12 @@
self.CreateWidgets()
self.resizable(height=FALSE,width=FALSE)
self.transient(parent)
-@@ -64,32 +66,36 @@
+@@ -64,32 +67,35 @@
self.wm_deiconify()
self.wait_window()
+ def SetupStyles(self):
+ style = Style(self.master)
-+ #style.configure('S.TFrame', padding=[0, 2])
+ style.configure('S.TButton', padding=[6, 3])
+ style.configure('S2.TFrame', padding=2)
+ style.configure('Color.TFrame', background='blue')
@@ -265,20 +300,9 @@
def PaintThemeSample(self):
if self.themeIsBuiltin.get(): #a default theme
-Index: Lib/idlelib/SearchEngine.py
-===================================================================
---- Lib/idlelib/SearchEngine.py (revision 63649)
-+++ Lib/idlelib/SearchEngine.py (working copy)
-@@ -1,5 +1,6 @@
- import re
- from Tkinter import *
-+from ttk import *
- import tkMessageBox
-
- def get(root):
Index: Lib/idlelib/ReplaceDialog.py
===================================================================
---- Lib/idlelib/ReplaceDialog.py (revision 63649)
+--- Lib/idlelib/ReplaceDialog.py (revision 63650)
+++ Lib/idlelib/ReplaceDialog.py (working copy)
@@ -11,9 +11,12 @@
dialog.open(text)
@@ -312,9 +336,9 @@
self.do_find(0)
Index: Lib/idlelib/tabbedpages.py
===================================================================
---- Lib/idlelib/tabbedpages.py (revision 63649)
+--- Lib/idlelib/tabbedpages.py (revision 63650)
+++ Lib/idlelib/tabbedpages.py (working copy)
-@@ -1,360 +1,28 @@
+@@ -1,360 +1,34 @@
-"""An implementation of tabbed pages using only standard Tkinter.
+"""Classes exported:
@@ -327,8 +351,14 @@
+TabbedPageSet -- A custom ttk.Notebook used by IDLE.
"""
from Tkinter import *
-+from ttk import *
++from idlelib.configHandler import idleConf
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
++else:
++ print "This will fail for now."
++ class Notebook(object): pass
++
class InvalidNameError(Exception): pass
class AlreadyExistsError(Exception): pass
@@ -684,7 +714,7 @@
"""Constructor arguments:
page_names -- A list of strings, each will be the dictionary key to a
-@@ -362,56 +30,13 @@
+@@ -362,56 +36,13 @@
specified in the desired page order. The first page will be the default
and first active page. If page_names is None or empty, the
TabbedPageSet will be initialized empty.
@@ -744,7 +774,7 @@
def add_page(self, page_name):
"""Add a new page with the name given in page_name."""
if not page_name:
-@@ -420,62 +45,32 @@
+@@ -420,62 +51,32 @@
raise AlreadyExistsError(
"TabPage named '%s' already exists" % page_name)
@@ -823,17 +853,21 @@
buttonAdd=Button(root, text='Add Page',
Index: Lib/idlelib/keybindingDialog.py
===================================================================
---- Lib/idlelib/keybindingDialog.py (revision 63649)
+--- Lib/idlelib/keybindingDialog.py (revision 63650)
+++ Lib/idlelib/keybindingDialog.py (working copy)
-@@ -2,6 +2,7 @@
- Dialog for building Tkinter accelerator key bindings
- """
- from Tkinter import *
-+from ttk import *
+@@ -5,6 +5,11 @@
import tkMessageBox
import string
-@@ -48,7 +49,7 @@
++from idlelib.configHandler import idleConf
++
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
++
+ class GetKeysDialog(Toplevel):
+ def __init__(self,parent,title,action,currentKeySequences):
+ """
+@@ -48,7 +53,7 @@
def CreateWidgets(self):
frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
@@ -844,17 +878,21 @@
width=8,command=self.OK)
Index: Lib/idlelib/configHelpSourceEdit.py
===================================================================
---- Lib/idlelib/configHelpSourceEdit.py (revision 63649)
+--- Lib/idlelib/configHelpSourceEdit.py (revision 63650)
+++ Lib/idlelib/configHelpSourceEdit.py (working copy)
-@@ -4,6 +4,7 @@
- import sys
-
+@@ -6,7 +6,11 @@
from Tkinter import *
-+from ttk import *
import tkMessageBox
import tkFileDialog
++from idlelib.configHandler import idleConf
-@@ -25,6 +26,7 @@
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
++
+ class GetHelpSourceDialog(Toplevel):
+ def __init__(self, parent, title, menuItem='', filePath=''):
+ """Get menu entry and url/ local file location for Additional Help
+@@ -25,6 +29,7 @@
self.protocol("WM_DELETE_WINDOW", self.Cancel)
self.parent = parent
self.result = None
@@ -862,7 +900,7 @@
self.CreateWidgets()
self.menu.set(menuItem)
self.path.set(filePath)
-@@ -64,11 +66,11 @@
+@@ -64,11 +69,11 @@
browseButton = Button(self.frameMain, text='Browse', width=8,
command=self.browseFile)
browseButton.pack(pady=3)
@@ -878,17 +916,21 @@
self.buttonCancel.grid(row=0, column=1, padx=5, pady=5)
Index: Lib/idlelib/GrepDialog.py
===================================================================
---- Lib/idlelib/GrepDialog.py (revision 63649)
+--- Lib/idlelib/GrepDialog.py (revision 63650)
+++ Lib/idlelib/GrepDialog.py (working copy)
-@@ -2,6 +2,7 @@
- import fnmatch
- import sys
+@@ -4,7 +4,11 @@
from Tkinter import *
-+from ttk import *
import SearchEngine
from SearchDialogBase import SearchDialogBase
++from idlelib.configHandler import idleConf
-@@ -15,10 +16,10 @@
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
++
+ def grep(text, io=None, flist=None):
+ root = text._root()
+ engine = SearchEngine.get(root)
+@@ -15,10 +19,10 @@
dialog.open(text, searchphrase, io)
class GrepDialog(SearchDialogBase):
@@ -900,7 +942,7 @@
def __init__(self, root, engine, flist):
SearchDialogBase.__init__(self, root, engine)
-@@ -40,20 +41,18 @@
+@@ -40,20 +44,18 @@
def create_entries(self):
SearchDialogBase.create_entries(self)
@@ -924,7 +966,7 @@
def default_command(self, event=None):
prog = self.engine.getprog()
-@@ -126,8 +125,3 @@
+@@ -126,8 +128,3 @@
for subdir in subdirs:
list.extend(self.findfiles(subdir, base, rec))
return list
@@ -935,17 +977,9 @@
- self.top.withdraw()
Index: Lib/idlelib/EditorWindow.py
===================================================================
---- Lib/idlelib/EditorWindow.py (revision 63649)
+--- Lib/idlelib/EditorWindow.py (revision 63650)
+++ Lib/idlelib/EditorWindow.py (working copy)
-@@ -4,6 +4,7 @@
- import imp
- from itertools import count
- from Tkinter import *
-+from ttk import *
- import tkSimpleDialog
- import tkMessageBox
- from MultiCall import MultiCallCreator
-@@ -365,7 +366,7 @@
+@@ -365,7 +365,7 @@
self.menudict = menudict = {}
for name, label in self.menu_specs:
underline, label = prepstr(label)
@@ -956,17 +990,29 @@
if sys.platform == 'darwin' and '.framework' in sys.executable:
Index: Lib/idlelib/aboutDialog.py
===================================================================
---- Lib/idlelib/aboutDialog.py (revision 63649)
+--- Lib/idlelib/aboutDialog.py (revision 63650)
+++ Lib/idlelib/aboutDialog.py (working copy)
-@@ -3,6 +3,7 @@
- """
-
+@@ -1,13 +1,15 @@
+-"""About Dialog for IDLE
+-
+-"""
+-
++"""About Dialog for IDLE"""
from Tkinter import *
-+from ttk import *
import os
import os.path
import textView
-@@ -15,10 +16,16 @@
+ import idlever
+
++from idlelib.configHandler import idleConf
++
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
++
+ class AboutDialog(Toplevel):
+ """Modal about dialog for idle
+
+@@ -15,10 +17,16 @@
def __init__(self,parent,title):
Toplevel.__init__(self, parent)
self.configure(borderwidth=5)
@@ -983,7 +1029,7 @@
self.CreateWidgets()
self.resizable(height=FALSE, width=FALSE)
self.title(title)
-@@ -31,40 +38,36 @@
+@@ -31,40 +39,36 @@
self.bind('<Escape>',self.Ok) #dismiss dialog
self.wait_window()
@@ -1035,7 +1081,7 @@
labelPythonVer.grid(row=9, column=0, sticky=W, padx=10, pady=0)
# handle weird tk version num in windoze python >= 1.6 (?!?)
tkVer = repr(TkVersion).split('.')
-@@ -73,40 +76,34 @@
+@@ -73,40 +77,34 @@
tkVer[len(tkVer)-1] = '0'
tkVer = '.'.join(tkVer)
labelTkVer = Label(frameBg, text='Tk version: '+
@@ -1082,52 +1128,68 @@
command=self.ShowIDLECredits)
idle_credits_b.pack(side=LEFT, padx=10, pady=10)
+Index: Lib/idlelib/config-main.def
+===================================================================
+--- Lib/idlelib/config-main.def (revision 63650)
++++ Lib/idlelib/config-main.def (working copy)
+@@ -49,6 +49,7 @@
+ print-command-posix=lpr %s
+ print-command-win=start /min notepad /p %s
+ delete-exitfunc= 1
++use-ttk=0
+
+ [EditorWindow]
+ width= 80
Index: Lib/idlelib/IOBinding.py
===================================================================
---- Lib/idlelib/IOBinding.py (revision 63649)
+--- Lib/idlelib/IOBinding.py (revision 63650)
+++ Lib/idlelib/IOBinding.py (working copy)
-@@ -14,6 +14,7 @@
- import tkMessageBox
- import re
- from Tkinter import *
-+from ttk import *
- from SimpleDialog import SimpleDialog
+@@ -18,6 +18,9 @@
from configHandler import idleConf
+
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
++
+ try:
+ from codecs import BOM_UTF8
+ except ImportError:
Index: Lib/idlelib/ScrolledList.py
===================================================================
---- Lib/idlelib/ScrolledList.py (revision 63649)
+--- Lib/idlelib/ScrolledList.py (revision 63650)
+++ Lib/idlelib/ScrolledList.py (working copy)
-@@ -1,4 +1,5 @@
+@@ -1,5 +1,9 @@
from Tkinter import *
-+from ttk import *
++from idlelib.configHandler import idleConf
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
++
class ScrolledList:
-Index: Lib/idlelib/FileList.py
-===================================================================
---- Lib/idlelib/FileList.py (revision 63649)
-+++ Lib/idlelib/FileList.py (working copy)
-@@ -1,5 +1,6 @@
- import os
- from Tkinter import *
-+from ttk import *
- import tkMessageBox
-
-
+ default = "(None)"
Index: Lib/idlelib/textView.py
===================================================================
---- Lib/idlelib/textView.py (revision 63649)
+--- Lib/idlelib/textView.py (revision 63650)
+++ Lib/idlelib/textView.py (working copy)
-@@ -3,6 +3,7 @@
- """
+@@ -1,10 +1,12 @@
+-"""Simple text browser for IDLE
++"""Simple text browser for IDLE"""
+-"""
+-
++import tkMessageBox
from Tkinter import *
-+from ttk import *
- import tkMessageBox
+-import tkMessageBox
++from idlelib.configHandler import idleConf
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
++
class TextViewer(Toplevel):
-@@ -38,19 +39,19 @@
+ """A simple text viewer dialog for IDLE
+
+@@ -38,19 +40,19 @@
def CreateWidgets(self):
frameText = Frame(self, relief=SUNKEN, height=700)
@@ -1154,12 +1216,15 @@
def Ok(self, event=None):
Index: Lib/idlelib/SearchDialogBase.py
===================================================================
---- Lib/idlelib/SearchDialogBase.py (revision 63649)
+--- Lib/idlelib/SearchDialogBase.py (revision 63650)
+++ Lib/idlelib/SearchDialogBase.py (working copy)
-@@ -1,35 +1,37 @@
+@@ -1,35 +1,40 @@
from Tkinter import *
-+from ttk import *
++from idlelib.configHandler import idleConf
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
++
class SearchDialogBase:
title = "Search Dialog"
@@ -1204,7 +1269,7 @@
def create_widgets(self):
top = Toplevel(self.root)
-@@ -38,103 +40,96 @@
+@@ -38,103 +43,96 @@
top.protocol("WM_DELETE_WINDOW", self.close)
top.wm_title(self.title)
top.wm_iconname(self.icon)
@@ -1356,17 +1421,21 @@
+ column += 1
Index: Lib/idlelib/CallTipWindow.py
===================================================================
---- Lib/idlelib/CallTipWindow.py (revision 63649)
+--- Lib/idlelib/CallTipWindow.py (revision 63650)
+++ Lib/idlelib/CallTipWindow.py (working copy)
-@@ -5,6 +5,7 @@
+@@ -5,7 +5,11 @@
"""
from Tkinter import *
-+from ttk import *
++from idlelib.configHandler import idleConf
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
++
HIDE_VIRTUAL_EVENT_NAME = "<<calltipwindow-hide>>"
HIDE_SEQUENCES = ("<Key-Escape>", "<FocusOut>")
-@@ -163,6 +164,8 @@
+ CHECKHIDE_VIRTUAL_EVENT_NAME = "<<calltipwindow-checkhide>>"
+@@ -163,6 +167,8 @@
def calltip_hide(self, event):
self.calltip.hidetip()
@@ -1377,7 +1446,7 @@
c=container()
Index: Lib/idlelib/SearchDialog.py
===================================================================
---- Lib/idlelib/SearchDialog.py (revision 63649)
+--- Lib/idlelib/SearchDialog.py (revision 63650)
+++ Lib/idlelib/SearchDialog.py (working copy)
@@ -21,10 +21,10 @@
return _setup(text).find_selection(text)
@@ -1394,17 +1463,21 @@
if not self.engine.getprog():
Index: Lib/idlelib/TreeWidget.py
===================================================================
---- Lib/idlelib/TreeWidget.py (revision 63649)
+--- Lib/idlelib/TreeWidget.py (revision 63650)
+++ Lib/idlelib/TreeWidget.py (working copy)
-@@ -16,6 +16,7 @@
+@@ -21,6 +21,11 @@
+ import ZoomHeight
+ from configHandler import idleConf
- import os
- from Tkinter import *
-+from ttk import *
- import imp
++from idlelib.configHandler import idleConf
++
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import *
++
+ ICONDIR = "Icons"
- import ZoomHeight
-@@ -68,6 +69,10 @@
+ # Look for Icons subdirectory in the same directory as this module
+@@ -68,6 +73,10 @@
self.x = self.y = None
self.iconimages = {} # cache of PhotoImage instances for icons
@@ -1415,7 +1488,7 @@
def destroy(self):
for c in self.children[:]:
self.children.remove(c)
-@@ -248,7 +253,7 @@
+@@ -248,7 +257,7 @@
label = self.label
except AttributeError:
# padding carefully selected (on Windows) to match Entry widget:
@@ -1424,7 +1497,7 @@
theme = idleConf.GetOption('main','Theme','name')
if self.selected:
self.label.configure(idleConf.GetHighlight(theme, 'hilite'))
-@@ -451,6 +456,8 @@
+@@ -451,6 +460,8 @@
# Testing functions
@@ -1435,15 +1508,19 @@
root = Toplevel(PyShell.root)
Index: Lib/idlelib/MultiStatusBar.py
===================================================================
---- Lib/idlelib/MultiStatusBar.py (revision 63649)
+--- Lib/idlelib/MultiStatusBar.py (revision 63650)
+++ Lib/idlelib/MultiStatusBar.py (working copy)
-@@ -1,4 +1,5 @@
+@@ -1,5 +1,9 @@
from Tkinter import *
-+from ttk import *
++from idlelib.configHandler import idleConf
++if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++ from ttk import Frame, Label
++
class MultiStatusBar(Frame):
-@@ -10,7 +11,7 @@
+ def __init__(self, master=None, **kw):
+@@ -10,7 +14,7 @@
def set_label(self, name, text='', side=LEFT):
if not self.labels.has_key(name):
More information about the Python-checkins
mailing list