Merge lp:~salgado/launchpad/remove-IDBSchema into lp:launchpad

Proposed by Guilherme Salgado
Status: Merged
Approved by: Francis J. Lacoste
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~salgado/launchpad/remove-IDBSchema
Merge into: lp:launchpad
Diff against target: None lines
To merge this branch: bzr merge lp:~salgado/launchpad/remove-IDBSchema
Reviewer Review Type Date Requested Status
Francis J. Lacoste (community) Approve
Review via email: mp+9826@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Guilherme Salgado (salgado) wrote :

= Summary =

While reading the breadcrumbs code I stumbled upon IDBSchema, which I
thought was gone already. After greping around I realized it was not
used anymore, and there were a couple related functions that were being
(ab)used only in a couple places.

== Proposed fix ==

I removed the class and the two functions, fixing the call sites of the
functions. There are a bunch of tests that rely on the unusual terms
generated by said function, so I had to keep them that way instead of
using the terms provided by IEnumeratedType. I added an XXX to explain
why we need to do that.

== Tests ==

I ran lp.bugs.stories and everything pass.

== Demo and Q/A ==

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/canonical/launchpad/webapp/interfaces.py
  lib/canonical/launchpad/webapp/vocabulary.py
  lib/lp/bugs/browser/bugtask.py

== Pylint notices ==

lib/lp/bugs/browser/bugtask.py
    88: [F0401] Unable to import 'lazr.uri' (No module named uri)

Revision history for this message
Francis J. Lacoste (flacoste) wrote :

