Merged revisions 59465-59487 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r59467 | georg.brandl | 2007-12-11 17:32:49 +0100 (Tue, 11 Dec 2007) | 2 lines

  Add another GHOP contributor.
........
  r59468 | kurt.kaiser | 2007-12-11 20:35:12 +0100 (Tue, 11 Dec 2007) | 3 lines

  IDLE_tabbedpages.071101.patch Tal Einat
  Cosmetic changes, one bug.  Remove tabpage.py, replaced by tabbedpages.py
........
  r59471 | gerhard.haering | 2007-12-11 22:07:40 +0100 (Tue, 11 Dec 2007) | 9 lines

  Forward-port of commit 59184.

  - Backported a workaround for a bug in SQLite 3.2.x/3.3.x versions where a
    statement recompilation with no bound parameters lead to a segfault
  - Backported a fix necessary because of an SQLite API change in version
    3.5.
    This prevents segfaults when executing empty queries, like our test suite
    does
........
  r59475 | christian.heimes | 2007-12-12 19:09:06 +0100 (Wed, 12 Dec 2007) | 1 line

  Fixed a nasty problem in the xxmodule.c
........
  r59478 | raymond.hettinger | 2007-12-13 01:08:37 +0100 (Thu, 13 Dec 2007) | 1 line

  Fix bug 1604. deque.__init__() did not clear existing contents like list.__init__. Not a backport candidate.
........
  r59480 | alexandre.vassalotti | 2007-12-13 18:58:23 +0100 (Thu, 13 Dec 2007) | 2 lines

  Fix issue #1313119: urlparse "caches" parses regardless of encoding
........
  r59482 | christian.heimes | 2007-12-13 20:23:16 +0100 (Thu, 13 Dec 2007) | 1 line

  Fixed bug #1613: Makefile's VPATH feature is broken
........
  r59484 | guido.van.rossum | 2007-12-13 21:50:10 +0100 (Thu, 13 Dec 2007) | 3 lines

  Patch #1608.  Someone with access to autoconf 2.61 or higher needs to
  run it and check in the resulting configure file.
........
  r59485 | thomas.heller | 2007-12-13 22:20:29 +0100 (Thu, 13 Dec 2007) | 1 line

  Ran autoconf.
........
  r59486 | raymond.hettinger | 2007-12-13 23:55:52 +0100 (Thu, 13 Dec 2007) | 1 line

  Simplify implementation of __replace__()
........
  r59487 | raymond.hettinger | 2007-12-14 00:52:59 +0100 (Fri, 14 Dec 2007) | 1 line

  Small speedup
........
This commit is contained in:
Christian Heimes 2007-12-14 01:24:44 +00:00
parent 8a78cadf56
commit 380532117c
16 changed files with 86 additions and 166 deletions

View File

@ -136,6 +136,7 @@ docs@python.org), and we'll be glad to correct the problem.
* Tomas Oppelstrup
* Denis S. Otkidach
* Zooko O'Whielacronx
* Shriphani Palakodety
* William Park
* Joonas Paalasmaa
* Harri Pasanen

View File

@ -429,7 +429,7 @@ Example::
return dict(zip(('x', 'y'), self))
def __replace__(self, **kwds):
'Return a new Point object replacing specified fields with new values'
return Point(**dict(zip(('x', 'y'), self) + kwds.items()))
return Point(**dict(zip(('x', 'y'), self), **kwds))
x = property(itemgetter(0))
y = property(itemgetter(1))

View File

@ -2,6 +2,7 @@ __all__ = ['deque', 'defaultdict', 'namedtuple']
from _collections import deque, defaultdict
from operator import itemgetter as _itemgetter
from itertools import izip as _izip
from keyword import iskeyword as _iskeyword
import sys as _sys
@ -70,14 +71,14 @@ def namedtuple(typename, field_names, verbose=False):
return dict(zip(%(field_names)r, self))
def __replace__(self, **kwds):
'Return a new %(typename)s object replacing specified fields with new values'
return %(typename)s(**dict(list(zip(%(field_names)r, self)) + list(kwds.items()))) \n''' % locals()
return %(typename)s(**dict(zip(%(field_names)r, self), **kwds)) \n''' % locals()
for i, name in enumerate(field_names):
template += ' %s = property(itemgetter(%d))\n' % (name, i)
if verbose:
print(template)
# Execute the template string in a temporary namespace
namespace = dict(itemgetter=_itemgetter)
namespace = dict(itemgetter=_itemgetter, zip=_izip)
try:
exec(template, namespace)
except SyntaxError as e:

