From 4eac016c089772c9085d8bb8c6ccd45198f20df8 Mon Sep 17 00:00:00 2001 From: Nicolas Evrard Date: Fri, 2 Jun 2017 10:31:17 +0200 Subject: [PATCH 1/2] Add support for Local Time --- examples/example-v0.4.0.toml | 9 +++++++++ tests/decoding_test.py | 4 +++- toml.py | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/examples/example-v0.4.0.toml b/examples/example-v0.4.0.toml index a8210c0..81cb415 100644 --- a/examples/example-v0.4.0.toml +++ b/examples/example-v0.4.0.toml @@ -175,6 +175,15 @@ key2 = 1979-05-27T00:32:00-07:00 key3 = 1979-05-27T00:32:00.999999-07:00 +################################################################################ +## Time + +# Time is only the time portion of an RFC 3339 date. + +lt1 = 07:32:00 +lt2 = 00:32:00.999999 + + ################################################################################ ## Array diff --git a/tests/decoding_test.py b/tests/decoding_test.py index 68055e9..2454395 100755 --- a/tests/decoding_test.py +++ b/tests/decoding_test.py @@ -1,4 +1,4 @@ -"""Decodes toml and outputs it as tagged JSON""" +"""Decodes toml and outputs it as tagged JSON""" import datetime import json @@ -46,6 +46,8 @@ def tag(value): elif isinstance(value, datetime.datetime): sdate = value.strftime('%Y-%m-%dT%H:%M:%SZ') return {'type': 'datetime', 'value': sdate} + elif isinstance(value, datetime.time): + return {'type': 'time', 'value': value.strftime('%H:%M:%S.%f')} assert False, 'Unknown type: %s' % type(value) diff --git a/toml.py b/toml.py index fda070a..62c694f 100644 --- a/toml.py +++ b/toml.py @@ -9,6 +9,8 @@ __version__ = "0.9.2" __spec__ = "0.4.0" +TIME_RE = re.compile("(\d{2}):(\d{2}):(\d{2})(\.(\d{3,6}))?", re.ASCII) + class TomlDecodeError(Exception): pass @@ -590,6 +592,10 @@ def _load_value(v, _dict, strictly_valid=True): inline_object = _get_empty_inline_table(_dict) _load_inline_object(v, inline_object, _dict) return (inline_object, "inline_object") + elif TIME_RE.match(v): + h, m, s, _, ms = TIME_RE.match(v).groups() + time = datetime.time(int(h), int(m), int(s), int(ms) if ms else 0) + return (time, "time") else: parsed_date = _load_date(v) if parsed_date is not None: @@ -817,6 +823,7 @@ def _dump_value(v): bool: lambda: str(v).lower(), float: lambda: _dump_float(v), datetime.datetime: lambda: v.isoformat()[:19]+'Z', + datetime.time: lambda: _dump_time(v), } # Lookup function corresponding to v's type dump_fn = dump_funcs.get(type(v)) @@ -854,3 +861,10 @@ def _dump_list(v): def _dump_float(v): return "{0:.16g}".format(v).replace("e+0", "e+").replace("e-0", "e-") + +def _dump_time(v): + utcoffset = v.utcoffset() + if utcoffset is None: + return v.isoformat() + # The TOML norm specifies that it's local time thus we drop the offset + return v.isoformat()[:-6] From 4a39a29c6a28229ac018aa14f338851f015debe5 Mon Sep 17 00:00:00 2001 From: Nicolas Evrard Date: Wed, 7 Jun 2017 12:45:47 +0200 Subject: [PATCH 2/2] Use regexp expression compatible with python < 3 --- toml.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toml.py b/toml.py index 62c694f..d48fc45 100644 --- a/toml.py +++ b/toml.py @@ -9,7 +9,7 @@ __version__ = "0.9.2" __spec__ = "0.4.0" -TIME_RE = re.compile("(\d{2}):(\d{2}):(\d{2})(\.(\d{3,6}))?", re.ASCII) +TIME_RE = re.compile("([0-9]{2}):([0-9]{2}):([0-9]{2})(\.([0-9]{3,6}))?") class TomlDecodeError(Exception): pass