Z Object Publishing Environment

Search | Download | Documentation | Resources | Members




Join Zope.org
Log in

Developer Home
Get Involved!
The Fishbowl

 Zope Exits

Zope Newbies

page served by app2

Proposals Table of Contents Last edited on Jan 20, 2001 8:37 pm

Note - this document is still a work in progress. Please do not make inline comments in the proposal - use the NamespacePassingRevisitedDiscussion to make comments.




Namespaces are the key to the magic of DTML. To resolve a <dtml-var> reference, the DTML machinery simply requests the reference from the current namespace.

Namespace objects are a stack of dictionaries. The most recently added dictionary is searched first. This algorithm is implemented in cDocumentTemplate.c, where it is called a "MultiMapping" or "MM" for short, and is exposed to Python as a "TemplateDict". The file pDocumentTemplate.py is the equivalent non-optimized version.

The name lookup gets more interesting when mixed with acquisition. By using an adapter called InstanceDict, it is possible to put any object in the namespace stack, including objects that are wrapped in acquisition wrappers.


Is there a diagram/list of what your avarage namespace (for example if you do <dtml-var object> or <dtml-var method>) looks like in terms of what is actually in it and what order it is searched? If not, then how about a NamespaceExplainerx

The effect is that it's possible to search for a name among a potentially large set without spending a lot of time on namespace construction. In fact, most namespace searches occur entirely in C-optimized code.

When a DTML method calls another DTML method, the namespace is usually passed. The subtemplate, rather than create a new namespace, just pushes entries onto the stack of dictionaries. That way it can access all names that were available in the first method. Before the subtemplate is finished, it pops the added entries.


While working on the PythonMethodx product, it became apparent that it would be useful to allow a method to access the DTML namespace. However, it also became apparent that the current implementation of namespaces has created a lot of inconsistency in calling conventions for different kinds of methods.

The document template invocation mechanism has also necessitated the infamous hack:

<dtml-var expr="someTemplate(_.None, _)">

This effectively duplicates what happens when a name is looked up in a namespace that refers to a DTML method. By default, namespace lookups try to execute the object found, and when the object has an isDocTemp attribute, it is invoked with two arguments: None and the namespace object.

The relevant code, in OFS/DTMLMethodx.py and DocumentTemplate/DT_String.py, is very difficult to understand. Only after studying it in depth does it become clear that the REQUEST variable passed to DTMLMethodx is not necessarily a REQUEST object; when called as a subtemplate it is a namespace object (a TemplateDictx) and the "client" argument is None. When DTMLMethodx objects are invoked through a URL, the mapply() method is tricked into sending the correct arguments by the apparently meaningless func_code object. All of this also depends on an obscure attribute called "isDocTemp", which is set in a base class. This level of obfuscation leads to poor maintainability and makes it very difficult to standardize on method invocation semantics.

Proposed Solution

Zope 2.2 now provides execution stacks for security purposes. The stacks are essentially bound to the thread. Until now, Zope had no dependency on thread-bound variables, but now that it does, why not extend the dependency by using a thread-bound namespace?

The namespace should be created when first invoking a method that uses a namespace. Subtemplates could then get the namespace from the thread rather than through an argument. Subtemplates would push new entries and remove them before finishing, the same as is done now.

DT_String.__call__ currently checks whether the "mapping" argument is an instance of TemplateDictx, and if it is then new entries will be pushed.

In this proposal DT_String would try to get the namespace from a thread-bound variable. If not created yet, it be would created. The mapping argument would still be added to the namespace, but for backward compatibility and safety it should not be added if it is an instance of TemplateDictx.

cDocumentTemplate and DT_Util would be modified since they don't need to check for the presence of an isDocTemp attribute anymore. Subtemplates would be invoked with no arguments by default.


  • Calling conventions simplified.

  • There would no longer be a need to pass namespace objects. The infamous hack mentioned above would no longer be necessary.

  • Methods other than DTML methods could safely access the namespace.

Risk Factors

  • If Zope makes use of microthreads, the code that binds variables to threads will have to adapt. Actually this will be an issue that affects ZODB and the security machinery as well, so we will probably need a module that implements thread-bound variables through either OS threads or microthreads.

  • This makes namespace passing more reliable. As a result, some DTML methods may pick up objects from the namespace where they didn't before.

  • This changes the meaning of certain arguments for often used methods. This proposal has been carefully crafted to not break existing code, but experience says that somehow, somewhere, it will.


This project is focused on reducing the complexity of namespace passing so as to make namespaces accessible to method types other than DTML methods.


  • Changes to DocumentTemplatex to provide the specified behavior

  • A new threadvars module for maintaining and eventually cleaning up thread-bound variables

  • A note in the CHANGES file

View source NamespacePassingRevisited
Advanced Actions / History
Visitor: Anonymous User
Jump to:
... by pagename prefix or search term.
For a plain search:
Privacy policy       Printable Page       Feedback about Zope.org