Details
-
Bug
-
Status: Closed
-
Major - P3
-
Resolution: Fixed
-
3.7.2
-
None
-
Installed via Anaconda
-
Fully Compatible
Description
The Issue
The error message produced by `bson.json_util.loads` when in incorrect date format is provided is unhelpful and, probably, incorrect.
To Reproduce
from bson import json_util |
json_util.loads('{"$date": "2019-01-01T01:02:03"}') |
This produces the following error (full traceback below):
ValueError: time data '2019-01-01T01' does not match format '%Y-%m-%dT%H:%M:%S'
This indicates that the format should be "%Y-%m-%dT%H:%M:%S and suggests that the value that was passed in is six characters shorter than the true input value. In reality, the format should be "%Y-%m-%dT%H:%M:%S.%L" in MongoDB's format syntax or "%Y-%m-%dT%H:%M:%S.%f" in the syntax used by Python's datetime package.
Full Traceback
In [4]: json_util.loads('\{"$date": "2019-01-01T01:02:03"}') |
--------------------------------------------------------------------------- |
ValueError Traceback (most recent call last)
|
<ipython-input-4-85a7366e7304> in <module> |
----> 1 json_util.loads('\{"$date": "2019-01-01T01:02:03"}') |
|
~/apps/anaconda3/lib/python3.6/site-packages/bson/json_util.py in loads(s, *args, **kwargs) |
436 else: |
437 kwargs["object_hook"] = lambda obj: object_hook(obj, json_options) |
--> 438 return json.loads(s, *args, **kwargs) |
439 |
440 |
|
~/apps/anaconda3/lib/python3.6/json/__init__.py in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw) |
365 if parse_constant is not None: |
366 kw['parse_constant'] = parse_constant |
--> 367 return cls(**kw).decode(s) |
|
~/apps/anaconda3/lib/python3.6/json/decoder.py in decode(self, s, _w) |
337 |
338 """ |
--> 339 obj, end = self.raw_decode(s, idx=_w(s, 0).end()) |
340 end = _w(s, end).end() |
341 if end != len(s): |
|
~/apps/anaconda3/lib/python3.6/json/decoder.py in raw_decode(self, s, idx) |
353 """ |
354 try: |
--> 355 obj, end = self.scan_once(s, idx) |
356 except StopIteration as err: |
357 raise JSONDecodeError("Expecting value", s, err.value) from None |
|
~/apps/anaconda3/lib/python3.6/site-packages/bson/json_util.py in <lambda>(pairs) |
433 if _HAS_OBJECT_PAIRS_HOOK: |
434 kwargs["object_pairs_hook"] = lambda pairs: object_pairs_hook( |
--> 435 pairs, json_options) |
436 else: |
437 kwargs["object_hook"] = lambda obj: object_hook(obj, json_options) |
|
~/apps/anaconda3/lib/python3.6/site-packages/bson/json_util.py in object_pairs_hook(pairs, json_options) |
455 |
456 def object_pairs_hook(pairs, json_options=DEFAULT_JSON_OPTIONS): |
--> 457 return object_hook(json_options.document_class(pairs), json_options) |
458 |
459 |
|
~/apps/anaconda3/lib/python3.6/site-packages/bson/json_util.py in object_hook(dct, json_options) |
464 return _parse_canonical_dbref(dct) |
465 if "$date" in dct: |
--> 466 return _parse_canonical_datetime(dct, json_options) |
467 if "$regex" in dct: |
468 return _parse_legacy_regex(dct) |
|
~/apps/anaconda3/lib/python3.6/site-packages/bson/json_util.py in _parse_canonical_datetime(doc, json_options) |
598 |
599 aware = datetime.datetime.strptime( |
--> 600 dt, "%Y-%m-%dT%H:%M:%S").replace(microsecond=microsecond, |
601 tzinfo=utc) |
602 |
|
~/apps/anaconda3/lib/python3.6/_strptime.py in _strptime_datetime(cls, data_string, format) |
563 """Return a class cls instance based on the input string and the |
564 format string."""
|
--> 565 tt, fraction = _strptime(data_string, format) |
566 tzname, gmtoff = tt[-2:] |
567 args = tt[:6] + (fraction,) |
|
~/apps/anaconda3/lib/python3.6/_strptime.py in _strptime(data_string, format) |
360 if not found: |
361 raise ValueError("time data %r does not match format %r" % |
--> 362 (data_string, format)) |
363 if len(data_string) != found.end(): |
364 raise ValueError("unconverted data remains: %s" % |
|
ValueError: time data '2019-01-01T01' does not match format '%Y-%m-%dT%H:%M:%S' |