> Thank you for your review. > > Most of the errors that you have reported can be also found in > bugmessage. Should I fix them in a separate branch? > > > > +# pylint: disable-msg=E0211,E0213 > > > > Why are you disabling these lint messages? > > I'm disabling E0213 because it says: > > Method should have "self" as first argument OK, sorry, this was a stupid question :-/ These are disabled in all interfaces for obvious reasons. > > > > + messageID = Int(title=u"The message id.", readonly=True) > > > > Why is this attribute needed? We only very rarely need to work with IDs. > Normally > > Storm should take care of references for us. > > I've included it because I saw that it is used in IBugMessage and in > ICodeReviewComment. I think you should avoid it unless you have no choice. This trick is used elsewhere for optimization, but as long as you don't have at least one call-site you shouldn't include this. > > > Here's the incremental diff: > > === modified file 'lib/lp/blueprints/doc/specificationmessage.txt' > --- lib/lp/blueprints/doc/specificationmessage.txt 2009-08-07 18:24:33 > +0000 > +++ lib/lp/blueprints/doc/specificationmessage.txt 2009-08-10 12:34:20 > +0000 > @@ -1,24 +1,26 @@ > = Specification Messages = > > -Specification messages are messages associated with blueprints. A > specifiction > -message is described by the ISpecificationMessage interface. > - > -One IMessage can be associated with many ISpecification, but one > -ISpecificationMessage is always associated with exactly one > specification. > - > - >>> from lp.blueprints.interfaces.specification import > ISpecificationSet > +Specification messages are messages associated with blueprints. A > +specifiction message is described by the ISpecificationMessage > +interface. > + > + > +== Creating specification messages == > + > +To create a specification message, use > +ISpecificationMessageSet.createMessage: > + > + >>> from lp.blueprints.interfaces.specification import ( > + ... ISpecificationSet) > >>> from lp.blueprints.interfaces.specificationmessage import ( > ... ISpecificationMessageSet) > >>> specset = getUtility(ISpecificationSet) > >>> specmessageset = getUtility(ISpecificationMessageSet) > > -== Creating specification messages == > - > -To create a specification message, use > ISpecificationMessageSet.createMessage: > - > >>> from canonical.launchpad.interfaces import IPersonSet > >>> sample_person = getUtility(IPersonSet).get(12) > - >>> spec = > specset.getByURL('http://developer.mozilla.org/en/docs/SVG') > + >>> spec = specset.getByURL( > + ... 'http://developer.mozilla.org/en/docs/SVG') > >>> test_message = specmessageset.createMessage( > ... subject="test message subject", > ... content="text message content", > @@ -27,10 +29,11 @@ > >>> test_message.message.subject > u'test message subject' > > + > == Retrieving specification messages == > > -ISpecificationMessageSet represents the set of all > ISpecificationMessages in > -the system. An individual ISpecificationMessage can be retrieved with > +ISpecificationMessageSet represents the set of all messages in the > +system. An individual ISpecificationMessage can be retrieved with > ISpecificationMessageSet.get: > > >>> specmessage_one = specmessageset.get(1) > > === modified file 'lib/lp/blueprints/interfaces/specificationmessage.py' > --- lib/lp/blueprints/interfaces/specificationmessage.py 2009-08-07 > 16:27:15 +0000 > +++ lib/lp/blueprints/interfaces/specificationmessage.py 2009-08-10 > 12:34:20 +0000 > @@ -1,7 +1,7 @@ > # Copyright 2009 Canonical Ltd. This software is licensed under the > # GNU Affero General Public License version 3 (see the file LICENSE). > > -# pylint: disable-msg=E0211,E0213 > +# pylint: disable-msg=E0213 > > """Specification message interfaces.""" > > @@ -11,23 +11,21 @@ > 'ISpecificationMessageSet', > ] > > -from zope.interface import Attribute, Interface > -from zope.schema import Bool, Bytes, Int, Object, Text, TextLine > +from lazr.restful.fields import Reference > +from zope.interface import Interface > +from zope.schema import Bool, Int > > -from canonical.launchpad.fields import Title > from lp.blueprints.interfaces.specification import ISpecification > from canonical.launchpad.interfaces.message import IMessage > -from canonical.launchpad.validators.attachment import ( > - attachment_size_constraint) > > > class ISpecificationMessage(Interface): > """A link between a specification and a message.""" > > - specification = Object(schema=ISpecification, title=u"The > specification.") > - messageID = Int(title=u"The message id.", readonly=True) > - message = Object(schema=IMessage, title=u"The message.") > - visible = Bool(title=u"This message is visible or not.", > required=False, > + specification = Reference(schema=ISpecification, > + title=u"The specification.") > + message = Reference(schema=IMessage, title=u"The message.") > + visible = Bool(title=u"Is this message visible?", required=False, > default=True) > > > > === modified file 'lib/lp/blueprints/model/specificationmessage.py' > --- lib/lp/blueprints/model/specificationmessage.py 2009-08-07 16:57:19 > +0000 > +++ lib/lp/blueprints/model/specificationmessage.py 2009-08-10 12:34:20 > +0000 > @@ -1,8 +1,6 @@ > # Copyright 2009 Canonical Ltd. This software is licensed under the > # GNU Affero General Public License version 3 (see the file LICENSE). > > -# pylint: disable-msg=E0611,W0212 > - > __metaclass__ = type > __all__ = [ > 'SpecificationMessage', > @@ -13,10 +11,10 @@ > > from zope.interface import implements > > -from sqlobject import BoolCol, ForeignKey, StringCol > +from sqlobject import BoolCol, ForeignKey > from storm.store import Store > > -from canonical.database.sqlbase import SQLBase, sqlvalues > +from canonical.database.sqlbase import SQLBase > from lp.blueprints.interfaces.specificationmessage import ( > ISpecificationMessage, ISpecificationMessageSet) > from canonical.launchpad.database.message import Message, MessageChunk > @@ -46,8 +44,6 @@ > owner=owner, rfc822msgid=make_msgid('blueprint'), > subject=subject) > chunk = MessageChunk(message=msg, content=content, sequence=1) > specmsg = SpecificationMessage(specification=spec, message=msg) > - > - Store.of(specmsg).flush() > return specmsg > > def get(self, specmessageid): Great, with these changes I think this branch is ready to land.