--- a/urltree.py Mon Feb 09 01:17:20 2009 +0200
+++ b/urltree.py Mon Feb 09 03:05:19 2009 +0200
@@ -56,10 +56,10 @@
key = match.group('key')
# type
- type = match.group("type")
+ type_name = match.group("type")
# lookup type, None -> default
- type = config.get_type(type)
+ type = config.get_type(type_name)
# defaults?
default = defaults.get(key)
@@ -72,7 +72,7 @@
default = type.parse(default)
# build
- return SimpleValueLabel(key, type, default)
+ return SimpleValueLabel(key, type_name, type, default)
# static?
match = StaticLabel.EXPR.match(mask)
@@ -219,12 +219,15 @@
EXPR = re.compile(r'^\{(?P<key>[a-zA-Z_][a-zA-Z0-9_]*)(:(?P<type>[a-zA-Z_][a-zA-Z0-9_]*))?(=(?P<default>[^}]+))?\}$')
- def __init__ (self, key, type, default) :
+ def __init__ (self, key, type_name, type, default) :
"""
- The given key is the name of this label's value
+ The given key is the name of this label's value.
+
+ The given type_name is is None for the default type, otherwise the type's name. Type is a URLType.
"""
# type
+ self.type_name = type_name
self.type = type
# store
@@ -254,7 +257,7 @@
def __str__ (self) :
return '{%s%s%s}' % (
self.key,
- ':%s' % (self.type, ), # XXX: omit if default
+ (':%s' % (self.type_name, ) if self.type_name else ''),
'=%s' % (self.default, ) if self.default else '',
)
@@ -263,13 +266,6 @@
Handles the type-ness of values in the URL
"""
- def _init_name (self, name) :
- """
- Initialize our .name attribute, called by URLConfig
- """
-
- self.name = name
-
def test (self, value) :
"""
Tests if the given value is valid for this type.
@@ -301,13 +297,6 @@
abstract
- def __str__ (self) :
- """
- Return a short string giving the name of this type, defaults to self.name
- """
-
- return self.name
-
class URLStringType (URLType) :
"""
The default URLType, just plain strings.
@@ -315,9 +304,6 @@
Note that this does not accept empty strings as valid
"""
- def __init__ (self) :
- super(URLStringType, self).__init__('str')
-
def parse (self, value) :
"""
Identitiy
@@ -342,8 +328,6 @@
to specifiy maximum value
"""
- super(URLIntegerType, self).__init__('int')
-
self.negative = negative
self.zero = zero
self.max = max
@@ -386,10 +370,15 @@
Global configuration relevant to all URLs. This can be used to construct a set of URLs and then create an
URLTree out of them. Simply call the url_config() instace with the normal URL arguments (except, of course,
config), and finally just pass the url_config to URLTree (it's iterable).
+
+ XXX: rename to URLFactory?
"""
# built-in type codes
BUILTIN_TYPES = {
+ # default - string
+ None : URLStringType(),
+
# string
'str' : URLStringType(),
@@ -397,16 +386,15 @@
'int' : URLIntegerType(),
}
- # init names
- for name, type in BUILTIN_TYPES.iteritems() :
- type._init_name(name)
-
- def __init__ (self, type_dict=None, default_type='str') :
+ def __init__ (self, type_dict=None, ignore_extra_args=True) :
"""
Create an URLConfig for use with URL
If type_dict is given, it should be a dict of { type_names: URLType }, and they will be available for
- type specifications in addition to the defaults.
+ type specifications in addition to the defaults. This will call type._init_name with the key, so do
+ *not* initialize the name yourself.
+
+ If ignore_extra_args is given, unrecognized query arguments will be ignored.
"""
# build our type_dict
@@ -414,26 +402,18 @@
# apply the given type_dict
if type_dict :
- # initialize names
- for name, type in type_dict.iteritems() :
- type._init_name(name)
-
# merge
self.type_dict.update(type_dict)
# init
- self.default_type = default_type
+ self.ignore_extra_args = ignore_extra_args
self.urls = []
def get_type (self, type_name=None) :
"""
- Lookup an URLType by type_name, None for default
+ Lookup an URLType by type_name, None for default.
"""
- # default type?
- if not type_name :
- type_name = self.default_type
-
# lookup + return
return self.type_dict[type_name]
@@ -537,6 +517,15 @@
# then parse all query args
for key, value in request.get_args() :
+ # unknown key?
+ if key not in self.query_args :
+ # ignore?
+ if self.config.ignore_extra_args :
+ continue
+
+ else :
+ raise URLError("Unrecognized query argument: %r" % (key, ))
+
# lookup spec
type, default = self.query_args[key]