[Zope3-checkins] CVS: Zope/lib/python/ZConfig - Exceptions.py:1.1.10.1 ApacheStyle.py:1.1.4.5 Config.py:1.2.4.6 Context.py:1.1.4.6 SchemaContext.py:1.1.2.6 SchemaParser.py:1.1.2.19 Substitution.py:1.3.6.2 __init__.py:1.1.4.8 Common.py:NONE
Fred L. Drake, Jr.
fred@zope.com
Fri, 6 Dec 2002 11:06:59 -0500
Update of /cvs-repository/Zope/lib/python/ZConfig
In directory cvs.zope.org:/tmp/cvs-serv7113/ZConfig
Modified Files:
Tag: chrism-install-branch
ApacheStyle.py Config.py Context.py SchemaContext.py
SchemaParser.py Substitution.py __init__.py
Added Files:
Tag: chrism-install-branch
Exceptions.py
Removed Files:
Tag: chrism-install-branch
Common.py
Log Message:
Merge ZConfig trunk into the chrism-install-branch.
=== Added File Zope/lib/python/ZConfig/Exceptions.py ===
"""Names used from all modules in the package.
Since some names are only defined if needed, this module should be
imported using the from-import-* syntax.
"""
class ConfigurationError(Exception):
def __init__(self, msg):
self.message = msg
Exception.__init__(self, msg)
def __str__(self):
return self.message
class ConfigurationMissingSectionError(ConfigurationError):
def __init__(self, type, name=None):
self.type = type
self.name = name
details = 'Missing section (type: %s' % type
if name is not None:
details += ', name: %s' % name
ConfigurationError.__init__(self, details + ')')
class ConfigurationConflictingSectionError(ConfigurationError):
def __init__(self, type, name=None):
self.type = type
self.name = name
details = 'Conflicting sections (type: %s' % type
if name is not None:
details += ', name: %s' % name
ConfigurationError.__init__(self, details + ')')
class ConfigurationSyntaxError(ConfigurationError):
def __init__(self, msg, url, lineno):
self.url = url
self.lineno = lineno
ConfigurationError.__init__(self, msg)
def __str__(self):
return "%s\n(line %s in %s)" % (self.message, self.lineno, self.url)
class ConfigurationTypeError(ConfigurationError):
def __init__(self, msg, found, expected):
self.found = found
self.expected = expected
ConfigurationError.__init__(self, msg)
class SubstitutionSyntaxError(ConfigurationError):
"""Raised when interpolation source text contains syntactical errors."""
class SubstitutionReplacementError(ConfigurationError, LookupError):
"""Raised when no replacement is available for a reference."""
def __init__(self, source, name):
self.source = source
self.name = name
ConfigurationError.__init__(self, "no replacement for " + `name`)
=== Zope/lib/python/ZConfig/ApacheStyle.py 1.1.4.4 => 1.1.4.5 ===
--- Zope/lib/python/ZConfig/ApacheStyle.py:1.1.4.4 Sat Nov 16 01:38:39 2002
+++ Zope/lib/python/ZConfig/ApacheStyle.py Fri Dec 6 11:06:23 2002
@@ -2,14 +2,14 @@
import urlparse
-from Common import *
+from ZConfig import ConfigurationError, ConfigurationSyntaxError
-def Parse(file, context, section, url):
+def Parse(resource, context, section):
lineno = 0
stack = []
while 1:
- line = file.readline()
+ line = resource.file.readline()
if not line:
break
lineno += 1
@@ -20,29 +20,31 @@
if line[0] == "#":
# comment
continue
+
if line[:2] == "</":
# section end
if line[-1] != ">":
raise ConfigurationSyntaxError(
- "malformed section end", url, lineno)
+ "malformed section end", resource.url, lineno)
if not stack:
raise ConfigurationSyntaxError(
- "unexpected section end", url, lineno)
+ "unexpected section end", resource.url, lineno)
type = line[2:-1].rstrip()
if type.lower() != section.type:
raise ConfigurationSyntaxError(
- "unbalanced section end", url, lineno)
+ "unbalanced section end", resource.url, lineno)
try:
section.finish()
except ConfigurationError, e:
- raise ConfigurationSyntaxError(e[0], url, lineno)
+ raise ConfigurationSyntaxError(e[0], resource.url, lineno)
section = stack.pop()
continue
+
if line[0] == "<":
# section start
if line[-1] != ">":
raise ConfigurationSyntaxError(
- "malformed section start", url, lineno)
+ "malformed section start", resource.url, lineno)
isempty = line[-2] == "/"
if isempty:
text = line[1:-2].rstrip()
@@ -52,43 +54,74 @@
m = _section_start_rx.match(text)
if not m:
raise ConfigurationSyntaxError(
- "malformed section header", url, lineno)
+ "malformed section header", resource.url, lineno)
type, name, delegatename = m.group('type', 'name', 'delegatename')
try:
newsect = context.nestSection(section, type, name,
delegatename)
except ConfigurationError, e:
- raise ConfigurationSyntaxError(e[0], url, lineno)
+ raise ConfigurationSyntaxError(e[0], resource.url, lineno)
if not isempty:
stack.append(section)
section = newsect
continue
+
+ if line[0] == "%":
+ # directive: import, include
+ m = _keyvalue_rx.match(line, 1)
+ if not m:
+ raise ConfigurationSyntaxError(
+ "missing or unrecognized directive", resource.url, lineno)
+ name, arg = m.group('key', 'value')
+ if name not in ("define", "import", "include"):
+ raise ConfigurationSyntaxError(
+ "unknown directive: " + `name`, resource.url, lineno)
+ if not arg:
+ raise ConfigurationSyntaxError(
+ "missing argument to %%%s directive" % name,
+ resource.url, lineno)
+ if name == "import":
+ if stack:
+ raise ConfigurationSyntaxError(
+ "import only allowed at outermost level of a resource",
+ resource.url, lineno)
+ newurl = urlparse.urljoin(resource.url, arg)
+ context.importConfiguration(section, newurl)
+ elif name == "include":
+ newurl = urlparse.urljoin(resource.url, arg)
+ context.includeConfiguration(section, newurl)
+ elif name == "define":
+ parts = arg.split(None, 1)
+ defname = parts[0]
+ defvalue = ''
+ if len(parts) == 2:
+ defvalue = parts[1]
+ try:
+ resource.define(defname, defvalue)
+ except ConfigurationError, e:
+ raise ConfigurationSyntaxError(e[0], resource.url, lineno)
+ else:
+ assert 0, "unexpected directive for " + `line`
+ continue
+
# key-value
m = _keyvalue_rx.match(line)
if not m:
raise ConfigurationSyntaxError(
- "malformed configuration data", url, lineno)
+ "malformed configuration data", resource.url, lineno)
key, value = m.group('key', 'value')
- if key == "import":
- if stack:
- raise ConfigurationSyntaxError(
- "import only allowed at the outermost level of a resource",
- url, lineno)
- newurl = urlparse.urljoin(url, value)
- context.importConfiguration(section, newurl)
- elif key == "include":
- newurl = urlparse.urljoin(section.url, value)
- context.includeConfiguration(section, newurl)
+ if not value:
+ value = ''
else:
- if not value:
- value = ''
- try:
- section.addValue(key, value)
- except ConfigurationError, e:
- raise ConfigurationSyntaxError(e[0], url, lineno)
+ value = resource.substitute(value)
+ try:
+ section.addValue(key, value)
+ except ConfigurationError, e:
+ raise ConfigurationSyntaxError(e[0], resource.url, lineno)
+
if stack:
raise ConfigurationSyntaxError(
- "unclosed sections no allowed", url, lineno + 1)
+ "unclosed sections not allowed", resource.url, lineno + 1)
import re
=== Zope/lib/python/ZConfig/Config.py 1.2.4.5 => 1.2.4.6 ===
--- Zope/lib/python/ZConfig/Config.py:1.2.4.5 Tue Nov 26 18:52:33 2002
+++ Zope/lib/python/ZConfig/Config.py Fri Dec 6 11:06:23 2002
@@ -1,6 +1,12 @@
"""Configuration data structure."""
-from Common import *
+import ZConfig
+
+try:
+ True
+except NameError:
+ True = 1
+ False = 0
class Configuration:
def __init__(self, container, type, name, url):
@@ -31,7 +37,7 @@
def setDelegate(self, section):
if self.delegate is not None:
- raise ConfigurationError("cannot modify delegation")
+ raise ZConfig.ConfigurationError("cannot modify delegation")
self.delegate = section
def addChildSection(self, section):
@@ -53,7 +59,7 @@
if child is None or child.url != self.url:
self._sections_by_name[key] = section
else:
- raise ConfigurationError(
+ raise ZConfig.ConfigurationError(
"cannot replace existing named section")
def getSection(self, type, name=None):
@@ -64,14 +70,14 @@
try:
return self._sections_by_name[key]
except KeyError:
- raise ConfigurationMissingSectionError(type, name)
+ raise ZConfig.ConfigurationMissingSectionError(type, name)
else:
L = []
for sect in self._sections:
if sect.type == type:
L.append(sect)
if len(L) > 1:
- raise ConfigurationConflictingSectionError(type, name)
+ raise ZConfig.ConfigurationConflictingSectionError(type, name)
if L:
return L[0]
elif self.delegate:
@@ -93,11 +99,16 @@
except KeyError:
self._data[key] = value
else:
- raise ConfigurationError("cannot add existing key")
+ raise ZConfig.ConfigurationError("cannot add existing key")
- def setValue(self, key, value):
+ def has_key(self, key):
key = key.lower()
- self._data[key] = value
+ if self._data.has_key(key):
+ return True
+ elif self.delegate:
+ return self.delegate.has_key(key)
+ else:
+ return False
def has_key(self, key):
key = key.lower()
@@ -206,3 +217,14 @@
if s is not default:
break
return s
+
+
+def asBoolean(s):
+ """Convert a string value to a boolean value."""
+ ss = str(s).lower()
+ if ss in ('yes', 'true', 'on'):
+ return True
+ elif ss in ('no', 'false', 'off'):
+ return False
+ else:
+ raise ValueError("not a valid boolean value: " + repr(s))
=== Zope/lib/python/ZConfig/Context.py 1.1.4.5 => 1.1.4.6 ===
--- Zope/lib/python/ZConfig/Context.py:1.1.4.5 Sun Nov 24 18:28:43 2002
+++ Zope/lib/python/ZConfig/Context.py Fri Dec 6 11:06:23 2002
@@ -5,14 +5,15 @@
import urllib2
import urlparse
-from Common import *
+import ZConfig
+
from Config import Configuration, ImportingConfiguration
+from Substitution import isname, substitute
class Context:
def __init__(self):
- #Configuration.__init__(self, None, None, url)
self._imports = [] # URL -> Configuration
self._named_sections = {} # name -> Configuration
self._needed_names = {} # name -> [needy Configuration, ...]
@@ -32,14 +33,17 @@
def createToplevelSection(self, url):
return ImportingConfiguration(url)
+ def createResource(self, file, url):
+ return Resource(file, url)
+
def getDelegateType(self, type):
# Applications must provide delegation typing information by
# overriding the Context.getDelegateType() method.
return type.lower()
- def parse(self, file, section, url):
+ def parse(self, resource, section):
from ApacheStyle import Parse
- Parse(file, self, section, url)
+ Parse(resource, self, section)
def _normalize_url(self, url):
if os.path.exists(url):
@@ -72,8 +76,9 @@
self._all_sections.append(top)
self._imports = [top]
self._current_imports.append(top)
+ r = self.createResource(file, url)
try:
- self.parse(file, top, url)
+ self.parse(r, top)
finally:
del self._current_imports[-1]
self._finish()
@@ -95,8 +100,9 @@
def includeConfiguration(self, section, url):
# XXX we always re-parse, unlike import
file = urllib2.urlopen(url)
+ r = self.createResource(file, url)
try:
- self.parse(file, section, url)
+ self.parse(r, section)
finally:
file.close()
@@ -111,10 +117,10 @@
# another resource.
oldsect = self._named_sections[name]
if oldsect.url == section.url:
- raise ConfigurationError(
+ raise ZConfig.ConfigurationError(
"named section cannot be defined twice in same resource")
if oldsect.type != type:
- raise ConfigurationError(
+ raise ZConfig.ConfigurationError(
"named section cannot change type")
newsect = self.createNestedSection(section, type, name, delegatename)
self._all_sections.append(newsect)
@@ -143,12 +149,13 @@
def _parse_url(self, url, section):
url, fragment = urlparse.urldefrag(url)
if fragment:
- raise ConfigurationError(
+ raise ZConfig.ConfigurationError(
"fragment identifiers are not currently supported")
file = urllib2.urlopen(url)
self._current_imports.append(section)
+ r = self.createResource(file, url)
try:
- self.parse(file, section, url)
+ self.parse(r, section)
finally:
del self._current_imports[-1]
file.close()
@@ -160,14 +167,14 @@
for referrer in L:
type = self.getDelegateType(referrer.type)
if type is None:
- raise ConfigurationTypeError(
+ raise ZConfig.ConfigurationTypeError(
"%s sections are not allowed to specify delegation\n"
"(in %s)"
% (repr(referrer.type), referrer.url),
referrer.type, None)
type = type.lower()
if type != section.type:
- raise ConfigurationTypeError(
+ raise ZConfig.ConfigurationTypeError(
"%s sections can only inherit from %s sections\n"
"(in %s)"
% (repr(referrer.type), repr(type), referrer.url),
@@ -188,3 +195,24 @@
if sect.delegate is not None:
sect.finish()
self._all_sections = None
+
+
+class Resource:
+ def __init__(self, file, url):
+ self.file = file
+ self.url = url
+ self._definitions = {}
+
+ def define(self, name, value):
+ key = name.lower()
+ if self._definitions.has_key(key):
+ raise ZConfig.ConfigurationError("cannot redefine " + `name`)
+ if not isname(name):
+ raise ZConfig.ConfigurationError(
+ "not a substitution legal name: " + `name`)
+ self._definitions[key] = value
+
+ def substitute(self, s):
+ # XXX I don't really like calling this substitute(),
+ # XXX but it will do for now.
+ return substitute(s, self._definitions)
=== Zope/lib/python/ZConfig/SchemaContext.py 1.1.2.5 => 1.1.2.6 ===
--- Zope/lib/python/ZConfig/SchemaContext.py:1.1.2.5 Tue Nov 26 12:09:12 2002
+++ Zope/lib/python/ZConfig/SchemaContext.py Fri Dec 6 11:06:23 2002
@@ -17,7 +17,6 @@
import Context
import SchemaParser
-from Common import *
from SchemaInterfaces import ISchemaContext
@@ -78,10 +77,10 @@
## can be true that two sections can exist in the same resource
##
## if oldsect.url == section.url:
-## raise ConfigurationError(
+## raise ZConfig.ConfigurationError(
## "named section cannot be defined twice in same resource")
if oldsect.type != type:
- raise ConfigurationError(
+ raise ZConfig.ConfigurationError(
"named section cannot change type")
newsect = self.createNestedSection(section, type, name, delegatename)
self._all_sections.append(newsect)
=== Zope/lib/python/ZConfig/SchemaParser.py 1.1.2.18 => 1.1.2.19 ===
--- Zope/lib/python/ZConfig/SchemaParser.py:1.1.2.18 Thu Dec 5 23:38:36 2002
+++ Zope/lib/python/ZConfig/SchemaParser.py Fri Dec 6 11:06:23 2002
@@ -20,7 +20,8 @@
import types
import xml.sax
-from Common import *
+import ZConfig
+
from Config import Configuration
from SchemaInterfaces import IConfigKey, IConfigSection, IConfigRoot,\
IConfigMultiKey, IConfigMultiSection
@@ -270,18 +271,18 @@
lineno = self._locator.getLineNumber()
raise SchemaError(msg, lineno, colno)
-class SchemaError(Exception):
+class SchemaError(ZConfig.ConfigurationError):
def __init__(self, msg, line, col):
- self.msg = msg
self.line = line
self.col = col
+ ZConfig.ConfigurationError.__init__(self, msg)
def __str__(self):
if self.line is not None:
pos = " at line %d, column %s" % (self.line, self.col)
else:
pos = " (unknown position)"
- return self.msg + pos
+ return self.message + pos
class SchemaConfiguration(Configuration):
resolved = missing
@@ -302,31 +303,31 @@
def hasDefault(self):
try:
self.default()
- except ConfigurationError:
+ except ZConfig.ConfigurationError:
return False
return True
# subclass required methods
def default(self):
- raise ConfigurationError(
+ raise ZConfig.ConfigurationError(
'no "default" method provided for "%s" named "%s"' %
(self.type, self.name)
)
def handle(self, *args):
- raise ConfigurationError(
+ raise ZConfig.ConfigurationError(
'no "handle" method provided for "%s" named "%s"' %
(self.type, self.name)
)
def multihandle(self, l):
- raise ConfigurationError(
+ raise ZConfig.ConfigurationError(
'no "multihandle" method provided for "%s" named "%s"' %
(self.type, self.name)
)
def validate(self, value):
- raise ConfigurationError(
+ raise ZConfig.ConfigurationError(
'no "validate" method provided for "%s" named "%s"' %
(self.type, self.name)
)
@@ -336,7 +337,7 @@
def populate(self, value):
if self.value is not missing:
- raise ConfigurationError, (
+ raise ZConfig.ConfigurationError, (
'The key "%s" cannot have multiple values' % self.name
)
self.setValue(value)
@@ -345,11 +346,11 @@
return []
def setValue(self, value):
- # set this key's value with prejudice (dont raise an error
+ # set this key's value with prejudice (don't raise an error
# unless the validator fails)
msg = self.validate(value)
if msg:
- raise ConfigurationError, msg
+ raise ZConfig.ConfigurationError, msg
self.value = value
def canFinish(self):
@@ -357,7 +358,8 @@
def finish(self):
if not self.canFinish():
- raise ConfigurationError, 'missing value for %s' % self.name
+ raise ZConfig.ConfigurationError('missing value for '
+ + `self.name`)
def getValue(self):
if self.resolved is missing:
@@ -375,11 +377,11 @@
self.setValue(value)
def setValue(self, value):
- # set this key's value with prejudice (dont raise an error
+ # set this key's value with prejudice (don't raise an error
# unless the validator fails)
msg = self.validate(value)
if msg:
- raise ConfigurationError, msg
+ raise ZConfig.ConfigurationError, msg
if self.value is missing:
self.value = []
self.value.append(value)
@@ -420,7 +422,7 @@
try:
return self.data[(meta_type, type, name)]
except KeyError:
- raise ConfigurationError(
+ raise ZConfig.ConfigurationError(
'invalid %s of type "%s" with name "%s"'
% (meta_type, type, name))
@@ -443,7 +445,7 @@
for type, name in unfinishable:
msg = msg + ' %s "%s",' % (type, name)
msg = msg[:-1]
- raise ConfigurationError, msg
+ raise ZConfig.ConfigurationError, msg
def unfinishable(self):
l = []
@@ -467,7 +469,7 @@
key = key.lower()
try:
return self.getSub(KEY_TYPE, KEY_TYPE, key).getValue()
- except ConfigurationError:
+ except ZConfig.ConfigurationError:
if self.delegate is None:
return default
else:
@@ -521,7 +523,7 @@
if meta_type == SECTION_TYPE and type == s_type:
L.append(self.getSub(meta_type, type, name))
if len(L) > 1:
- raise ConfigurationConflictingSectionError(type, name)
+ raise ZConfig.ConfigurationConflictingSectionError(type, name)
if L:
return L[0]
elif self.delegate:
@@ -566,7 +568,7 @@
self.current = None
self.finished = []
if self.prototype_class is None:
- raise ConfigurationError(
+ raise ZConfig.ConfigurationError(
'No prototype_class for section typed "%s" named "%s"' %
(type, name)
)
=== Zope/lib/python/ZConfig/Substitution.py 1.3.6.1 => 1.3.6.2 ===
--- Zope/lib/python/ZConfig/Substitution.py:1.3.6.1 Fri Nov 15 20:26:17 2002
+++ Zope/lib/python/ZConfig/Substitution.py Fri Dec 6 11:06:23 2002
@@ -1,111 +1,76 @@
"""Substitution support for ZConfig values."""
-class SubstitutionError(Exception):
- """Base exception for string substitution errors."""
+import ZConfig
- def __init__(self, msg, context):
- self.message = msg
- self.context = context
-
- def __str__(self):
- return self.message
-
-class SubstitutionSyntaxError(SubstitutionError):
- """Raised when interpolation source text contains syntactical errors."""
-
- def __init__(self, msg, context):
- if context is not None:
- context = context[:]
- SubstitutionError.__init__(self, msg, context)
-
-class SubstitutionRecursionError(SubstitutionError):
- """Raised when a nested interpolation is recursive."""
-
- def __init__(self, name, context):
- self.name = name
- msg = ("recursion on %s; current context:\n%s"
- % (repr(name), ", ".join(context)))
- SubstitutionError.__init__(self, msg, context[:])
-
-
-def get(section, name, default=None):
- # XXX should this interpolate from default if that's what's used?
- missing = []
- s = section.get(name, missing)
- if s is missing:
- return default
- if "$" in s:
- accum = []
- _interp(accum, s, section, [name])
- s = ''.join(accum)
- return s
+try:
+ True
+except NameError:
+ True = 1
+ False = 0
-def substitute(s, section):
+def substitute(s, mapping):
"""Interpolate variables from `section` into `s`."""
- if '$' in s:
- accum = []
- _interp(accum, s, section, None)
- s = ''.join(accum)
- return s
-
-
-def _interp(accum, rest, section, context):
- while 1:
- i = rest.find("$")
- if i < 0:
- accum.append(rest)
- break
- accum.append(rest[:i])
- rest = rest[i+1:]
- if not rest:
- accum.append("$")
- break
- if rest[0] == "$":
- accum.append("$")
- rest = rest[1:]
- elif rest[0] == "{":
- rest = rest[1:]
- m = _name_match(rest[:])
+ if "$" in s:
+ result = ''
+ rest = s
+ while rest:
+ p, name, rest = _split(rest)
+ result += p
+ if name:
+ v = mapping.get(name)
+ if v is None:
+ raise ZConfig.SubstitutionReplacementError(s, name)
+ result += v
+ return result
+ else:
+ return s
+
+
+def isname(s):
+ """Return True iff s is a valid substitution name."""
+ m = _name_match(s)
+ if m:
+ return m.group() == s
+ else:
+ return False
+
+
+def _split(s):
+ # Return a triple: prefix, name, suffix
+ # - prefix is text that can be used literally in the result (may be '')
+ # - name is a referenced name, or None
+ # - suffix is trailling text that may contain additional references
+ # (may be '' or None)
+ if "$" in s:
+ i = s.find("$")
+ c = s[i+1:i+2]
+ if c == "":
+ raise ZConfig.SubstitutionSyntaxError(
+ "illegal lone '$' at end of source")
+ if c == "$":
+ return s[:i+1], None, s[i+2:]
+ prefix = s[:i]
+ if c == "{":
+ m = _name_match(s, i + 2)
if not m:
- raise SubstitutionSyntaxError("'${' not followed by name",
- context)
+ raise ZConfig.SubstitutionSyntaxError(
+ "'${' not followed by name")
name = m.group(0)
- length = len(name)
- if rest[length:length+1] != "}":
- raise SubstitutionSyntaxError(
- "'${%s' not followed by '}'" % name, context)
- v = section.get(name)
- if v is None:
- parent = getattr(section, "container", None)
- while parent is not None:
- v = parent.get(name)
- if v is not None:
- break
- parent = getattr(parent, "container", None)
- else:
- v = ""
- if "$" in v and context:
- if name in context:
- raise SubstitutionRecursionError(name, context)
- _interp(accum, v, section, context + [name])
- else:
- accum.append(v)
- rest = rest[length+1:]
+ i = m.end() + 1
+ if not s.startswith("}", i - 1):
+ raise ZConfig.SubstitutionSyntaxError(
+ "'${%s' not followed by '}'" % name)
else:
- m = _name_match(rest)
+ m = _name_match(s, i+1)
if not m:
- accum.append("$")
- continue
+ raise ZConfig.SubstitutionSyntaxError(
+ "'$' not followed by '$' or name")
name = m.group(0)
- v = section.get(name, "")
- if "$" in v and context:
- if name in context:
- raise SubstitutionRecursionError(name, context)
- _interp(accum, v, section, context + [name])
- else:
- accum.append(v)
- rest = rest[len(name):]
+ i = m.end()
+ return prefix, name.lower(), s[i:]
+ else:
+ return s, None, None
import re
=== Zope/lib/python/ZConfig/__init__.py 1.1.4.7 => 1.1.4.8 ===
--- Zope/lib/python/ZConfig/__init__.py:1.1.4.7 Tue Dec 3 16:24:50 2002
+++ Zope/lib/python/ZConfig/__init__.py Fri Dec 6 11:06:23 2002
@@ -16,6 +16,8 @@
$Id$
"""
+from ZConfig.Exceptions import *
+
def load(url):
import Context
return Context.Context().load(url)
=== Removed File Zope/lib/python/ZConfig/Common.py ===