history indexing replaced namedtuple with SimpleNamespace

This commit is contained in:
laerus 2017-01-29 15:22:46 +02:00
parent e88735807b
commit 487366592d
4 changed files with 43 additions and 32 deletions

View file

@ -1,6 +1,6 @@
**Added:**
* HistoryEntry, a namedtuple that represents a command in history.
* HistoryEntry, a SimpleNamespace object that represents a command in history.
**Changed:**

View file

@ -258,14 +258,21 @@ def test_parser_show(args, exp):
@pytest.mark.parametrize('index, exp', [
(-1, ('grep from me', 'out', 0, (5, 5))),
(1, ('cat hello kitty', 'out', 0, (1, 1))),
(slice(1, 3), [('cat hello kitty', 'out', 0, (1, 1)),
('abc', 'out', 0, (2, 2))]),
(-1, ('grep from me', 'out', 0, (5, 6))),
(1, ('cat hello kitty', 'out', 0, (1, 2))),
(slice(1, 3), [('cat hello kitty', 'out', 0, (1, 2)),
('abc', 'out', 0, (2, 3))]),
])
def test_history_getitem(index, exp, hist, xonsh_builtins):
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = set()
for ts,cmd in enumerate(CMDS): # populate the shell history
hist.append({'inp': cmd, 'rtn': 0, 'ts':(ts, ts), 'out': 'out'})
attrs = ('inp', 'out', 'rtn', 'ts')
assert hist[index] == exp
for ts,cmd in enumerate(CMDS): # populate the shell history
entry = {k: v for k, v in zip(attrs, [cmd, 'out', 0, (ts, ts+1)])}
hist.append(entry)
entry = hist[index]
if isinstance(entry, list):
assert [(e.cmd, e.out, e.rtn, e.ts) for e in entry] == exp
else:
assert (entry.cmd, entry.out, entry.rtn, entry.ts) == exp

View file

@ -161,17 +161,3 @@ def test_histcontrol(hist, xonsh_builtins):
assert '/bin/ls' == items[-1]['inp']
assert 0 == items[-1]['rtn']
assert -1 == hist.rtns[-1]
@pytest.mark.parametrize('index, exp', [
(-1, ('grep from me', None, 0, (5, 5))),
(1, ('cat hello kitty', None, 0, (1, 1))),
(slice(1, 3), [('cat hello kitty', None, 0, (1, 1)),
('abc', None, 0, (2, 2))]),
])
def test_history_getitem(index, exp, hist, xonsh_builtins):
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = set()
for ts,cmd in enumerate(CMDS): # populate the shell history
hist.append({'inp': cmd, 'rtn': 0, 'ts':(ts, ts), 'out': None})
assert hist[index] == exp

View file

@ -1,13 +1,33 @@
# -*- coding: utf-8 -*-
"""Base class of Xonsh History backends."""
import types
import uuid
from collections import namedtuple
import xonsh.tools as xt
# represents a command in the history
HistoryEntry = namedtuple('HistoryEntry', ['inp', 'out', 'rtn', 'ts'])
class HistoryEntry(types.SimpleNamespace):
"""Represent a command in history.
Attributes
----------
cmd: str
The command as typed by the user, including newlines
out: str
The output of the command, if xonsh is configured to save it
rtn: int
The return of the command (ie, 0 on success)
ts: two-tuple of floats
The timestamps of when the command started and finished, including
fractions.
"""
def __init__(self, *, cmd, out, rtn, ts):
self.cmd = cmd
self.out = out
self.rtn = rtn
self.ts = ts
class History:
@ -18,10 +38,7 @@ class History:
Indexing
--------
History acts like a sequence that can be indexed to return
a HistoryEntry.
HistoryEntry is a namedtuple with fields ('inp', 'out', 'rtn', 'ts')
that correspond to input, output, return code and timestamp respectively.
``HistoryEntry`` objects.
Note that the most recent command is the last item in history.
@ -71,14 +88,15 @@ class History:
if isinstance(item, int):
if item >= len(self):
raise IndexError('history index out of range')
return HistoryEntry(inp=self.inps[item], out=self.outs[item],
return HistoryEntry(cmd=self.inps[item], out=self.outs[item],
rtn=self.rtns[item], ts=self.tss[item])
elif isinstance(item, slice):
inps = self.inps[item]
cmds = self.inps[item]
outs = self.outs[item]
rtns = self.rtns[item]
tss = self.tss[item]
return [HistoryEntry(i, o, r, t) for i, o, r, t in zip(inps, outs, rtns, tss)]
return [HistoryEntry(cmd=c, out=o, rtn=r, ts=t)
for c, o, r, t in zip(cmds, outs, rtns, tss)]
else:
raise TypeError('history indices must be integers '
'or slices, not {}'.format(type(item)))