View File

@ -32,7 +32,7 @@ if os.name == "nt" and "pcbuild" in project_base[-8:].lower():
# building an extension with an un-installed Python, so we use
# different (hard-wired) directories.
python_build = os.path.isfile(os.path.join(project_base, "Modules",
"Setup.dist"))
"Setup.local"))
def get_python_version():
"""Return a string containing the major and minor Python version,

View File

@ -4,7 +4,7 @@ Originally developed for use in IDLE. Based on tabpage.py.
Classes exported:
TabbedPageSet -- A Tkinter implementation of a tabbed-page widget.
TabBarSet -- A widget containing tabs (buttons) in one or more rows.
TabSet -- A widget containing tabs (buttons) in one or more rows.
"""
from Tkinter import *
@ -13,7 +13,7 @@ class InvalidNameError(Exception): pass
class AlreadyExistsError(Exception): pass
class TabBarSet(Frame):
class TabSet(Frame):
"""A widget containing tabs (buttons) in one or more rows.
Only one tab may be selected at a time.
@ -30,11 +30,11 @@ class TabBarSet(Frame):
tabs -- A list of strings, the names of the tabs. Should be specified in
the desired tab order. The first tab will be the default and first
active tab. If tabs is None or empty, the TabBarSet will be initialized
active tab. If tabs is None or empty, the TabSet will be initialized
empty.
n_rows -- Number of rows of tabs to be shown. If n_rows <= 0 or is
None, then the number of rows will be decided by TabBarSet. See
None, then the number of rows will be decided by TabSet. See
_arrange_tabs() for details.
max_tabs_per_row -- Used for deciding how many rows of tabs are needed,
@ -76,15 +76,15 @@ class TabBarSet(Frame):
self._arrange_tabs()
def remove_tab(self, tab_name):
"""Remove the tab with the name given in tab_name."""
"""Remove the tab named <tab_name>"""
if not tab_name in self._tab_names:
raise KeyError("No such Tab: '%s" % page_name)
self._tab_names.remove(tab_name)
self._arrange_tabs()
def select_tab(self, tab_name):
"""Select the tab with the name given in tab_name."""
def set_selected_tab(self, tab_name):
"""Show the tab named <tab_name> as the selected one"""
if tab_name == self._selected_tab:
return
if tab_name is not None and tab_name not in self._tabs:
@ -111,14 +111,11 @@ class TabBarSet(Frame):
tab_row = Frame(self)
tab_row.pack(side=TOP, fill=X, expand=0)
tab_row.tab_set = self
self._tab_rows.append(tab_row)
for tab_name in tab_names:
def tab_command(select_command=self.select_command,
tab_name=tab_name):
return select_command(tab_name)
tab = TabBarSet.TabButton(tab_row, tab_name, tab_command)
tab = TabSet.TabButton(tab_name, self.select_command,
tab_row, self)
if expand_tabs:
tab.pack(side=LEFT, fill=X, expand=True)
else:
@ -126,6 +123,7 @@ class TabBarSet(Frame):
self._tabs[tab_name] = tab
self._tab2row[tab] = tab_row
# tab is the last one created in the above loop
tab.is_last_in_row = True
def _reset_tab_rows(self):
@ -158,8 +156,9 @@ class TabBarSet(Frame):
# calculate the required number of rows
n_rows = (len(self._tab_names) - 1) // self.max_tabs_per_row + 1
i = 0
# not expanding the tabs with more than one row is very ugly
expand_tabs = self.expand_tabs or n_rows > 1
i = 0 # index in self._tab_names
for row_index in range(n_rows):
# calculate required number of tabs in this row
n_tabs = (len(self._tab_names) - i - 1) // (n_rows - row_index) + 1
@ -169,47 +168,60 @@ class TabBarSet(Frame):
# re-select selected tab so it is properly displayed
selected = self._selected_tab
self.select_tab(None)
self.set_selected_tab(None)
if selected in self._tab_names:
self.select_tab(selected)
self.set_selected_tab(selected)
class TabButton(Frame):
"""A simple tab-like widget."""
bw = 2 # borderwidth
def __init__(self, tab_row, name, command):
def __init__(self, name, select_command, tab_row, tab_set):
"""Constructor arguments:
name -- The tab's name, which will appear in its button.
command -- The command to be called upon selection of the tab. It
is called with the tab's name as an argument.
select_command -- The command to be called upon selection of the
tab. It is called with the tab's name as an argument.
"""
Frame.__init__(self, tab_row, borderwidth=self.bw)
self.button = Radiobutton(self, text=name, command=command,
Frame.__init__(self, tab_row, borderwidth=self.bw, relief=RAISED)
self.name = name
self.select_command = select_command
self.tab_set = tab_set
self.is_last_in_row = False
self.button = Radiobutton(
self, text=name, command=self._select_event,
padx=5, pady=1, takefocus=FALSE, indicatoron=FALSE,
highlightthickness=0, selectcolor='', borderwidth=0)
self.button.pack(side=LEFT, fill=X, expand=True)
self.tab_set = tab_row.tab_set
self.is_last_in_row = False
self._init_masks()
self.set_normal()
def _select_event(self, *args):
"""Event handler for tab selection.
With TabbedPageSet, this calls TabbedPageSet.change_page, so that
selecting a tab changes the page.
Note that this does -not- call set_selected -- it will be called by
TabSet.set_selected_tab, which should be called when whatever the
tabs are related to changes.
"""
self.select_command(self.name)
return
def set_selected(self):
"""Assume selected look"""
for widget in self, self.mskl.ml, self.mskr.mr:
widget.config(relief=RAISED)
self._place_masks(selected=True)
def set_normal(self):
"""Assume normal look"""
for widget in self, self.mskl.ml, self.mskr.mr:
widget.config(relief=RAISED)
self._place_masks(selected=False)
def _init_masks(self):
@ -351,8 +363,8 @@ class TabbedPageSet(Frame):
and first active page. If page_names is None or empty, the
TabbedPageSet will be initialized empty.
n_rows, max_tabs_per_row -- Parameters for the TabBarSet which will
manage the tabs. See TabBarSet's docs for details.
n_rows, max_tabs_per_row -- Parameters for the TabSet which will
manage the tabs. See TabSet's docs for details.
page_class -- Pages can be shown/hidden using three mechanisms:
@ -372,7 +384,7 @@ class TabbedPageSet(Frame):
TabbedPageSet to resize when the page is changed.
"""
Frame.__init__(self, parent, kw)
Frame.__init__(self, parent, **kw)
self.page_class = page_class
self.pages = {}
@ -390,7 +402,7 @@ class TabbedPageSet(Frame):
self.pages_frame.rowconfigure(0, weight=1)
# the order of the following commands is important
self._tab_set = TabBarSet(self, self.change_page, n_rows=n_rows,
self._tab_set = TabSet(self, self.change_page, n_rows=n_rows,
max_tabs_per_row=max_tabs_per_row,
expand_tabs=expand_tabs)
if page_names:
@ -453,7 +465,7 @@ class TabbedPageSet(Frame):
self._current_page = page_name
self.pages[page_name]._show()
self._tab_set.select_tab(page_name)
self._tab_set.set_selected_tab(page_name)
if __name__ == '__main__':
# test dialog

View File

@ -1,113 +0,0 @@
"""
a couple of classes for implementing partial tabbed-page like behaviour
"""
from Tkinter import *
class InvalidTabPage(Exception): pass
class AlreadyExists(Exception): pass
class PageTab(Frame):
"""
a 'page tab' like framed button
"""
def __init__(self,parent):
Frame.__init__(self, parent,borderwidth=2,relief=RIDGE)
self.button=Radiobutton(self,padx=5,pady=5,takefocus=FALSE,
indicatoron=FALSE,highlightthickness=0,
borderwidth=0,selectcolor=self.cget('bg'))
self.button.pack()
class TabPageSet(Frame):
"""
a set of 'pages' with TabButtons for controlling their display
"""
def __init__(self,parent,pageNames=[],**kw):
"""
pageNames - a list of strings, each string will be the dictionary key
to a page's data, and the name displayed on the page's tab. Should be
specified in desired page order. The first page will be the default
and first active page.
"""
Frame.__init__(self, parent, kw)
self.grid_location(0,0)
self.columnconfigure(0,weight=1)
self.rowconfigure(1,weight=1)
self.tabBar=Frame(self)
self.tabBar.grid(row=0,column=0,sticky=EW)
self.activePage=StringVar(self)
self.defaultPage=''
self.pages={}
for name in pageNames:
self.AddPage(name)
def ChangePage(self,pageName=None):
if pageName:
if pageName in self.pages:
self.activePage.set(pageName)
else:
raise InvalidTabPage('Invalid TabPage Name')
## pop up the active 'tab' only
for page in self.pages:
self.pages[page]['tab'].config(relief=RIDGE)
self.pages[self.GetActivePage()]['tab'].config(relief=RAISED)
## switch page
self.pages[self.GetActivePage()]['page'].lift()
def GetActivePage(self):
return self.activePage.get()
def AddPage(self,pageName):
if pageName in self.pages.keys():
raise AlreadyExists('TabPage Name Already Exists')
self.pages[pageName]={'tab':PageTab(self.tabBar),
'page':Frame(self,borderwidth=2,relief=RAISED)}
self.pages[pageName]['tab'].button.config(text=pageName,
command=self.ChangePage,variable=self.activePage,
value=pageName)
self.pages[pageName]['tab'].pack(side=LEFT)
self.pages[pageName]['page'].grid(row=1,column=0,sticky=NSEW)
if len(self.pages)==1: # adding first page
self.defaultPage=pageName
self.activePage.set(self.defaultPage)
self.ChangePage()
def RemovePage(self,pageName):
if not pageName in self.pages:
raise InvalidTabPage('Invalid TabPage Name')
self.pages[pageName]['tab'].pack_forget()
self.pages[pageName]['page'].grid_forget()
self.pages[pageName]['tab'].destroy()
self.pages[pageName]['page'].destroy()
del(self.pages[pageName])
# handle removing last remaining, or default, or active page
if not self.pages: # removed last remaining page
self.defaultPage=''
return
if pageName==self.defaultPage: # set a new default page
self.defaultPage=\
self.tabBar.winfo_children()[0].button.cget('text')
if pageName==self.GetActivePage(): # set a new active page
self.activePage.set(self.defaultPage)
self.ChangePage()
if __name__ == '__main__':
#test dialog
root=Tk()
tabPage=TabPageSet(root,pageNames=['Foobar','Baz'])
tabPage.pack(expand=TRUE,fill=BOTH)
Label(tabPage.pages['Foobar']['page'],text='Foo',pady=20).pack()
Label(tabPage.pages['Foobar']['page'],text='Bar',pady=20).pack()
Label(tabPage.pages['Baz']['page'],text='Baz').pack()
entryPgName=Entry(root)
buttonAdd=Button(root,text='Add Page',
command=lambda:tabPage.AddPage(entryPgName.get()))
buttonRemove=Button(root,text='Remove Page',
command=lambda:tabPage.RemovePage(entryPgName.get()))
labelPgName=Label(root,text='name of page to add/remove:')
buttonAdd.pack(padx=5,pady=5)
buttonRemove.pack(padx=5,pady=5)
labelPgName.pack(padx=5)
entryPgName.pack(padx=5)
tabPage.ChangePage()
root.mainloop()

View File

@ -29,8 +29,8 @@ class MutateCmp:
class TestBasic(unittest.TestCase):
def test_basics(self):
d = deque(range(100))
d.__init__(range(100, 200))
d = deque(range(-5125, -5000))
d.__init__(range(200))
for i in range(200, 400):
d.append(i)
for i in reversed(range(-200, 0)):
@ -433,8 +433,8 @@ class DequeWithBadIter(deque):
class TestSubclass(unittest.TestCase):
def test_basics(self):
d = Deque(range(100))
d.__init__(range(100, 200))
d = Deque(range(25))
d.__init__(range(200))
for i in range(200, 400):
d.append(i)
for i in reversed(range(-200, 0)):

View File

@ -287,7 +287,6 @@ class UrlParseTestCase(unittest.TestCase):
self.assertEqual(p.port, None)
self.assertEqual(p.geturl(), uri)
def test_main():
test_support.run_unittest(UrlParseTestCase)

View File

@ -184,7 +184,7 @@ def urlsplit(url, scheme='', allow_fragments=True):
Note that we don't break the components up in smaller bits
(e.g. netloc is a single string) and we don't expand % escapes."""
allow_fragments = bool(allow_fragments)
key = url, scheme, allow_fragments
key = url, scheme, allow_fragments, type(url), type(scheme)
cached = _parse_cache.get(key, None)
if cached:
return cached

View File

@ -168,6 +168,7 @@ Yves Dionne
Daniel Dittmar
Walter Dörwald
Jaromir Dolecek
Ismail Donmez
Dima Dorfman
Cesar Douady
Dean Draayer

View File

@ -784,6 +784,7 @@ deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs)
}
}
deque->maxlen = maxlen;
deque_clear(deque);
if (iterable != NULL) {
PyObject *rv = deque_extend(deque, iterable);
if (rv == NULL)

View File

@ -231,7 +231,11 @@ int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* params)
*/
#ifdef SQLITE_VERSION_NUMBER
#if SQLITE_VERSION_NUMBER >= 3002002
/* The check for the number of parameters is necessary to not trigger a
* bug in certain SQLite versions (experienced in 3.2.8 and 3.3.4). */
if (sqlite3_bind_parameter_count(self->st) > 0) {
(void)sqlite3_transfer_bindings(self->st, new_st);
}
#endif
#else
statement_bind_parameters(self, params);

