Merge lp:~sinzui/launchpad/stop-shouting-0 into lp:launchpad

Proposed by Curtis Hovey
Status: Merged
Approved by: Brad Crittenden
Approved revision: no longer in the source branch.
Merged at revision: 11285
Proposed branch: lp:~sinzui/launchpad/stop-shouting-0
Merge into: lp:launchpad
Diff against target: 517 lines (+84/-95)
10 files modified
lib/canonical/launchpad/doc/tales.txt (+5/-4)
lib/lp/registry/browser/tests/milestone-views.txt (+2/-5)
lib/lp/registry/browser/tests/product-files-views.txt (+4/-2)
lib/lp/registry/browser/tests/productseries-views.txt (+6/-12)
lib/lp/registry/browser/tests/test_breadcrumbs.py (+2/-0)
lib/lp/registry/configure.zcml (+2/-0)
lib/lp/registry/tests/test_distribution.py (+3/-9)
lib/lp/registry/tests/test_distroseries.py (+16/-24)
lib/lp/registry/tests/test_sourcepackage.py (+7/-10)
lib/lp/testing/factory.py (+37/-29)
To merge this branch: bzr merge lp:~sinzui/launchpad/stop-shouting-0
Reviewer Review Type Date Requested Status
Brad Crittenden (community) code Approve
Review via email: mp+31423@code.launchpad.net

Description of the change

