Two minor whitespace tweaks please, or rather the same one in two places. Other than that, awesome! > === modified file 'lib/lp/code/interfaces/branchtarget.py' > --- lib/lp/code/interfaces/branchtarget.py 2010-01-05 08:18:23 +0000 > +++ lib/lp/code/interfaces/branchtarget.py 2010-03-26 01:45:34 +0000 > @@ -88,6 +88,9 @@ > supports_merge_proposals = Attribute( > "Does this target support merge proposals at all?") > > + supports_code_imports = Attribute( > + "Does this target support code imports at all?") > + > def areBranchesMergeable(other_target): > """Are branches from other_target mergeable into this target.""" > > @@ -113,3 +116,18 @@ > > def getBugTask(bug): > """Get the BugTask for a given bug related to the branch target.""" > + > + def newCodeImport(registrant, branch_name, rcs_type, > + url=None, cvs_root=None, cvs_module=None): This should be formatted like so: def newCodeImport(registrant, branch_name, rcs_type, url=None, cvs_root=None, cvs_module=None): (https://dev.launchpad.net/PythonStyleGuide#Wrapping%20long%20arguments%20in%20function%20definitions) > + """Create a new code import for this target. > + > + :param registrant: the `IPerson` who should be recorded as creating > + the import and will own the resulting branch. > + :param branch_name: the name the resulting branch should have. > + :param rcs_type: the type of the foreign VCS. > + :param url: the url to import from if the import isn't CVS. > + :param cvs_root: if the import is from CVS the CVSROOT to import from. > + :param cvs_module: if the import is from CVS the module to import. > + :returns: an `ICodeImport`. > + :raises AssertionError: if supports_code_imports is False. > + """ > === modified file 'lib/lp/code/model/branchtarget.py' > --- lib/lp/code/model/branchtarget.py 2010-01-05 08:18:23 +0000 > +++ lib/lp/code/model/branchtarget.py 2010-03-26 01:45:34 +0000 > @@ -19,6 +19,7 @@ > from lp.code.interfaces.branchcollection import IAllBranches > from lp.code.interfaces.branchtarget import ( > check_default_stacked_on, IBranchTarget) > +from lp.code.interfaces.codeimport import ICodeImportSet > from lp.registry.interfaces.pocket import PackagePublishingPocket > from canonical.launchpad.webapp.interfaces import ICanonicalUrlData > > @@ -36,6 +37,12 @@ > def __ne__(self, other): > return self.context != other.context > > + def newCodeImport(self, registrant, branch_name, rcs_type, url=None, > + cvs_root=None, cvs_module=None): Similarly. > + return getUtility(ICodeImportSet).new( > + registrant, self, branch_name, rcs_type, url=url, > + cvs_root=cvs_root, cvs_module=cvs_module) > + > > class PackageBranchTarget(_BaseBranchTarget): > implements(IBranchTarget) > @@ -95,6 +102,11 @@ > """See `IBranchTarget`.""" > return True > > + @property > + def supports_code_imports(self): > + """See `IBranchTarget`.""" > + return False > + > def areBranchesMergeable(self, other_target): > """See `IBranchTarget`.""" > # Branches are mergable into a PackageTarget if the source package > @@ -182,6 +194,11 @@ > """See `IBranchTarget`.""" > return False > > + @property > + def supports_code_imports(self): > + """See `IBranchTarget`.""" > + return False > + > def areBranchesMergeable(self, other_target): > """See `IBranchTarget`.""" > return False > @@ -258,6 +275,11 @@ > """See `IBranchTarget`.""" > return True > > + @property > + def supports_code_imports(self): > + """See `IBranchTarget`.""" > + return True > + > def areBranchesMergeable(self, other_target): > """See `IBranchTarget`.""" > # Branches are mergable into a PackageTarget if the source package > @@ -311,6 +333,11 @@ > """See `IBranchTarget`.""" > return self.productseries > > + @property > + def supports_code_imports(self): > + """See `IBranchTarget`.""" > + return False > + > > def get_canonical_url_data_for_target(branch_target): > """Return the `ICanonicalUrlData` for an `IBranchTarget`.""" > === modified file 'lib/lp/code/model/codeimport.py' > --- lib/lp/code/model/codeimport.py 2010-03-26 01:44:52 +0000 > +++ lib/lp/code/model/codeimport.py 2010-03-26 01:45:34 +0000 > @@ -225,6 +225,8 @@ > review_status = CodeImportReviewStatus.REVIEWED > else: > review_status = CodeImportReviewStatus.NEW > + if not target.supports_code_imports: > + raise AssertionError("%r doesn't support code imports" % target) > # Create the branch for the CodeImport. > namespace = target.getNamespace(registrant) > import_branch = namespace.createBranch( I think raising AssertionError here is OK.