Merge ~twom/launchpad:oci-recipe-target into launchpad:master
- Git
- lp:~twom/launchpad
- oci-recipe-target
- Merge into master
Proposed by
Tom Wardill
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Tom Wardill | ||||
Approved revision: | fcbd484fb807a247fc69e4cbfd737e4d2232896c | ||||
Merge reported by: | Otto Co-Pilot | ||||
Merged at revision: | not available | ||||
Proposed branch: | ~twom/launchpad:oci-recipe-target | ||||
Merge into: | launchpad:master | ||||
Prerequisite: | ~twom/launchpad:oci-recipe-name | ||||
Diff against target: |
467 lines (+339/-0) 6 files modified
database/schema/security.cfg (+11/-0) lib/lp/registry/configure.zcml (+24/-0) lib/lp/registry/interfaces/ociproject.py (+90/-0) lib/lp/registry/model/ociproject.py (+123/-0) lib/lp/registry/tests/test_ociproject.py (+71/-0) lib/lp/testing/factory.py (+20/-0) |
||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Colin Watson (community) | Approve | ||
Review via email: mp+373756@code.launchpad.net |
Commit message
Implement OCIProject
Description of the change
Add model, interfaces, ZCML and security.cfg
To post a comment you must log in.
- 399e651... by Tom Wardill
-
Rename IOCIRecipeTarge
tSource to IOCIRecipeTargetSet - f84a3fc... by Tom Wardill
-
Add file headers from standard_template
- 8c59ca2... by Tom Wardill
-
Docstrings
Revision history for this message
Colin Watson (cjwatson) : | # |
review:
Needs Fixing
- 03052cf... by Tom Wardill
-
Format imports
- acef142... by Tom Wardill
-
person-merge-job needs UPDATE
- a905e39... by Tom Wardill
-
More standard_template application
- 5895367... by Tom Wardill
-
Interface changes for removing product
- 50007ab... by Tom Wardill
-
Swap distribution for pillar
- 90bd54c... by Tom Wardill
-
Refactor for separate OCIRecipeTargetSet
- 327b7a7... by Tom Wardill
-
Move to getByDistributi
onAndName - 350f719... by Tom Wardill
-
Implement IBugTarget
- 46d29ac... by Tom Wardill
-
Lint errors
- a5f7ee9... by Tom Wardill
-
Split tests
- d047e4a... by Tom Wardill
-
Lint
- 546542a... by Tom Wardill
-
Rename OCIRecipeName to OCIProjectName
- 5b2b9ee... by Tom Wardill
-
Rename OCIRecipeTarget to OCIProject
- ece95d8... by Tom Wardill
-
Bug_supervisor doesn't exist anymore
- a07881b... by Tom Wardill
-
Fix rebase problems
- f232995... by Tom Wardill
-
Erroneous whitespace
- 292ca5c... by Tom Wardill
-
Rename more Recipe to Project
Revision history for this message
Colin Watson (cjwatson) : | # |
review:
Needs Fixing
Revision history for this message
Colin Watson (cjwatson) : | # |
- 610e814... by Tom Wardill
-
Wording fixes and we don't need to implement IHasOwner
- 2aef9e5... by Tom Wardill
-
More wording fixes
- 8147347... by Tom Wardill
-
Test variable fixes
- 0154ec9... by Tom Wardill
-
Export pillar as read only
- fcbd484... by Tom Wardill
-
Export pillar
Revision history for this message
Colin Watson (cjwatson) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/database/schema/security.cfg b/database/schema/security.cfg |
2 | index 899ddde..0e0e91e 100644 |
3 | --- a/database/schema/security.cfg |
4 | +++ b/database/schema/security.cfg |
5 | @@ -1241,6 +1241,7 @@ public.ociproject = SELECT, INSERT, UPDATE, DELETE |
6 | public.ociprojectname = SELECT, INSERT, UPDATE |
7 | public.ociprojectseries = SELECT, INSERT, UPDATE, DELETE |
8 | public.openididentifier = SELECT |
9 | +public.ociproject = SELECT, INSERT, UPDATE, DELETE |
10 | public.ociprojectname = SELECT, INSERT, UPDATE |
11 | public.packageupload = SELECT, INSERT, UPDATE |
12 | public.packageuploadbuild = SELECT, INSERT, UPDATE |
13 | @@ -1417,6 +1418,7 @@ public.message = SELECT, INSERT |
14 | public.messagechunk = SELECT, INSERT |
15 | public.milestone = SELECT |
16 | public.milestonetag = SELECT |
17 | +public.ociproject = SELECT |
18 | public.ociprojectname = SELECT |
19 | public.openididentifier = SELECT |
20 | public.packagecopyjob = SELECT, INSERT |
21 | @@ -1534,6 +1536,7 @@ public.message = SELECT, INSERT |
22 | public.messagechunk = SELECT, INSERT |
23 | public.milestone = SELECT |
24 | public.milestonetag = SELECT |
25 | +public.ociproject = SELECT |
26 | public.ociprojectname = SELECT |
27 | public.openididentifier = SELECT |
28 | public.packagecopyjob = SELECT, INSERT, UPDATE |
29 | @@ -1637,6 +1640,7 @@ public.message = SELECT, INSERT |
30 | public.messagechunk = SELECT, INSERT |
31 | public.milestone = SELECT |
32 | public.milestonetag = SELECT |
33 | +public.ociproject = SELECT |
34 | public.ociprojectname = SELECT |
35 | public.person = SELECT |
36 | public.personlanguage = SELECT |
37 | @@ -1839,6 +1843,7 @@ public.message = SELECT, INSERT |
38 | public.messagechunk = SELECT, INSERT |
39 | public.milestone = SELECT |
40 | public.milestonetag = SELECT, INSERT, DELETE |
41 | +public.ociproject = SELECT |
42 | public.ociprojectname = SELECT |
43 | public.openididentifier = SELECT |
44 | public.packageset = SELECT |
45 | @@ -1959,6 +1964,7 @@ public.libraryfilealias = SELECT, INSERT |
46 | public.libraryfilecontent = SELECT, INSERT |
47 | public.message = SELECT, INSERT |
48 | public.messagechunk = SELECT, INSERT |
49 | +public.ociproject = SELECT |
50 | public.ociprojectname = SELECT |
51 | public.openididentifier = SELECT |
52 | public.person = SELECT |
53 | @@ -2017,6 +2023,7 @@ public.libraryfilecontent = SELECT, INSERT |
54 | public.message = SELECT, INSERT |
55 | public.messagechunk = SELECT, INSERT |
56 | public.milestone = SELECT |
57 | +public.ociproject = SELECT |
58 | public.ociprojectname = SELECT |
59 | public.person = SELECT |
60 | public.personsettings = SELECT |
61 | @@ -2154,6 +2161,7 @@ public.job = SELECT, INSERT, UPDATE |
62 | public.message = SELECT, INSERT |
63 | public.messagechunk = SELECT, INSERT |
64 | public.milestonetag = SELECT |
65 | +public.ociproject = SELECT |
66 | public.ociprojectname = SELECT |
67 | public.person = SELECT, INSERT |
68 | public.personsettings = SELECT, INSERT |
69 | @@ -2544,6 +2552,7 @@ public.distroseries = SELECT |
70 | public.emailaddress = SELECT |
71 | public.gitrepository = SELECT |
72 | public.job = SELECT, INSERT, UPDATE |
73 | +public.ociproject = SELECT |
74 | public.ociprojectname = SELECT |
75 | public.person = SELECT |
76 | public.packaging = SELECT |
77 | @@ -2567,6 +2576,7 @@ public.bugtask = SELECT |
78 | public.bugtaskflat = SELECT |
79 | public.distribution = SELECT |
80 | public.distroseries = SELECT |
81 | +public.ociproject = SELECT |
82 | public.ociprojectname = SELECT |
83 | public.product = SELECT |
84 | public.productseries = SELECT |
85 | @@ -2579,6 +2589,7 @@ public.branch = SELECT |
86 | public.distribution = SELECT |
87 | public.gitrepository = SELECT |
88 | public.job = SELECT, UPDATE |
89 | +public.ociproject = SELECT |
90 | public.ociprojectname = SELECT |
91 | public.person = SELECT |
92 | public.product = SELECT |
93 | diff --git a/lib/lp/registry/configure.zcml b/lib/lp/registry/configure.zcml |
94 | index 730efbb..66f1d14 100644 |
95 | --- a/lib/lp/registry/configure.zcml |
96 | +++ b/lib/lp/registry/configure.zcml |
97 | @@ -734,6 +734,30 @@ |
98 | interface="lp.registry.interfaces.ociprojectname.IOCIProjectNameSet"/> |
99 | </class> |
100 | |
101 | + <!-- OCIProject --> |
102 | + <class |
103 | + class="lp.registry.model.ociproject.OCIProject"> |
104 | + <require |
105 | + permission="launchpad.View" |
106 | + interface="lp.registry.interfaces.ociproject.IOCIProjectView |
107 | + lp.registry.interfaces.ociproject.IOCIProjectEditableAttributes"/> |
108 | + <require |
109 | + permission="launchpad.Edit" |
110 | + set_schema="lp.registry.interfaces.ociproject.IOCIProjectEditableAttributes" /> |
111 | + </class> |
112 | + <securedutility |
113 | + class="lp.registry.model.ociproject.OCIProject" |
114 | + provides="lp.registry.interfaces.ociproject.IOCIProject"> |
115 | + <allow |
116 | + interface="lp.registry.interfaces.ociproject.IOCIProject"/> |
117 | + </securedutility> |
118 | + <securedutility |
119 | + class="lp.registry.model.ociproject.OCIProjectSet" |
120 | + provides="lp.registry.interfaces.ociproject.IOCIProjectSet"> |
121 | + <allow |
122 | + interface="lp.registry.interfaces.ociproject.IOCIProjectSet"/> |
123 | + </securedutility> |
124 | + |
125 | <!-- SourcePackageName --> |
126 | |
127 | <class |
128 | diff --git a/lib/lp/registry/interfaces/ociproject.py b/lib/lp/registry/interfaces/ociproject.py |
129 | new file mode 100644 |
130 | index 0000000..64bb50c |
131 | --- /dev/null |
132 | +++ b/lib/lp/registry/interfaces/ociproject.py |
133 | @@ -0,0 +1,90 @@ |
134 | +# Copyright 2019 Canonical Ltd. This software is licensed under the |
135 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
136 | + |
137 | +"""OCI Project interfaces.""" |
138 | + |
139 | +from __future__ import absolute_import, print_function, unicode_literals |
140 | + |
141 | +__metaclass__ = type |
142 | +__all__ = [ |
143 | + 'IOCIProject', |
144 | + 'IOCIProjectSet', |
145 | + ] |
146 | + |
147 | +from lazr.restful.declarations import ( |
148 | + export_as_webservice_entry, |
149 | + exported, |
150 | + ) |
151 | +from lazr.restful.fields import Reference |
152 | +from zope.interface import ( |
153 | + Attribute, |
154 | + Interface, |
155 | + ) |
156 | +from zope.schema import ( |
157 | + Datetime, |
158 | + Int, |
159 | + Text, |
160 | + ) |
161 | + |
162 | +from lp import _ |
163 | +from lp.bugs.interfaces.bugtarget import IBugTarget |
164 | +from lp.registry.interfaces.distribution import IDistribution |
165 | +from lp.registry.interfaces.ociprojectname import IOCIProjectName |
166 | +from lp.registry.interfaces.role import IHasOwner |
167 | +from lp.services.fields import PublicPersonChoice |
168 | + |
169 | + |
170 | +class IOCIProjectView(Interface): |
171 | + """IOCIProject attributes that require launchpad.View permission.""" |
172 | + |
173 | + id = Int(title=_("ID"), required=True, readonly=True) |
174 | + date_created = exported( |
175 | + Datetime(title=_("Date created"), required=True), readonly=True) |
176 | + date_last_modified = exported( |
177 | + Datetime(title=_("Date last modified"), required=True), readonly=True) |
178 | + |
179 | + registrant = exported(PublicPersonChoice( |
180 | + title=_("Registrant"), |
181 | + description=_("The person that registered this project."), |
182 | + vocabulary='ValidPersonOrTeam', required=True, readonly=True)) |
183 | + |
184 | + |
185 | +class IOCIProjectEditableAttributes(IBugTarget): |
186 | + """IOCIProject attributes that can be edited. |
187 | + |
188 | + These attributes need launchpad.View to see, and launchpad.Edit to change. |
189 | + """ |
190 | + |
191 | + distribution = Reference( |
192 | + IDistribution, |
193 | + title=_("The distribution that this OCI project is associated with.")) |
194 | + ociprojectname = exported(Reference( |
195 | + IOCIProjectName, |
196 | + title=_("The name of this OCI project."), |
197 | + required=True, |
198 | + readonly=True)) |
199 | + description = exported( |
200 | + Text(title=_("The description for this OCI project."))) |
201 | + pillar = exported(Reference( |
202 | + IDistribution, |
203 | + title=_("The pillar containing this target."), readonly=True)) |
204 | + |
205 | + |
206 | +class IOCIProject(IOCIProjectView, |
207 | + IOCIProjectEditableAttributes): |
208 | + """A project containing Open Container Initiative recipes.""" |
209 | + |
210 | + export_as_webservice_entry() |
211 | + |
212 | + |
213 | +class IOCIProjectSet(Interface): |
214 | + """A utility to create and access OCI Projects.""" |
215 | + |
216 | + def new(registrant, pillar, ociprojectname, |
217 | + date_created=None, description=None, |
218 | + bug_reporting_guidelines=None, bug_reported_acknowledgement=None, |
219 | + bugfiling_duplicate_search=False): |
220 | + """Create an `IOCIProject`.""" |
221 | + |
222 | + def getByDistributionAndName(distribution, name): |
223 | + """Get the OCIProjects for a given distribution.""" |
224 | diff --git a/lib/lp/registry/model/ociproject.py b/lib/lp/registry/model/ociproject.py |
225 | new file mode 100644 |
226 | index 0000000..45de84d |
227 | --- /dev/null |
228 | +++ b/lib/lp/registry/model/ociproject.py |
229 | @@ -0,0 +1,123 @@ |
230 | +# Copyright 2019 Canonical Ltd. This software is licensed under the |
231 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
232 | + |
233 | +"""OCI Project implementation.""" |
234 | + |
235 | +from __future__ import absolute_import, print_function, unicode_literals |
236 | + |
237 | +__metaclass__ = type |
238 | +__all__ = [ |
239 | + 'OCIProject', |
240 | + 'OCIProjectSet', |
241 | + ] |
242 | + |
243 | +import pytz |
244 | +from storm.locals import ( |
245 | + Bool, |
246 | + DateTime, |
247 | + Int, |
248 | + Reference, |
249 | + Unicode, |
250 | + ) |
251 | +from zope.interface import implementer |
252 | + |
253 | +from lp.bugs.model.bugtarget import BugTargetBase |
254 | +from lp.registry.interfaces.distribution import IDistribution |
255 | +from lp.registry.interfaces.ociproject import ( |
256 | + IOCIProject, |
257 | + IOCIProjectSet, |
258 | + ) |
259 | +from lp.registry.model.ociprojectname import OCIProjectName |
260 | +from lp.services.database.constants import DEFAULT |
261 | +from lp.services.database.interfaces import ( |
262 | + IMasterStore, |
263 | + IStore, |
264 | + ) |
265 | +from lp.services.database.stormbase import StormBase |
266 | + |
267 | + |
268 | +@implementer(IOCIProject) |
269 | +class OCIProject(BugTargetBase, StormBase): |
270 | + """See `IOCIProject` and `IOCIProjectSet`.""" |
271 | + |
272 | + __storm_table__ = "OCIProject" |
273 | + |
274 | + id = Int(primary=True) |
275 | + date_created = DateTime( |
276 | + name="date_created", tzinfo=pytz.UTC, allow_none=False) |
277 | + date_last_modified = DateTime( |
278 | + name="date_last_modified", tzinfo=pytz.UTC, allow_none=False) |
279 | + |
280 | + registrant_id = Int(name='registrant', allow_none=False) |
281 | + registrant = Reference(registrant_id, "Person.id") |
282 | + |
283 | + distribution_id = Int(name="distribution", allow_none=True) |
284 | + distribution = Reference(distribution_id, "Distribution.id") |
285 | + |
286 | + ociprojectname_id = Int(name="ociprojectname", allow_none=False) |
287 | + ociprojectname = Reference(ociprojectname_id, "OCIProjectName.id") |
288 | + |
289 | + description = Unicode(name="description") |
290 | + |
291 | + bug_reporting_guidelines = Unicode(name="bug_reporting_guidelines") |
292 | + bug_reported_acknowledgement = Unicode(name="bug_reported_acknowledgement") |
293 | + enable_bugfiling_duplicate_search = Bool( |
294 | + name="enable_bugfiling_duplicate_search") |
295 | + |
296 | + @property |
297 | + def pillar(self): |
298 | + """See `IBugTarget`.""" |
299 | + return self.distribution |
300 | + |
301 | + @property |
302 | + def bugtargetname(self): |
303 | + """See `IBugTarget`.""" |
304 | + return "OCI project %s for %s" % ( |
305 | + self.ociprojectname.name, self.pillar.name) |
306 | + |
307 | + @property |
308 | + def bugtargetdisplayname(self): |
309 | + """See `IBugTarget`.""" |
310 | + return "OCI project %s for %s" % ( |
311 | + self.ociprojectname.name, self.pillar.name) |
312 | + |
313 | + |
314 | +@implementer(IOCIProjectSet) |
315 | +class OCIProjectSet: |
316 | + |
317 | + def new(self, registrant, pillar, ociprojectname, |
318 | + date_created=DEFAULT, description=None, |
319 | + bug_reporting_guidelines=None, |
320 | + bug_reported_acknowledgement=None, |
321 | + bugfiling_duplicate_search=False): |
322 | + """See `IOCIProjectSet`.""" |
323 | + store = IMasterStore(OCIProject) |
324 | + target = OCIProject() |
325 | + target.date_created = date_created |
326 | + target.date_last_modified = date_created |
327 | + |
328 | + # XXX twom 2019-10-10 This needs to have IProduct support |
329 | + # when the model supports it |
330 | + if IDistribution.providedBy(pillar): |
331 | + target.distribution = pillar |
332 | + else: |
333 | + raise ValueError( |
334 | + 'The target of an OCIProject must be an ' |
335 | + 'IDistribution instance.') |
336 | + |
337 | + target.registrant = registrant |
338 | + target.ociprojectname = ociprojectname |
339 | + target.description = description |
340 | + target.bug_reporting_guidelines = bug_reporting_guidelines |
341 | + target.enable_bugfiling_duplicate_search = bugfiling_duplicate_search |
342 | + store.add(target) |
343 | + return target |
344 | + |
345 | + def getByDistributionAndName(self, distribution, name): |
346 | + """See `IOCIProjectSet`.""" |
347 | + target = IStore(OCIProject).find( |
348 | + OCIProject, |
349 | + OCIProject.distribution == distribution, |
350 | + OCIProject.ociprojectname == OCIProjectName.id, |
351 | + OCIProjectName.name == name).one() |
352 | + return target |
353 | diff --git a/lib/lp/registry/tests/test_ociproject.py b/lib/lp/registry/tests/test_ociproject.py |
354 | new file mode 100644 |
355 | index 0000000..a68f786 |
356 | --- /dev/null |
357 | +++ b/lib/lp/registry/tests/test_ociproject.py |
358 | @@ -0,0 +1,71 @@ |
359 | +# Copyright 2019 Canonical Ltd. This software is licensed under the |
360 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
361 | + |
362 | +"""Tests for `OCIProject` and `OCIProjectSet`.""" |
363 | + |
364 | +from __future__ import absolute_import, print_function, unicode_literals |
365 | + |
366 | +__metaclass__ = type |
367 | + |
368 | +from zope.component import getUtility |
369 | + |
370 | +from lp.registry.interfaces.ociproject import ( |
371 | + IOCIProject, |
372 | + IOCIProjectSet, |
373 | + ) |
374 | +from lp.testing import ( |
375 | + admin_logged_in, |
376 | + person_logged_in, |
377 | + TestCaseWithFactory, |
378 | + ) |
379 | +from lp.testing.layers import DatabaseFunctionalLayer |
380 | + |
381 | + |
382 | +class TestOCIProject(TestCaseWithFactory): |
383 | + |
384 | + layer = DatabaseFunctionalLayer |
385 | + |
386 | + def test_implements_interface(self): |
387 | + oci_project = self.factory.makeOCIProject() |
388 | + with admin_logged_in(): |
389 | + self.assertProvides(oci_project, IOCIProject) |
390 | + |
391 | + |
392 | +class TestOCIProjectSet(TestCaseWithFactory): |
393 | + |
394 | + layer = DatabaseFunctionalLayer |
395 | + |
396 | + def test_implements_interface(self): |
397 | + target_set = getUtility(IOCIProjectSet) |
398 | + with admin_logged_in(): |
399 | + self.assertProvides(target_set, IOCIProjectSet) |
400 | + |
401 | + def test_new_oci_project(self): |
402 | + registrant = self.factory.makePerson() |
403 | + distribution = self.factory.makeDistribution(owner=registrant) |
404 | + oci_project_name = self.factory.makeOCIProjectName() |
405 | + target = getUtility(IOCIProjectSet).new( |
406 | + registrant, |
407 | + distribution, |
408 | + oci_project_name) |
409 | + with person_logged_in(registrant): |
410 | + self.assertEqual(target.registrant, registrant) |
411 | + self.assertEqual(target.distribution, distribution) |
412 | + self.assertEqual(target.pillar, distribution) |
413 | + self.assertEqual(target.ociprojectname, oci_project_name) |
414 | + |
415 | + def test_getByDistributionAndName(self): |
416 | + registrant = self.factory.makePerson() |
417 | + distribution = self.factory.makeDistribution(owner=registrant) |
418 | + oci_project = self.factory.makeOCIProject( |
419 | + registrant=registrant, pillar=distribution) |
420 | + |
421 | + # Make sure there's more than one to get the result from |
422 | + self.factory.makeOCIProject( |
423 | + pillar=self.factory.makeDistribution()) |
424 | + |
425 | + with person_logged_in(registrant): |
426 | + fetched_result = getUtility( |
427 | + IOCIProjectSet).getByDistributionAndName( |
428 | + distribution, oci_project.ociprojectname.name) |
429 | + self.assertEqual(oci_project, fetched_result) |
430 | diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py |
431 | index ed2536b..5c0cc18 100644 |
432 | --- a/lib/lp/testing/factory.py |
433 | +++ b/lib/lp/testing/factory.py |
434 | @@ -200,6 +200,7 @@ from lp.registry.interfaces.mailinglist import ( |
435 | from lp.registry.interfaces.mailinglistsubscription import ( |
436 | MailingListAutoSubscribePolicy, |
437 | ) |
438 | +from lp.registry.interfaces.ociproject import IOCIProjectSet |
439 | from lp.registry.interfaces.ociprojectname import IOCIProjectNameSet |
440 | from lp.registry.interfaces.packaging import ( |
441 | IPackagingUtil, |
442 | @@ -4902,6 +4903,25 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
443 | name = self.getUniqueString(u"oci-project-name") |
444 | return getUtility(IOCIProjectNameSet).new(name) |
445 | |
446 | + def makeOCIProject(self, registrant=None, pillar=None, |
447 | + ociprojectname=None, date_created=DEFAULT, |
448 | + description=None, bug_reporting_guidelines=None, |
449 | + bug_reported_acknowledgement=None, |
450 | + bugfiling_duplicate_search=False): |
451 | + """Make a new OCIProject.""" |
452 | + if registrant is None: |
453 | + registrant = self.makePerson() |
454 | + if pillar is None: |
455 | + pillar = self.makeDistribution() |
456 | + if ociprojectname is None or isinstance(ociprojectname, six.text_type): |
457 | + ociprojectname = self.makeOCIProjectName(ociprojectname) |
458 | + return getUtility(IOCIProjectSet).new( |
459 | + registrant, pillar, ociprojectname, date_created=date_created, |
460 | + description=description, |
461 | + bug_reporting_guidelines=bug_reporting_guidelines, |
462 | + bug_reported_acknowledgement=bug_reported_acknowledgement, |
463 | + bugfiling_duplicate_search=bugfiling_duplicate_search) |
464 | + |
465 | |
466 | # Some factory methods return simple Python types. We don't add |
467 | # security wrappers for them, as well as for objects created by |