On August 7, 2009, Guilherme Salgado wrote:
> + # XXX: salgado, 2009-08-07:
> + # We shouldn't have to build our vocabulary out of
> (item.title, + # item) tuples -- iterating over an
> EnumeratedType gives us + # ITokenizedTerms that we could use.
> However, the terms generated + # by EnumeratedType have their
> name as the token and there are + # plenty of tests that expect
> the title as the token.

Hi Salgado,

Good clean-up job.

My only gripe is that XXX should require a bug number. If this is something
that we truly want to change (and break all scripts used to using titles to
pass in status value), then file one. Otherwise, don't use an XXX there.

  status approved
  review approve

Cheers

--
Francis J. Lacoste
<email address hidden>

review: Approve
Revision history for this message
Guilherme Salgado (salgado) wrote :

On Fri, 2009-08-07 at 19:33 +0000, Francis J. Lacoste wrote:
> Review: Approve
> On August 7, 2009, Guilherme Salgado wrote:
> > + # XXX: salgado, 2009-08-07:
> > + # We shouldn't have to build our vocabulary out of
> > (item.title, + # item) tuples -- iterating over an
> > EnumeratedType gives us + # ITokenizedTerms that we could use.
> > However, the terms generated + # by EnumeratedType have their
> > name as the token and there are + # plenty of tests that expect
> > the title as the token.
>
>
> Hi Salgado,
>
> Good clean-up job.
>
> My only gripe is that XXX should require a bug number. If this is something
> that we truly want to change (and break all scripts used to using titles to
> pass in status value), then file one. Otherwise, don't use an XXX there.

There's no easy way of figuring out why this was done (as there's no
comment in the code), but I guess we don't want to break existing
scripts, so I've changed the comment slightly and removed the XXX.

Cheers,

--
Guilherme Salgado <email address hidden>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/webapp/interfaces.py'
2--- lib/canonical/launchpad/webapp/interfaces.py 2009-06-25 05:30:52 +0000
3+++ lib/canonical/launchpad/webapp/interfaces.py 2009-08-07 13:11:49 +0000
4@@ -293,54 +293,6 @@
5 (object_url_requested_for, broken_link_in_chain)
6 )
7
8-#
9-# DBSchema
10-#
11-
12-
13-# XXX kiko 2007-02-08: this is currently unused. We need somebody to come
14-# in and set up interfaces for the enums.
15-class IDBSchema(Interface):
16- """A DBSchema enumeration."""
17-
18- name = Attribute("Lower-cased-spaces-inserted class name of this schema.")
19-
20- title = Attribute("Title of this schema.")
21-
22- description = Attribute("Description of this schema.")
23-
24- items = Attribute("A mapping of [name or value] -> dbschema item.")
25-
26-
27-class IDBSchemaItem(Interface):
28- """An Item in a DBSchema enumeration."""
29-
30- value = Attribute("Integer value of this enum item.")
31-
32- name = Attribute("Symbolic name of this item.")
33-
34- title = Attribute("Title text of this item.")
35-
36- description = Attribute("Description text of this item.")
37-
38- def __sqlrepr__(dbname):
39- """Return an SQL representation of this item.
40-
41- The dbname attribute is required as part of the sqlobject
42- interface, but it not used in this case.
43- """
44-
45- def __eq__(other):
46- """An item is equal if it is from the same DBSchema and has the same
47- value.
48- """
49-
50- def __ne__(other):
51- """not __eq__"""
52-
53- def __hash__():
54- """Returns a hash value."""
55-
56 # XXX kiko 2007-02-08: this needs reconsideration if we are to make it a truly
57 # generic thing. The problem lies in the fact that half of this (user, login,
58 # time zone, developer) is actually useful inside webapp/, and the other half
59
60=== modified file 'lib/canonical/launchpad/webapp/vocabulary.py'
61--- lib/canonical/launchpad/webapp/vocabulary.py 2009-06-25 05:30:52 +0000
62+++ lib/canonical/launchpad/webapp/vocabulary.py 2009-08-07 13:11:49 +0000
63@@ -1,6 +1,8 @@
64 # Copyright 2009 Canonical Ltd. This software is licensed under the
65 # GNU Affero General Public License version 3 (see the file LICENSE).
66
67+# pylint: disable-msg=E0211,E0213
68+
69 """Vocabularies pulling stuff from the database.
70
71 You probably don't want to use these classes directly - see the
72@@ -14,10 +16,8 @@
73 'SQLObjectVocabularyBase',
74 'NamedSQLObjectVocabulary',
75 'NamedSQLObjectHugeVocabulary',
76- 'sortkey_ordered_vocab_factory',
77 'CountableIterator',
78 'BatchedCountableIterator',
79- 'vocab_factory'
80 ]
81
82 from sqlobject import AND, CONTAINSSTRING
83@@ -26,7 +26,6 @@
84 from zope.schema.interfaces import IVocabulary, IVocabularyTokenized
85 from zope.schema.vocabulary import SimpleTerm
86 from zope.security.proxy import isinstance as zisinstance
87-from zope.schema.vocabulary import SimpleVocabulary
88
89 from canonical.database.sqlbase import SQLBase
90
91@@ -353,39 +352,3 @@
92 clause = AND(clause, self._filter)
93 results = self._table.select(clause, orderBy=self._orderBy)
94 return self.iterator(results.count(), results, self.toTerm)
95-
96-
97-# TODO: Make DBSchema classes provide an interface, so we can directly
98-# adapt IDBSchema to IVocabulary
99-def vocab_factory(schema, noshow=None):
100- """Factory for IDBSchema -> IVocabulary adapters.
101-
102- This function returns a callable object that creates vocabularies
103- from dbschemas.
104-
105- The items appear in value order, lowest first.
106- """
107- if noshow is None:
108- noshow = []
109- def factory(context, schema=schema, noshow=noshow):
110- """Adapt IDBSchema to IVocabulary."""
111- items = [(item.title, item) for item in schema.items
112- if item not in noshow]
113- return SimpleVocabulary.fromItems(items)
114- return factory
115-
116-def sortkey_ordered_vocab_factory(schema, noshow=None):
117- """Another factory for IDBSchema -> IVocabulary.
118-
119- This function returns a callable object that creates a vocabulary
120- from a dbschema ordered by that schema's sortkey.
121- """
122- if noshow is None:
123- noshow = []
124- def factory(context, schema=schema, noshow=noshow):
125- """Adapt IDBSchema to IVocabulary."""
126- items = [(item.title, item)
127- for item in schema.items
128- if item not in noshow]
129- return SimpleVocabulary.fromItems(items)
130- return factory
131
132=== modified file 'lib/lp/bugs/browser/bugtask.py'
133--- lib/lp/bugs/browser/bugtask.py 2009-08-04 14:57:07 +0000
134+++ lib/lp/bugs/browser/bugtask.py 2009-08-07 13:11:49 +0000
135@@ -133,7 +133,6 @@
136 from canonical.launchpad.webapp.batching import TableBatchNavigator
137 from canonical.launchpad.webapp.menu import structured
138 from canonical.launchpad.webapp.tales import PersonFormatterAPI
139-from canonical.launchpad.webapp.vocabulary import vocab_factory
140
141 from canonical.lazr.interfaces import IObjectPrivacy
142 from lazr.restful.interfaces import IJSONRequestCache
143@@ -1187,12 +1186,18 @@
144 # The user has to be able to see the current value.
145 status_noshow.remove(self.context.status)
146
147- status_vocab_factory = vocab_factory(
148- BugTaskStatus, noshow=status_noshow)
149+ # XXX: salgado, 2009-08-07:
150+ # We shouldn't have to build our vocabulary out of (item.title,
151+ # item) tuples -- iterating over an EnumeratedType gives us
152+ # ITokenizedTerms that we could use. However, the terms generated
153+ # by EnumeratedType have their name as the token and there are
154+ # plenty of tests that expect the title as the token.
155+ status_items = [
156+ (item.title, item) for item in BugTaskStatus.items
157+ if item not in status_noshow]
158 status_field = Choice(
159- __name__='status',
160- title=self.schema['status'].title,
161- vocabulary=status_vocab_factory(self.context))
162+ __name__='status', title=self.schema['status'].title,
163+ vocabulary=SimpleVocabulary.fromItems(status_items))
164
165 self.form_fields = self.form_fields.omit('status')
166 self.form_fields += formlib.form.Fields(status_field)
167@@ -3013,14 +3018,21 @@
168 def status_widget_items(self):
169 """The available status items as JSON."""
170 if self.user is not None:
171- status_vocab_factory = vocab_factory(
172- BugTaskStatus, noshow=[BugTaskStatus.UNKNOWN])
173+ # XXX: salgado, 2009-08-07:
174+ # We shouldn't have to build our vocabulary out of (item.title,
175+ # item) tuples -- iterating over an EnumeratedType gives us
176+ # ITokenizedTerms that we could use. However, the terms generated
177+ # by EnumeratedType have their name as the token and there are
178+ # plenty of tests that expect the title as the token.
179+ status_items = [
180+ (item.title, item) for item in BugTaskStatus.items
181+ if item != BugTaskStatus.UNKNOWN]
182
183 disabled_items = [status for status in BugTaskStatus.items
184 if not self.context.canTransitionToStatus(status, self.user)]
185
186 items = vocabulary_to_choice_edit_items(
187- status_vocab_factory(self.context),
188+ SimpleVocabulary.fromItems(status_items),
189 css_class_prefix='status',
190 disabled_items=disabled_items)
191 else:
192@@ -3032,11 +3044,18 @@
193 def importance_widget_items(self):
194 """The available status items as JSON."""
195 if self.user is not None:
196- importance_vocab_factory = vocab_factory(
197- BugTaskImportance, noshow=[BugTaskImportance.UNKNOWN])
198+ # XXX: salgado, 2009-08-07:
199+ # We shouldn't have to build our vocabulary out of (item.title,
200+ # item) tuples -- iterating over an EnumeratedType gives us
201+ # ITokenizedTerms that we could use. However, the terms generated
202+ # by EnumeratedType have their name as the token and there are
203+ # plenty of tests that expect the title as the token.
204+ importance_items = [
205+ (item.title, item) for item in BugTaskImportance.items
206+ if item != BugTaskImportance.UNKNOWN]
207
208 items = vocabulary_to_choice_edit_items(
209- importance_vocab_factory(self.context),
210+ SimpleVocabulary.fromItems(importance_items),
211 css_class_prefix='importance')
212 else:
213 items = '[]'
214