View File

@ -28,9 +28,15 @@ int _sqlite_step_with_busyhandler(sqlite3_stmt* statement, pysqlite_Connection*
{
int rc;
if (statement == NULL) {
/* this is a workaround for SQLite 3.5 and later. it now apparently
* returns NULL for "no-operation" statements */
rc = SQLITE_OK;
} else {
Py_BEGIN_ALLOW_THREADS
rc = sqlite3_step(statement);
Py_END_ALLOW_THREADS
}
return rc;
}

View File

@ -349,7 +349,7 @@ initxx(void)
Str_Type.tp_base = &PyUnicode_Type;
/* Finalize the type object including setting type of the new type
* object; doing it here is required for portability, too. /*
* object; doing it here is required for portability, too. */
if (PyType_Ready(&Xxo_Type) < 0)
return;

8
configure vendored
View File

@ -1,5 +1,5 @@
#! /bin/sh
# From configure.in Revision: 59247 .
# From configure.in Revision: 59484 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61 for python 3.0.
#
@ -4403,6 +4403,10 @@ then
if test "$CC" != 'g++' ; then
STRICT_PROTO="-Wstrict-prototypes"
fi
# For gcc 4.x we need to use -fwrapv so lets check if its supported
if "$CC" -v --help 2>/dev/null |grep -- -fwrapv > /dev/null; then
WRAP="-fwrapv"
fi
case $ac_cv_prog_cc_g in
yes)
if test "$Py_DEBUG" = 'true' ; then
@ -4410,7 +4414,7 @@ then
# debug builds.
OPT="-g -Wall $STRICT_PROTO"
else
OPT="-g -O3 -Wall $STRICT_PROTO"
OPT="-g $WRAP -O3 -Wall $STRICT_PROTO"
fi
;;
*)

View File

@ -732,6 +732,10 @@ then
if test "$CC" != 'g++' ; then
STRICT_PROTO="-Wstrict-prototypes"
fi
# For gcc 4.x we need to use -fwrapv so lets check if its supported
if "$CC" -v --help 2>/dev/null |grep -- -fwrapv > /dev/null; then
WRAP="-fwrapv"
fi
case $ac_cv_prog_cc_g in
yes)
if test "$Py_DEBUG" = 'true' ; then
@ -739,7 +743,7 @@ then
# debug builds.
OPT="-g -Wall $STRICT_PROTO"
else
OPT="-g -O3 -Wall $STRICT_PROTO"
OPT="-g $WRAP -O3 -Wall $STRICT_PROTO"
fi
;;
*)