[Zodb-checkins] CVS: Zope/lib/python/ZConfig - cfgparser.py:1.6.2.1 datatypes.py:1.5.2.1 loader.py:1.10.2.2 matcher.py:1.4.2.1 schema.py:1.11.2.2 url.py:1.4.2.1
Fred L. Drake, Jr.
fred@zope.com
Thu, 23 Jan 2003 17:02:29 -0500
Update of /cvs-repository/Zope/lib/python/ZConfig
In directory cvs.zope.org:/tmp/cvs-serv32578
Modified Files:
Tag: chrism-install-branch
cfgparser.py datatypes.py loader.py matcher.py schema.py
url.py
Log Message:
Merge from the ZConfig trunk.
=== Zope/lib/python/ZConfig/cfgparser.py 1.6 => 1.6.2.1 ===
--- Zope/lib/python/ZConfig/cfgparser.py:1.6 Thu Jan 9 11:34:43 2003
+++ Zope/lib/python/ZConfig/cfgparser.py Thu Jan 23 17:01:52 2003
@@ -13,9 +13,10 @@
##############################################################################
"""Configuration parser."""
-from ZConfig import ConfigurationError, ConfigurationSyntaxError
+import ZConfig
+import ZConfig.url
+
from ZConfig.substitution import isname, substitute
-from ZConfig.url import urljoin
try:
True
@@ -95,7 +96,7 @@
try:
newsect = self.context.startSection(section, type, name,
delegatename)
- except ConfigurationError, e:
+ except ZConfig.ConfigurationError, e:
self.error(e[0])
if isempty:
@@ -115,7 +116,7 @@
try:
self.context.endSection(
prevsection, type, name, delegatename, section)
- except ConfigurationError, e:
+ except ZConfig.ConfigurationError, e:
self.error(e[0])
return prevsection
@@ -130,7 +131,7 @@
value = substitute(value, self.defs)
try:
section.addValue(key, value, (self.lineno, None, self.url))
- except ConfigurationError, e:
+ except ZConfig.ConfigurationError, e:
self.error(e[0])
def handle_directive(self, section, rest):
@@ -150,7 +151,7 @@
assert 0, "unexpected directive for " + `"%" + rest`
def handle_include(self, section, rest):
- newurl = urljoin(self.url, rest)
+ newurl = ZConfig.url.urljoin(self.url, rest)
self.context.includeConfiguration(section, newurl, self.defs)
def handle_define(self, section, rest):
@@ -166,7 +167,7 @@
self.defs[defname] = substitute(defvalue, self.defs)
def error(self, message):
- raise ConfigurationSyntaxError(message, self.url, self.lineno)
+ raise ZConfig.ConfigurationSyntaxError(message, self.url, self.lineno)
import re
=== Zope/lib/python/ZConfig/datatypes.py 1.5 => 1.5.2.1 ===
--- Zope/lib/python/ZConfig/datatypes.py:1.5 Thu Jan 9 11:34:43 2003
+++ Zope/lib/python/ZConfig/datatypes.py Thu Jan 23 17:01:52 2003
@@ -103,32 +103,6 @@
RegularExpressionConversion.__init__(self, "[_a-zA-Z][_a-zA-Z0-9]*")
-class LogLevelConversion:
- # This uses the 'logging' package conventions; only makes sense
- # for Zope 2.7 (and newer) and Zope 3. Not sure what the
- # compatibility should be.
-
- _levels = {
- "critical": 50,
- "fatal": 50,
- "error": 40,
- "warn": 30,
- "info": 20,
- "debug": 10,
- "all": 0,
- }
-
- def __call__(self, value):
- s = str(value).lower()
- if self._levels.has_key(s):
- return self._levels[s]
- else:
- v = int(s)
- if v < 0 or v > 50:
- raise ValueError("log level not in range: " + `v`)
- return v
-
-
if sys.version[:3] < "2.3":
def integer(value):
try:
@@ -154,6 +128,11 @@
raise ValueError("not a valid boolean value: " + repr(s))
+def string_list(s):
+ """Convert a string to a list of strings using .split()."""
+ return s.split()
+
+
port_number = RangeCheckedConversion(integer, min=1, max=0xffff).__call__
@@ -200,9 +179,12 @@
r"(\d|[01]?\d\d|2[0-4]\d|25[0-5])\." #ipaddr cont'd
r"(\d|[01]?\d\d|2[0-4]\d|25[0-5])\." #ipaddr cont'd
r"(\d|[01]?\d\d|2[0-4]\d|25[0-5])$)" #ipaddr cont'd
- r"|([^0-9][A-Za-z0-9-_.]+)") # or hostname
+ r"|([A-Za-z_][-A-Za-z0-9_.]*[-A-Za-z0-9_])") # or hostname
RegularExpressionConversion.__init__(self, expr)
+ def __call__(self, value):
+ return RegularExpressionConversion.__call__(self, value).lower()
+
def existing_directory(v):
if os.path.isdir(v):
return v
@@ -304,11 +286,11 @@
"integer": integer,
"float": float_conversion,
"string": str,
+ "string-list": string_list,
"null": null_conversion,
"locale": MemoizedConversion(check_locale),
"port-number": port_number,
"basic-key": BasicKeyConversion(),
- "logging-level": LogLevelConversion(),
"inet-address": inet_address,
"socket-address": SocketAddress,
"ipaddr-or-hostname":IpaddrOrHostname(),
@@ -331,15 +313,24 @@
class Registry:
__metatype__ = type
- __slots__ = '_stock', '_other'
+ __slots__ = '_stock', '_other', '_basic_key'
def __init__(self, stock=None):
if stock is None:
stock = stock_datatypes.copy()
self._stock = stock
self._other = {}
+ self._basic_key = None
def get(self, name):
+ if '.' not in name:
+ if self._basic_key is None:
+ self._basic_key = self._other.get("basic-key")
+ if self._basic_key is None:
+ self._basic_key = self._stock.get("basic-key")
+ if self._basic_key is None:
+ self._basic_key = stock_datatypes["basic-key"]
+ name = self._basic_key(name)
t = self._stock.get(name)
if t is None:
t = self._other.get(name)
=== Zope/lib/python/ZConfig/loader.py 1.10.2.1 => 1.10.2.2 ===
--- Zope/lib/python/ZConfig/loader.py:1.10.2.1 Mon Jan 13 20:17:27 2003
+++ Zope/lib/python/ZConfig/loader.py Thu Jan 23 17:01:52 2003
@@ -19,10 +19,11 @@
import urllib2
import ZConfig
-
-from ZConfig import datatypes
-from ZConfig import matcher
-from ZConfig.url import urlnormalize, urldefrag, urljoin, urlsplit, urlunsplit
+import ZConfig.cfgparser
+import ZConfig.datatypes
+import ZConfig.matcher
+import ZConfig.schema
+import ZConfig.url
try:
True
@@ -77,13 +78,21 @@
# change and provide the cached resource when the remote
# resource is not accessible.
url = str(url)
- file = urllib2.urlopen(url)
+ try:
+ file = urllib2.urlopen(url)
+ except (IOError, OSError), e:
+ # Python 2.1 raises a different error from Python 2.2+,
+ # so we catch both to make sure we detect the situation.
+ error = ZConfig.ConfigurationError("error opening resource %s: %s"
+ % (url, str(e)))
+ error.url = url
+ raise error
return self.createResource(file, url)
def normalizeURL(self, url):
- if os.path.exists(url):
+ if os.path.exists(url) or ":" not in url:
url = "file://" + urllib.pathname2url(os.path.abspath(url))
- url, fragment = urldefrag(url)
+ url, fragment = ZConfig.url.urldefrag(url)
if fragment:
raise ZConfig.ConfigurationError(
"fragment identifiers are not supported")
@@ -101,7 +110,7 @@
class SchemaLoader(BaseLoader):
def __init__(self, registry=None):
if registry is None:
- registry = datatypes.Registry()
+ registry = ZConfig.datatypes.Registry()
BaseLoader.__init__(self)
self.registry = registry
self._cache = {}
@@ -110,8 +119,8 @@
if resource.url and self._cache.has_key(resource.url):
schema = self._cache[resource.url]
else:
- from ZConfig.schema import parseResource
- schema = parseResource(resource, self.registry, self)
+ schema = ZConfig.schema.parseResource(resource,
+ self.registry, self)
self._cache[resource.url] = schema
return schema
@@ -155,9 +164,11 @@
def loadResource(self, resource):
self.handlers = []
- sm = matcher.SchemaMatcher(self.schema, self.handlers)
+ sm = ZConfig.matcher.SchemaMatcher(self.schema, self.handlers)
self._parse_resource(sm, resource)
- return sm.finish(), CompositeHandler(self.handlers, self.schema)
+ result = sm.finish(), CompositeHandler(self.handlers, self.schema)
+ del self.handlers
+ return result
# config parser support API
@@ -175,7 +186,7 @@
raise ZConfig.ConfigurationError(
"%s is not an allowed name for %s sections"
% (`name`, `ci.sectiontype.name`))
- return matcher.SectionMatcher(ci, t, name, self.handlers)
+ return ZConfig.matcher.SectionMatcher(ci, t, name, self.handlers)
def endSection(self, parent, type, name, delegatename, matcher):
assert not delegatename
@@ -183,14 +194,14 @@
parent.addSection(type, name, sectvalue)
def includeConfiguration(self, section, url, defines):
+ url = self.normalizeURL(url)
r = self.openResource(url)
self._parse_resource(section, r, defines)
# internal helper
def _parse_resource(self, matcher, resource, defines=None):
- from ZConfig.cfgparser import ZConfigParser
- parser = ZConfigParser(resource, self, defines)
+ parser = ZConfig.cfgparser.ZConfigParser(resource, self, defines)
parser.parse(matcher)
=== Zope/lib/python/ZConfig/matcher.py 1.4 => 1.4.2.1 ===
--- Zope/lib/python/ZConfig/matcher.py:1.4 Mon Jan 6 15:29:33 2003
+++ Zope/lib/python/ZConfig/matcher.py Thu Jan 23 17:01:52 2003
@@ -57,11 +57,15 @@
"too many instances of %s section" % `ci.sectiontype.name`)
def addValue(self, key, value, position):
+ try:
+ realkey = self.type.keytype(key)
+ except ValueError, e:
+ raise ZConfig.DataConversionError(e, key, position)
length = len(self.type)
arbkey_info = None
for i in range(length):
k, ci = self.type[i]
- if k == key:
+ if k == realkey:
break
if ci.name == "+" and not ci.issection():
arbkey_info = i, k, ci
@@ -97,15 +101,15 @@
value = ValueInfo(value, position)
if k == '+':
if ismulti:
- if v.has_key(key):
- v[key].append(value)
+ if v.has_key(realkey):
+ v[realkey].append(value)
else:
- v[key] = [value]
+ v[realkey] = [value]
else:
- if v.has_key(key):
+ if v.has_key(realkey):
raise ZConfig.ConfigurationError(
"too many values for " + `key`)
- v[key] = value
+ v[realkey] = value
elif ismulti:
v.append(value)
else:
@@ -134,7 +138,7 @@
if key:
s = `key`
else:
- s = "section type " + `ci.typename`
+ s = "section type " + `ci.sectiontype.name`
raise ZConfig.ConfigurationError(
"no values for %s; %s required" % (s, ci.minOccurs))
else:
=== Zope/lib/python/ZConfig/schema.py 1.11.2.1 => 1.11.2.2 ===
--- Zope/lib/python/ZConfig/schema.py:1.11.2.1 Mon Jan 13 20:17:27 2003
+++ Zope/lib/python/ZConfig/schema.py Thu Jan 23 17:01:52 2003
@@ -218,11 +218,14 @@
return name, None, aname
else:
# run the keytype converter to make sure this is a valid key
- name = self._stack[-1].keytype(name)
+ try:
+ name = self._stack[-1].keytype(name)
+ except ValueError, e:
+ self.error("could not convert key name to keytype: " + str(e))
if not aname:
aname = self.basic_key(name)
aname = self.identifier(aname.replace('-', '_'))
- return None, self.basic_key(name), aname
+ return None, name, aname
# schema loading logic
@@ -304,6 +307,7 @@
else:
sectinfo = self._schema.createSectionType(
name, keytype, valuetype, datatype)
+ self._localtypes[name] = sectinfo
if attrs.has_key("implements"):
ifname = self.basic_key(attrs["implements"])
interface = self._schema.gettype(ifname)
@@ -442,41 +446,36 @@
class BaseComponentParser(BaseParser):
- def __init__(self, registry, loader, url, localtypes):
- self._localtypes = localtypes
+ def __init__(self, registry, loader, url, schema, localtypes):
BaseParser.__init__(self, registry, loader, url)
+ self._localtypes = localtypes
+ self._parent = schema
def characters_description(self, data):
if self._stack:
self._stack[-1].description = data
def start_key(self, attrs):
- if not self._stack:
- self.error(
- "cannot define top-level keys in a schema " + self._top_level)
+ self._check_not_toplevel("key")
BaseParser.start_key(self, attrs)
def start_multikey(self, attrs):
- if not self._stack:
- self.error(
- "cannot define top-level multikeys in a schema "
- + self._top_level)
+ self._check_not_toplevel("multikey")
BaseParser.start_multikey(self, attrs)
def start_section(self, attrs):
- if not self._stack:
- self.error(
- "cannot define top-level sections in a schema "
- + self._top_level)
+ self._check_not_toplevel("section")
BaseParser.start_section(self, attrs)
def start_multisection(self, attrs):
- if not self._stack:
- self.error(
- "cannot define top-level multisections in a schema "
- + self._top_level)
+ self._check_not_toplevel("multisection")
BaseParser.start_multisection(self, attrs)
+ def _check_not_toplevel(self, what):
+ if not self._stack:
+ self.error("cannot define top-level %s in a schema %s"
+ % (what, self._top_level))
+
class ComponentParser(BaseComponentParser):
@@ -484,8 +483,7 @@
_top_level = "component"
def __init__(self, registry, loader, url, schema):
- BaseComponentParser.__init__(self, registry, loader, url, {})
- self._parent = schema
+ BaseComponentParser.__init__(self, registry, loader, url, schema, {})
def start_component(self, attrs):
self._schema = self._parent
@@ -505,10 +503,6 @@
_handled_tags = BaseComponentParser._handled_tags + ("extension",)
_top_level = "extension"
-
- def __init__(self, registry, loader, url, schema, localtypes):
- BaseComponentParser.__init__(self, registry, loader, url, localtypes)
- self._parent = schema
def start_extension(self, attrs):
self._schema = self._parent
=== Zope/lib/python/ZConfig/url.py 1.4 => 1.4.2.1 ===
--- Zope/lib/python/ZConfig/url.py:1.4 Wed Jan 8 00:42:45 2003
+++ Zope/lib/python/ZConfig/url.py Thu Jan 23 17:01:52 2003
@@ -41,12 +41,8 @@
def urlnormalize(url):
- parts = urlsplit(url)
- if not parts[0]:
- raise ValueError("invalid URL, or file does not exist:\n"
- + repr(url))
- url = urlunsplit(parts)
- if url.startswith("file:/") and not url.startswith("file:///"):
+ lc = url.lower()
+ if lc.startswith("file:/") and not lc.startswith("file:///"):
url = "file://" + url[5:]
return url