{ "info": { "author": "Zope Corporation and Contributors", "author_email": "zope-dev@zope.org", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Zope3", "Intended Audience :: Developers", "License :: OSI Approved :: Zope Public License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Internet :: WWW/HTTP" ], "description": "This Zope 3 package provides helper utilities to discover your Application API\nand the Zopen Component Registry.\n\n\n.. contents::\n\n========================\nZope 3 API Documentation\n========================\n\nThis Zope 3 package provides fully dynamic API documentation of Zope 3 and\nregistered add-on components. The package is very extensible and can be easily\nextended by implementing new modules.\n\nBesides being an application, the API doctool also provides several public\nAPIs to extract information from various objects used by Zope 3.\n\n * utilities -- Miscellaneous classes and functions that aid all documentation\n modules. They are broadly usable.\n\n * interface -- This module contains functions to inspect interfaces and\n schemas.\n\n * component -- This modules provides utility functions to lookup components\n given an interface.\n\n * presentation -- Presentation components are generally more complex than\n others, so a separate utilities module is provided to inspect views.\n\n * classregistry -- Here a simple dictionary-based registry for all known\n classes is provided. It allows us to search in classes.\n\n\n==============================\nComponent Inspection Utilities\n==============================\n\nOnce you have an interface, you really want to discover on how this interface\ninteracts with other components in Zope 3. The functions in\n\n >>> from zope.apidoc import component\n\nprovide you with utilities to make those discoveries. The functions are\nexplained in detail in this document. Before we start though, we have to have\nsome interfaces to work with:\n\n >>> from zope.interface import Interface\n >>> class IFoo(Interface):\n ... pass\n\n >>> class IBar(Interface):\n ... pass\n\n >>> class IFooBar(IFoo, IBar):\n ... pass\n\n >>> class IResult(Interface):\n ... pass\n\n >>> class ISpecialResult(IResult):\n ... pass\n\n\n`getRequiredAdapters(iface, withViews=False)`\n---------------------------------------------\n\nThis function returns adapter registrations for adapters that require the\nspecified interface. So let's create some adapter registrations:\n\n >>> from zope.publisher.interfaces import IRequest\n >>> from zope.component import provideAdapter, provideHandler\n >>> provideAdapter(None, (IFoo,), IResult)\n >>> provideAdapter(None, (IFoo, IBar), ISpecialResult)\n >>> provideAdapter(None, (IFoo, IRequest), ISpecialResult)\n >>> provideHandler('stubFactory', (IFoo,))\n\n >>> regs = list(component.getRequiredAdapters(IFoo))\n >>> regs.sort()\n >>> regs\n [AdapterRegistration(,\n [IFoo, IBar], ISpecialResult, u'', None, u''),\n AdapterRegistration(,\n [IFoo], IResult, u'', None, u''),\n HandlerRegistration(,\n [IFoo], u'', 'stubFactory', u'')]\n\nNote how the adapter requiring an `IRequest` at the end of the required\ninterfaces is neglected. This is because it is recognized as a view and views\nare not returned by default. But you can simply turn this flag on:\n\n >>> regs = list(component.getRequiredAdapters(IFoo, withViews=True))\n >>> regs.sort()\n >>> regs\n [AdapterRegistration(,\n [IFoo, IBar], ISpecialResult, u'', None, u''),\n AdapterRegistration(,\n [IFoo, IRequest], ISpecialResult, u'', None, u''),\n AdapterRegistration(,\n [IFoo], IResult, u'', None, u''),\n HandlerRegistration(,\n [IFoo], u'', 'stubFactory', u'')]\n\nThe function will also pick up registrations that have required interfaces the\nspecified interface extends:\n\n >>> regs = list(component.getRequiredAdapters(IFoo))\n >>> regs.sort()\n >>> regs\n [AdapterRegistration(,\n [IFoo, IBar], ISpecialResult, u'', None, u''),\n AdapterRegistration(,\n [IFoo], IResult, u'', None, u''),\n HandlerRegistration(,\n [IFoo], u'', 'stubFactory', u'')]\n\nAnd all of the required interfaces are considered, of course:\n\n >>> regs = list(component.getRequiredAdapters(IBar))\n >>> regs.sort()\n >>> regs\n [AdapterRegistration(,\n [IFoo, IBar], ISpecialResult, u'', None, u'')]\n\n\n`getProvidedAdapters(iface, withViews=False)`\n---------------------------------------------\n\nOf course, we are also interested in the adapters that provide a certain\ninterface. This function returns those adapter registrations, again ignoring\nviews by default.\n\n >>> regs = list(component.getProvidedAdapters(ISpecialResult))\n >>> regs.sort()\n >>> regs\n [AdapterRegistration(,\n [IFoo, IBar], ISpecialResult, u'', None, u'')]\n\nAnd by specifying the `withView` flag, we get views as well:\n\n >>> regs = list(component.getProvidedAdapters(ISpecialResult, withViews=True))\n >>> regs.sort()\n >>> regs\n [AdapterRegistration(,\n [IFoo, IBar], ISpecialResult, u'', None, u''),\n AdapterRegistration(,\n [IFoo, IRequest], ISpecialResult, u'', None, u'')]\n\nWe can of course also ask for adapters specifying `IResult`:\n\n >>> regs = list(component.getProvidedAdapters(IResult, withViews=True))\n >>> regs.sort()\n >>> regs\n [AdapterRegistration(,\n [IFoo, IBar], ISpecialResult, u'', None, u''),\n AdapterRegistration(,\n [IFoo, IRequest], ISpecialResult, u'', None, u''),\n AdapterRegistration(,\n [IFoo], IResult, u'', None, u'')]\n\n\n`getClasses(iface)`\n-------------------\n\nThis package comes with a little tool called the class registry\n(see `classregistry.txt`). It provides a dictionary of all classes in the\nvisible packages. This function utilizes the registry to retrieve all classes\nthat implement the specified interface.\n\nLet's start by creating and registering some classes:\n\n >>> from zope.interface import implements\n >>> from zope.apidoc.classregistry import classRegistry\n\n >>> class MyFoo(object):\n ... implements(IFoo)\n >>> classRegistry['MyFoo'] = MyFoo\n\n >>> class MyBar(object):\n ... implements(IBar)\n >>> classRegistry['MyBar'] = MyBar\n\n >>> class MyFooBar(object):\n ... implements(IFooBar)\n >>> classRegistry['MyFooBar'] = MyFooBar\n\nLet's now see whether what results we get:\n\n >>> classes = component.getClasses(IFooBar)\n >>> classes.sort()\n >>> classes\n [('MyFooBar', )]\n\n >>> classes = component.getClasses(IFoo)\n >>> classes.sort()\n >>> classes\n [('MyFoo', ),\n ('MyFooBar', )]\n\n\n`getFactories(ifaces)`\n----------------------\n\nReturn the factory registrations of the factories that will return objects\nproviding this interface.\n\nAgain, the first step is to create some factories:\n\n >>> from zope.component.factory import Factory\n >>> from zope.component.interfaces import IFactory\n >>> from zope.component import provideUtility\n >>> provideUtility(Factory(MyFoo), IFactory, 'MyFoo')\n >>> provideUtility(Factory(MyBar), IFactory, 'MyBar')\n >>> provideUtility(\n ... Factory(MyFooBar, 'MyFooBar', 'My Foo Bar'), IFactory, 'MyFooBar')\n\nLet's see whether we will be able to get them:\n\n >>> regs = list(component.getFactories(IFooBar))\n >>> regs.sort()\n >>> regs\n [UtilityRegistration(,\n IFactory, 'MyFooBar',\n >, None, u'')]\n\n >>> regs = list(component.getFactories(IFoo))\n >>> regs.sort()\n >>> regs\n [UtilityRegistration(, IFactory, 'MyFoo',\n >, None, u''),\n UtilityRegistration(, IFactory, 'MyFooBar',\n >, None, u'')]\n\n\n`getUtilities(iface)`\n---------------------\n\nReturn all utility registrations for utilities that provide the specified\ninterface.\n\nAs usual, we have to register some utilities first:\n\n >>> provideUtility(MyFoo(), IFoo)\n >>> provideUtility(MyBar(), IBar)\n >>> provideUtility(MyFooBar(), IFooBar)\n\nNow let's have a look what we have:\n\n >>> regs = list(component.getUtilities(IFooBar))\n >>> regs.sort()\n >>> regs #doctest:+ELLIPSIS\n [UtilityRegistration(, IFooBar, u'',\n , None, u'')]\n\n >>> regs = list(component.getUtilities(IFoo))\n >>> regs.sort()\n >>> regs #doctest:+ELLIPSIS\n [UtilityRegistration(, IFoo, u'',\n , None, u''),\n UtilityRegistration(, IFooBar, u'',\n , None, u'')]\n\n\n`getRealFactory(factory)`\n-------------------------\n\nDuring registration, factories are commonly masked by wrapper functions. Also,\nfactories are sometimes also `IFactory` instances, which are not referencable,\nso that we would like to return the class. If the wrapper objects/functions\nplay nice, then they provide a `factory` attribute that points to the next\nwrapper or the original factory.\n\nThe task of this function is to remove all the factory wrappers and make sure\nthat the returned factory is referencable.\n\n >>> class Factory(object):\n ... pass\n\n >>> def wrapper1(*args):\n ... return Factory(*args)\n >>> wrapper1.factory = Factory\n\n >>> def wrapper2(*args):\n ... return wrapper1(*args)\n >>> wrapper2.factory = wrapper1\n\nSo whether we pass in `Factory`,\n\n >>> component.getRealFactory(Factory)\n \n\n`wrapper1`,\n\n >>> component.getRealFactory(wrapper1)\n \n\nor `wrapper2`,\n\n >>> component.getRealFactory(wrapper2)\n \n\nthe answer should always be the `Factory` class. Next we are going to pass in\nan instance, and again we should get our class aas a result:\n\n >>> factory = Factory()\n >>> component.getRealFactory(factory)\n \n\nEven, if the factory instance is wrapped, we should get the factory class:\n\n >>> def wrapper3(*args):\n ... return factory(*args)\n >>> wrapper3.factory = factory\n\n >>> component.getRealFactory(wrapper3)\n \n\n\n`getInterfaceInfoDictionary(iface)`\n-----------------------------------\n\nThis function returns a small info dictionary for an interface. It only\nreports the module and the name. This is useful for cases when we only want to\nlist interfaces in the context of other components, like adapters and\nutilities.\n\n >>> from pprint import pprint\n >>> pprint(component.getInterfaceInfoDictionary(IFoo), width=1)\n {'module': 'zope.apidoc.doctest', 'name': 'IFoo'}\n\nThe functions using this function use it with little care and can also\nsometimes pass in `None`. In these cases we want to return `None`:\n\n >>> component.getInterfaceInfoDictionary(None) is None\n True\n\nIt's also possible for this function to be passed a\nzope.interface.declarations.Implements instance. For instance, this function\nis sometimes used to analyze the required elements of an adapter registration:\nif an adapter or subscriber is registered against a class, then the required\nelement will be an Implements instance. In this case, we currently believe\nthat we want to return the module and name of the object that the Implements\nobject references. This may change.\n\n >>> from zope.interface import implementedBy\n >>> pprint(component.getInterfaceInfoDictionary(implementedBy(MyFoo)), width=1)\n {'module': 'zope.apidoc.doctest', 'name': 'MyFoo'}\n\n\n`getTypeInfoDictionary(type)`\n-----------------------------\n\nThis function returns the info dictionary of a type.\n\n >>> pprint(component.getTypeInfoDictionary(tuple), width=1)\n {'module': '__builtin__',\n 'name': 'tuple',\n 'url': '__builtin__/tuple'}\n\n\n`getSpecificationInfoDictionary(spec)`\n--------------------------------------\n\nThsi function returns an info dictionary for the given specification. A\nspecification can either be an interface or class. If it is an interface, it\nsimply returns the interface dictionary:\n\n >>> pprint(component.getSpecificationInfoDictionary(IFoo))\n {'isInterface': True,\n 'isType': False,\n 'module': 'zope.apidoc.doctest',\n 'name': 'IFoo'}\n\nIn addition to the usual interface infos, there are two flags indicating\nwhether the specification was an interface or type. In our case it is an\ninterface.\n\nLet's now look at the behavior when passing a type:\n\n >>> import zope.interface\n >>> tupleSpec = zope.interface.implementedBy(tuple)\n\n >>> pprint(component.getSpecificationInfoDictionary(tupleSpec))\n {'isInterface': False,\n 'isType': True,\n 'module': '__builtin__',\n 'name': 'tuple',\n 'url': '__builtin__/tuple'}\n\nFor the type, we simply reuse the type info dictionary function.\n\n\n`getAdapterInfoDictionary(reg)`\n-------------------------------\n\nThis function returns a page-template-friendly dictionary representing the\ndata of an adapter registration in an output-friendly format.\n\nLet's first create an adapter registration:\n\n >>> class MyResult(object):\n ... implements(IResult)\n\n >>> from zope.component.registry import AdapterRegistration\n >>> reg = AdapterRegistration(None, (IFoo, IBar), IResult, 'FooToResult',\n ... MyResult, 'doc info')\n\nAnd now get the info dictionary:\n\n >>> pprint(component.getAdapterInfoDictionary(reg), width=1)\n {'doc': 'doc info',\n 'factory': 'zope.apidoc.doctest.MyResult',\n 'factory_url': 'zope/apidoc/doctest/MyResult',\n 'name': u'FooToResult',\n 'provided': {'module': 'zope.apidoc.doctest',\n 'name': 'IResult'},\n 'required': [{'isInterface': True,\n 'isType': False,\n 'module': 'zope.apidoc.doctest',\n 'name': 'IFoo'},\n {'isInterface': True,\n 'isType': False,\n 'module': 'zope.apidoc.doctest',\n 'name': 'IBar'}],\n 'zcml': None}\n\nIf the factory's path cannot be referenced, for example if a type has been\ncreated using the ``type()`` builtin function, then the URL of the factory\nwill be ``None``:\n\n >>> MyResultType = type('MyResult2', (object,), {})\n >>> from zope.interface import classImplements\n >>> classImplements(MyResultType, IResult)\n\n >>> reg = AdapterRegistration(None, (IFoo, IBar), IResult, 'FooToResult',\n ... MyResultType, 'doc info')\n >>> pprint(component.getAdapterInfoDictionary(reg), width=1)\n {'doc': 'doc info',\n 'factory': 'zope.apidoc.doctest.MyResult2',\n 'factory_url': None,\n 'name': u'FooToResult',\n 'provided': {'module': 'zope.apidoc.doctest',\n 'name': 'IResult'},\n 'required': [{'isInterface': True,\n 'isType': False,\n 'module': 'zope.apidoc.doctest',\n 'name': 'IFoo'},\n {'isInterface': True,\n 'isType': False,\n 'module': 'zope.apidoc.doctest',\n 'name': 'IBar'}],\n 'zcml': None}\n\nThis function can also handle subscription registrations, which are pretty\nmuch like adapter registrations, except that they do not have a name. So let's\nsee how the function handles subscriptions:\n\n >>> from zope.component.registry import HandlerRegistration\n >>> reg = HandlerRegistration(None, (IFoo, IBar), u'', MyResult, 'doc info')\n\n >>> pprint(component.getAdapterInfoDictionary(reg))\n {'doc': 'doc info',\n 'factory': 'zope.apidoc.doctest.MyResult',\n 'factory_url': 'zope/apidoc/doctest/MyResult',\n 'name': u'',\n 'provided': None,\n 'required': [{'isInterface': True,\n 'isType': False,\n 'module': 'zope.apidoc.doctest',\n 'name': 'IFoo'},\n {'isInterface': True,\n 'isType': False,\n 'module': 'zope.apidoc.doctest',\n 'name': 'IBar'}],\n 'zcml': None}\n\n\n`getFactoryInfoDictionary(reg)`\n-------------------------------\n\nThis function returns a page-template-friendly dictionary representing the\ndata of a factory (utility) registration in an output-friendly format.\n\nLuckily we have already registered some factories, so we just reuse their\nregistrations:\n\n >>> pprint(component.getFactoryInfoDictionary(\n ... component.getFactories(IFooBar).next()))\n {'description': u'

My Foo Bar

\\n',\n 'name': u'MyFooBar',\n 'title': 'MyFooBar',\n 'url': 'zope/apidoc/doctest/MyFooBar'}\n\nIf the factory's path cannot be referenced, for example if a type has been\ncreated using the ``type()`` builtin function, then the URL of the factory\nwill be ``None``:\n\n >>> class IMine(Interface):\n ... pass\n\n >>> class FactoryBase(object):\n ... def getInterfaces(self): return [IMine]\n\n >>> MyFactoryType = type('MyFactory', (FactoryBase,), {})\n >>> from zope.interface import classImplements\n >>> classImplements(MyFactoryType, IFactory)\n >>> provideUtility(MyFactoryType(), IFactory, 'MyFactory')\n\n >>> pprint(component.getFactoryInfoDictionary(\n ... component.getFactories(IMine).next()), width=1)\n {'description': u'',\n 'name': u'MyFactory',\n 'title': u'',\n 'url': None}\n\n\n`getUtilityInfoDictionary(name, factory)`\n-----------------------------------------\n\nThis function returns a page-template-friendly dictionary representing the\ndata of a utility registration in an output-friendly format.\n\nLuckily we have already registered some utilities, so we just reuse their\nregistrations:\n\n >>> pprint(component.getUtilityInfoDictionary(\n ... component.getUtilities(IFooBar).next()))\n {'iface_id': 'zope.apidoc.doctest.IFooBar',\n 'name': u'no name',\n 'path': 'zope.apidoc.doctest.MyFooBar',\n 'url': 'Code/zope/apidoc/doctest/MyFooBar',\n 'url_name': 'X19ub25hbWVfXw=='}\n\n\n==============================\nInterface Inspection Utilities\n==============================\n\nThis document is a presentation of the utility functions provided by\n\n >>> from zope.apidoc import interface\n\nFor the following demonstrations, we need a nice interface that we can inspect:\n\n >>> from zope.interface import Interface, Attribute\n >>> from zope.schema import Field, TextLine\n\n >>> class IFoo(Interface):\n ... foo = Field(title=u\"Foo\")\n ...\n ... bar = TextLine(title=u\"Bar\",\n ... description=u\"The Bar\",\n ... required=True,\n ... default=u\"My Bar\")\n ...\n ... baz = Attribute('baz',\n ... 'This is the baz attribute')\n ...\n ... def blah(one, two, three=None, *args, **kwargs):\n ... \"\"\"This is the `blah` method.\"\"\"\n\n\n`getElements(iface, type=IElement)`\n-----------------------------------\n\nReturn a dictionary containing all elements in an interface. The type\nspecifies whether we are looking for attributes, fields or methods. So let's\nlook at an example.\n\nFirst, let's get the methods of an interface:\n\n >>> from zope.interface.interfaces import IMethod\n >>> interface.getElements(IFoo, type=IMethod).keys()\n ['blah']\n\nand now the fields:\n\n >>> from zope.schema.interfaces import IField\n >>> names = interface.getElements(IFoo, type=IField).keys()\n >>> names.sort()\n >>> names\n ['bar', 'foo']\n\nWe can also get all attributes of course.\n\n >>> from zope.interface.interfaces import IAttribute\n >>> names = interface.getElements(IFoo, type=IAttribute).keys()\n >>> names.sort()\n >>> names\n ['bar', 'baz', 'blah', 'foo']\n\nYou might be surprised by the above result, since the fields and methods are\nagain included. However, fields and methods are just attributes and thus\nextend the simple attribute implementation. If you want to get a list of\nattributes that does not include fields and methods, see the\n`getAttributes(iface)` function.\n\nThe default type is `IElement` which will simply return all elements of the\ninterface:\n\n >>> names = interface.getElements(IFoo).keys()\n >>> names.sort()\n >>> names\n ['bar', 'baz', 'blah', 'foo']\n\nNote: The interface you pass to this function *cannot* be proxied!\nPresentation code often like to wrap interfaces in security proxies and apidoc\neven uses location proxies for interface.\n\n\n`getFieldsInOrder(iface, _itemsorter=...)`\n-----------------------------------------------------------\n\nFor presentation purposes we often want fields to have the a certain order,\nmost comonly the order they have in the interface. This function returns a\nlist of (name, field) tuples in a specified order.\n\nThe `_itemsorter` argument provides the function that is used to order the\nfields. The default function, which sorts by the fields' `order` attribute,\nshould be the correct one for 99% of your needs.\n\nReusing the interface created above, we check the output:\n\n >>> [n for n, a in interface.getFieldsInOrder(IFoo)]\n ['foo', 'bar']\n\nBy changing the sort method to sort by names, we get:\n\n >>> [n for n, a in interface.getFieldsInOrder(\n ... IFoo, _itemsorter=lambda x, y: cmp(x[0], y[0]))]\n ['bar', 'foo']\n\n\n`getAttributes(iface)`\n----------------------\n\nThis function returns a (name, attr) tuple for every attribute in the\ninterface. Note that this function will only return pure attributes; it\nignores methods and fields.\n\n >>> attrs = interface.getAttributes(IFoo)\n >>> attrs.sort()\n >>> attrs #doctest: +ELLIPSIS\n [('baz', )]\n\n\n`getMethods(iface)`\n-------------------\n\nThis function returns a (name, method) tuple for every declared method in the\ninterface.\n\n >>> methods = interface.getMethods(IFoo)\n >>> methods.sort()\n >>> methods #doctest: +ELLIPSIS\n [('blah', )]\n\n\n`getFields(iface)`\n------------------\n\nThis function returns a (name, field) tuple for every declared field in the\ninterface.\n\n >>> interface.getFields(IFoo) #doctest: +ELLIPSIS\n [('foo', ),\n ('bar', )]\n\nNote that this returns the same result as `getFieldsInOrder()` with the fields\nsorted by their `order` attribute, except that you cannot specify the sort\nfunction here. This function was mainly provided for symmetry with the other\nfunctions.\n\n\n`getInterfaceTypes(iface)`\n--------------------------\n\nInterfaces can be categorized/grouped by using interface types. Interface\ntypes simply extend `zope.interface.interfaces.IInterface`, which are\nbasically meta-interfaces. The interface types are then provided by particular\ninterfaces.\n\nThe `getInterfaceTypes()` function returns a list of interface types that are\nprovided for the specified interface. Note that you commonly expect only one\ntype per interface, though.\n\nBefore we assign any type to our `IFoo` interface, there are no types\ndeclared.\n\n >>> interface.getInterfaceTypes(IFoo)\n []\n\nNow we define a new type called `IContentType`\n\n >>> from zope.interface.interfaces import IInterface\n >>> class IContentType(IInterface):\n ... pass\n\nand have our interface provide it:\n\n >>> from zope.interface import directlyProvides\n >>> directlyProvides(IFoo, IContentType)\n\nNote that ZCML has some more convenient methods of doing this. Now let's get\nthe interface types again:\n\n >>> interface.getInterfaceTypes(IFoo)\n []\n\nAgain note that the interface passed to this function *cannot* be proxied,\notherwise this method will pick up the proxy's interfaces as well.\n\n\n`getFieldInterface(field)`\n--------------------------\n\nThis function tries pretty hard to determine the best-matching interface that\nrepresents the field. Commonly the field class has the same name as the field\ninterface (minus an \"I\"). So this is our first choice:\n\n >>> from zope.schema import Text, Int\n >>> interface.getFieldInterface(Text())\n \n\n >>> interface.getFieldInterface(Int())\n \n\nIf the name matching method fails, it picks the first interface that extends\n`IField`:\n\n >>> from zope.schema.interfaces import IField\n >>> class ISpecialField(IField):\n ... pass\n >>> class ISomething(Interface):\n ... pass\n\n >>> from zope.interface import implements\n >>> class MyField:\n ... implements(ISomething, ISpecialField)\n\n >>> interface.getFieldInterface(MyField())\n \n\n\n`getAttributeInfoDictionary(attr, format='restructuredtext')`\n-------------------------------------------------------------\n\nThis function returns a page-template-friendly dictionary for a simple\nattribute:\n\n >>> from pprint import pprint\n >>> pprint(interface.getAttributeInfoDictionary(IFoo['baz']))\n {'doc': u'

This is the baz attribute

\\n',\n 'name': 'baz'}\n\n\n`getMethodInfoDictionary(method, format='restructuredtext')`\n-------------------------------------------------------------\n\nThis function returns a page-template-friendly dictionary for a method:\n\n >>> pprint(interface.getMethodInfoDictionary(IFoo['blah'])) #doc\n {'doc':\n u'

This is the blah method.

\\n',\n 'name': 'blah',\n 'signature': '(one, two, three=None, *args, **kwargs)'}\n\n\n`getFieldInfoDictionary(field, format='restructuredtext')`\n----------------------------------------------------------\n\nThis function returns a page-template-friendly dictionary for a field:\n\n >>> pprint(interface.getFieldInfoDictionary(IFoo['bar']), width=1)\n {'class': {'name': 'TextLine',\n 'path': 'zope/schema/_bootstrapfields/TextLine'},\n 'default': \"u'My Bar'\",\n 'description': u'

The Bar

\\n',\n 'iface': {'id': 'zope.schema.interfaces.ITextLine',\n 'name': 'ITextLine'},\n 'name': 'bar',\n 'required': True,\n 'required_string': u'required',\n 'title': u'Bar'}\n\n\n=================================\nPresentation Inspection Utilities\n=================================\n\nThe `presentation` module provides some nice utilities to inspect presentation\nregistrations.\n\n >>> from zope.apidoc import presentation\n\n\n`getViewFactoryData(factory)`\n-----------------------------\n\nThis function tries really hard to determine the correct information about a\nview factory. For example, when you create a page, a new type is dynamically\ngenerated upon registration. Let's look at a couple examples.\n\nFirst, let's inspect a case where a simple browser page was configured without\na special view class. In these cases the factory is a `SimpleViewClass`:\n\n >>> from zope.browserpage.simpleviewclass import SimpleViewClass\n >>> view = SimpleViewClass('sample.pt')\n >>> info = presentation.getViewFactoryData(view)\n\nBefore we can check the result, we have to make sure that all Windows paths\nare converted to Unix-like paths. We also clip off instance-specific parts of\nthe template path:\n\n >>> info['template'] = info['template'].replace('\\\\', '/')[-21:]\n >>> from pprint import pprint\n >>> pprint(info)\n {'path': 'zope.browserpage.simpleviewclass.simple',\n 'referencable': True,\n 'resource': None,\n 'template': 'zope/apidoc/sample.pt',\n 'template_obj': ,\n 'url': 'zope/browserpage/simpleviewclass/simple'}\n\nSo in the result above we see what the function returns. It is a dictionary\n(converted to a list for test purposes) that contains the Python path of the\nview class, a flag that specifies whether the factory can be referenced and\nthus be viewed by the class browser, the (page) template used for the view and\nthe URL under which the factory will be found in the class browser. Some\nviews, like icons, also use resources to provide their data. In these cases\nthe name of the resource will be provided. Of course, not in all cases all\nvalues will be available. Empty values are marked with `None`.\n\nBelieve it or not, in some cases the factory is just a simple type. In these\ncases we cannot retrieve any useful information:\n\n >>> info = presentation.getViewFactoryData(3)\n >>> pprint(info)\n {'path': None,\n 'referencable': False,\n 'resource': None,\n 'template': None,\n 'url': None}\n\nIn some cases factories are callable class instances, where we cannot directly\nhave a referencable name, so we lookup the class and use its name:\n\n >>> class Factory(object):\n ... pass\n\n >>> info = presentation.getViewFactoryData(Factory())\n >>> pprint(info)\n {'path': 'zope.apidoc.doctest.Factory',\n 'referencable': True,\n 'resource': None,\n 'template': None,\n 'url': 'zope/apidoc/doctest/Factory'}\n\nOne of the more common cases, however, is that the factory is a class or\ntype. In this case we can just retrieve the reference directly:\n\n >>> info = presentation.getViewFactoryData(Factory)\n >>> pprint(info)\n {'path': 'zope.apidoc.doctest.Factory',\n 'referencable': True,\n 'resource': None,\n 'template': None,\n 'url': 'zope/apidoc/doctest/Factory'}\n\nWhen factories are created by a directive, they can also be functions. In\nthose cases we just simply return the function path:\n\n >>> def factory():\n ... pass\n\n # The testing framework does not set the __module__ correctly\n >>> factory.__module__ = '__builtin__'\n\n >>> info = presentation.getViewFactoryData(factory)\n >>> pprint(info)\n {'path': '__builtin__.factory',\n 'referencable': True,\n 'resource': None,\n 'template': None,\n 'url': '__builtin__/factory'}\n\nHowever, the function is rather unhelpful, since it will be the same for all\nviews that use that code path. For this reason the function keeps track of the\noriginal factory component in a function attribute called ``factory``:\n\n >>> factory.factory = Factory\n\n >>> info = presentation.getViewFactoryData(factory)\n >>> pprint(info)\n {'path': 'zope.apidoc.doctest.Factory',\n 'referencable': True,\n 'resource': None,\n 'template': None,\n 'url': 'zope/apidoc/doctest/Factory'}\n\nLet's now have a look at some extremly specific cases. If a view is registered\nusing the ``zope:view`` directive and a permission is specified, a\n``ProxyView`` class instance is created that references its original factory:\n\n >>> class ProxyView(object):\n ...\n ... def __init__(self, factory):\n ... self.factory = factory\n >>> proxyView = ProxyView(Factory)\n\n >>> info = presentation.getViewFactoryData(proxyView)\n >>> pprint(info)\n {'path': 'zope.apidoc.doctest.Factory',\n 'referencable': True,\n 'resource': None,\n 'template': None,\n 'url': 'zope/apidoc/doctest/Factory'}\n\nAnother use case is when a new type is created by the ``browser:page`` or\n``browser:view`` directive. In those cases the true/original factory is really\nthe first base class. Those cases are detected by inspecting the\n``__module__`` string of the type:\n\n >>> new_class = type(Factory.__name__, (Factory,), {})\n >>> new_class.__module__ = 'zope.browserpage.viewmeta'\n\n >>> info = presentation.getViewFactoryData(new_class)\n >>> pprint(info)\n {'path': 'zope.apidoc.doctest.Factory',\n 'referencable': True,\n 'resource': None,\n 'template': None,\n 'url': 'zope/apidoc/doctest/Factory'}\n\nThe same sort of thing happens for XML-RPC views, except that those are\nwrapped twice:\n\n >>> new_class = type(Factory.__name__, (Factory,), {})\n >>> new_class.__module__ = 'zope.app.publisher.xmlrpc.metaconfigure'\n\n >>> new_class2 = type(Factory.__name__, (new_class,), {})\n >>> new_class2.__module__ = 'zope.app.publisher.xmlrpc.metaconfigure'\n\n >>> info = presentation.getViewFactoryData(new_class2)\n >>> pprint(info)\n {'path': 'zope.apidoc.doctest.Factory',\n 'referencable': True,\n 'resource': None,\n 'template': None,\n 'url': 'zope/apidoc/doctest/Factory'}\n\nFinally, it sometimes happens that a factory is wrapped and the wrapper is\nwrapped in return:\n\n >>> def wrapper1(*args):\n ... return Factory(*args)\n >>> wrapper1.__module__ = None\n\n >>> def wrapper2(*args):\n ... return wrapper1(*args)\n >>> wrapper2.__module__ = None\n\nInitially, the documentation is not very helpful:\n\n >>> info = presentation.getViewFactoryData(wrapper2)\n >>> pprint(info)\n {'path': 'None.wrapper2',\n 'referencable': True,\n 'resource': None,\n 'template': None,\n 'url': 'None/wrapper2'}\n\nHowever, if those wrappers play nicely, they provide a factory attribute each\nstep of the way ...\n\n >>> wrapper1.factory = Factory\n >>> wrapper2.factory = wrapper1\n\nand the result is finally our original factory:\n\n >>> info = presentation.getViewFactoryData(wrapper2)\n >>> pprint(info)\n {'path': 'zope.apidoc.doctest.Factory',\n 'referencable': True,\n 'resource': None,\n 'template': None,\n 'url': 'zope/apidoc/doctest/Factory'}\n\n\n`getPresentationType(iface)`\n----------------------------\n\nIn Zope 3, presentation types (i.e. browser, ftp, ...) are defined through\ntheir special request interface, such as `IBrowserRequest` or\n`IFTPRequest`. To complicate matters further, layer interfaces are used in\nbrowser presentations to allow skinning. Layers extend any request type, but\nmost commonly `IBrowserRequest`. This function inspects the request interface\nof any presentation multi-adapter and determines its type, which is returned\nin form of an interface.\n\n >>> from zope.apidoc.presentation import getPresentationType\n >>> from zope.publisher.interfaces.http import IHTTPRequest\n >>> from zope.publisher.interfaces.browser import IBrowserRequest\n\n >>> class ILayer1(IBrowserRequest):\n ... pass\n\n >>> presentation.getPresentationType(ILayer1)\n \n\n >>> class ILayer2(IHTTPRequest):\n ... pass\n\n >>> presentation.getPresentationType(ILayer2)\n \n\nIf the function cannot determine the presentation type, the interface itself\nis returned:\n\n >>> from zope.interface import Interface\n >>> class ILayer3(Interface):\n ... pass\n\n >>> presentation.getPresentationType(ILayer3)\n \n\nNote that more specific presentation types are considered first. For example,\n`IBrowserRequest` extends `IHTTPRequest`, but it will always determine the\npresentation type to be an `IBrowserRequest`.\n\n\n`getViews(iface, type=IRequest)`\n--------------------------------\n\nThis function retrieves all available view registrations for a given interface\nand presentation type. The default argument for the presentation type is\n`IRequest`, which will effectively return all views for the specified\ninterface.\n\nTo see how this works, we first have to register some views:\n\n >>> class IFoo(Interface):\n ... pass\n\n >>> from zope.component import provideAdapter\n >>> provideAdapter(None, (IFoo, IHTTPRequest), Interface, name='foo')\n >>> provideAdapter(None, (Interface, IHTTPRequest), Interface,\n ... name='bar')\n >>> provideAdapter(None, (IFoo, IBrowserRequest), Interface,\n ... name='blah')\n\nNow let's see what we've got. If we do not specify a type, all registrations\nshould be returned:\n\n >>> regs = list(presentation.getViews(IFoo))\n >>> regs.sort()\n >>> regs #doctest:+ELLIPSIS\n [AdapterRegistration(,\n [IFoo, IBrowserRequest], Interface, 'blah', None, u''),\n AdapterRegistration(,\n [IFoo, IHTTPRequest], Interface, 'foo', None, u''),\n AdapterRegistration(,\n [Interface, IHTTPRequest], Interface, 'bar', None, u'')]\n\n >>> regs = list(presentation.getViews(Interface, IHTTPRequest))\n >>> regs.sort()\n >>> regs #doctest:+ELLIPSIS\n [AdapterRegistration(,\n [Interface, IHTTPRequest], Interface, 'bar', None, u'')]\n\n\n`filterViewRegistrations(regs, iface, level=SPECIFC_INTERFACE_LEVEL)`\n---------------------------------------------------------------------\n\nOftentimes the amount of views that are being returned for a particular\ninterface are too much to show at once. It is then good to split the view into\ncategories. The `filterViewRegistrations()` function allows you to filter the\nviews on how specific they are to the interface. Here are the three levels you\ncan select from:\n\n * SPECIFC_INTERFACE_LEVEL -- Only return registrations that require the\n specified interface directly.\n\n * EXTENDED_INTERFACE_LEVEL -- Only return registrations that require an\n interface that the specified interface extends.\n\n * GENERIC_INTERFACE_LEVEL -- Only return registrations that explicitely\n require the `Interface` interface.\n\nSo, let's see how this is done. We first need to create a couple of interfaces\nand register some views:\n\n >>> class IContent(Interface):\n ... pass\n >>> class IFile(IContent):\n ... pass\n\n Clear out the registries first, so we know what we have.\n >>> from zope.testing.cleanup import cleanUp\n >>> cleanUp()\n\n >>> provideAdapter(None, (IContent, IHTTPRequest), Interface,\n ... name='view.html')\n >>> provideAdapter(None, (IContent, IHTTPRequest), Interface,\n ... name='edit.html')\n >>> provideAdapter(None, (IFile, IHTTPRequest), Interface,\n ... name='view.html')\n >>> provideAdapter(None, (Interface, IHTTPRequest), Interface,\n ... name='view.html')\n\nNow we get all the registrations:\n\n >>> regs = list(presentation.getViews(IFile, IHTTPRequest))\n\nLet's now filter those registrations:\n\n >>> result = list(presentation.filterViewRegistrations(\n ... regs, IFile, level=presentation.SPECIFIC_INTERFACE_LEVEL))\n >>> result.sort()\n >>> result\n [AdapterRegistration(,\n [IFile, IHTTPRequest], Interface, 'view.html', None, u'')]\n\n >>> result = list(presentation.filterViewRegistrations(\n ... regs, IFile, level=presentation.EXTENDED_INTERFACE_LEVEL))\n >>> result.sort()\n >>> result\n [AdapterRegistration(,\n [IContent, IHTTPRequest], Interface, 'edit.html', None, u''),\n AdapterRegistration(,\n [IContent, IHTTPRequest], Interface, 'view.html', None, u'')]\n\n >>> result = list(presentation.filterViewRegistrations(\n ... regs, IFile, level=presentation.GENERIC_INTERFACE_LEVEL))\n >>> result.sort()\n >>> result\n [AdapterRegistration(,\n [Interface, IHTTPRequest], Interface, 'view.html', None, u'')]\n\nYou can also specify multiple levels at once using the Boolean OR operator,\nsince all three levels are mutually exclusive.\n\n >>> result = list(presentation.filterViewRegistrations(\n ... regs, IFile, level=presentation.SPECIFIC_INTERFACE_LEVEL |\n ... presentation.EXTENDED_INTERFACE_LEVEL))\n >>> result.sort()\n >>> result\n [AdapterRegistration(,\n [IContent, IHTTPRequest], Interface, 'edit.html', None, u''),\n AdapterRegistration(,\n [IContent, IHTTPRequest], Interface, 'view.html', None, u''),\n AdapterRegistration(,\n [IFile, IHTTPRequest], Interface, 'view.html', None, u'')]\n\n >>> result = list(presentation.filterViewRegistrations(\n ... regs, IFile, level=presentation.SPECIFIC_INTERFACE_LEVEL |\n ... presentation.GENERIC_INTERFACE_LEVEL))\n >>> result.sort()\n >>> result\n [AdapterRegistration(,\n [IFile, IHTTPRequest], Interface, 'view.html', None, u''),\n AdapterRegistration(,\n [Interface, IHTTPRequest], Interface, 'view.html', None, u'')]\n\n\n`getViewInfoDictionary(reg)`\n----------------------------\n\nNow that we have all these utilities to select the registrations, we need to\nprepare the them for output. For page templates the best data structures are\ndictionaries and tuples/lists. This utility will generate an informational\ndictionary for the specified registration.\n\nLet's first create a registration:\n\n >>> from zope.component.registry import AdapterRegistration\n >>> reg = AdapterRegistration(None, (IFile, Interface, IHTTPRequest),\n ... Interface, 'view.html', Factory, 'reg info')\n\n >>> pprint(presentation.getViewInfoDictionary(reg), width=1)\n {'doc': 'reg info',\n 'factory': {'path': 'zope.apidoc.doctest.Factory',\n 'referencable': True,\n 'resource': None,\n 'template': None,\n 'url': 'zope/apidoc/doctest/Factory'},\n 'name': u'view.html',\n 'provided': {'module': 'zope.interface',\n 'name': 'Interface'},\n 'read_perm': None,\n 'required': [{'module': 'zope.apidoc.doctest',\n 'name': 'IFile'},\n {'module': 'zope.interface',\n 'name': 'Interface'},\n {'module': 'zope.publisher.interfaces.http',\n 'name': 'IHTTPRequest'}],\n 'type': 'zope.publisher.interfaces.http.IHTTPRequest',\n 'write_perm': None,\n 'zcml': None}\n\n\n=======================\nMiscellaneous Utilities\n=======================\n\nThe utilities module provides some useful helper functions and classes that\nmake the work of the API doctool and inspection code easier.\n\n >>> from zope.apidoc import utilities\n\n\n`relativizePath(path)`\n----------------------\n\nWhen dealing with files, such as page templates and text files, and not with\nPython paths, it is necessary to keep track of the the absolute path of the\nfile. However, for presentation purposes, the absolute path is inappropriate\nand we are commonly interested in the path starting at the Zope 3 root\ndirectory. This function attempts to remove the absolute path to the root\ndirectory and replaces it with \"Zope3\".\n\n >>> import os\n >>> path = os.path.join(utilities.BASEDIR, 'src', 'zope', 'README.txt')\n\n >>> utilities.BASEDIR in path\n True\n\n >>> path = utilities.relativizePath(path)\n\n >>> utilities.BASEDIR in path\n False\n\n # Be kind to Windows users\n >>> path.replace('\\\\', '/')\n 'Zope3/src/zope/README.txt'\n\nIf the base path is not found in a particular path, the original path is\nreturned:\n\n >>> otherpath = 'foo/bar/blah.txt'\n >>> utilities.relativizePath(otherpath)\n 'foo/bar/blah.txt'\n\n\n`truncateSysPath(path)`\n-----------------------\n\nIn some cases it is useful to just know the path after the sys path of a\nmodule. For example, you have a path of a file in a module. To look up the\nmodule, the simplest to do is to retrieve the module path and look into the\nsystem's modules list.\n\n >>> import sys\n >>> sysBase = sys.path[0]\n\n >>> utilities.truncateSysPath(sysBase + '/some/module/path')\n 'some/module/path'\n\nIf there is no matching system path, then the whole path is returned:\n\n >>> utilities.truncateSysPath('some/other/path')\n 'some/other/path'\n\n\n`getPythonPath(obj)`\n--------------------\n\nReturn the path of the object in standard Python dot-notation.\n\nThis function makes only sense for objects that provide a name, since we\ncannot determine the path otherwise. Instances, for example, do not have a\n`__name__` attribute, so we would expect them to fail.\n\nFor interfaces we simply get\n\n >>> from zope.interface import Interface\n >>> class ISample(Interface):\n ... pass\n\n >>> utilities.getPythonPath(ISample)\n 'zope.apidoc.doctest.ISample'\n\nand for classes\n\n >>> class Sample(object):\n ... def sample(self):\n ... pass\n\n >>> utilities.getPythonPath(Sample.sample)\n 'zope.apidoc.doctest.Sample'\n\nOne can also pass functions\n\n >>> def sample():\n ... pass\n\n >>> utilities.getPythonPath(sample)\n 'zope.apidoc.doctest.sample'\n\nand even methods. If a method is passed in, its class path is returned.\n\n >>> utilities.getPythonPath(Sample.sample)\n 'zope.apidoc.doctest.Sample'\n\nModules are another kind of objects that can return a python path:\n\n >>> utilities.getPythonPath(utilities)\n 'zope.apidoc.utilities'\n\nPassing in `None` returns `None`:\n\n >>> utilities.getPythonPath(None)\n\nClearly, instance lookups should fail:\n\n >>> utilities.getPythonPath(Sample())\n Traceback (most recent call last):\n ...\n AttributeError: 'Sample' object has no attribute '__name__'\n\n\n`isReferencable(path)`\n----------------------\n\nDetermine whether a path can be referenced in the API doc, usually by the code\nbrowser module. Initially you might think that all objects that have paths can\nbe referenced somehow. But that's not true, partially by design of apidoc, but\nalso due to limitations of the Python language itself.\n\nFirst, here are some cases that work:\n\n >>> utilities.isReferencable('zope')\n True\n >>> utilities.isReferencable('zope.app')\n True\n >>> utilities.isReferencable('zope.apidoc.classregistry.ClassRegistry')\n True\n >>> utilities.isReferencable('zope.apidoc.utilities.isReferencable')\n True\n\nThe first case is ``None``. When you ask for the python path of ``None``, you\nget ``None``, so that result should not be referencable:\n\n >>> utilities.isReferencable(None)\n False\n\nBy design we also do not document any private classes and functions:\n\n >>> utilities.isReferencable('some.path.to._Private')\n False\n >>> utilities.isReferencable('some.path.to.__Protected')\n False\n >>> utilities.isReferencable('zope.apidoc.__doc__')\n True\n\nSome objects might fake their module name, so that it does not exist:\n\n >>> utilities.isReferencable('foo.bar')\n False\n\nOn the other hand, you might have a valid module, but non-existent attribute:\n\n >>> utilities.isReferencable('zope.apidoc.MyClass')\n False\n\nNote that this case is also used for types that are generated using the\n``type()`` function:\n\n >>> mytype = type('MyType', (object,), {})\n >>> path = utilities.getPythonPath(mytype)\n >>> path\n 'zope.apidoc.doctest.MyType'\n\n >>> utilities.isReferencable(path)\n False\n\nNext, since API doc does not allow the documentation of instances yet, it\nis not possible to document singletons, so they are not referencable:\n\n >>> class Singelton(object):\n ... pass\n\n >>> utilities.isReferencable('zope.apidoc.doctest.Singelton')\n True\n\n >>> Singelton = Singelton()\n\n >>> utilities.isReferencable('zope.apidoc.doctest.Singelton')\n False\n\nFinally, the global ``IGNORE_MODULES`` list from the class registry is also\nused to give a negative answer. If a module is listed in ``IGNORE_MODULES``,\nthen ``False`` is returned.\n\n >>> import classregistry\n >>> classregistry.IGNORE_MODULES.append('zope.apidoc')\n\n >>> utilities.isReferencable('zope.app')\n True\n >>> utilities.isReferencable('zope.apidoc')\n False\n >>> utilities.isReferencable('zope.apidoc.apidoc.APIDocumentation')\n False\n\n >>> classregistry.IGNORE_MODULES.pop()\n 'zope.apidoc'\n >>> utilities.isReferencable('zope.apidoc')\n True\n\n\n`getPermissionIds(name, checker=_marker, klass=_marker)`\n--------------------------------------------------------\n\nGet the permissions of a class attribute. The attribute is specified by name.\n\nEither the `klass` or the `checker` argument must be specified. If the class\nis specified, then the checker for it is looked up. Furthermore, this function\nonly works with `INameBasedChecker` checkers. If another checker is found,\n``None`` is returned for the permissions.\n\nWe start out by defining the class and then the checker for it:\n\n >>> from zope.security.checker import Checker, defineChecker\n >>> from zope.security.checker import CheckerPublic\n\n >>> class Sample(object):\n ... attr = 'value'\n ... attr3 = 'value3'\n\n >>> class Sample2(object):\n ... pass\n\n >>> checker = Checker({'attr': 'zope.Read', 'attr3': CheckerPublic},\n ... {'attr': 'zope.Write', 'attr3': CheckerPublic})\n >>> defineChecker(Sample, checker)\n\nNow let's see how this function works:\n\n >>> entries = utilities.getPermissionIds('attr', klass=Sample)\n >>> entries['read_perm']\n 'zope.Read'\n >>> entries['write_perm']\n 'zope.Write'\n\n >>> from zope.security.checker import getCheckerForInstancesOf\n >>> entries = utilities.getPermissionIds('attr',\n ... getCheckerForInstancesOf(Sample))\n >>> entries['read_perm']\n 'zope.Read'\n >>> entries['write_perm']\n 'zope.Write'\n\nThe `Sample` class does not know about the `attr2` attribute:\n\n >>> entries = utilities.getPermissionIds('attr2', klass=Sample)\n >>> print entries['read_perm']\n n/a\n >>> print entries['write_perm']\n n/a\n\nThe `Sample2` class does not have a checker:\n\n >>> entries = utilities.getPermissionIds('attr', klass=Sample2)\n >>> entries['read_perm'] is None\n True\n >>> print entries['write_perm'] is None\n True\n\nFinally, the `Sample` class' `attr3` attribute is public:\n\n >>> entries = utilities.getPermissionIds('attr3', klass=Sample)\n >>> print entries['read_perm']\n zope.Public\n >>> print entries['write_perm']\n zope.Public\n\n\n`getFunctionSignature(func)`\n----------------------------\n\nReturn the signature of a function or method. The `func` argument *must* be a\ngeneric function or a method of a class.\n\nFirst, we get the signature of a function that has a specific positional and\nkeyword argument:\n\n >>> def func(attr, attr2=None):\n ... pass\n >>> utilities.getFunctionSignature(func)\n '(attr, attr2=None)'\n\nHere is a function that has an unspecified amount of keyword arguments:\n\n >>> def func(attr, **kw):\n ... pass\n >>> utilities.getFunctionSignature(func)\n '(attr, **kw)'\n\nAnd here we mix specified and unspecified keyword arguments:\n\n >>> def func(attr, attr2=None, **kw):\n ... pass\n >>> utilities.getFunctionSignature(func)\n '(attr, attr2=None, **kw)'\n\nIn the next example we have unspecified positional and keyword arguments:\n\n >>> def func(*args, **kw):\n ... pass\n >>> utilities.getFunctionSignature(func)\n '(*args, **kw)'\n\nAnd finally an example, where we have on unspecified keyword arguments without\nany positional arguments:\n\n >>> def func(**kw):\n ... pass\n >>> utilities.getFunctionSignature(func)\n '(**kw)'\n\nNext we test whether the signature is correctly determined for class\nmethods. Note that the `self` argument is removed from the signature, since it\nis not essential for documentation.\n\nWe start out with a simple positional argument:\n\n >>> class Klass(object):\n ... def func(self, attr):\n ... pass\n >>> utilities.getFunctionSignature(Klass.func)\n '(attr)'\n\nNext we have specific and unspecified positional arguments as well as\nunspecified keyword arguments:\n\n >>> class Klass(object):\n ... def func(self, attr, *args, **kw):\n ... pass\n >>> utilities.getFunctionSignature(Klass.func)\n '(attr, *args, **kw)'\n\nIf you do not pass a function or method to the function, it will fail:\n\n >>> utilities.getFunctionSignature('func')\n Traceback (most recent call last):\n ...\n TypeError: func must be a function or method\n\nA very uncommon, but perfectly valid, case is that tuple arguments are\nunpacked inside the argument list of the function. Here is an example:\n\n >>> def func((arg1, arg2)):\n ... pass\n >>> utilities.getFunctionSignature(func)\n '((arg1, arg2))'\n\nEven default assignment is allowed:\n\n >>> def func((arg1, arg2)=(1, 2)):\n ... pass\n >>> utilities.getFunctionSignature(func)\n '((arg1, arg2)=(1, 2))'\n\nHowever, lists of this type are not allowed inside the argument list:\n\n >>> def func([arg1, arg2]):\n ... pass\n Traceback (most recent call last):\n ...\n SyntaxError: invalid syntax\n\nInternal assignment is also not legal:\n\n >>> def func((arg1, arg2=1)):\n ... pass\n Traceback (most recent call last):\n ...\n SyntaxError: invalid syntax\n\n\n`getPublicAttributes(obj)`\n--------------------------\n\nReturn a list of public attribute names for a given object.\n\nThis excludes any attribute starting with '_', which includes attributes of\nthe form `__attr__`, which are commonly considered public, but they are so\nspecial that they are excluded. The `obj` argument can be either a classic\nclass, type or instance of the previous two. Note that the term \"attributes\"\nhere includes methods and properties.\n\nFirst we need to create a class with some attributes, properties and methods:\n\n >>> class Nonattr(object):\n ... def __get__(*a):\n ... raise AttributeError('nonattr')\n\n >>> class Sample(object):\n ... attr = None\n ... def __str__(self):\n ... return ''\n ... def func(self):\n ... pass\n ... def _getAttr(self):\n ... return self.attr\n ... attr2 = property(_getAttr)\n ...\n ... nonattr = Nonattr() # Should not show up in public attrs\n\nWe can simply pass in the class and get the public attributes:\n\n >>> attrs = utilities.getPublicAttributes(Sample)\n >>> attrs.sort()\n >>> attrs\n ['attr', 'attr2', 'func']\n\nNote that we exclude attributes that would raise attribute errors,\nlike our silly Nonattr.\n\nBut an instance of that class will work as well.\n\n >>> attrs = utilities.getPublicAttributes(Sample())\n >>> attrs.sort()\n >>> attrs\n ['attr', 'attr2', 'func']\n\nThe function will also take inheritance into account and return all inherited\nattributes as well:\n\n >>> class Sample2(Sample):\n ... attr3 = None\n\n >>> attrs = utilities.getPublicAttributes(Sample2)\n >>> attrs.sort()\n >>> attrs\n ['attr', 'attr2', 'attr3', 'func']\n\n\n`getInterfaceForAttribute(name, interfaces=_marker, klass=_marker, asPath=True)`\n--------------------------------------------------------------------------------\n\nDetermine the interface in which an attribute is defined. This function is\nnice, if you have an attribute name which you retrieved from a class and want\nto know which interface requires it to be there.\n\nEither the `interfaces` or `klass` argument must be specified. If `interfaces`\nis not specified, the `klass` is used to retrieve a list of\ninterfaces. `interfaces` must be iterable.\n\n`asPath` specifies whether the dotted name of the interface or the interface\nobject is returned.\n\nFirst, we need to create some interfaces and a class that implements them:\n\n >>> from zope.interface import Interface, Attribute, implements\n >>> class I1(Interface):\n ... attr = Attribute('attr')\n\n >>> class I2(I1):\n ... def getAttr():\n ... '''get attr'''\n\n >>> class Sample(object):\n ... implements(I2)\n\nFirst we check whether an aatribute can be found in a list of interfaces:\n\n >>> utilities.getInterfaceForAttribute('attr', (I1, I2), asPath=False)\n \n >>> utilities.getInterfaceForAttribute('getAttr', (I1, I2), asPath=False)\n \n\nNow we are repeating the same lookup, but using the class, instead of a list\nof interfaces:\n\n >>> utilities.getInterfaceForAttribute('attr', klass=Sample, asPath=False)\n \n >>> utilities.getInterfaceForAttribute('getAttr', klass=Sample, asPath=False)\n \n\nBy default, `asPath` is `True`, which means the path of the interface is\nreturned:\n\n >>> utilities.getInterfaceForAttribute('attr', (I1, I2))\n 'zope.apidoc.doctest.I1'\n\nIf no match is found, ``None`` is returned.\n\n >>> utilities.getInterfaceForAttribute('attr2', (I1, I2)) is None\n True\n >>> utilities.getInterfaceForAttribute('attr2', klass=Sample) is None\n True\n\nIf both, the `interfaces` and `klass` argument are missing, raise an error:\n\n >>> utilities.getInterfaceForAttribute('getAttr')\n Traceback (most recent call last):\n ...\n ValueError: need to specify interfaces or klass\n\nSimilarly, it does not make sense if both are specified:\n\n >>> utilities.getInterfaceForAttribute('getAttr', interfaces=(I1,I2),\n ... klass=Sample)\n Traceback (most recent call last):\n ...\n ValueError: must specify only one of interfaces and klass\n\n\n`columnize(entries, columns=3)`\n-------------------------------\n\nThis function places a list of entries into columns.\n\nHere are some examples:\n\n >>> utilities.columnize([1], 3)\n [[1]]\n\n >>> utilities.columnize([1, 2], 3)\n [[1], [2]]\n\n >>> utilities.columnize([1, 2, 3], 3)\n [[1], [2], [3]]\n\n >>> utilities.columnize([1, 2, 3, 4], 3)\n [[1, 2], [3], [4]]\n\n >>> utilities.columnize([1], 2)\n [[1]]\n\n >>> utilities.columnize([1, 2], 2)\n [[1], [2]]\n\n >>> utilities.columnize([1, 2, 3], 2)\n [[1, 2], [3]]\n\n >>> utilities.columnize([1, 2, 3, 4], 2)\n [[1, 2], [3, 4]]\n\n\n`getDocFormat(module)`\n----------------------\n\nThis function inspects a module to determine the supported documentation\nformat. The function returns a valid renderer source factory id.\n\nIf the `__docformat__` module attribute is specified, its value will be used\nto look up the factory id:\n\n >>> from zope.apidoc import utilities\n >>> utilities.getDocFormat(utilities)\n 'zope.source.rest'\n\nBy default structured text is returned:\n\n >>> from zope.apidoc import tests\n >>> utilities.getDocFormat(tests)\n 'zope.source.stx'\n\nThis is a sensible default, since we only decided later in development to\nendorse restructured text, so that many files are still in the structured text\nformat. All converted and new modules will have the `__docformat__` attribute.\n\nThe `__docformat__` attribute can also optionally specify a language field. We\nsimply ignore it:\n\n >>> class Module(object):\n ... pass\n >>> module = Module()\n >>> module.__docformat__ = 'restructuredtext en'\n >>> utilities.getDocFormat(module)\n 'zope.source.rest'\n\n\n`dedentString(text)`\n---------------------\n\nBefore doc strings can be processed using STX or ReST they must be dendented,\nsince otherwise the output will be incorrect. Let's have a look at some\ndocstrings and see how they are correctly dedented.\n\nLet's start with a simple one liner. Nothing should happen:\n\n >>> def func():\n ... '''One line documentation string'''\n\n >>> utilities.dedentString(func.__doc__)\n 'One line documentation string'\n\nNow what about one line docstrings that start on the second line? While this\nformat is discouraged, it is frequently used:\n\n >>> def func():\n ... '''\n ... One line documentation string\n ... '''\n\n >>> utilities.dedentString(func.__doc__)\n '\\nOne line documentation string\\n'\n\nWe can see that the leading whitespace on the string is removed, but not the\nnewline character. Let's now try a simple multi-line docstring:\n\n >>> def func():\n ... '''Short description\n ...\n ... Lengthy description, giving some more background information and\n ... discuss some edge cases.\n ... '''\n\n >>> print utilities.dedentString(func.__doc__)\n Short description\n \n Lengthy description, giving some more background information and\n discuss some edge cases.\n \n\nAgain, the whitespace was removed only after the first line. Also note that\nthe function determines the indentation level correctly. So what happens if\nthere are multiple indentation levels? The smallest amount of indentation is\nchosen:\n\n >>> def func():\n ... '''Short description\n ...\n ... Root Level\n ...\n ... Second Level\n ... '''\n\n >>> print utilities.dedentString(func.__doc__)\n Short description\n \n Root Level\n \n Second Level\n \n\n >>> def func():\n ... '''Short description\n ...\n ... $$$ print 'example'\n ... example\n ...\n ... And now the description.\n ... '''\n\n >>> print utilities.dedentString(func.__doc__)\n Short description\n \n $$$ print 'example'\n example\n \n And now the description.\n \n\n\n`renderText(text, module=None, format=None)`\n--------------------------------------------\n\nA function that quickly renders the given text using the specified format.\n\nIf the `module` argument is specified, the function will try to determine the\nformat using the module. If the `format` argument is given, it is simply\nused. Clearly, you cannot specify both, the `module` and `format` argument.\n\nYou specify the format as follows:\n\n >>> utilities.renderText('Hello!\\n', format='zope.source.rest')\n u'

Hello!

\\n'\n\nNote that the format string must be a valid source factory id; if the factory\nid is not given, 'zope.source.stx' is used. Thus, specifying the module is\noften safer (if available):\n\n >>> utilities.renderText('Hello!\\n', module=utilities)\n u'

Hello!

\\n'\n\n\n==================\nThe Class Registry\n==================\n\nThis little registry allows us to quickly query a complete list of classes\nthat are defined and used by Zope 3. The prime feature of the class is the\n``getClassesThatImplement(iface)`` method that returns all classes that\nimplement the passed interface. Another method, ``getSubclassesOf(klass)``\nreturns all registered subclassess of the given class.\n\nThe class registry, subclassing the dictionary type, can be instantiated like\nany other dictionary:\n\n >>> from zope.apidoc.classregistry import ClassRegistry\n >>> reg = ClassRegistry()\n\nLet's now add a couple of classes to registry. The classes should implement\nsome interfaces, so that we can test all methods on the class registry:\n\n >>> from zope.interface import Interface, implements\n\n >>> class IA(Interface):\n ... pass\n >>> class IB(IA):\n ... pass\n >>> class IC(Interface):\n ... pass\n >>> class ID(Interface):\n ... pass\n\n >>> class A(object):\n ... implements(IA)\n >>> reg['A'] = A\n\n >>> class B:\n ... implements(IB)\n >>> reg['B'] = B\n\n >>> class B2(object):\n ... implements(IB)\n >>> reg['B2'] = B2\n\n >>> class C(object):\n ... implements(IC)\n >>> reg['C'] = C\n >>> class A2(A):\n ... pass\n >>> reg['A2'] = A2\n\nSince the registry is just a dictionary, we can ask for all its keys, which\nare the names of the classes:\n\n >>> names = reg.keys()\n >>> names.sort()\n >>> names\n ['A', 'A2', 'B', 'B2', 'C']\n\n >>> reg['A'] is A\n True\n\nThere are two API methods specific to the class registry:\n\n`getClassesThatImplement(iface)`\n--------------------------------\n\nThis method returns all classes that implement the specified interface:\n\n >>> from pprint import pprint\n >>> pprint(reg.getClassesThatImplement(IA)) #doctest:+ELLIPSIS\n [('A', ),\n ('B', ),\n ('A2', ),\n ('B2', )]\n\n >>> pprint(reg.getClassesThatImplement(IB)) #doctest:+ELLIPSIS\n [('B', ),\n ('B2', )]\n\n >>> pprint(reg.getClassesThatImplement(IC))\n [('C', )]\n\n >>> pprint(reg.getClassesThatImplement(ID))\n []\n\n`getSubclassesOf(klass)`\n------------------------\n\nThis method will find all classes that inherit the specified class:\n\n >>> pprint(reg.getSubclassesOf(A))\n [('A2', )]\n\n >>> pprint(reg.getSubclassesOf(B))\n []\n\n\nSafe Imports\n------------\n\nUsing the ``safe_import()`` we can quickly look up modules by minimizing\nimport calls.\n\n >>> from zope.apidoc import classregistry\n >>> from zope.apidoc.classregistry import safe_import\n\nFirst we try to find the path in ``sys.modules``, since this lookup is much\nmore efficient than importing it. If it was not found, we go back and try\nto import the path. For security reasons, importing new modules is disabled by\ndefault, unless the global ``__import_unknown_modules__`` variable is set to\ntrue. If that also fails, we return the `default` value.\n\nHere are some examples::\n\n >>> import sys\n >>> 'zope' in sys.modules\n True\n\n >>> safe_import('zope') is sys.modules['zope']\n True\n\n >>> safe_import('weirdname') is None\n True\n\nFor this example, we'll create a dummy module:\n\n >>> import os\n >>> import tempfile\n >>> dir = tempfile.mkdtemp()\n >>> filename = os.path.join(dir, 'testmodule.py')\n >>> sys.path.insert(0, dir)\n >>> f = open(filename, 'w')\n >>> f.write('# dummy module\\n')\n >>> f.close()\n\nThe temporary module is not already imported:\n\n >>> module_name = 'testmodule'\n >>> module_name in sys.modules\n False\n\nWhen we try ``safe_import()`` now, we will still get the `default` value,\nbecause importing new modules is disabled by default:\n\n >>> safe_import(module_name) is None\n True\n\nBut once we activate the ``__import_unknown_modules__`` hook, the module\nshould be imported:\n\n >>> classregistry.__import_unknown_modules__ = True\n\n >>> safe_import(module_name).__name__ == module_name\n True\n >>> module_name in sys.modules\n True\n\nNow clean up the temporary module, just to play nice:\n\n >>> del sys.modules[module_name]\n\nImporting some code we cannot control, such as twisted, might raise errors\nwhen imported without having a certain environment. In those cases, the safe\nimport should prevent the error from penetrating:\n\n >>> open(os.path.join(dir, 'alwaysfail.py'), 'w').write('raise ValueError\\n')\n >>> sys.path.insert(0, dir)\n\n >>> safe_import('alwaysfail') is None\n True\n\nLet's clean up the python path and temporary files:\n\n >>> del sys.path[0]\n >>> import shutil\n >>> shutil.rmtree(dir)\n\nAnother method to explicitely turning off the import of certain modules is to\ndeclare that they should be ignored. For example, if we tell the class\nregistry to ignore ``zope``,\n\n >>> classregistry.IGNORE_MODULES.append('zope')\n\nthen we cannot import it anymore, even though we know it is available:\n\n >>> safe_import('zope') is None\n True\n\nNote that all sub-packages are also unavailable:\n\n >>> safe_import('zope.apidoc') is None\n True\n\nWe also need to play nice concerning variables and have to reset the module\nglobals:\n\n >>> classregistry.IGNORE_MODULES.pop()\n 'zope'\n >>> classregistry.__import_unknown_modules__ = False\n\n\n=======\nCHANGES\n=======\n\n\n1.0.0 (2013-02-25)\n------------------\n\n- Initial release independent of ``zope.app.api``.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://pypi.python.org/pypi/zope.apidoc", "keywords": "zope3 api documentation", "license": "ZPL 2.1", "maintainer": null, "maintainer_email": null, "name": "zope.apidoc", "package_url": "https://pypi.org/project/zope.apidoc/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/zope.apidoc/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://pypi.python.org/pypi/zope.apidoc" }, "release_url": "https://pypi.org/project/zope.apidoc/1.0.0/", "requires_dist": null, "requires_python": null, "summary": "API Documentation and Component Inspection for Zope 3", "version": "1.0.0" }, "last_serial": 802331, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "c188d1576698977479384d10e1a59c95", "sha256": "2c2996812ec144fd21f9fdda3f6af24308738e486c9395c262e437a7a9fc3b83" }, "downloads": -1, "filename": "zope.apidoc-1.0.0.tar.gz", "has_sig": false, "md5_digest": "c188d1576698977479384d10e1a59c95", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 59204, "upload_time": "2013-02-26T03:51:28", "url": "https://files.pythonhosted.org/packages/fa/15/58465b9eb3601533eae98e9a4568deea897c8a0f73fbc32ef961315458e6/zope.apidoc-1.0.0.tar.gz" } ], "2.0.0a1": [ { "comment_text": "", "digests": { "md5": "82f94606f55b007522e5afb32fae9827", "sha256": "5dd964c0d090770ceb3c3256074fe6fd4b5e3fecca45c442c63c227ca90a21a5" }, "downloads": -1, "filename": "zope.apidoc-2.0.0a1.zip", "has_sig": false, "md5_digest": "82f94606f55b007522e5afb32fae9827", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 74977, "upload_time": "2013-03-01T22:18:22", "url": "https://files.pythonhosted.org/packages/2c/7f/da36a9e549986d5c3aba196b9bccaaa7939977f1f259d2ef47a2b7d20e13/zope.apidoc-2.0.0a1.zip" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c188d1576698977479384d10e1a59c95", "sha256": "2c2996812ec144fd21f9fdda3f6af24308738e486c9395c262e437a7a9fc3b83" }, "downloads": -1, "filename": "zope.apidoc-1.0.0.tar.gz", "has_sig": false, "md5_digest": "c188d1576698977479384d10e1a59c95", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 59204, "upload_time": "2013-02-26T03:51:28", "url": "https://files.pythonhosted.org/packages/fa/15/58465b9eb3601533eae98e9a4568deea897c8a0f73fbc32ef961315458e6/zope.apidoc-1.0.0.tar.gz" } ] }