Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

don't automatically unpack datetime objects in the message spec #4497

Merged
merged 6 commits into from Nov 10, 2013
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 8 additions & 6 deletions IPython/kernel/zmq/session.py
Expand Up @@ -81,9 +81,9 @@ def squash_unicode(obj):

# ISO8601-ify datetime objects
json_packer = lambda obj: jsonapi.dumps(obj, default=date_default)
json_unpacker = lambda s: extract_dates(jsonapi.loads(s))
json_unpacker = lambda s: jsonapi.loads(s)

pickle_packer = lambda o: pickle.dumps(o,-1)
pickle_packer = lambda o: pickle.dumps(squash_dates(o),-1)
pickle_unpacker = pickle.loads

default_packer = json_packer
Expand Down Expand Up @@ -429,7 +429,7 @@ def msg_id(self):
return str(uuid.uuid4())

def _check_packers(self):
"""check packers for binary data and datetime support."""
"""check packers for datetime support."""
pack = self.pack
unpack = self.unpack

Expand Down Expand Up @@ -469,9 +469,11 @@ def _check_packers(self):
msg = dict(t=datetime.now())
try:
unpacked = unpack(pack(msg))
if isinstance(unpacked['t'], datetime):
raise ValueError("Shouldn't deserialize to datetime")
except Exception:
self.pack = lambda o: pack(squash_dates(o))
self.unpack = lambda s: extract_dates(unpack(s))
self.unpack = lambda s: unpack(s)

def msg_header(self, msg_type):
return msg_header(self.msg_id, msg_type, self.username, self.session)
Expand Down Expand Up @@ -815,10 +817,10 @@ def unserialize(self, msg_list, content=True, copy=True):
if not len(msg_list) >= minlen:
raise TypeError("malformed message, must have at least %i elements"%minlen)
header = self.unpack(msg_list[1])
message['header'] = header
message['header'] = extract_dates(header)
message['msg_id'] = header['msg_id']
message['msg_type'] = header['msg_type']
message['parent_header'] = self.unpack(msg_list[2])
message['parent_header'] = extract_dates(self.unpack(msg_list[2]))
message['metadata'] = self.unpack(msg_list[3])
if content:
message['content'] = self.unpack(msg_list[4])
Expand Down
17 changes: 12 additions & 5 deletions IPython/parallel/client/client.py
Expand Up @@ -37,7 +37,7 @@

from IPython.utils.capture import RichOutput
from IPython.utils.coloransi import TermColors
from IPython.utils.jsonutil import rekey
from IPython.utils.jsonutil import rekey, extract_dates
from IPython.utils.localinterfaces import localhost, is_local_ip
from IPython.utils.path import get_ipython_dir
from IPython.utils.py3compat import cast_bytes, string_types, xrange, iteritems
Expand Down Expand Up @@ -675,7 +675,7 @@ def _extract_metadata(self, msg):
if 'date' in parent:
md['submitted'] = parent['date']
if 'started' in msg_meta:
md['started'] = msg_meta['started']
md['started'] = extract_dates(msg_meta['started'])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to separate out the function for turning a single iso8601 string into a datetime, so that it's clearer where we're handling a single value as opposed to a container?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could, though almost everywhere there might be a datetime the value could also be None, and extract_dates handles that logic.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd still be inclined to split that bit out - extract_dates could simply call the new function on anything that's not a list or a dict.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, will do.

if 'date' in header:
md['completed'] = header['date']
return md
Expand Down Expand Up @@ -1564,8 +1564,8 @@ def result_status(self, msg_ids, status_only=True):
for msg_id in sorted(theids):
if msg_id in content['completed']:
rec = content[msg_id]
parent = rec['header']
header = rec['result_header']
parent = extract_dates(rec['header'])
header = extract_dates(rec['result_header'])
rcontent = rec['result_content']
iodict = rec['io']
if isinstance(rcontent, str):
Expand All @@ -1580,7 +1580,7 @@ def result_status(self, msg_ids, status_only=True):
)
md.update(self._extract_metadata(md_msg))
if rec.get('received'):
md['received'] = rec['received']
md['received'] = extract_dates(rec['received'])
md.update(iodict)

if rcontent['status'] == 'ok':
Expand Down Expand Up @@ -1842,6 +1842,13 @@ def db_query(self, query, keys=None):
has_bufs = buffer_lens is not None
has_rbufs = result_buffer_lens is not None
for i,rec in enumerate(records):
# unpack datetime objects
for dtkey in ('header', 'result_header',
'submitted', 'started',
'completed', 'received',
):
if dtkey in rec:
rec[dtkey] = extract_dates(rec[dtkey])
# relink buffers
if has_bufs:
blen = buffer_lens[i]
Expand Down
3 changes: 2 additions & 1 deletion IPython/parallel/controller/hub.py
Expand Up @@ -30,6 +30,7 @@

# internal:
from IPython.utils.importstring import import_item
from IPython.utils.jsonutil import extract_dates
from IPython.utils.localinterfaces import localhost
from IPython.utils.py3compat import cast_bytes, unicode_type, iteritems
from IPython.utils.traitlets import (
Expand Down Expand Up @@ -1385,7 +1386,7 @@ def get_history(self, client_id, msg):
def db_query(self, client_id, msg):
"""Perform a raw query on the task record database."""
content = msg['content']
query = content.get('query', {})
query = extract_dates(content.get('query', {}))
keys = content.get('keys', None)
buffers = []
empty = list()
Expand Down
4 changes: 2 additions & 2 deletions IPython/utils/jsonutil.py
Expand Up @@ -33,8 +33,8 @@
#-----------------------------------------------------------------------------

# timestamp formats
ISO8601="%Y-%m-%dT%H:%M:%S.%f"
ISO8601_PAT=re.compile(r"^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+)Z?([\+\-]\d{2}:?\d{2})?$")
ISO8601 = "%Y-%m-%dT%H:%M:%S.%f"
ISO8601_PAT=re.compile(r"^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{1,6})Z?([\+\-]\d{2}:?\d{2})?$")

#-----------------------------------------------------------------------------
# Classes and functions
Expand Down