[Zodb-checkins] CVS: Packages/ZConfig - Config.py:1.16 __init__.py:1.5 cfgparser.py:1.3 info.py:1.4 matcher.py:1.3 schema.py:1.4
Fred L. Drake, Jr.
fred@zope.com
Mon, 6 Jan 2003 14:36:18 -0500
Update of /cvs-repository/Packages/ZConfig
In directory cvs.zope.org:/tmp/cvs-serv8539
Modified Files:
Config.py __init__.py cfgparser.py info.py matcher.py
schema.py
Log Message:
Values now have location information stored along with the actual text of the
value. This is used to improve error reporting to the end user.
=== Packages/ZConfig/Config.py 1.15 => 1.16 ===
--- Packages/ZConfig/Config.py:1.15 Fri Jan 3 16:05:51 2003
+++ Packages/ZConfig/Config.py Mon Jan 6 14:35:41 2003
@@ -102,7 +102,8 @@
type = type.lower()
return [sect for sect in self._sections if sect.type == type]
- def addValue(self, key, value):
+ def addValue(self, key, value, position=None):
+ # position is needed for interface compatibility, but isn't used here
key = key.lower()
try:
self._data[key]
=== Packages/ZConfig/__init__.py 1.4 => 1.5 ===
--- Packages/ZConfig/__init__.py:1.4 Fri Jan 3 16:05:51 2003
+++ Packages/ZConfig/__init__.py Mon Jan 6 14:35:41 2003
@@ -102,6 +102,27 @@
ConfigurationError.__init__(self, msg)
+class DataConversionError(ConfigurationError, ValueError):
+ """Raised when a data type conversion function raises ValueError."""
+
+ def __init__(self, exception, value, position):
+ ConfigurationError.__init__(self, str(exception))
+ self.exception = exception
+ self.value = value
+ self.position = position
+ self.lineno, self.colno, self.url = position
+
+ def __str__(self):
+ s = "%s (line %d" % (self.message, self.lineno)
+ if self.colno is not None:
+ s += ", %d" % self.colno
+ if self.url:
+ s += ", in %s)" % self.url
+ else:
+ s += ")"
+ return s
+
+
class SubstitutionSyntaxError(ConfigurationError):
"""Raised when interpolation source text contains syntactical errors."""
=== Packages/ZConfig/cfgparser.py 1.2 => 1.3 ===
--- Packages/ZConfig/cfgparser.py:1.2 Fri Jan 3 16:05:51 2003
+++ Packages/ZConfig/cfgparser.py Mon Jan 6 14:35:41 2003
@@ -123,7 +123,7 @@
else:
value = substitute(value, self.defs)
try:
- section.addValue(key, value)
+ section.addValue(key, value, (self.lineno, None, self.url))
except ConfigurationError, e:
self.error(e[0])
=== Packages/ZConfig/info.py 1.3 => 1.4 ===
--- Packages/ZConfig/info.py:1.3 Mon Jan 6 13:19:38 2003
+++ Packages/ZConfig/info.py Mon Jan 6 14:35:41 2003
@@ -48,6 +48,19 @@
Unbounded = UnboundedThing()
+class ValueInfo:
+ def __init__(self, value, position):
+ self.value = value
+ # position is (lineno, colno, url)
+ self.position = position
+
+ def convert(self, datatype):
+ try:
+ return datatype(self.value)
+ except ValueError, e:
+ raise ZConfig.DataConversionError(e, self.value, self.position)
+
+
class BaseInfo:
"""Information about a single configuration key."""
@@ -100,10 +113,11 @@
"cannot finish KeyInfo more than once")
self._finished = True
- def adddefault(self, value):
+ def adddefault(self, value, position):
if self._finished:
raise ZConfig.SchemaError(
"cannot add default values to finished KeyInfo")
+ value = ValueInfo(value, position)
if self.maxOccurs > 1:
if self._default is None:
self._default = [value]
=== Packages/ZConfig/matcher.py 1.2 => 1.3 ===
--- Packages/ZConfig/matcher.py:1.2 Fri Jan 3 16:05:51 2003
+++ Packages/ZConfig/matcher.py Mon Jan 6 14:35:41 2003
@@ -17,6 +17,8 @@
import ZConfig
+from ZConfig.info import ValueInfo
+
class BaseMatcher:
def __init__(self, info, type, handlers):
@@ -54,7 +56,7 @@
raise ZConfig.ConfigurationError(
"too many instances of %s section" % `ci.sectiontype.name`)
- def addValue(self, key, value):
+ def addValue(self, key, value, position):
length = len(self.type)
arbkey_info = None
for i in range(length):
@@ -92,6 +94,7 @@
raise ZConfig.ConfigurationError(
"too many values for " + `name`)
+ value = ValueInfo(value, position)
if k == '+':
if ismulti:
if v.has_key(key):
@@ -165,9 +168,9 @@
elif ci.name == '+':
v = values[i]
for key, val in v.items():
- v[key] = [ci.datatype(s) for s in val]
+ v[key] = [vi.convert(ci.datatype) for vi in val]
else:
- v = [ci.datatype(s) for s in values[i]]
+ v = [vi.convert(ci.datatype) for vi in values[i]]
elif ci.issection():
if values[i] is not None:
v = values[i]._type.datatype(values[i])
@@ -176,11 +179,11 @@
elif name == '+':
v = values[i]
for key, val in v.items():
- v[key] = ci.datatype(val)
+ v[key] = val.convert(ci.datatype)
else:
v = values[i]
if v is not None:
- v = ci.datatype(v)
+ v = v.convert(ci.datatype)
values[i] = v
if ci.handler is not None:
self._handlers.append((ci.handler, v))
=== Packages/ZConfig/schema.py 1.3 => 1.4 ===
--- Packages/ZConfig/schema.py:1.3 Mon Jan 6 13:19:38 2003
+++ Packages/ZConfig/schema.py Mon Jan 6 14:35:41 2003
@@ -84,11 +84,14 @@
if self._cdata is not None:
self.error(name + " element improperly nested")
self._cdata = []
+ self._position = None
else:
self.error("Unknown tag " + name)
def characters(self, data):
if self._cdata is not None:
+ if self._position is None:
+ self._position = self.get_position()
self._cdata.append(data)
elif data.strip():
self.error("unexpected non-blank character data: "
@@ -102,7 +105,7 @@
self._cdata = None
if name == "default":
# value for a key
- self._stack[-1].adddefault(data)
+ self._stack[-1].adddefault(data, self._position)
else:
setattr(self._stack[-1], name, data)
@@ -136,6 +139,14 @@
def end_import(self):
pass
+ def get_position(self):
+ if self._locator:
+ return (self._locator.getLineNumber(),
+ self._locator.getColumnNumber(),
+ self._url)
+ else:
+ return None, None, self._url
+
def get_handler(self, attrs):
v = attrs.get("handler")
if v is None:
@@ -313,7 +324,8 @@
if attrs.has_key("default"):
if min:
self.error("required key cannot have a default value")
- key.adddefault(str(attrs["default"]).strip())
+ key.adddefault(str(attrs["default"]).strip(),
+ self.get_position())
key.finish()
self._stack[-1].addkey(key)
self._stack.append(key)