diff options
author | Christian Heimes <christian@cheimes.de> | 2007-12-14 01:24:44 (GMT) |
---|---|---|
committer | Christian Heimes <christian@cheimes.de> | 2007-12-14 01:24:44 (GMT) |
commit | 380532117c2547bb0dedf6f85efa66d18a9abb88 (patch) | |
tree | 33e690cd422859aa0272fbe0a9d1f163e77fbaf2 /Lib | |
parent | 8a78cadf561ea67649a84d9b4055dd4c24e2e0ba (diff) | |
download | cpython-380532117c2547bb0dedf6f85efa66d18a9abb88.zip cpython-380532117c2547bb0dedf6f85efa66d18a9abb88.tar.gz cpython-380532117c2547bb0dedf6f85efa66d18a9abb88.tar.bz2 |
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
........
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/collections.py | 5 | ||||
-rw-r--r-- | Lib/distutils/sysconfig.py | 2 | ||||
-rw-r--r-- | Lib/idlelib/tabbedpages.py | 82 | ||||
-rw-r--r-- | Lib/idlelib/tabpage.py | 113 | ||||
-rw-r--r-- | Lib/test/test_deque.py | 8 | ||||
-rw-r--r-- | Lib/test/test_urlparse.py | 1 | ||||
-rw-r--r-- | Lib/urlparse.py | 2 |
7 files changed, 56 insertions, 157 deletions
diff --git a/Lib/collections.py b/Lib/collections.py index f5c524b..5fb0e05 100644 --- a/Lib/collections.py +++ b/Lib/collections.py @@ -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: diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py index 191f3d1..c450cd5 100644 --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -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, diff --git a/Lib/idlelib/tabbedpages.py b/Lib/idlelib/tabbedpages.py index bb8b1ae..f8d89a4 100644 --- a/Lib/idlelib/tabbedpages.py +++ b/Lib/idlelib/tabbedpages.py @@ -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,9 +402,9 @@ 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, - max_tabs_per_row=max_tabs_per_row, - expand_tabs=expand_tabs) + 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: for name in page_names: self.add_page(name) @@ -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 diff --git a/Lib/idlelib/tabpage.py b/Lib/idlelib/tabpage.py deleted file mode 100644 index 105ef90..0000000 --- a/Lib/idlelib/tabpage.py +++ /dev/null @@ -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() diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py index 890378e..12f77a9 100644 --- a/Lib/test/test_deque.py +++ b/Lib/test/test_deque.py @@ -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)): diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 5cee458..de08613 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -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) diff --git a/Lib/urlparse.py b/Lib/urlparse.py index e5de53a..4317714 100644 --- a/Lib/urlparse.py +++ b/Lib/urlparse.py @@ -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 |