This is my branch to stop the shouting about naked objects in tests.

    lp:~sinzui/launchpad/stop-shouting-0
    Diff size: 290
    Test command: ./bin/test -vv \
          -t registry.*test_(distroseries|sourcepackage
          -t milestone-views -t productseries-views
    Pre-implementation: jml, bigjools
    Target release: 10.08

Stop the shouting about naked objects in tests
----------------------------------------------

I cannot work because I keep seeing annoying messages. This branch address
the ones that affect my feature branch.

ADDENDUM: There was a real error in a test that would have been caught if
the test has not removed the proxy. I will explain below.

Rules
-----

    * Return a proxied object from the factory.
    * Do not unwrap objects, log in to make the factory hack the attribute
      for the test.

QA
--

None, this is a test runner.

Lint
----

Linting changed files:
  lib/lp/registry/browser/tests/milestone-views.txt
  lib/lp/registry/browser/tests/productseries-views.txt
  lib/lp/registry/tests/test_distroseries.py
  lib/lp/registry/tests/test_sourcepackage.py
  lib/lp/testing/factory.py

Test
----

    * lib/lp/registry/browser/tests/milestone-views.txt
      * Login as the project owner to set the driver.
    * lib/lp/registry/browser/tests/productseries-views.txt
      * Use a better factory method to get a product series
      * Wrap the long line.
      * Print the title of the enum ()
      * Change the factory to hack the non-writable ProductSeries.datecreated
    * lib/lp/registry/tests/test_distroseries.py
      * Login as the distro or project owner to set the object field.
      * NOTE: product.bugtracker was misspelled in the first test!
        The prioritised listing is incrementing the score for *missing*
        information. Thus by adding a bugtracker, to cold, we expect that
        package to have a lower score...it is missing less information.
        This test was always wrong.
    * lib/lp/registry/tests/test_sourcepackage.py
      * Login as project owner to set the status.

Implementation
--------------

    * lib/lp/testing/factory.py
      * Hush lint: remove unused or redundant imports, wrap long lines.
      * Return proxied milestone, productseries,
        SourcePackagePublishingHistory (note that it was created, then
        looked up again??).
      * DistributionSourcePackage is implicitly wrapped when called via
        distribution.getSourcePackage()

To post a comment you must log in.
Revision history for this message
Brad Crittenden (bac) wrote :

Thanks for doing this work Curtis. Hopefully the other areas of LP will do the same soon.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/doc/tales.txt'
2--- lib/canonical/launchpad/doc/tales.txt 2010-07-15 08:38:19 +0000
3+++ lib/canonical/launchpad/doc/tales.txt 2010-08-03 22:52:48 +0000
4@@ -635,7 +635,8 @@
5 When the ProductReleaseFile is not signed, the link for the signature is
6 not included.
7
8- >>> release_file = factory.makeProductReleaseFile(signed=False)
9+ >>> release_file = factory.makeProductReleaseFile(
10+ ... signed=False)
11 >>> html = test_tales("release_file/fmt:link", release_file=release_file)
12 >>> soup = BeautifulSoup(html)
13 >>> print_hrefs_with_titles(html)
14@@ -649,8 +650,8 @@
15
16 HTML in the file description is escaped in the fmt:link.
17
18- >>> release_file.description = (
19- ... '><script>XSS failed</script>')
20+ >>> release_file = factory.makeProductReleaseFile(
21+ ... signed=False, description='><script>XSS failed</script>')
22 >>> print test_tales("release_file/fmt:link", release_file=release_file)
23 <img ...
24 <a title="&gt;&lt;script&gt;XSS failed&lt;/script&gt; (4 bytes)"
25@@ -661,7 +662,7 @@
26 Product series
27 ..............
28
29- >>> product_series = factory.makeSeries()
30+ >>> product_series = factory.makeProductSeries()
31 >>> test_tales("product_series/fmt:link", product_series=product_series)
32 u'... series...'
33
34
35=== modified file 'lib/lp/registry/browser/tests/milestone-views.txt'
36--- lib/lp/registry/browser/tests/milestone-views.txt 2010-07-20 17:50:45 +0000
37+++ lib/lp/registry/browser/tests/milestone-views.txt 2010-08-03 22:52:48 +0000
38@@ -579,13 +579,10 @@
39 The driver of a series that belongs to an `IDerivativeDistribution` is a
40 release manager and can create milestones.
41
42- >>> from lp.testing.factory import (
43- ... remove_security_proxy_and_shout_at_engineer)
44 >>> distroseries = factory.makeDistroRelease(name='pumpkin')
45 >>> driver = factory.makePerson(name='a-driver')
46- >>> naked_distroseries = remove_security_proxy_and_shout_at_engineer(
47- ... distroseries)
48- >>> naked_distroseries.driver = driver
49+ >>> login_person(distroseries.distribution.owner)
50+ >>> distroseries.driver = driver
51 >>> login_person(driver)
52
53 >>> form = {
54
55=== modified file 'lib/lp/registry/browser/tests/product-files-views.txt'
56--- lib/lp/registry/browser/tests/product-files-views.txt 2010-06-11 14:25:40 +0000
57+++ lib/lp/registry/browser/tests/product-files-views.txt 2010-08-03 22:52:48 +0000
58@@ -4,7 +4,8 @@
59 Test for the product/+download page.
60
61 >>> product = factory.makeProduct(name='alfajore')
62- >>> productseries = factory.makeSeries(product=product, name="sammy")
63+ >>> productseries = factory.makeProductSeries(
64+ ... product=product, name="sammy")
65 >>> milestone = factory.makeMilestone(productseries=productseries,
66 ... name="apple")
67 >>> release_file = factory.makeProductReleaseFile(
68@@ -28,7 +29,8 @@
69
70 >>> product = factory.makeProduct(name='bombilla')
71 >>> for i in range(1,5):
72- ... productseries = factory.makeSeries(product=product, name="s%d"%i)
73+ ... productseries = factory.makeProductSeries(
74+ ... product=product, name="s%d"%i)
75 ... for j in range(1,4):
76 ... milestone = factory.makeMilestone(productseries=productseries,
77 ... name="%d.%d"%(i,j))
78
79=== modified file 'lib/lp/registry/browser/tests/productseries-views.txt'
80--- lib/lp/registry/browser/tests/productseries-views.txt 2010-07-20 17:50:45 +0000
81+++ lib/lp/registry/browser/tests/productseries-views.txt 2010-08-03 22:52:48 +0000
82@@ -12,7 +12,7 @@
83 >>> from lp.testing.menu import check_menu_links
84
85 >>> product = factory.makeProduct(name='app')
86- >>> series = factory.makeSeries(name='simple', product=product)
87+ >>> series = factory.makeProductSeries(name='simple', product=product)
88 >>> check_menu_links(ProductSeriesOverviewMenu(series))
89 True
90
91@@ -80,7 +80,8 @@
92 >>> script = find_tag_by_id(view.render(), 'milestone-script')
93 >>> print script
94 <script id="milestone-script" type="text/javascript">
95- YUI().use(... 'lp.registry.milestoneoverlay', 'lp.registry.milestonetable'...
96+ YUI().use(... 'lp.registry.milestoneoverlay',
97+ 'lp.registry.milestonetable'...
98 var series_uri = '/app/simple';
99 var milestone_form_uri = '.../app/simple/+addmilestone/++form++';
100 var milestone_row_uri =
101@@ -130,7 +131,7 @@
102
103 >>> from lp.registry.interfaces.series import SeriesStatus
104
105- >>> print series.status
106+ >>> print series.status.title
107 Active Development
108 >>> view.is_obsolete
109 False
110@@ -255,20 +256,13 @@
111
112 >>> from datetime import datetime
113 >>> from pytz import UTC
114- >>> from lp.testing.factory import (
115- ... remove_security_proxy_and_shout_at_engineer)
116
117+ >>> test_date = datetime(2009, 05, 01, 19, 34, 24, tzinfo=UTC)
118 >>> product = factory.makeProduct(name="field", displayname='Field')
119 >>> productseries = factory.makeProductSeries(
120- ... product=product, name='rabbit')
121+ ... product=product, name='rabbit', date_created=test_date)
122 >>> productseries.releasefileglob = 'http://eg.dom/rabbit/*'
123
124- # Hack the creation date for testing purposes.
125- >>> test_date = datetime(2009, 05, 01, 19, 34, 24, tzinfo=UTC)
126- >>> naked_productseries = remove_security_proxy_and_shout_at_engineer(
127- ... productseries)
128- >>> naked_productseries.datecreated = test_date
129-
130 Users without edit permission cannot access the view.
131
132 >>> from canonical.launchpad.webapp.authorization import check_permission
133
134=== modified file 'lib/lp/registry/browser/tests/test_breadcrumbs.py'
135--- lib/lp/registry/browser/tests/test_breadcrumbs.py 2010-04-28 10:13:00 +0000
136+++ lib/lp/registry/browser/tests/test_breadcrumbs.py 2010-08-03 22:52:48 +0000
137@@ -10,6 +10,7 @@
138 from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
139 from canonical.launchpad.webapp.publisher import canonical_url
140
141+from lp.testing import login_person
142 from lp.testing.breadcrumbs import BaseBreadcrumbTestCase
143
144
145@@ -90,6 +91,7 @@
146 self.assertEqual(self.milestone.name, last_crumb.text)
147
148 def test_milestone_with_code_name(self):
149+ login_person(self.milestone.productseries.product.owner)
150 self.milestone.code_name = "duck"
151 crumbs = self.getBreadcrumbsForObject(self.milestone)
152 last_crumb = crumbs[-1]
153
154=== modified file 'lib/lp/registry/configure.zcml'
155--- lib/lp/registry/configure.zcml 2010-07-28 19:18:14 +0000
156+++ lib/lp/registry/configure.zcml 2010-08-03 22:52:48 +0000
157@@ -403,6 +403,8 @@
158 bugtargetdisplayname
159 bugtargetname
160 getBugCounts
161+ bug_count
162+ total_bug_heat
163 bug_subscriptions
164 getSubscriptions
165 getSubscription
166
167=== modified file 'lib/lp/registry/tests/test_distribution.py'
168--- lib/lp/registry/tests/test_distribution.py 2010-06-21 13:33:36 +0000
169+++ lib/lp/registry/tests/test_distribution.py 2010-08-03 22:52:48 +0000
170@@ -5,8 +5,6 @@
171
172 __metaclass__ = type
173
174-import unittest
175-
176 from zope.security.proxy import removeSecurityProxy
177
178 from lp.registry.tests.test_distroseries import (
179@@ -115,7 +113,7 @@
180
181 def test_get_current(self):
182 distro = self.factory.makeDistribution()
183- series = self.factory.makeDistroSeries(distribution=distro,
184+ series = self.factory.makeDistroSeries(distribution=distro,
185 status=SeriesStatus.CURRENT)
186 self.assertEquals([series],
187 list(distro.getSeriesByStatus(SeriesStatus.CURRENT)))
188@@ -133,16 +131,12 @@
189
190 def test_get_by_name(self):
191 distro = self.factory.makeDistribution()
192- series = self.factory.makeDistroSeries(distribution=distro,
193+ series = self.factory.makeDistroSeries(distribution=distro,
194 name="dappere")
195 self.assertEquals(series, distro.getSeries("dappere"))
196
197 def test_get_by_version(self):
198 distro = self.factory.makeDistribution()
199- series = self.factory.makeDistroSeries(distribution=distro,
200+ series = self.factory.makeDistroSeries(distribution=distro,
201 name="dappere", version="42.6")
202 self.assertEquals(series, distro.getSeries("42.6"))
203-
204-
205-def test_suite():
206- return unittest.TestLoader().loadTestsFromName(__name__)
207
208=== modified file 'lib/lp/registry/tests/test_distroseries.py'
209--- lib/lp/registry/tests/test_distroseries.py 2010-07-29 15:16:43 +0000
210+++ lib/lp/registry/tests/test_distroseries.py 2010-08-03 22:52:48 +0000
211@@ -3,10 +3,10 @@
212
213 """Tests for distroseries."""
214
215+from __future__ import with_statement
216+
217 __metaclass__ = type
218
219-import unittest
220-
221 import transaction
222
223 from zope.component import getUtility
224@@ -23,8 +23,7 @@
225 from lp.soyuz.interfaces.publishing import (
226 active_publishing_status, PackagePublishingStatus)
227 from lp.soyuz.model.processor import ProcessorFamilySet
228-from lp.testing import TestCase, TestCaseWithFactory
229-from lp.testing.factory import remove_security_proxy_and_shout_at_engineer
230+from lp.testing import person_logged_in, TestCase, TestCaseWithFactory
231 from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
232 from lp.translations.interfaces.translations import (
233 TranslationsBranchImportMode)
234@@ -293,12 +292,11 @@
235 self.linkPackage('hot')
236 self.makeSeriesPackage('cold')
237 product_series = self.linkPackage('cold')
238- naked_product_series = remove_security_proxy_and_shout_at_engineer(
239- product_series)
240- naked_product_series.product.bugtraker = self.factory.makeBugTracker()
241+ with person_logged_in(product_series.product.owner):
242+ product_series.product.bugtracker = self.factory.makeBugTracker()
243 packagings = self.series.getPrioritizedPackagings()
244 names = [packaging.sourcepackagename.name for packaging in packagings]
245- expected = [u'hot', u'cold', u'linked']
246+ expected = [u'hot', u'linked', u'cold']
247 self.assertEqual(expected, names)
248
249 def test_getPrioritizedPackagings_branch(self):
250@@ -306,9 +304,8 @@
251 self.linkPackage('translatable')
252 self.makeSeriesPackage('withbranch')
253 product_series = self.linkPackage('withbranch')
254- naked_product_series = remove_security_proxy_and_shout_at_engineer(
255- product_series)
256- naked_product_series.branch = self.factory.makeBranch()
257+ with person_logged_in(product_series.product.owner):
258+ product_series.branch = self.factory.makeBranch()
259 packagings = self.series.getPrioritizedPackagings()
260 names = [packaging.sourcepackagename.name for packaging in packagings]
261 expected = [u'translatable', u'linked', u'withbranch']
262@@ -320,11 +317,10 @@
263 self.linkPackage('translatable')
264 self.makeSeriesPackage('importabletranslatable')
265 product_series = self.linkPackage('importabletranslatable')
266- naked_product_series = remove_security_proxy_and_shout_at_engineer(
267- product_series)
268- naked_product_series.branch = self.factory.makeBranch()
269- naked_product_series.translations_autoimport_mode = (
270- TranslationsBranchImportMode.IMPORT_TEMPLATES)
271+ with person_logged_in(product_series.product.owner):
272+ product_series.branch = self.factory.makeBranch()
273+ product_series.translations_autoimport_mode = (
274+ TranslationsBranchImportMode.IMPORT_TEMPLATES)
275 packagings = self.series.getPrioritizedPackagings()
276 names = [packaging.sourcepackagename.name for packaging in packagings]
277 expected = [u'translatable', u'linked', u'importabletranslatable']
278@@ -357,9 +353,8 @@
279
280 new_distroseries = (
281 self.factory.makeDistroRelease(name=u"sampleseries"))
282- naked_new_distroseries = remove_security_proxy_and_shout_at_engineer(
283- new_distroseries)
284- naked_new_distroseries.hide_all_translations = False
285+ with person_logged_in(new_distroseries.distribution.owner):
286+ new_distroseries.hide_all_translations = False
287 transaction.commit()
288 translatables = self._get_translatables()
289 self.failUnlessEqual(
290@@ -381,7 +376,8 @@
291 translatables,
292 self._ref_translatables(u"sampleseries")))
293
294- naked_new_distroseries.hide_all_translations = True
295+ with person_logged_in(new_distroseries.distribution.owner):
296+ new_distroseries.hide_all_translations = True
297 transaction.commit()
298 translatables = self._get_translatables()
299 self.failUnlessEqual(
300@@ -409,7 +405,3 @@
301 NoSuchDistroSeries,
302 getUtility(IDistroSeriesSet).fromSuite,
303 distribution, 'doesntexist')
304-
305-
306-def test_suite():
307- return unittest.TestLoader().loadTestsFromName(__name__)
308
309=== modified file 'lib/lp/registry/tests/test_sourcepackage.py'
310--- lib/lp/registry/tests/test_sourcepackage.py 2010-07-20 17:50:45 +0000
311+++ lib/lp/registry/tests/test_sourcepackage.py 2010-08-03 22:52:48 +0000
312@@ -3,6 +3,8 @@
313
314 """Unit tests for ISourcePackage implementations."""
315
316+from __future__ import with_statement
317+
318 __metaclass__ = type
319
320 import unittest
321@@ -21,8 +23,7 @@
322 from lp.soyuz.interfaces.publishing import PackagePublishingStatus
323 from lp.code.interfaces.seriessourcepackagebranch import (
324 IMakeOfficialBranchLinks)
325-from lp.testing import TestCaseWithFactory
326-from lp.testing.factory import remove_security_proxy_and_shout_at_engineer
327+from lp.testing import person_logged_in, TestCaseWithFactory
328 from lp.testing.views import create_initialized_view
329 from canonical.testing.layers import DatabaseFunctionalLayer
330
331@@ -253,17 +254,13 @@
332
333 self.obsolete_productseries = self.factory.makeProductSeries(
334 name='obsolete', product=self.product)
335- naked_obsolete_productseries = (
336- remove_security_proxy_and_shout_at_engineer(
337- self.obsolete_productseries))
338- naked_obsolete_productseries.status = SeriesStatus.OBSOLETE
339+ with person_logged_in(self.product.owner):
340+ self.obsolete_productseries.status = SeriesStatus.OBSOLETE
341
342 self.dev_productseries = self.factory.makeProductSeries(
343 name='current', product=self.product)
344- naked_dev_productseries = (
345- remove_security_proxy_and_shout_at_engineer(
346- self.dev_productseries))
347- naked_dev_productseries.status = SeriesStatus.DEVELOPMENT
348+ with person_logged_in(self.product.owner):
349+ self.dev_productseries.status = SeriesStatus.DEVELOPMENT
350
351 self.distribution = self.factory.makeDistribution(
352 name='youbuntu', displayname='Youbuntu', owner=self.owner)
353
354=== modified file 'lib/lp/testing/factory.py'
355--- lib/lp/testing/factory.py 2010-08-03 17:27:52 +0000
356+++ lib/lp/testing/factory.py 2010-08-03 22:52:48 +0000
357@@ -111,8 +111,6 @@
358 from lp.codehosting.codeimport.worker import CodeImportSourceDetails
359
360 from lp.registry.interfaces.distribution import IDistributionSet
361-from lp.registry.model.distributionsourcepackage import (
362- DistributionSourcePackage)
363 from lp.registry.interfaces.distroseries import IDistroSeries
364 from lp.registry.interfaces.gpg import GPGKeyAlgorithm, IGPGKeySet
365 from lp.registry.interfaces.mailinglist import (
366@@ -161,17 +159,17 @@
367 ANONYMOUS,
368 login,
369 login_as,
370+ person_logged_in,
371 run_with_login,
372 temp_dir,
373 time_counter,
374 )
375 from lp.translations.interfaces.potemplate import IPOTemplateSet
376-from lp.translations.interfaces.translationgroup import (
377- ITranslationGroupSet)
378 from lp.translations.interfaces.translationimportqueue import (
379 RosettaImportStatus)
380 from lp.translations.interfaces.translationfileformat import (
381 TranslationFileFormat)
382+from lp.translations.interfaces.translationgroup import ITranslationGroupSet
383 from lp.translations.interfaces.translationsperson import ITranslationsPerson
384 from lp.translations.interfaces.translationtemplatesbuildjob import (
385 ITranslationTemplatesBuildJobSource)
386@@ -630,13 +628,20 @@
387 self, product=None, distribution=None, productseries=None, name=None):
388 if product is None and distribution is None and productseries is None:
389 product = self.makeProduct()
390- if productseries is not None:
391- product = productseries.product
392+ if distribution is None:
393+ if productseries is not None:
394+ product = productseries.product
395+ else:
396+ productseries = self.makeProductSeries(product=product)
397+ distroseries = None
398+ else:
399+ distroseries = self.makeDistroRelease(distribution=distribution)
400 if name is None:
401 name = self.getUniqueString()
402- return Milestone(product=product, distribution=distribution,
403- productseries=productseries,
404- name=name)
405+ return ProxyFactory(
406+ Milestone(product=product, distribution=distribution,
407+ productseries=productseries, distroseries=distroseries,
408+ name=name))
409
410 def makeProcessor(self, family=None, name=None, title=None,
411 description=None):
412@@ -682,8 +687,10 @@
413 if milestone is None:
414 milestone = self.makeMilestone(product=product,
415 productseries=productseries)
416- return milestone.createProductRelease(
417- milestone.product.owner, datetime.now(pytz.UTC))
418+ with person_logged_in(milestone.productseries.product.owner):
419+ release = milestone.createProductRelease(
420+ milestone.product.owner, datetime.now(pytz.UTC))
421+ return release
422
423 def makeProductReleaseFile(self, signed=True,
424 product=None, productseries=None,
425@@ -699,12 +706,14 @@
426 release = self.makeProductRelease(product=product,
427 productseries=productseries,
428 milestone=milestone)
429- return release.addReleaseFile(
430- 'test.txt', 'test', 'text/plain',
431- uploader=release.milestone.product.owner,
432- signature_filename=signature_filename,
433- signature_content=signature_content,
434- description=description)
435+ with person_logged_in(release.milestone.product.owner):
436+ release_file = release.addReleaseFile(
437+ 'test.txt', 'test', 'text/plain',
438+ uploader=release.milestone.product.owner,
439+ signature_filename=signature_filename,
440+ signature_content=signature_content,
441+ description=description)
442+ return release_file
443
444 def makeProduct(
445 self, name=None, project=None, displayname=None,
446@@ -747,7 +756,7 @@
447 return product
448
449 def makeProductSeries(self, product=None, name=None, owner=None,
450- summary=None):
451+ summary=None, date_created=None):
452 """Create and return a new ProductSeries."""
453 if product is None:
454 product = self.makeProduct()
455@@ -760,8 +769,11 @@
456 # We don't want to login() as the person used to create the product,
457 # so we remove the security proxy before creating the series.
458 naked_product = removeSecurityProxy(product)
459- return ProxyFactory(
460- naked_product.newSeries(owner=owner, name=name, summary=summary))
461+ series = naked_product.newSeries(
462+ owner=owner, name=name, summary=summary)
463+ if date_created is not None:
464+ series.datecreated = date_created
465+ return ProxyFactory(series)
466
467 def makeProject(self, name=None, displayname=None, title=None,
468 homepageurl=None, summary=None, owner=None,
469@@ -2437,7 +2449,7 @@
470 dsc_binaries=dsc_binaries,
471 date_uploaded=date_uploaded)
472
473- sspph = SourcePackagePublishingHistory(
474+ return ProxyFactory(SourcePackagePublishingHistory(
475 distroseries=distroseries,
476 sourcepackagerelease=spr,
477 component=spr.component,
478@@ -2447,11 +2459,7 @@
479 dateremoved=dateremoved,
480 scheduleddeletiondate=scheduleddeletiondate,
481 pocket=pocket,
482- archive=archive)
483-
484- # SPPH and SSPPH IDs are the same, since they are SPPH is a SQLVIEW
485- # of SSPPH and other useful attributes.
486- return SourcePackagePublishingHistory.get(sspph.id)
487+ archive=archive))
488
489 def makeBinaryPackagePublishingHistory(self, binarypackagerelease=None,
490 distroarchseries=None,
491@@ -2588,7 +2596,7 @@
492 if distribution is None:
493 distribution = self.makeDistribution()
494
495- return DistributionSourcePackage(distribution, sourcepackagename)
496+ return distribution.getSourcePackage(sourcepackagename)
497
498 def makeEmailMessage(self, body=None, sender=None, to=None,
499 attachments=None, encode_attachments=False):
500@@ -2768,7 +2776,7 @@
501 # other Python libraries.
502 unwrapped_types = (
503 BaseRecipeBranch, DSCFile, InstanceType, MergeDirective2, Message,
504- datetime, int, str, unicode,)
505+ datetime, int, str, unicode)
506
507
508 def is_security_proxied_or_harmless(obj):
509@@ -2793,7 +2801,7 @@
510 def __init__(self, method_name):
511 super(UnproxiedFactoryMethodWarning, self).__init__(
512 "PLEASE FIX: LaunchpadObjectFactory.%s returns an "
513- "unproxied object." % (method_name,))
514+ "unproxied object." % (method_name, ))
515
516
517 class ShouldThisBeUsingRemoveSecurityProxy(UserWarning):