[Zope-Checkins] CVS: Zope3/lib/python/Zope/Configuration - meta.py:1.1.2.7.6.1 name.py:1.1.2.9.6.1 xmlconfig.py:1.1.2.10.4.1
Barry Warsaw
barry@wooz.org
Thu, 21 Mar 2002 19:27:28 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/Configuration
In directory cvs.zope.org:/tmp/cvs-serv22971/lib/python/Zope/Configuration
Modified Files:
Tag: contextual-directives
meta.py name.py xmlconfig.py
Log Message:
This is work to pass context to zcml directives, so that directives
know where they live. This is inspired by some suggested changes to
the naming syntax that Stephan and I discussed with Jim.
Specifically, a leading dot, as in
.JobBoardEx.JobList.
would signify a name relative to the current package, instead of
relative to ZopeProducts. Also, we'd like to change the trailing dot
to a `+' for signifying "look-the-last-name-up-recursively-until-you-
can't-anymore". E.g.:
.JobBoardEx.JobList+
I'm committing this on a branch because it breaks the unit tests and
I'm not sure of the best way to fix the remaining 10 failures. Jim
suggests that we commit these to the branch so that he can work on
them too.
=== Zope3/lib/python/Zope/Configuration/meta.py 1.1.2.7 => 1.1.2.7.6.1 ===
from ConfigurationDirectiveInterfaces import INonEmptyDirective
from ConfigurationDirectiveInterfaces import ISubdirectiveHandler
-from name import resolve
_directives = {}
@@ -34,15 +33,15 @@
directives[name] = subdirs
return subdirs
-def _exe(callable, subs, kw):
- r = callable(**kw)
+def _exe(callable, subs, context, kw):
+ r = callable(context, **kw)
if subs or INonEmptyDirective.isImplementedBy(callable):
return r, subs
else:
return lambda: r, subs
-def begin(_custom_directives, _name, **kw):
+def begin(_custom_directives, _name, context, **kw):
if _custom_directives and (_name in _custom_directives):
callable, subs = _custom_directives[_name]
else:
@@ -51,9 +50,9 @@
except KeyError:
raise InvalidDirective(_name)
- return _exe(callable, subs, kw)
+ return _exe(callable, subs, context, kw)
-def sub(subs, _name, **kw):
+def sub(subs, _name, context, **kw):
base, subdirs = subs
@@ -64,7 +63,7 @@
callable = getattr(base, _name[1])
- return _exe(callable, subs, kw)
+ return _exe(callable, subs, context, kw)
defaultkw = ({},)
def end(base):
@@ -83,16 +82,17 @@
def __init__(self, namespace):
self._namespace = namespace
- def directive(self, name, handler, attributes='', namespace=None):
+ def directive(self, _context, name, handler, attributes='',
+ namespace=None):
namespace = namespace or self._namespace
- subs = register((namespace, name), resolve(handler))
+ subs = register((namespace, name), _context.resolve(handler))
return Subdirective(subs, namespace)
def __call__(self):
return ()
-def Directive(namespace, name, handler, attributes=''):
- subs = register((namespace, name), resolve(handler))
+def Directive(_context, namespace, name, handler, attributes=''):
+ subs = register((namespace, name), _context.resolve(handler))
return Subdirective(subs, namespace)
Directive.__implements__ = INonEmptyDirective
@@ -114,7 +114,7 @@
self._subs = subs
self._namespace = namespace
- def subdirective(self, name, attributes='', namespace=None):
+ def subdirective(self, _context, name, attributes='', namespace=None):
namespace = namespace or self._namespace
if not namespace:
raise InvaliDirectiveDefinition(name)
=== Zope3/lib/python/Zope/Configuration/name.py 1.1.2.9 => 1.1.2.9.6.1 ===
from types import ModuleType
-def resolve(name, _silly=('__doc__',), _globals={}):
+def resolve(name, package='ZopeProducts', _silly=('__doc__',), _globals={}):
if name.startswith('.'):
- name='ZopeProducts'+name
+ name=package+name
- if name.endswith('.'):
+ if name.endswith('.') or name.endswith('+'):
name = name[:-1]
repeat = 1
else:
=== Zope3/lib/python/Zope/Configuration/xmlconfig.py 1.1.2.10 => 1.1.2.10.4.1 ===
__top_name = 'http://namespaces.zope.org/zope', 'zopeConfigure'
- def __init__(self, actions, level=None, directives=None):
+ def __init__(self, actions, context, directives=None):
self.__stack = []
- self.__level = level
self.__actions = actions
self.__directives = directives
+ self.__context = context
+ context.resolve
def setDocumentLocator(self, locator):
self.__locator=locator
@@ -85,7 +86,8 @@
if len(stack) == 1:
try:
- stack.append(begin(self.__directives, name, **kw))
+ stack.append(begin(self.__directives, name, self.__context,
+ **kw))
except Exception, v:
raise ZopeXMLConfigurationError, (
self.__locator, v), sys.exc_info()[2]
@@ -96,7 +98,7 @@
raise ZopeXMLConfigurationError(self.__locator,
'Invalid sub-directive')
try:
- stack.append(sub(subs, name, **kw))
+ stack.append(sub(subs, name, self.__context, **kw))
except Exception, v:
raise ZopeXMLConfigurationError, (
self.__locator, v), sys.exc_info()[2]
@@ -117,7 +119,7 @@
try:
for des, callable, args, kw in actions:
- append((self.__level,
+ append((self.__context,
(self.__locator.getLineNumber(),
self.__locator.getColumnNumber(),
self.__locator.getSystemId(),
@@ -141,7 +143,25 @@
and% at line %s column %s of %s
""" % ((self.des,) + self.l1 + self.l2)
-def xmlconfig(file, actions=None, level=None, directives=None):
+class Context:
+ def __init__(self, stack, module=None):
+ self.__stackcopy = tuple(stack)
+ if module is None:
+ self.__package = 'ZopeProducts'
+ else:
+ self.__package = module.__name__
+
+ def _stackcopy(self):
+ return self.__stackcopy
+
+ def resolve(self, dottedname):
+ name.resolve(dottedname, self.__package)
+
+
+def xmlconfig(file, actions=None, context=None, directives=None):
+ if context is None:
+ context = name
+
if actions is None:
call=actions=[]
else:
@@ -150,7 +170,8 @@
src=InputSource(getattr(file, 'name', '<string>'))
src.setByteStream(file)
parser=make_parser()
- parser.setContentHandler(ConfigurationHandler(actions, level, directives))
+ parser.setContentHandler(ConfigurationHandler(actions, context,
+ directives))
parser.setFeature(feature_namespaces, 1)
parser.parse(src)
@@ -186,22 +207,22 @@
f = open(file_name)
self._stack=[file_name]
- xmlconfig(f, self._actions, tuple(self._stack), self._directives)
+ xmlconfig(f, self._actions, Context(self._stack), self._directives)
f.close()
- def include(self, file, package=None):
+ def include(self, _context, file, package=None):
if package is not None:
try:
- module = name.resolve(package)
- if len(module.__path__) != 1:
+ package = _context.resolve(package)
+ if len(package.__path__) != 1:
print ("Module Path: '%s' has wrong number of elements"
- % str(module.__path__))
+ % str(package.__path__))
# XXX: This should work for 99% of cases
# We may want to revisit this with a more robust
# mechanism later. Specifically, sometimes __path__
# will have more than one element. Also, we could
- # use module.__file__, and lop the tail off that.
- prefix = module.__path__[0]
+ # use package.__file__, and lop the tail off that.
+ prefix = package.__path__[0]
except (ImportError, AttributeError, ValueError):
raise ValueError, "Invalid package attribute: %s" % package
else:
@@ -211,7 +232,8 @@
f = open(file_name)
self._stack.append(file_name)
- xmlconfig(f, self._actions, tuple(self._stack), self._directives)
+ xmlconfig(f, self._actions, Context(self._stack, package),
+ self._directives)
self._stack.pop()
f.close()
return ()