[Zope-Checkins] CVS: Packages/ZConfig - datatypes.py:1.1.2.19
Chris McDonough
chrism@zope.com
Sat, 21 Dec 2002 23:19:16 -0500
Update of /cvs-repository/Packages/ZConfig
In directory cvs.zope.org:/tmp/cvs-serv4104
Modified Files:
Tag: zconfig-schema-devel-branch
datatypes.py
Log Message:
Added following "stock" datatypes and tests:
"ipaddr-or-hostname": Validates a valid IP address or hostname.
"existing-directory": Ensures that a directory by the given name exists.
"existing-path": Ensures that a path by the given name exists.
"existing-file": Ensure that a file by the given name exists.
"existing-dirpath": Ensure that the directory implied by path exists.
"constructor": Parse a "constructor(1,2,3)" value into klass, pos, kw.
"key-value": Space-separated key-value pairs in values.
Changed Zope schema to make use of these datatypes.
=== Packages/ZConfig/datatypes.py 1.1.2.18 => 1.1.2.19 ===
--- Packages/ZConfig/datatypes.py:1.1.2.18 Fri Dec 20 15:39:43 2002
+++ Packages/ZConfig/datatypes.py Sat Dec 21 23:18:45 2002
@@ -15,6 +15,7 @@
import re
import sys
+import os
try:
True
@@ -181,13 +182,95 @@
else:
return socket.AF_INET, inet_address(s)
-
def float_conversion(v):
if isinstance(v, type('')) or isinstance(v, type(u'')):
if v.lower() in ["inf", "-inf", "nan"]:
raise ValueError(`v` + " is not a portable float representation")
return float(v)
+class IpaddrOrHostname(RegularExpressionConversion):
+ def __init__(self):
+ # IP address regex from the Perl Cookbook, Recipe 6.23 (revised ed.)
+ # We allow underscores in hostnames although this is considered
+ # illegal according to RFC1034.
+ expr = (r"(^(\d|[01]?\d\d|2[0-4]\d|25[0-5])\." #ipaddr
+ 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
+ RegularExpressionConversion.__init__(self, expr)
+
+def existing_directory(v):
+ if os.path.isdir(v):
+ return v
+ raise ValueError, '%s is not an existing directory' % v
+
+def existing_path(v):
+ if os.path.exists(v):
+ return v
+ raise ValueError, '%s is not an existing path' % v
+
+def existing_file(v):
+ if os.path.exists(v):
+ return v
+ raise ValueError, '%s is not an existing file' % v
+
+def existing_dirpath(v):
+ if not os.path.split(v)[0]:
+ # relative pathname
+ return v
+ dir = os.path.dirname(v)
+ if os.path.isdir(dir):
+ return v
+ raise ValueError, ('The directory named as part of the path %s '
+ 'does not exist.')
+
+def parse_constructor(v):
+ parenmsg = (
+ 'Invalid constructor (unbalanced parenthesis in "%s")' % v
+ )
+ openparen = v.find('(')
+ if openparen < 0:
+ raise ValueError(parenmsg)
+ klass = v[:openparen]
+ if not v.endswith(')'):
+ raise ValueError(parenmsg)
+ arglist = v[openparen+1:-1]
+ return klass, arglist
+
+def get_arglist(s):
+ # someone could do a better job at this.
+ pos = []
+ kw = {}
+ args = s.split(',')
+ args = filter(None, args)
+ while args:
+ arg = args.pop(0)
+ try:
+ if '=' in arg:
+ k,v=arg.split('=', 1)
+ k = k.strip()
+ v = v.strip()
+ kw[k] = eval(v)
+ else:
+ arg = arg.strip()
+ pos.append(eval(arg))
+ except SyntaxError:
+ if not args:
+ raise
+ args[0] = '%s, %s' % (arg, args[0])
+ return pos, kw
+
+def constructor_conversion(v):
+ klass, arglist = parse_constructor(v)
+ pos, kw = get_arglist(arglist)
+ return klass, pos, kw
+
+def space_sep_key_value_conversion(v):
+ l = v.split(' ', 1)
+ if len(l) < 2:
+ l.append('')
+ return l
stock_datatypes = {
"boolean": asBoolean,
@@ -202,6 +285,13 @@
"logging-level": LogLevelConversion().__call__,
"inet-address": inet_address,
"socket-address":socket_address,
+ "ipaddr-or-hostname":IpaddrOrHostname().__call__,
+ "existing-directory":existing_directory,
+ "existing-path":existing_path,
+ "existing-file":existing_file,
+ "existing-dirpath":existing_dirpath,
+ "constructor":constructor_conversion,
+ "key-value":space_sep_key_value_conversion,
}
class Registry: