[Checkins] SVN: zope.app.apidoc/trunk/src/zope/app/apidoc/ * Fixed
one of the major issues with broken links. The required
Stephan Richter
srichter at cosmos.phy.tufts.edu
Thu Sep 27 17:18:47 EDT 2007
Log message for revision 80259:
* Fixed one of the major issues with broken links. The required
specification of adapters can now have classes, not just interfaces,
so we have to handle this case.
Changed:
U zope.app.apidoc/trunk/src/zope/app/apidoc/component.py
U zope.app.apidoc/trunk/src/zope/app/apidoc/component.txt
U zope.app.apidoc/trunk/src/zope/app/apidoc/ifacemodule/browser.txt
U zope.app.apidoc/trunk/src/zope/app/apidoc/ifacemodule/component_macros.pt
-=-
Modified: zope.app.apidoc/trunk/src/zope/app/apidoc/component.py
===================================================================
--- zope.app.apidoc/trunk/src/zope/app/apidoc/component.py 2007-09-27 20:47:08 UTC (rev 80258)
+++ zope.app.apidoc/trunk/src/zope/app/apidoc/component.py 2007-09-27 21:18:46 UTC (rev 80259)
@@ -177,7 +177,34 @@
return {'module': getattr(iface, '__module__', _('<unknown>')),
'name': getattr(iface, '__name__', _('<unknown>'))}
+def getInterfaceInfoDictionary(iface):
+ """Return a PT-friendly info dictionary for an interface."""
+ if isinstance(iface, zope.interface.declarations.Implements):
+ iface = iface.inherit
+ if iface is None:
+ return None
+ return {'module': getattr(iface, '__module__', _('<unknown>')),
+ 'name': getattr(iface, '__name__', _('<unknown>'))}
+
+def getTypeInfoDictionary(type):
+ """Return a PT-friendly info dictionary for a type."""
+ path = getPythonPath(type)
+ return {'name': type.__name__,
+ 'module': type.__module__,
+ 'url': isReferencable(path) and path.replace('.', '/') or None}
+
+def getSpecificationInfoDictionary(spec):
+ """Return an info dictionary for one specification."""
+ info = {'isInterface': False, 'isType': False}
+ if zope.interface.interfaces.IInterface.providedBy(spec):
+ info.update(getInterfaceInfoDictionary(spec))
+ info['isInterface'] = True
+ else:
+ info.update(getTypeInfoDictionary(spec.inherit))
+ info['isType'] = True
+ return info
+
def getAdapterInfoDictionary(reg):
"""Return a PT-friendly info dictionary for an adapter registration."""
factory = getRealFactory(reg.factory)
@@ -196,7 +223,7 @@
return {
'provided': getInterfaceInfoDictionary(reg.provided),
- 'required': [getInterfaceInfoDictionary(iface)
+ 'required': [getSpecificationInfoDictionary(iface)
for iface in reg.required
if iface is not None],
'name': unicode(getattr(reg, 'name', u'')),
Modified: zope.app.apidoc/trunk/src/zope/app/apidoc/component.txt
===================================================================
--- zope.app.apidoc/trunk/src/zope/app/apidoc/component.txt 2007-09-27 20:47:08 UTC (rev 80258)
+++ zope.app.apidoc/trunk/src/zope/app/apidoc/component.txt 2007-09-27 21:18:46 UTC (rev 80259)
@@ -44,11 +44,11 @@
>>> regs = list(component.getRequiredAdapters(IFoo))
>>> regs.sort()
>>> regs
- [AdapterRegistration(<BaseGlobalComponents base>,
- [IFoo, IBar], ISpecialResult, '', None, u''),
- AdapterRegistration(<BaseGlobalComponents base>,
- [IFoo], IResult, '', None, u''),
- HandlerRegistration(<BaseGlobalComponents base>,
+ [AdapterRegistration(<BaseGlobalComponents base>,
+ [IFoo, IBar], ISpecialResult, '', None, u''),
+ AdapterRegistration(<BaseGlobalComponents base>,
+ [IFoo], IResult, '', None, u''),
+ HandlerRegistration(<BaseGlobalComponents base>,
[IFoo], u'', 'stubFactory', u'')]
Note how the adapter requiring an `IRequest` at the end of the required
@@ -58,13 +58,13 @@
>>> regs = list(component.getRequiredAdapters(IFoo, withViews=True))
>>> regs.sort()
>>> regs
- [AdapterRegistration(<BaseGlobalComponents base>,
- [IFoo, IBar], ISpecialResult, '', None, u''),
- AdapterRegistration(<BaseGlobalComponents base>,
- [IFoo, IRequest], ISpecialResult, '', None, u''),
- AdapterRegistration(<BaseGlobalComponents base>,
- [IFoo], IResult, '', None, u''),
- HandlerRegistration(<BaseGlobalComponents base>,
+ [AdapterRegistration(<BaseGlobalComponents base>,
+ [IFoo, IBar], ISpecialResult, '', None, u''),
+ AdapterRegistration(<BaseGlobalComponents base>,
+ [IFoo, IRequest], ISpecialResult, '', None, u''),
+ AdapterRegistration(<BaseGlobalComponents base>,
+ [IFoo], IResult, '', None, u''),
+ HandlerRegistration(<BaseGlobalComponents base>,
[IFoo], u'', 'stubFactory', u'')]
The function will also pick up registrations that have required interfaces the
@@ -73,10 +73,10 @@
>>> regs = list(component.getRequiredAdapters(IFoo))
>>> regs.sort()
>>> regs
- [AdapterRegistration(<BaseGlobalComponents base>,
+ [AdapterRegistration(<BaseGlobalComponents base>,
[IFoo, IBar], ISpecialResult, '', None, u''),
AdapterRegistration(<BaseGlobalComponents base>,
- [IFoo], IResult, '', None, u''),
+ [IFoo], IResult, '', None, u''),
HandlerRegistration(<BaseGlobalComponents base>,
[IFoo], u'', 'stubFactory', u'')]
@@ -85,7 +85,7 @@
>>> regs = list(component.getRequiredAdapters(IBar))
>>> regs.sort()
>>> regs
- [AdapterRegistration(<BaseGlobalComponents base>,
+ [AdapterRegistration(<BaseGlobalComponents base>,
[IFoo, IBar], ISpecialResult, '', None, u'')]
@@ -99,7 +99,7 @@
>>> regs = list(component.getProvidedAdapters(ISpecialResult))
>>> regs.sort()
>>> regs
- [AdapterRegistration(<BaseGlobalComponents base>,
+ [AdapterRegistration(<BaseGlobalComponents base>,
[IFoo, IBar], ISpecialResult, '', None, u'')]
And by specifying the `withView` flag, we get views as well:
@@ -107,9 +107,9 @@
>>> regs = list(component.getProvidedAdapters(ISpecialResult, withViews=True))
>>> regs.sort()
>>> regs
- [AdapterRegistration(<BaseGlobalComponents base>,
- [IFoo, IBar], ISpecialResult, '', None, u''),
- AdapterRegistration(<BaseGlobalComponents base>,
+ [AdapterRegistration(<BaseGlobalComponents base>,
+ [IFoo, IBar], ISpecialResult, '', None, u''),
+ AdapterRegistration(<BaseGlobalComponents base>,
[IFoo, IRequest], ISpecialResult, '', None, u'')]
We can of course also ask for adapters specifying `IResult`:
@@ -117,7 +117,7 @@
>>> regs = list(component.getProvidedAdapters(IResult, withViews=True))
>>> regs.sort()
>>> regs
- [AdapterRegistration(<BaseGlobalComponents base>,
+ [AdapterRegistration(<BaseGlobalComponents base>,
[IFoo, IBar], ISpecialResult, '', None, u''),
AdapterRegistration(<BaseGlobalComponents base>,
[IFoo, IRequest], ISpecialResult, '', None, u''),
@@ -184,14 +184,14 @@
>>> regs = list(component.getFactories(IFooBar))
>>> regs.sort()
>>> regs
- [UtilityRegistration(<BaseGlobalComponents base>,
+ [UtilityRegistration(<BaseGlobalComponents base>,
IFactory, 'MyFooBar',
<Factory for <class 'zope.app.apidoc.doctest.MyFooBar'>>, u'')]
>>> regs = list(component.getFactories(IFoo))
>>> regs.sort()
>>> regs
- [UtilityRegistration(<BaseGlobalComponents base>, IFactory, 'MyFoo',
+ [UtilityRegistration(<BaseGlobalComponents base>, IFactory, 'MyFoo',
<Factory for <class 'zope.app.apidoc.doctest.MyFoo'>>, u''),
UtilityRegistration(<BaseGlobalComponents base>, IFactory, 'MyFooBar',
<Factory for <class 'zope.app.apidoc.doctest.MyFooBar'>>, u'')]
@@ -214,15 +214,15 @@
>>> regs = list(component.getUtilities(IFooBar))
>>> regs.sort()
>>> regs #doctest:+ELLIPSIS
- [UtilityRegistration(<BaseGlobalComponents base>, IFooBar, '',
+ [UtilityRegistration(<BaseGlobalComponents base>, IFooBar, '',
<zope.app.apidoc.doctest.MyFooBar object at ...>, u'')]
>>> regs = list(component.getUtilities(IFoo))
>>> regs.sort()
>>> regs #doctest:+ELLIPSIS
- [UtilityRegistration(<BaseGlobalComponents base>, IFoo, '',
+ [UtilityRegistration(<BaseGlobalComponents base>, IFoo, '',
<zope.app.apidoc.doctest.MyFoo object at ...>, u''),
- UtilityRegistration(<BaseGlobalComponents base>, IFooBar, '',
+ UtilityRegistration(<BaseGlobalComponents base>, IFooBar, '',
<zope.app.apidoc.doctest.MyFooBar object at ...>, u'')]
@@ -298,7 +298,7 @@
>>> component.getInterfaceInfoDictionary(None) is None
True
-It's also possible for this function to be passed a
+It's also possible for this function to be passed a
zope.interface.declarations.Implements instance. For instance, this function
is sometimes used to analyze the required elements of an adapter registration:
if an adapter or subscriber is registered against a class, then the required
@@ -311,6 +311,49 @@
{'module': 'zope.app.apidoc.doctest', 'name': 'MyFoo'}
+`getTypeInfoDictionary(type)`
+-----------------------------
+
+This function returns the info dictionary of a type.
+
+ >>> pprint(component.getTypeInfoDictionary(tuple))
+ {'module': '__builtin__',
+ 'name': 'tuple',
+ 'url': '__builtin__/tuple'}
+
+
+`getSpecificationInfoDictionary(spec)`
+--------------------------------------
+
+Thsi function returns an info dictionary for the given specification. A
+specification can either be an interface or class. If it is an interface, it
+simply returns the interface dictionary:
+
+ >>> pprint(component.getSpecificationInfoDictionary(IFoo))
+ {'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.app.apidoc.doctest',
+ 'name': 'IFoo'}
+
+In addition to the usual interface infos, there are two flags indicating
+whether the specification was an interface or type. In our case it is an
+interface.
+
+Let's now look at the behavior when passing a type:
+
+ >>> import zope.interface
+ >>> tupleSpec = zope.interface.implementedBy(tuple)
+
+ >>> pprint(component.getSpecificationInfoDictionary(tupleSpec))
+ {'isInterface': False,
+ 'isType': True,
+ 'module': '__builtin__',
+ 'name': 'tuple',
+ 'url': '__builtin__/tuple'}
+
+For the type, we simply reuse the type info dictionary function.
+
+
`getAdapterInfoDictionary(reg)`
-------------------------------
@@ -333,9 +376,16 @@
'factory': 'zope.app.apidoc.doctest.MyResult',
'factory_url': 'zope/app/apidoc/doctest/MyResult',
'name': u'FooToResult',
- 'provided': {'module': 'zope.app.apidoc.doctest', 'name': 'IResult'},
- 'required': [{'module': 'zope.app.apidoc.doctest', 'name': 'IFoo'},
- {'module': 'zope.app.apidoc.doctest', 'name': 'IBar'}],
+ 'provided': {'module': 'zope.app.apidoc.doctest',
+ 'name': 'IResult'},
+ 'required': [{'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.app.apidoc.doctest',
+ 'name': 'IFoo'},
+ {'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.app.apidoc.doctest',
+ 'name': 'IBar'}],
'zcml': None}
If the factory's path cannot be referenced, for example if a type has been
@@ -353,9 +403,16 @@
'factory': 'zope.app.apidoc.doctest.MyResult2',
'factory_url': None,
'name': u'FooToResult',
- 'provided': {'module': 'zope.app.apidoc.doctest', 'name': 'IResult'},
- 'required': [{'module': 'zope.app.apidoc.doctest', 'name': 'IFoo'},
- {'module': 'zope.app.apidoc.doctest', 'name': 'IBar'}],
+ 'provided': {'module': 'zope.app.apidoc.doctest',
+ 'name': 'IResult'},
+ 'required': [{'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.app.apidoc.doctest',
+ 'name': 'IFoo'},
+ {'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.app.apidoc.doctest',
+ 'name': 'IBar'}],
'zcml': None}
This function can also handle subscription registrations, which are pretty
@@ -371,8 +428,14 @@
'factory_url': 'zope/app/apidoc/doctest/MyResult',
'name': u'',
'provided': None,
- 'required': [{'module': 'zope.app.apidoc.doctest', 'name': 'IFoo'},
- {'module': 'zope.app.apidoc.doctest', 'name': 'IBar'}],
+ 'required': [{'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.app.apidoc.doctest',
+ 'name': 'IFoo'},
+ {'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.app.apidoc.doctest',
+ 'name': 'IBar'}],
'zcml': None}
Modified: zope.app.apidoc/trunk/src/zope/app/apidoc/ifacemodule/browser.txt
===================================================================
--- zope.app.apidoc/trunk/src/zope/app/apidoc/ifacemodule/browser.txt 2007-09-27 20:47:08 UTC (rev 80258)
+++ zope.app.apidoc/trunk/src/zope/app/apidoc/ifacemodule/browser.txt 2007-09-27 21:18:46 UTC (rev 80259)
@@ -307,7 +307,9 @@
'factory_url': None,
'name': u'',
'provided': None,
- 'required': [{'module': 'zope.interface',
+ 'required': [{'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.interface',
'name': 'Interface'}],
'zcml': None},
{'doc': u'',
@@ -316,7 +318,9 @@
'name': u'',
'provided': {'module': 'zope.traversing.interfaces',
'name': 'IPhysicallyLocatable'},
- 'required': [{'module': 'zope.interface',
+ 'required': [{'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.interface',
'name': 'Interface'}],
'zcml': None},
{'doc': u'',
@@ -325,7 +329,9 @@
'name': u'',
'provided': {'module': 'zope.traversing.interfaces',
'name': 'ITraversable'},
- 'required': [{'module': 'zope.interface',
+ 'required': [{'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.interface',
'name': 'Interface'}],
'zcml': None},
{'doc': u'',
@@ -334,7 +340,9 @@
'name': u'',
'provided': {'module': 'zope.traversing.interfaces',
'name': 'ITraverser'},
- 'required': [{'module': 'zope.interface',
+ 'required': [{'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.interface',
'name': 'Interface'}],
'zcml': None},
{'doc': u'',
@@ -343,7 +351,9 @@
'name': u'etc',
'provided': {'module': 'zope.traversing.interfaces',
'name': 'ITraversable'},
- 'required': [{'module': 'zope.interface',
+ 'required': [{'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.interface',
'name': 'Interface'}],
'zcml': None},
{'doc': u'',
@@ -352,9 +362,13 @@
'name': u'etc',
'provided': {'module': 'zope.traversing.interfaces',
'name': 'ITraversable'},
- 'required': [{'module': 'zope.interface',
+ 'required': [{'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.interface',
'name': 'Interface'},
- {'module': 'zope.interface',
+ {'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.interface',
'name': 'Interface'}],
'zcml': None},
{'doc': u'',
@@ -363,9 +377,13 @@
'name': u'etc',
'provided': {'module': 'zope.traversing.interfaces',
'name': 'ITraversable'},
- 'required': [{'module': 'zope.interface',
+ 'required': [{'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.interface',
'name': 'Interface'},
- {'module': 'zope.interface',
+ {'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.interface',
'name': 'Interface'}],
'zcml': None},
{'doc': u'',
@@ -374,9 +392,13 @@
'name': u'etc',
'provided': {'module': 'zope.traversing.interfaces',
'name': 'ITraversable'},
- 'required': [{'module': 'zope.interface',
+ 'required': [{'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.interface',
'name': 'Interface'},
- {'module': 'zope.interface',
+ {'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.interface',
'name': 'Interface'}],
'zcml': None},
{'doc': u'',
@@ -385,9 +407,13 @@
'name': u'etc',
'provided': {'module': 'zope.traversing.interfaces',
'name': 'ITraversable'},
- 'required': [{'module': 'zope.interface',
+ 'required': [{'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.interface',
'name': 'Interface'},
- {'module': 'zope.interface',
+ {'isInterface': True,
+ 'isType': False,
+ 'module': 'zope.interface',
'name': 'Interface'}],
'zcml': None}]
@@ -402,11 +428,16 @@
'factory': '__builtin__.Foo',
'factory_url': None,
'name': u'',
- 'provided': {'module': '__builtin__', 'name': 'IFoo'},
- 'required': [{'module': '__builtin__', 'name': 'IBar'}],
+ 'provided': {'module': '__builtin__',
+ 'name': 'IFoo'},
+ 'required': [{'isInterface': True,
+ 'isType': False,
+ 'module': '__builtin__',
+ 'name': 'IBar'}],
'zcml': None}]
+
`getClasses()`
---------------
Modified: zope.app.apidoc/trunk/src/zope/app/apidoc/ifacemodule/component_macros.pt
===================================================================
--- zope.app.apidoc/trunk/src/zope/app/apidoc/ifacemodule/component_macros.pt 2007-09-27 20:47:08 UTC (rev 80258)
+++ zope.app.apidoc/trunk/src/zope/app/apidoc/ifacemodule/component_macros.pt 2007-09-27 21:18:46 UTC (rev 80259)
@@ -2,6 +2,10 @@
><span tal:replace="iface/module" />.<u tal:content="iface/name"
/></metal:block>
+<metal:block define-macro="typename">
+ <span tal:replace="type/module" />.<span tal:replace="type/name" />
+</metal:block>
+
<metal:block define-macro="zcml" i18n:domain="zope">
<a href=""
tal:attributes="href
@@ -38,13 +42,22 @@
<div>
<i i18n:translate="">requires:</i>
- <tal:block repeat="iface adapter/required">
+ <tal:block repeat="spec adapter/required">
<a href=""
- tal:condition="iface"
- tal:attributes="href
- string:$rootURL/Interface/${iface/module}.${iface/name}/index.html">
- <metal:block use-macro="context/@@interface_macros/ifacename"
- /></a><tal:block condition="not:repeat/iface/end">, </tal:block>
+ tal:condition="spec/isInterface"
+ tal:define="iface spec"
+ tal:attributes="href
+ string:$rootURL/Interface/${iface/module}.${spec/name}/index.html">
+ <metal:block use-macro="context/@@interface_macros/ifacename"
+ /></a>
+ <a href=""
+ tal:condition="spec/isType"
+ tal:define="type spec"
+ tal:attributes="href
+ string:$rootURL/Code/${type/url}/index.html">
+ <metal:block use-macro="context/@@interface_macros/typename"
+ /></a>
+ <tal:block condition="not:repeat/spec/end">, </tal:block>
</tal:block>
<span tal:condition="not:adapter/required" i18n:translate="">
No interface required.
More information about the Checkins
mailing list