# HG changeset patch # User Atul Varma # Date 1271210411 25200 # Node ID 798f8f33c4183cea11eb137a51c876d87280618b # Parent 0910577d08fa7dcbb1c345bfbc026262514a8e8e added bzapi.users, bzapi.attachments, and bzapi.bugs as primary accessors of bugzilla information. diff -r 0910577d08fa -r 798f8f33c418 bugzilla.py --- a/bugzilla.py Tue Apr 13 18:02:12 2010 -0700 +++ b/bugzilla.py Tue Apr 13 19:00:11 2010 -0700 @@ -133,6 +133,9 @@ self.config = config self.__jsonreq = jsonreq + self.users = LazyMapping(self, User, keytype=unicode) + self.attachments = LazyMapping(self, Attachment, keytype=int) + self.bugs = LazyMapping(self, Bug, keytype=int) def post_attachment(self, bug_id, contents, filename, description, content_type=None, is_patch=False, is_private=False, @@ -230,6 +233,10 @@ def _set_bzprops(self, jsonobj): for name, proptype in self.__bzprops__.items(): + if name not in jsonobj: + raise KeyError("key '%s' not found in JSON " + "%s object" % (name, + self.__class__.__name__)) if proptype == bool: if jsonobj[name] == '0': setattr(self, name, False) @@ -248,18 +255,20 @@ name, repr(proptype)) class LazyMapping(object): - def __init__(self, bzapi, klass): + def __init__(self, bzapi, klass, keytype): self.__klass = klass self.__bzapi = bzapi + self.__keytype = keytype self.__mapping = {} def get(self, name, jsonobj=None): + name = self.__keytype(name) if name not in self.__mapping: if jsonobj: obj = self.__klass(jsonobj, self.__bzapi) else: obj = self.__klass.fetch(self.__bzapi, name) - self.mapping[name] = obj + self.__mapping[name] = obj return self.__mapping[name] @@ -341,7 +350,7 @@ class Attachment(BugzillaObject): """ - >>> bzapi = Mock('bzapi') + >>> bzapi = MockBugzillaApi() >>> bzapi.request.mock_returns = TEST_ATTACHMENT_WITH_DATA >>> a = Attachment(TEST_ATTACHMENT_WITHOUT_DATA, bzapi) >>> a.data @@ -363,20 +372,18 @@ 'is_obsolete': bool } - def __init__(self, jsonobj, bzapi, bug=None): + def __init__(self, jsonobj, bzapi): BugzillaObject.__init__(self, jsonobj, bzapi) if 'data' in jsonobj: self.__data = self.__decode_data(jsonobj) else: self.__data = None - self.__bug = bug - self.attacher = User(jsonobj['attacher'], bzapi) + self.attacher = self.bzapi.users.get(jsonobj['attacher']['name'], + jsonobj['attacher']) @property def bug(self): - if self.__bug is None: - self.__bug = Bug.fetch(self.bzapi, self.bug_id) - return self.__bug + return self.bzapi.bugs.get(self.bug_id) @property def data(self): @@ -402,7 +409,7 @@ @classmethod def fetch(klass, bzapi, attach_id): """ - >>> bzapi = Mock('bzapi') + >>> bzapi = MockBugzillaApi() >>> bzapi.request.mock_returns = TEST_ATTACHMENT_WITH_DATA >>> Attachment.fetch(bzapi, 438797) Called bzapi.request( @@ -417,7 +424,7 @@ class Bug(BugzillaObject): """ - >>> Bug(TEST_BUG, bzapi=None) + >>> Bug(TEST_BUG, MockBugzillaApi()) """ @@ -428,7 +435,7 @@ def __init__(self, jsonobj, bzapi): BugzillaObject.__init__(self, jsonobj, bzapi) - self.attachments = [Attachment(attach, bzapi, self) + self.attachments = [bzapi.attachments.get(attach['id'], attach) for attach in jsonobj['attachments']] def __repr__(self): @@ -437,7 +444,7 @@ @classmethod def fetch(klass, bzapi, bug_id): """ - >>> bzapi = Mock('bzapi') + >>> bzapi = MockBugzillaApi() >>> bzapi.request.mock_returns = TEST_BUG >>> Bug.fetch(bzapi, 558680) Called bzapi.request('GET', '/bug/558680') diff -r 0910577d08fa -r 798f8f33c418 test_bugzilla.py --- a/test_bugzilla.py Tue Apr 13 18:02:12 2010 -0700 +++ b/test_bugzilla.py Tue Apr 13 19:00:11 2010 -0700 @@ -59,8 +59,16 @@ u'id': u'558680' } +class MockBugzillaApi(object): + def __init__(self): + self.request = Mock('bzapi.request') + self.users = bugzilla.LazyMapping(self, bugzilla.User, keytype=unicode) + self.attachments = bugzilla.LazyMapping(self, bugzilla.Attachment, keytype=int) + self.bugs = bugzilla.LazyMapping(self, bugzilla.Bug, keytype=int) + DOCTEST_EXTRA_GLOBS = { - 'Mock': Mock + 'Mock': Mock, + 'MockBugzillaApi': MockBugzillaApi } for globname in globals().keys():