*needs-reply (Edwin)
This seems like a very nice new feature.
I tried to run the tests with nose, as you implied might work. At least with
a simple run, nose fails a few tests because it does not recognize (is not
told that) the ELLIPSIS and NORMALIZE_WHITESPACE flags are supposed to be on.
This would be fixed with making wadllib use zc.buildout and the zope
testrunner, like the lazr packages. Barring objections, I may do that
soonish. For now, I think having the tests run in the Launchpad testrunner is
OK.
Comments below.
> === modified file 'wadllib/application.py'
> --- wadllib/application.py 2008-08-13 13:26:16 +0000
> +++ wadllib/application.py 2009-01-21 19:58:38 +0000
> @@ -43,6 +43,8 @@
> 'WADLError',
> ]
>
> +import datetime
> +import time
> import urllib
> import simplejson
> try:
> @@ -52,6 +54,8 @@
> import cElementTree as ET
> except ImportError:
> import elementtree.ElementTree as ET
> +
> +from iso_strptime import iso_strptime
> from wadllib._utils import uri
>
> def wadl_tag(tag_name):
> @@ -424,7 +428,22 @@
> raise NotImplementedError(
> "Don't know how to find value for a parameter of "
> "type %s." % parameter.style)
> - return self.representation[parameter.name]
> + value = self.representation[parameter.name]
> + if value is not None:
> + if parameter.type in ['xsd:dateTime', 'xsd:date']:
As you said in the cover letter, it would be nice if this were using proper
namespacing. In the "Parsing with Prefixes" section of
http://effbot.org/zone/element-namespaces.htm that doesn't look too bad--at
least he seems to have a recipe for an almost-identical situation.
Perhaps I suggest looking that over and seeing if that can be incorporated
quickly? If not, I'm OK with this for now, particularly if there is an XXX
and a bug number.
> + try:
> + # Parse it as an ISO 1601 date and time.
> + value = iso_strptime(value)
> + except ValueError:
> + # Parse it as an ISO 1601 date.
> + try:
> + value = datetime.datetime(
> + *(time.strptime(value, "%Y-%m-%d")[0:6]))
> + except ValueError:
> + # Oh well. Leave it as a string.
> + pass
Does wadllib have an error channel for this sort of thing? logging seems
minimally appropriate.
Alternatively, I think raising an error would be appropriate, and more
"Pythonic".
A strawman: if the value is None, you leave it alone. If the value parses to
a datetime, you parse it. If it is a string that doesn't parse (or anything
else), you raise an error, with the bad value as an attribute.
If wadl allows you to specify whether a value may be None, then that could be
a better, tighter constraint (that is, if it can be None, let it through;
otherwise raise an error).
That's what I would recommend and prefer.
> +
> + return value
>
> raise NotImplementedError("Path traversal not implemented for "
> "a representation of media type %s."
> @@ -786,6 +805,11 @@
> return self.tag.attrib.get('style')
>
> @property
> + def type(self):
> + """The XSD type of this parameter."""
> + return self.tag.attrib.get('type')
> +
> + @property
> def fixed_value(self):
> """The value to which this parameter is fixed, if any.
>
> @@ -935,7 +959,7 @@
> # representation of a non-root resource to its definition at
> # the server root.
> raise NotImplementedError("Can't look up definition in another "
> - "url (%s)" % url)
> + "url (%s)" % (url))
This doesn't accomplish anything, because (string) == string. Because
strings are iterable in Python and string interpolation can get confused, I
usually use (string,), that is, a tuple of one value. Is that what is
intended here?
>
> def get_resource_by_path(self, path):
> """Locate one of the resources described by this document.
>
> === removed file 'wadllib/diff'
> --- wadllib/diff 2008-08-01 15:07:59 +0000
> +++ wadllib/diff 1970-01-01 00:00:00 +0000
> @@ -1,327 +0,0 @@
> -=== added file 'COPYING.txt'
> ---- COPYING.txt 1970-01-01 00:00:00 +0000
> -+++ COPYING.txt 2008-08-01 14:41:07 +0000
> -@@ -0,0 +1,165 @@
> -+ GNU LESSER GENERAL PUBLIC LICENSE
> -+ Version 3, 29 June 2007
> -+
> -+ Copyright (C) 2007 Free Software Foundation, Inc.
> -+ Everyone is permitted to copy and distribute verbatim copies
> -+ of this license document, but changing it is not allowed.
> -+
> -+
> -+ This version of the GNU Lesser General Public License incorporates
> -+the terms and conditions of version 3 of the GNU General Public
> -+License, supplemented by the additional permissions listed below.
> -+
> -+ 0. Additional Definitions.
> -+
> -+ As used herein, "this License" refers to version 3 of the GNU Lesser
> -+General Public License, and the "GNU GPL" refers to version 3 of the GNU
> -+General Public License.
> -+
> -+ "The Library" refers to a covered work governed by this License,
> -+other than an Application or a Combined Work as defined below.
> -+
> -+ An "Application" is any work that makes use of an interface provided
> -+by the Library, but which is not otherwise based on the Library.
> -+Defining a subclass of a class defined by the Library is deemed a mode
> -+of using an interface provided by the Library.
> -+
> -+ A "Combined Work" is a work produced by combining or linking an
> -+Application with the Library. The particular version of the Library
> -+with which the Combined Work was made is also called the "Linked
> -+Version".
> -+
> -+ The "Minimal Corresponding Source" for a Combined Work means the
> -+Corresponding Source for the Combined Work, excluding any source code
> -+for portions of the Combined Work that, considered in isolation, are
> -+based on the Application, and not on the Linked Version.
> -+
> -+ The "Corresponding Application Code" for a Combined Work means the
> -+object code and/or source code for the Application, including any data
> -+and utility programs needed for reproducing the Combined Work from the
> -+Application, but excluding the System Libraries of the Combined Work.
> -+
> -+ 1. Exception to Section 3 of the GNU GPL.
> -+
> -+ You may convey a covered work under sections 3 and 4 of this License
> -+without being bound by section 3 of the GNU GPL.
> -+
> -+ 2. Conveying Modified Versions.
> -+
> -+ If you modify a copy of the Library, and, in your modifications, a
> -+facility refers to a function or data to be supplied by an Application
> -+that uses the facility (other than as an argument passed when the
> -+facility is invoked), then you may convey a copy of the modified
> -+version:
> -+
> -+ a) under this License, provided that you make a good faith effort to
> -+ ensure that, in the event an Application does not supply the
> -+ function or data, the facility still operates, and performs
> -+ whatever part of its purpose remains meaningful, or
> -+
> -+ b) under the GNU GPL, with none of the additional permissions of
> -+ this License applicable to that copy.
> -+
> -+ 3. Object Code Incorporating Material from Library Header Files.
> -+
> -+ The object code form of an Application may incorporate material from
> -+a header file that is part of the Library. You may convey such object
> -+code under terms of your choice, provided that, if the incorporated
> -+material is not limited to numerical parameters, data structure
> -+layouts and accessors, or small macros, inline functions and templates
> -+(ten or fewer lines in length), you do both of the following:
> -+
> -+ a) Give prominent notice with each copy of the object code that the
> -+ Library is used in it and that the Library and its use are
> -+ covered by this License.
> -+
> -+ b) Accompany the object code with a copy of the GNU GPL and this license
> -+ document.
> -+
> -+ 4. Combined Works.
> -+
> -+ You may convey a Combined Work under terms of your choice that,
> -+taken together, effectively do not restrict modification of the
> -+portions of the Library contained in the Combined Work and reverse
> -+engineering for debugging such modifications, if you also do each of
> -+the following:
> -+
> -+ a) Give prominent notice with each copy of the Combined Work that
> -+ the Library is used in it and that the Library and its use are
> -+ covered by this License.
> -+
> -+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
> -+ document.
> -+
> -+ c) For a Combined Work that displays copyright notices during
> -+ execution, include the copyright notice for the Library among
> -+ these notices, as well as a reference directing the user to the
> -+ copies of the GNU GPL and this license document.
> -+
> -+ d) Do one of the following:
> -+
> -+ 0) Convey the Minimal Corresponding Source under the terms of this
> -+ License, and the Corresponding Application Code in a form
> -+ suitable for, and under terms that permit, the user to
> -+ recombine or relink the Application with a modified version of
> -+ the Linked Version to produce a modified Combined Work, in the
> -+ manner specified by section 6 of the GNU GPL for conveying
> -+ Corresponding Source.
> -+
> -+ 1) Use a suitable shared library mechanism for linking with the
> -+ Library. A suitable mechanism is one that (a) uses at run time
> -+ a copy of the Library already present on the user's computer
> -+ system, and (b) will operate properly with a modified version
> -+ of the Library that is interface-compatible with the Linked
> -+ Version.
> -+
> -+ e) Provide Installation Information, but only if you would otherwise
> -+ be required to provide such information under section 6 of the
> -+ GNU GPL, and only to the extent that such information is
> -+ necessary to install and execute a modified version of the
> -+ Combined Work produced by recombining or relinking the
> -+ Application with a modified version of the Linked Version. (If
> -+ you use option 4d0, the Installation Information must accompany
> -+ the Minimal Corresponding Source and Corresponding Application
> -+ Code. If you use option 4d1, you must provide the Installation
> -+ Information in the manner specified by section 6 of the GNU GPL
> -+ for conveying Corresponding Source.)
> -+
> -+ 5. Combined Libraries.
> -+
> -+ You may place library facilities that are a work based on the
> -+Library side by side in a single library together with other library
> -+facilities that are not Applications and are not covered by this
> -+License, and convey such a combined library under terms of your
> -+choice, if you do both of the following:
> -+
> -+ a) Accompany the combined library with a copy of the same work based
> -+ on the Library, uncombined with any other library facilities,
> -+ conveyed under the terms of this License.
> -+
> -+ b) Give prominent notice with the combined library that part of it
> -+ is a work based on the Library, and explaining where to find the
> -+ accompanying uncombined form of the same work.
> -+
> -+ 6. Revised Versions of the GNU Lesser General Public License.
> -+
> -+ The Free Software Foundation may publish revised and/or new versions
> -+of the GNU Lesser General Public License from time to time. Such new
> -+versions will be similar in spirit to the present version, but may
> -+differ in detail to address new problems or concerns.
> -+
> -+ Each version is given a distinguishing version number. If the
> -+Library as you received it specifies that a certain numbered version
> -+of the GNU Lesser General Public License "or any later version"
> -+applies to it, you have the option of following the terms and
> -+conditions either of that published version or of any later version
> -+published by the Free Software Foundation. If the Library as you
> -+received it does not specify a version number of the GNU Lesser
> -+General Public License, you may choose any version of the GNU Lesser
> -+General Public License ever published by the Free Software Foundation.
> -+
> -+ If the Library as you received it specifies that a proxy can decide
> -+whether future versions of the GNU Lesser General Public License shall
> -+apply, that proxy's public statement of acceptance of any version is
> -+permanent authorization for you to choose that version for the
> -+Library.
> -
> -=== modified file 'README'
> ---- README 2008-08-01 14:40:55 +0000
> -+++ README 2008-08-01 14:53:44 +0000
> -@@ -1,5 +1,15 @@
> --Copyright (C) 2008 Canonical Ltd. All rights reserved.
> --
> --wadllib is a client-side package for inspecting and navigating between
> --HTTP resources described using the Web Application Description
> --Language.
> -+Copyright (C) 2008 Canonical Ltd.
> -+
> -+wadllib is free software: you can redistribute it and/or modify it
> -+under the terms of the GNU Lesser General Public License as published
> -+by the Free Software Foundation, either version 3 of the License, or
> -+(at your option) any later version.
> -+
> -+wadllib is distributed in the hope that it will be useful, but WITHOUT
> -+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> -+FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
> -+License for more details.
> -+
> -+You should have received a copy of the GNU Lesser General Public
> -+License along with wadllib. If not, see
> -+.
> -
> -=== modified file 'setup.py'
> ---- setup.py 2008-08-01 14:40:55 +0000
> -+++ setup.py 2008-08-01 14:41:07 +0000
> -@@ -27,6 +27,7 @@
> - 'setuptools_bzr',
> - ]
> - ,
> -+ license='LGPL 3',
> - extras_require = {
> - 'nose': ['nose'],
> - },
> -
> -=== modified file 'wadllib/__init__.py'
> ---- wadllib/__init__.py 2008-08-01 14:40:55 +0000
> -+++ wadllib/__init__.py 2008-08-01 14:53:01 +0000
> -@@ -1,3 +1,19 @@
> - # Copyright 2008 Canonical Ltd. All rights reserved.
> -
> -+# This file is part of wadllib.
> -+#
> -+# wadllib is free software: you can redistribute it and/or modify it
> -+# under the terms of the GNU Lesser General Public License as
> -+# published by the Free Software Foundation, either version 3 of the
> -+# License, or (at your option) any later version.
> -+#
> -+# wadllib is distributed in the hope that it will be useful, but
> -+# WITHOUT ANY WARRANTY; without even the implied warranty of
> -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> -+# Lesser General Public License for more details.
> -+#
> -+# You should have received a copy of the GNU Lesser General Public
> -+# License along with wadllib. If not, see
> -+# .
> -+
> - __version__ = '0.1'
> -
> -=== modified file 'wadllib/_utils/__init__.py'
> ---- wadllib/_utils/__init__.py 2008-08-01 14:40:55 +0000
> -+++ wadllib/_utils/__init__.py 2008-08-01 14:53:08 +0000
> -@@ -0,0 +1,17 @@
> -+# Copyright 2008 Canonical Ltd. All rights reserved.
> -+
> -+# This file is part of wadllib.
> -+#
> -+# wadllib is free software: you can redistribute it and/or modify it
> -+# under the terms of the GNU Lesser General Public License as
> -+# published by the Free Software Foundation, either version 3 of the
> -+# License, or (at your option) any later version.
> -+#
> -+# wadllib is distributed in the hope that it will be useful, but
> -+# WITHOUT ANY WARRANTY; without even the implied warranty of
> -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> -+# Lesser General Public License for more details.
> -+#
> -+# You should have received a copy of the GNU Lesser General Public
> -+# License along with wadllib. If not, see
> -+# .
> -
> -=== modified file 'wadllib/_utils/uri.py'
> ---- wadllib/_utils/uri.py 2008-08-01 14:40:55 +0000
> -+++ wadllib/_utils/uri.py 2008-08-01 14:53:22 +0000
> -@@ -1,4 +1,20 @@
> --# Copyright 2006 Canonical Ltd. All rights reserved.
> -+# Copyright 2008 Canonical Ltd. All rights reserved.
> -+
> -+# This file is part of wadllib.
> -+#
> -+# wadllib is free software: you can redistribute it and/or modify it
> -+# under the terms of the GNU Lesser General Public License as
> -+# published by the Free Software Foundation, either version 3 of the
> -+# License, or (at your option) any later version.
> -+#
> -+# wadllib is distributed in the hope that it will be useful, but
> -+# WITHOUT ANY WARRANTY; without even the implied warranty of
> -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> -+# Lesser General Public License for more details.
> -+#
> -+# You should have received a copy of the GNU Lesser General Public
> -+# License along with wadllib. If not, see
> -+# .
> -
> - """Functions for working with generic syntax URIs."""
> -
> -
> -=== modified file 'wadllib/application.py'
> ---- wadllib/application.py 2008-08-01 14:40:55 +0000
> -+++ wadllib/application.py 2008-08-01 14:52:57 +0000
> -@@ -1,5 +1,21 @@
> - # Copyright 2008 Canonical Ltd. All rights reserved.
> -
> -+# This file is part of wadllib.
> -+#
> -+# wadllib is free software: you can redistribute it and/or modify it
> -+# under the terms of the GNU Lesser General Public License as
> -+# published by the Free Software Foundation, either version 3 of the
> -+# License, or (at your option) any later version.
> -+#
> -+# wadllib is distributed in the hope that it will be useful, but
> -+# WITHOUT ANY WARRANTY; without even the implied warranty of
> -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> -+# Lesser General Public License for more details.
> -+#
> -+# You should have received a copy of the GNU Lesser General Public
> -+# License along with wadllib. If not, see
> -+# .
> -+
> - """Navigate the resources exposed by a web service.
> -
> - The wadllib library helps a web client navigate the resources
> -
> -=== modified file 'wadllib/docs/__init__.py'
> ---- wadllib/docs/__init__.py 2008-08-01 14:40:55 +0000
> -+++ wadllib/docs/__init__.py 2008-08-01 14:54:47 +0000
> -@@ -0,0 +1,17 @@
> -+# Copyright 2008 Canonical Ltd. All rights reserved.
> -+
> -+# This file is part of wadllib.
> -+#
> -+# wadllib is free software: you can redistribute it and/or modify it
> -+# under the terms of the GNU Lesser General Public License as
> -+# published by the Free Software Foundation, either version 3 of the
> -+# License, or (at your option) any later version.
> -+#
> -+# wadllib is distributed in the hope that it will be useful, but
> -+# WITHOUT ANY WARRANTY; without even the implied warranty of
> -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> -+# Lesser General Public License for more details.
> -+#
> -+# You should have received a copy of the GNU Lesser General Public
> -+# License along with wadllib. If not, see
> -+# .
> -
>
> === added file 'wadllib/docs/testdata/data-types-wadl.xml'
> --- wadllib/docs/testdata/data-types-wadl.xml 1970-01-01 00:00:00 +0000
> +++ wadllib/docs/testdata/data-types-wadl.xml 2009-01-21 19:58:38 +0000
> @@ -0,0 +1,24 @@
> +
> + + xmlns="http://research.sun.com/wadl/2006/10"
> + xmlns:xsd="http://www.w3.org/2001/XMLSchema"
> + xsi:schemaLocation="http://research.sun.com/wadl/2006/10/wadl.xsd">
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> + + path="$['a_date']" name="a_date" />
> + + path="$['a_datetime']" name="a_datetime" />
> +
> +
>
> === modified file 'wadllib/docs/wadllib.txt'
> --- wadllib/docs/wadllib.txt 2008-08-11 17:56:11 +0000
> +++ wadllib/docs/wadllib.txt 2009-01-21 19:58:38 +0000
> @@ -116,8 +116,8 @@
> test data.
>
> >>> bound_service_root = bind_to_testdata(service_root, 'root')
> - >>> bound_service_root.parameter_names()
> - ['people_collection_link', 'bugs_collection_link']
> + >>> sorted(bound_service_root.parameter_names())
> + ['bugs_collection_link', 'people_collection_link']
> >>> [method.id for method in bound_service_root.method_iter]
> ['service-root-get']
>
> @@ -266,7 +266,8 @@
>
> >>> bound_limi = bind_to_testdata(limi_person, 'person-limi')
> >>> sorted(bound_limi.parameter_names())[:3]
> - ['admins_collection_link', 'confirmed_email_addresses_collection_link', 'date_created']
> + ['admins_collection_link', 'confirmed_email_addresses_collection_link',
> + 'date_created']
> >>> languages_link = bound_limi.get_parameter("languages_collection_link")
> >>> languages_link.get_value()
> u'http://api.launchpad.dev/beta/~limi/languages'
> @@ -302,7 +303,7 @@
> an example.
>
> There's a method on a person resource such as bound_limi that's
> -identified by a distinctive query argument: ws.op=findPathToTeam.
> +identified by a distinctive query argument: ws.op=getMembersByStatus.
>
> >>> method = bound_limi.get_method(
> ... query_params={'ws.op' : 'findPathToTeam'})
> @@ -353,6 +354,51 @@
> >>> print method.response.get_representation_definition('text/html')
> None
>
> +=== Data type converstion ===
> +
> +The values of date and dateTime parameters are automatically converted to
> +Python datetime objects.
> +
> + >>> data_type_stream = pkg_resources.resource_stream(
> + ... 'wadllib.docs.testdata', 'data-types-wadl.xml')
> + >>> data_type_wadl = Application(
> + ... "http://www.example.com/", data_type_stream)
> + >>> service_root = data_type_wadl.get_resource_by_path('')
> +
> + >>> representation = simplejson.dumps(
> + ... {'a_date': '2007-10-20',
> + ... 'a_datetime': '2005-06-06T08:59:51.619713+00:00'})
> + >>> bound_root = service_root.bind(representation, 'application/json')
> +
> + >>> bound_root.get_parameter('a_date').get_value()
> + datetime.datetime(2007, 10, 20, 0, 0)
> + >>> bound_root.get_parameter('a_datetime').get_value()
> + datetime.datetime(2005, 6, 6, 8, ...)
> +
> +A 'date' field can include a timestamp, and a 'datetime' field can
> +omit one. wadllib will turn both into datetime objects.
> +
> + >>> representation = simplejson.dumps(
> + ... {'a_date': '2005-06-06T08:59:51.619713+00:00',
> + ... 'a_datetime': '2007-10-20'})
> + >>> bound_root = service_root.bind(representation, 'application/json')
> +
> + >>> bound_root.get_parameter('a_datetime').get_value()
> + datetime.datetime(2007, 10, 20, 0, 0)
> + >>> bound_root.get_parameter('a_date').get_value()
> + datetime.datetime(2005, 6, 6, 8, ...)
> +
> +If a date or dateTime parameter has a value that can't be parsed to a
> +datetime object, you get the original value.
> +
> + >>> representation = simplejson.dumps(
> + ... {'a_date': 'foo', 'a_datetime': None})
> + >>> bound_root = service_root.bind(representation, 'application/json')
> + >>> bound_root.get_parameter('a_date').get_value()
> + u'foo'
> + >>> print bound_root.get_parameter('a_datetime').get_value()
> + None
> +
>
> == Representation creation ==
>
>
> === added file 'wadllib/iso_strptime.py'
> --- wadllib/iso_strptime.py 1970-01-01 00:00:00 +0000
> +++ wadllib/iso_strptime.py 2009-01-21 19:58:38 +0000
> @@ -0,0 +1,85 @@
> +# Copyright 2009 Canonical Ltd. All rights reserved.
> +
> +# This file is part of wadllib.
> +#
> +# wadllib is free software: you can redistribute it and/or modify it
> +# under the terms of the GNU Lesser General Public License as
> +# published by the Free Software Foundation, either version 3 of the
> +# License, or (at your option) any later version.
> +#
> +# wadllib is distributed in the hope that it will be useful, but
> +# WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +# Lesser General Public License for more details.
> +#
> +# You should have received a copy of the GNU Lesser General Public
> +# License along with wadllib. If not, see
> +# .
> +"""
> +Parser for ISO 1601 time strings
> +================================
> +
> +>>> d = iso_strptime("2008-01-07T05:30:30.345323+03:00")
> +>>> d
> +datetime.datetime(2008, 1, 7, 5, 30, 30, 345323, tzinfo=TimeZone(10800))
> +>>> d.timetuple()
> +(2008, 1, 7, 5, 30, 30, 0, 7, 0)
> +>>> d.utctimetuple()
> +(2008, 1, 7, 2, 30, 30, 0, 7, 0)
> +>>> iso_strptime("2008-01-07T05:30:30.345323-03:00")
> +datetime.datetime(2008, 1, 7, 5, 30, 30, 345323, tzinfo=TimeZone(-10800))
> +>>> iso_strptime("2008-01-07T05:30:30.345323")
> +datetime.datetime(2008, 1, 7, 5, 30, 30, 345323)
> +>>> iso_strptime("2008-01-07T05:30:30")
> +datetime.datetime(2008, 1, 7, 5, 30, 30)
> +>>> iso_strptime("2008-01-07T05:30:30+02:00")
> +datetime.datetime(2008, 1, 7, 5, 30, 30, tzinfo=TimeZone(7200))
> +"""
This is not currently hooked up as a doc test, I believe. It should be.
> +
> +
> +import re
> +import datetime
> +
> +RE_TIME = re.compile(r"""^
> + (?P\d{4})\-(?P\d{2})\-(?P\d{2}) # pattern matching date
> + T # seperator
> + (?P\d{2})\:(?P\d{2})\:(?P\d{2}) # pattern matching time
> + (\.(?P\d{6}))? # pattern matching optional microseconds
> + (?P[\-\+]\d{2}\:\d{2})? # pattern matching optional timezone offset
> + $""", re.VERBOSE)
Would be really nice if this (and other lines below) could fit within the
79-char limit. Maybe the regex can't be made to fit attractively (though I
think it can) but certainly the other lines can.
It's actually a shame that this is in wadllib. IMO it actually belongs in
a separate package. It is small, but fills a unique, stand-alone need.
> +
> +class TimeZone(datetime.tzinfo):
> +
> + def __init__(self, tz_string):
> + hours, minutes = tz_string.lstrip("-+").split(":")
> + self.stdoffset = datetime.timedelta(hours=int(hours), minutes=int(minutes))
> + if tz_string.startswith("-"):
> + self.stdoffset *= -1
> +
> + def __repr__(self):
> + return "TimeZone(%s)" %(self.stdoffset.days*24*60*60 + self.stdoffset.seconds)
> +
> + def utcoffset(self, dt):
> + return self.stdoffset
> +
> + def dst(self, dt):
> + return datetime.timedelta(0)
> +
> +
> +
> +def iso_strptime(time_str):
> + x = RE_TIME.match(time_str)
> + if not x:
> + raise ValueError
> + d = datetime.datetime(int(x.group("year")), int(x.group("month")),
> + int(x.group("day")), int(x.group("hour")), int(x.group("minutes")),
> + int(x.group("seconds")))
> + if x.group("microseconds"):
> + d = d.replace(microsecond=int(x.group("microseconds")))
> + if x.group("tz_offset"):
> + d = d.replace(tzinfo=TimeZone(x.group("tz_offset")))
> + return d
> +
> +if __name__ == '__main__':
> + import doctest
> + doctest.testmod()
I don't think we want if __name__ == '__main__' stuff in this kind of file.
>
>