In https://bugs.launchpad.net/zope.configuration/+bug/274655, Devin (devin@charityfinders.com) reported:
Adding an attribute to a grouping directive's schema that is directly accessed by zope.configuration.config.GroupingStackItem using its 'context' member variable exposes a bug in the configuration machinery. There are two attributes that I know of that are problematic ('action', 'factory'), but members of zope.configuration.config.ConfigurationMachine (and its superclasses) could be suspect as well.
Attached is a sample traceback from 'transcript.log' that occurred when I attempted to use the 'factory' attribute for one of my custom grouping directives.
Note that the last line in the traceback:
ZopeXMLConfigurationError: File "/var/lib/zope3/instance/sandbox/lib/python/powersite/browser/configure.zcml", line 20.4
... refers to the first subdirective of the directive that contains the factory attribute. The subdirective is also registered as a grouping directive.
I believe that the intended 'factory' attribute is the 'factory' method of zope.configuration.configure.ConfigurationAdapterRegistry.
I've read that complex directives will eventually be deprecated in favor of grouping directives. If that's true, then this change will need to be made for complex directives that currently have a factory or action attribute.
and linked a traceback: https://bugs.launchpad.net/zope.configuration/+bug/274655/+attachment/360145/+files/traceback.txt
Devin later followed up:
Also, if the grouping directive you create doesn't subclass zope.configuration.config.GroupingContextDecorator and/or doesn't have similar 'getattr' functionality (and still satisfies the interface contract of zope.configuration.interfaces.IGroupingContext), then Zope will terminate with an AttributeError message complaining about the lack of a 'factory' attribute.
I> nstead of attempting to find the needed methods on its 'context' member, perhaps the various stack item class instances should find the objects with the methods they need by searching up the tree until an object that implements zope.configuration.interfaces.IConfigurationContext is found. Something like:
def __getConfigurationContext(self):
context = self.context
while not IConfigurationContext.providedBy(context):
context = context.context
return context
... and replacing self.context with self.__getConfigurationContext() (where appropriate) should work (I haven't tested it), and would still allow grouping directives to contain attributes like 'action' and 'factory'.
@do3cc asked:
Can you provide a working example?
Devin replied:
I can provide a simple example that demonstrates the bug (attached). Here's the result of running the example from the command line:
devin@development:~/temporary$ python2.5 demo.py
Traceback (most recent call last):
File "demo.py", line 66, in <module>
main()
File "demo.py", line 63, in main
string(_CONFIG)
File "/usr/lib/python2.5/site-packages/zope/configuration/xmlconfig.py", line 627, in string
processxmlfile(f, context)
File "/usr/lib/python2.5/site-packages/zope/configuration/xmlconfig.py", line 378, in processxmlfile
parser.parse(src)
File "/usr/lib/python2.5/xml/sax/expatreader.py", line 107, in parse
xmlreader.IncrementalParser.parse(self, source)
File "/usr/lib/python2.5/xml/sax/xmlreader.py", line 123, in parse
self.feed(buffer)
File "/usr/lib/python2.5/xml/sax/expatreader.py", line 207, in feed
self._parser.Parse(data, isFinal)
File "/usr/lib/python2.5/xml/sax/expatreader.py", line 338, in start_element_ns
AttributesNSImpl(newattrs, qnames))
File "/usr/lib/python2.5/site-packages/zope/configuration/xmlconfig.py", line 230, in startElementNS
self.context.begin(name, data, info)
File "/usr/lib/python2.5/site-packages/zope/configuration/config.py", line 539, in begin
self.stack.append(self.stack[-1].contained(__name, __data, __info))
File "/usr/lib/python2.5/site-packages/zope/configuration/config.py", line 840, in contained
return RootStackItem.contained(self, name, data, info)
File "/usr/lib/python2.5/site-packages/zope/configuration/config.py", line 708, in contained
factory = self.context.factory(self.context, name)
File "demo.py", line 37, in __call__
raise Exception("You rang?")
zope.configuration.xmlconfig.ZopeXMLConfigurationError: File "<string>", line 20.6
Exception: You rang?
The Zope package is the Zope 3.4 package from Ubuntu's stable 9.04 repository.
Devin attached a file: https://bugs.launchpad.net/zope.configuration/+bug/274655/+attachment/714017/+files/demo.py
In https://bugs.launchpad.net/zope.configuration/+bug/274655, Devin (devin@charityfinders.com) reported:
Devin later followed up:
@do3cc asked:
Devin replied:
Devin attached a file: https://bugs.launchpad.net/zope.configuration/+bug/274655/+attachment/714017/+files/demo.py