Merge lp:~richardw/pydoctor/moduleprovides-1132527 into lp:~mwhudson/pydoctor/dev

Proposed by Richard Wall on 2013-02-27
Status: Merged
Merged at revision: 595
Proposed branch: lp:~richardw/pydoctor/moduleprovides-1132527
Merge into: lp:~mwhudson/pydoctor/dev
Diff against target: 113 lines (+57/-3)
2 files modified
pydoctor/test/test_zopeinterface.py (+17/-1)
pydoctor/zopeinterface.py (+40/-2)
To merge this branch: bzr merge lp:~richardw/pydoctor/moduleprovides-1132527
Reviewer Review Type Date Requested Status
Michael Hudson-Doyle 2013-02-27 Approve on 2013-03-05
Review via email: mp+150932@code.launchpad.net

Description of the change

Hi Michael,

I copied the existing code for handling implements and @implementer and adapted it to handle moduleProvides.

Added a new test case which I think demonstrates the new feature.

Tested on the twisted.names.client.lookup functions in the following Twisted branch:
 * https://twistedmatrix.com/trac/log/branches/moduleprovides-iresolver-6328

Seems to work and even handles documentation from Interface subclasses since your recent change.

Let me know what you think.

-RichardW.

To post a comment you must log in.
Michael Hudson-Doyle (mwhudson) wrote :

Looks good to me, thanks! addInterfaceInfoToModule and addInterfaceInfoToClass seem a bit similar, but I'd forgotten how gross the data model there was so that can probably be fixed as some part of a general clean up. I'll merge now.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'pydoctor/test/test_zopeinterface.py'
--- pydoctor/test/test_zopeinterface.py 2013-02-24 22:40:48 +0000
+++ pydoctor/test/test_zopeinterface.py 2013-02-27 22:40:26 +0000
@@ -64,7 +64,6 @@
64 '''64 '''
65 implements_test(src)65 implements_test(src)
6666
67
68def implements_test(src):67def implements_test(src):
69 mod = fromText(src, 'zi', systemcls=ZopeInterfaceSystem)68 mod = fromText(src, 'zi', systemcls=ZopeInterfaceSystem)
70 ifoo = mod.contents['IFoo']69 ifoo = mod.contents['IFoo']
@@ -222,3 +221,20 @@
222 method = mod.contents['Implementation'].contents['method']221 method = mod.contents['Implementation'].contents['method']
223 assert imethod in method.docsources(), list(method.docsources())222 assert imethod in method.docsources(), list(method.docsources())
224223
224def test_docsources_from_moduleprovides():
225 src = '''
226 from zope import interface
227
228 class IBase(interface.Interface):
229 def bar():
230 """documentation"""
231
232 interface.moduleProvides(IBase)
233
234 def bar():
235 pass
236 '''
237 mod = fromText(src, systemcls=ZopeInterfaceSystem)
238 imethod = mod.contents['IBase'].contents['bar']
239 function = mod.contents['bar']
240 assert imethod in function.docsources(), list(function.docsources())
225241
=== modified file 'pydoctor/zopeinterface.py'
--- pydoctor/zopeinterface.py 2013-02-24 22:40:48 +0000
+++ pydoctor/zopeinterface.py 2013-02-27 22:40:26 +0000
@@ -4,6 +4,19 @@
4from compiler import ast4from compiler import ast
5import re5import re
66
7
8class ZopeInterfaceModule(model.Module):
9 def setup(self):
10 super(ZopeInterfaceModule, self).setup()
11 self.implements_directly = [] # [name of interface]
12
13 @property
14 def allImplementedInterfaces(self):
15 """Return all the interfaces provided by this module
16 """
17 return list(self.implements_directly)
18
19
7class ZopeInterfaceClass(model.Class):20class ZopeInterfaceClass(model.Class):
8 isinterface = False21 isinterface = False
9 isschemafield = False22 isschemafield = False
@@ -50,7 +63,7 @@
50 def docsources(self):63 def docsources(self):
51 for source in super(ZopeInterfaceFunction, self).docsources():64 for source in super(ZopeInterfaceFunction, self).docsources():
52 yield source65 yield source
53 if not isinstance(self.parent, model.Class):66 if not isinstance(self.parent, (model.Class, model.Module)):
54 return67 return
55 for interface in self.parent.allImplementedInterfaces:68 for interface in self.parent.allImplementedInterfaces:
56 io = self.system.objForFullName(interface)69 io = self.system.objForFullName(interface)
@@ -59,6 +72,24 @@
59 if self.name in io2.contents:72 if self.name in io2.contents:
60 yield io2.contents[self.name]73 yield io2.contents[self.name]
6174
75def addInterfaceInfoToModule(module, interfaceargs):
76 for arg in interfaceargs:
77 if not isinstance(arg, tuple):
78 fullName = module.expandName(ast_pp.pp(arg))
79 else:
80 fullName = arg[1]
81 module.implements_directly.append(fullName)
82 obj = module.system.objForFullName(fullName)
83 if obj is not None:
84 if not obj.isinterface:
85 obj.system.msg(
86 'zopeinterface',
87 'probable interface %r not marked as such'%obj,
88 thresh=1)
89 obj.isinterface = True
90 obj.kind = "Interface"
91 obj.implementedby_directly = []
92 obj.implementedby_directly.append(module.fullName())
6293
63def addInterfaceInfoToClass(cls, interfaceargs, implementsOnly):94def addInterfaceInfoToClass(cls, interfaceargs, implementsOnly):
64 cls.implementsOnly = implementsOnly95 cls.implementsOnly = implementsOnly
@@ -193,6 +224,13 @@
193 if meth is not None:224 if meth is not None:
194 meth(base, node)225 meth(base, node)
195226
227 def visitCallFunc_zope_interface_moduleProvides(self, funcName, node):
228 if not isinstance(self.builder.current, model.Module):
229 self.default(node)
230 return
231
232 addInterfaceInfoToModule(self.builder.current, node.args)
233
196 def visitCallFunc_zope_interface_implements(self, funcName, node):234 def visitCallFunc_zope_interface_implements(self, funcName, node):
197 if not isinstance(self.builder.current, model.Class):235 if not isinstance(self.builder.current, model.Class):
198 self.default(node)236 self.default(node)
@@ -237,7 +275,7 @@
237275
238276
239class ZopeInterfaceSystem(model.System):277class ZopeInterfaceSystem(model.System):
278 Module = ZopeInterfaceModule
240 Class = ZopeInterfaceClass279 Class = ZopeInterfaceClass
241 Function = ZopeInterfaceFunction280 Function = ZopeInterfaceFunction
242 defaultBuilder = ZopeInterfaceASTBuilder281 defaultBuilder = ZopeInterfaceASTBuilder
243

Subscribers

People subscribed via source and target branches

to all changes:
to status/vote changes: