summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2013-06-23 14:37:07 +0200
committerBram Moolenaar <Bram@vim.org>2013-06-23 14:37:07 +0200
commit841fbd290790376561eaaaccaad9fc52f45ded89 (patch)
tree6bc85ba98d6432a5b3ca3c5f71e7d21793f290a7
parentc4b99e0be76e0fbb9b43efb16f2d56607ce45de0 (diff)
updated for version 7.3.1233v7.3.1233
Problem: Various Python problems. Solution: Fix VimTryEnd. Crash with debug build and PYTHONDUMPREFS=1. Memory leaks in StringToLine(), BufferMark() and convert_dl. (ZyX)
-rw-r--r--src/if_py_both.h37
-rw-r--r--src/testdir/test86.in200
-rw-r--r--src/testdir/test86.ok577
-rw-r--r--src/testdir/test87.in202
-rw-r--r--src/testdir/test87.ok577
-rw-r--r--src/version.c2
6 files changed, 929 insertions, 666 deletions
diff --git a/src/if_py_both.h b/src/if_py_both.h
index 5319466e57..e48740c275 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -544,20 +544,30 @@ VimTryStart(void)
VimTryEnd(void)
{
--trylevel;
+ /* Without this it stops processing all subsequent VimL commands and
+ * generates strange error messages if I e.g. try calling Test() in a cycle */
+ did_emsg = FALSE;
+ /* Keyboard interrupt should be preferred over anything else */
if (got_int)
{
+ did_throw = got_int = FALSE;
PyErr_SetNone(PyExc_KeyboardInterrupt);
- return 1;
+ return -1;
}
else if (!did_throw)
- return 0;
+ return (PyErr_Occurred() ? -1 : 0);
+ /* Python exception is preferred over vim one; unlikely to occur though */
else if (PyErr_Occurred())
- return 1;
+ {
+ did_throw = FALSE;
+ return -1;
+ }
+ /* Finally transform VimL exception to python one */
else
{
PyErr_SetVim((char *) current_exception->value);
discard_current_exception();
- return 1;
+ return -1;
}
}
@@ -2649,7 +2659,14 @@ FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
static PyObject *
FunctionRepr(FunctionObject *self)
{
- return PyString_FromFormat("<vim.Function '%s'>", self->name);
+#ifdef Py_TRACE_REFS
+ /* For unknown reason self->name may be NULL after calling
+ * Finalize */
+ return PyString_FromFormat("<vim.Function '%s'>",
+ (self->name == NULL ? "<NULL>" : (char *) self->name));
+#else
+ return PyString_FromFormat("<vim.Function '%s'>", (char *) self->name);
+#endif
}
static struct PyMethodDef FunctionMethods[] = {
@@ -3534,6 +3551,7 @@ StringToLine(PyObject *obj)
else
{
PyErr_SET_VIM("string cannot contain newlines");
+ Py_XDECREF(bytes);
return NULL;
}
}
@@ -3545,6 +3563,7 @@ StringToLine(PyObject *obj)
if (save == NULL)
{
PyErr_NoMemory();
+ Py_XDECREF(bytes);
return NULL;
}
@@ -4551,6 +4570,7 @@ BufferMark(BufferObject *self, PyObject *pmarkObject)
{
PyErr_SET_STRING(PyExc_ValueError,
"mark name must be a single character");
+ Py_XDECREF(todecref);
return NULL;
}
@@ -5298,6 +5318,9 @@ convert_dl(PyObject *obj, typval_T *tv,
tv->v_type = VAR_UNKNOWN;
return -1;
}
+
+ Py_DECREF(capsule);
+
if (py_to_tv(obj, tv, lookup_dict) == -1)
{
tv->v_type = VAR_UNKNOWN;
@@ -5378,13 +5401,13 @@ _ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
++tv->vval.v_dict->dv_refcount;
}
- else if (obj->ob_type == &ListType)
+ else if (PyType_IsSubtype(obj->ob_type, &ListType))
{
tv->v_type = VAR_LIST;
tv->vval.v_list = (((ListObject *)(obj))->list);
++tv->vval.v_list->lv_refcount;
}
- else if (obj->ob_type == &FunctionType)
+ else if (PyType_IsSubtype(obj->ob_type, &FunctionType))
{
if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
return -1;
diff --git a/src/testdir/test86.in b/src/testdir/test86.in
index a46a70ac32..d8afc96d46 100644
--- a/src/testdir/test86.in
+++ b/src/testdir/test86.in
@@ -11,8 +11,8 @@ STARTTEST
:set noswapfile
:if !has('python') | e! test.ok | wq! test.out | endif
:lang C
-:py import vim
:fun Test()
+:py import vim
:let l = []
:py l=vim.bindeval('l')
:py f=vim.bindeval('function("strlen")')
@@ -58,6 +58,9 @@ EOF
: $put =string(key) . ' : ' . string(Val)
: unlet key Val
:endfor
+:py del dk
+:py del di
+:py del dv
:"
:" removing items with del
:py del l[2]
@@ -176,12 +179,12 @@ EOF
:unlockvar! l
:"
:" Function calls
-:function New(...)
-:return ['NewStart']+a:000+['NewEnd']
-:endfunction
-:function DictNew(...) dict
-:return ['DictNewStart']+a:000+['DictNewEnd', self]
-:endfunction
+:fun New(...)
+: return ['NewStart']+a:000+['NewEnd']
+:endfun
+:fun DictNew(...) dict
+: return ['DictNewStart']+a:000+['DictNewEnd', self]
+:endfun
:let l=[function('New'), function('DictNew')]
:py l=vim.bindeval('l')
:py l.extend(list(l[0](1, 2, 3)))
@@ -211,6 +214,7 @@ EOF
: $put ='[0.0, 0.0]'
:endif
:let messages=[]
+:delfunction DictNew
py <<EOF
d=vim.bindeval('{}')
m=vim.bindeval('messages')
@@ -220,15 +224,17 @@ def em(expr, g=globals(), l=locals()):
except:
m.extend([sys.exc_type.__name__])
-em('d["abc"]')
-em('d["abc"]="\\0"')
-em('d["abc"]=vim')
+em('d["abc1"]')
+em('d["abc1"]="\\0"')
+em('d["abc1"]=vim')
em('d[""]=1')
em('d["a\\0b"]=1')
em('d[u"a\\0b"]=1')
-em('d.pop("abc")')
+em('d.pop("abc1")')
em('d.popitem()')
+del em
+del m
EOF
:$put =messages
:unlet messages
@@ -240,8 +246,8 @@ EOF
: let toput=s.' : '.join(map(['locked', 'scope'], 'v:val.":".pyeval(name.".".v:val)'), ';')
: $put =toput
:endfor
-:silent! let d.abc=1
-:silent! let dl.abc=1
+:silent! let d.abc2=1
+:silent! let dl.abc3=1
:py d.locked=True
:py dl.locked=False
:silent! let d.def=1
@@ -307,12 +313,15 @@ class T(threading.Thread):
time.sleep(0.1)
t = T()
+del T
t.start()
EOF
:sleep 1
:py t.running = False
:py t.join()
:py l[0] = t.t > 8 # check if the background thread is working
+:py del time
+:py del threading
:$put =string(l)
:"
:" settrace
@@ -333,6 +342,8 @@ def trace_main():
EOF
:py sys.settrace(traceit)
:py trace_main()
+:py del traceit
+:py del trace_main
:py sys.settrace(None)
:$put =string(l)
:"
@@ -363,7 +374,7 @@ EOF
:"
:" Vars
:let g:foo = 'bac'
-:let w:abc = 'def'
+:let w:abc3 = 'def'
:let b:baz = 'bar'
:let t:bar = 'jkl'
:try
@@ -372,7 +383,7 @@ EOF
: put =pyeval('vim.vvars[''exception'']')
:endtry
:put =pyeval('vim.vars[''foo'']')
-:put =pyeval('vim.current.window.vars[''abc'']')
+:put =pyeval('vim.current.window.vars[''abc3'']')
:put =pyeval('vim.current.buffer.vars[''baz'']')
:put =pyeval('vim.current.tabpage.vars[''bar'']')
:"
@@ -420,16 +431,16 @@ def ev(s, g=globals(), l=locals()):
vim.command('let exc=' + repr(sys.exc_type.__name__))
return 0
EOF
-:function E(s)
+:fun E(s)
: python e(vim.eval('a:s'))
-:endfunction
-:function Ev(s)
+:endfun
+:fun Ev(s)
: let r=pyeval('ev(vim.eval("a:s"))')
: if exists('exc')
: throw exc
: endif
: return r
-:endfunction
+:endfun
:py gopts1=vim.options
:py wopts1=vim.windows[2].options
:py wopts2=vim.windows[0].options
@@ -444,7 +455,7 @@ EOF
:let lst+=[['operatorfunc', 'A', 'B', 'C', 2, 0, 1, 0 ]]
:let lst+=[['number', 0, 1, 1, 0, 1, 0, 1 ]]
:let lst+=[['numberwidth', 2, 3, 5, -100, 0, 0, 1 ]]
-:let lst+=[['colorcolumn', '+1', '+2', '+3', 'abc', 0, 0, 1 ]]
+:let lst+=[['colorcolumn', '+1', '+2', '+3', 'abc4', 0, 0, 1 ]]
:let lst+=[['statusline', '1', '2', '4', 0, 0, 1, 1 ]]
:let lst+=[['autoindent', 0, 1, 1, 2, 1, 0, 2 ]]
:let lst+=[['shiftwidth', 0, 2, 1, 3, 0, 0, 2 ]]
@@ -494,10 +505,27 @@ EOF
: endfor
: call RecVars(oname)
:endfor
+:delfunction RecVars
+:delfunction E
+:delfunction Ev
+:py del ev
+:py del e
:only
:for buf in g:bufs[1:]
: execute 'bwipeout!' buf
:endfor
+:py del gopts1
+:py del wopts1
+:py del wopts2
+:py del wopts3
+:py del bopts1
+:py del bopts2
+:py del bopts3
+:py del oval1
+:py del oval2
+:py del oval3
+:py del oname
+:py del invval
:"
:" Test buffer object
:vnew
@@ -517,7 +545,7 @@ cb = vim.current.buffer
# Tests BufferAppend and BufferItem
cb.append(b[0])
# Tests BufferSlice and BufferAssSlice
-cb.append('abc') # Will be overwritten
+cb.append('abc5') # Will be overwritten
cb[-1:] = b[:-2]
# Test BufferLength and BufferAssSlice
cb.append('def') # Will not be overwritten
@@ -541,13 +569,14 @@ b.name = 'bar'
cb.append(b.name[-11:].replace(os.path.sep, '/'))
cb.name = old_name
cb.append(cb.name[-17:].replace(os.path.sep, '/'))
+del old_name
# Test CheckBuffer
for _b in vim.buffers:
if _b is not cb:
vim.command('bwipeout! ' + str(_b.number))
del _b
cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid)))
-for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc")', 'b.name = "!"'):
+for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")', 'b.name = "!"'):
try:
exec(expr)
except vim.error:
@@ -557,6 +586,7 @@ for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc")', 'b.name = "!"'
# Should not happen in any case
cb.append('No exception for ' + expr)
vim.command('cd .')
+del b
EOF
:augroup BUFS
: autocmd!
@@ -598,6 +628,7 @@ for b in vim.buffers:
# Check indexing: vim.buffers[number].number == number
cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b))
prevnum = b.number
+del prevnum
cb.append(str(len(vim.buffers)))
@@ -621,6 +652,8 @@ try:
next(i4)
except StopIteration:
cb.append('StopIteration')
+del i4
+del bnums
EOF
:"
:" Test vim.{tabpage,window}list and vim.{tabpage,window} objects
@@ -663,7 +696,11 @@ for t in vim.tabpages:
raise ValueError
except Exception:
cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + sys.exc_type.__name__)
+ del aval
+ del attr
w.cursor = (len(w.buffer), 0)
+del W
+del Cursor
cb.append('Number of windows in current tab page: ' + str(len(vim.windows)))
if list(vim.windows) != list(vim.current.tabpage.windows):
cb.append('!!!!!! Windows differ')
@@ -676,6 +713,7 @@ def H(o):
cb.append('Current tab page: ' + repr(vim.current.tabpage))
cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window))
cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ ' is ' + H(vim.current.tabpage.window.buffer))
+del H
# Assigning: fails
try:
vim.current.window = vim.tabpages[0].window
@@ -687,6 +725,7 @@ for attr in ('window', 'tabpage', 'buffer'):
setattr(vim.current, attr, None)
except TypeError:
cb.append('Type error at assigning None to vim.current.' + attr)
+del attr
# Assigning: success
vim.current.tabpage = vim.tabpages[-2]
@@ -702,8 +741,13 @@ ts = list(vim.tabpages)
for b in vim.buffers:
if b is not cb:
vim.command('bwipeout! ' + str(b.number))
+del b
cb.append('w.valid: ' + repr([w.valid for w in ws]))
cb.append('t.valid: ' + repr([t.valid for t in ts]))
+del w
+del t
+del ts
+del ws
EOF
:tabonly!
:only!
@@ -722,6 +766,8 @@ for expr, attr in (
('vim.current.tabpage', 'TabPage'),
):
cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr)))
+del expr
+del attr
EOF
:"
:" Test __dir__() method
@@ -747,15 +793,15 @@ EOF
:$put =string(pyeval('vim.Dictionary(a=1)'))
:$put =string(pyeval('vim.Dictionary(((''a'', 1),))'))
:$put =string(pyeval('vim.List()'))
-:$put =string(pyeval('vim.List(iter(''abc''))'))
+:$put =string(pyeval('vim.List(iter(''abc7''))'))
:$put =string(pyeval('vim.Function(''tr'')'))
:"
:" Test stdout/stderr
:redir => messages
-:py sys.stdout.write('abc') ; sys.stdout.write('def')
-:py sys.stderr.write('abc') ; sys.stderr.write('def')
-:py sys.stdout.writelines(iter('abc'))
-:py sys.stderr.writelines(iter('abc'))
+:py sys.stdout.write('abc8') ; sys.stdout.write('def')
+:py sys.stderr.write('abc9') ; sys.stderr.write('def')
+:py sys.stdout.writelines(iter('abcA'))
+:py sys.stderr.writelines(iter('abcB'))
:redir END
:$put =string(substitute(messages, '\d\+', '', 'g'))
:" Test subclassing
@@ -776,7 +822,7 @@ class DupList(vim.List):
return [super(DupList, self).__getitem__(idx)] * 2
dl = DupList()
-dl2 = DupList(iter('abc'))
+dl2 = DupList(iter('abcC'))
dl.extend(dl2[0])
class DupFun(vim.Function):
@@ -789,6 +835,19 @@ EOF
:$put =string(pyeval('dl'))
:$put =string(pyeval('dl2'))
:$put =string(pyeval('df(2)'))
+:$put =string(pyeval('dl') is# pyeval('dl'))
+:$put =string(pyeval('dd') is# pyeval('dd'))
+:$put =string(pyeval('df'))
+:delfunction Put
+py << EOF
+del DupDict
+del DupList
+del DupFun
+del dd
+del dl
+del dl2
+del df
+EOF
:"
:" Test chdir
py << EOF
@@ -802,6 +861,7 @@ cb.append(vim.eval('@%').replace(os.path.sep, '/'))
os.chdir('testdir')
cb.append(fnamemodify('.', ':p:h:t'))
cb.append(vim.eval('@%'))
+del fnamemodify
EOF
:"
:" Test errors
@@ -828,11 +888,11 @@ def ee(expr, g=globals(), l=locals()):
else:
cb.append(expr + ':NOT FAILED')
d = vim.Dictionary()
-ned = vim.Dictionary(foo='bar', baz='abc')
+ned = vim.Dictionary(foo='bar', baz='abcD')
dl = vim.Dictionary(a=1)
dl.locked = True
l = vim.List()
-ll = vim.List('abc')
+ll = vim.List('abcE')
ll.locked = True
f = vim.Function('string')
fd = vim.Function('F')
@@ -869,11 +929,11 @@ def convertfrompyobject_test(expr, recurse=True):
# pydict_to_tv
stringtochars_test(expr % '{%s : 1}')
if recurse:
- convertfrompyobject_test(expr % '{"abc" : %s}', False)
+ convertfrompyobject_test(expr % '{"abcF" : %s}', False)
# pymap_to_tv
stringtochars_test(expr % 'Mapping({%s : 1})')
if recurse:
- convertfrompyobject_test(expr % 'Mapping({"abc" : %s})', False)
+ convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False)
# pyseq_to_tv
iter_test(expr)
return subexpr_test(expr, 'ConvertFromPyObject', (
@@ -916,7 +976,7 @@ class FailingMappingKey(object):
raise NotImplementedError
def keys(self):
- return list("abc")
+ return list("abcH")
class FailingMapping(object):
def __getitem__(self):
@@ -958,7 +1018,7 @@ cb.append("> VimStrwidth")
ee('vim.strwidth(1)')
cb.append("> Dictionary")
cb.append(">> DictionaryConstructor")
-ee('vim.Dictionary("abc")')
+ee('vim.Dictionary("abcI")')
##! Not checked: py_dict_alloc failure
cb.append(">> DictionarySetattr")
ee('del d.locked')
@@ -973,6 +1033,7 @@ ee('d.pop("a")')
ee('dl.pop("a")')
cb.append(">> DictionaryIterNext")
ee('for i in ned: ned["a"] = 1')
+del i
cb.append(">> DictionaryAssItem")
ee('dl["b"] = 1')
stringtochars_test('d[%s] = 1')
@@ -1002,7 +1063,7 @@ cb.append(">> ListAssItem")
ee('ll[1] = 2')
ee('l[1000] = 3')
cb.append(">> ListAssSlice")
-ee('ll[1:100] = "abc"')
+ee('ll[1:100] = "abcJ"')
#iter_test('l[:] = %s')
convertfrompyobject_test('l[:] = [%s]')
cb.append(">> ListConcatInPlace")
@@ -1033,8 +1094,8 @@ cb.append(">> WindowSetattr")
ee('vim.current.window.buffer = 0')
ee('vim.current.window.cursor = (100000000, 100000000)')
ee('vim.current.window.cursor = True')
-ee('vim.current.window.height = "abc"')
-ee('vim.current.window.width = "abc"')
+ee('vim.current.window.height = "abcK"')
+ee('vim.current.window.width = "abcL"')
ee('vim.current.window.xxxxxx = True')
cb.append("> WinList")
cb.append(">> WinListItem")
@@ -1044,7 +1105,7 @@ cb.append(">> StringToLine (indirect)")
ee('vim.current.buffer[0] = "\\na"')
cb.append(">> SetBufferLine (indirect)")
ee('vim.current.buffer[0] = True')
-cb.append(">> SetBufferLines (indirect)")
+cb.append(">> SetBufferLineList (indirect)")
ee('vim.current.buffer[:] = True')
ee('vim.current.buffer[:] = ["\\na", "bc"]')
cb.append(">> InsertBufferLines (indirect)")
@@ -1062,7 +1123,7 @@ ee('vim.current.buffer.name = True')
ee('vim.current.buffer.xxx = True')
cb.append(">> BufferMark")
ee('vim.current.buffer.mark(0)')
-ee('vim.current.buffer.mark("abc")')
+ee('vim.current.buffer.mark("abcM")')
ee('vim.current.buffer.mark("!")')
cb.append(">> BufferRange")
ee('vim.current.buffer.range(1, 2, 3)')
@@ -1079,7 +1140,28 @@ ee('vim.current.buffer = True')
ee('vim.current.window = True')
ee('vim.current.tabpage = True')
ee('vim.current.xxx = True')
+del d
+del ned
+del dl
+del l
+del ll
+del f
+del fd
+del fdel
+del subexpr_test
+del stringtochars_test
+del Mapping
+del convertfrompyobject_test
+del convertfrompymapping_test
+del iter_test
+del FailingTrue
+del FailingIter
+del FailingIterNext
+del FailingMapping
+del FailingMappingKey
+del FailingList
EOF
+:delfunction F
:"
:" Test import
py << EOF
@@ -1093,6 +1175,10 @@ import before
cb.append(before.dir)
import after
cb.append(after.dir)
+del before
+del after
+del d
+del ddir
EOF
:"
:" Test exceptions
@@ -1101,18 +1187,48 @@ EOF
:endfun
py << EOF
Exe = vim.bindeval('function("Exe")')
-ee('vim.command("throw \'abc\'")')
+ee('vim.command("throw \'abcN\'")')
ee('Exe("throw \'def\'")')
ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")')
ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")')
ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")')
ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")')
+del Exe
+EOF
+:delfunction Exe
+:"
+:" Cleanup
+py << EOF
+del cb
+del ee
+del sys
+del os
+del vim
EOF
:endfun
:"
-:call Test()
+:fun RunTest()
+:let checkrefs = !empty($PYTHONDUMPREFS)
+:let start = getline(1, '$')
+:for i in range(checkrefs ? 10 : 1)
+: if i != 0
+: %d _
+: call setline(1, start)
+: endif
+: call Test()
+: if i == 0
+: let result = getline(1, '$')
+: endif
+:endfor
+:if checkrefs
+: %d _
+: call setline(1, result)
+:endif
+:endfun
:"
-:delfunc Test
+:call RunTest()
+:delfunction RunTest
+:delfunction Test
:call garbagecollect(1)
:"
:/^start:/,$wq! test.out
diff --git a/src/testdir/test86.ok b/src/testdir/test86.ok
index ab6017be5f..b4abcc28c9 100644
--- a/src/testdir/test86.ok
+++ b/src/testdir/test86.ok
@@ -68,7 +68,7 @@ d : locked:0;scope:0
dl : locked:1;scope:0
v: : locked:2;scope:1
g: : locked:0;scope:2
-d:{'abc': 1}
+d:{'abc2': 1}
dl:{'def': 1}
l : locked:0
ll : locked:1
@@ -202,12 +202,12 @@ jkl
B: 1:3 2:5 3:2 4:8
>>> colorcolumn
p/gopts1! KeyError
- inv: 'abc'! KeyError
+ inv: 'abc4'! KeyError
gopts1! KeyError
p/wopts1: ''
- inv: 'abc'! error
+ inv: 'abc4'! error
p/bopts1! KeyError
- inv: 'abc'! KeyError
+ inv: 'abc4'! KeyError
bopts1! KeyError
bopts2! KeyError
bopts3! KeyError
@@ -415,20 +415,23 @@ output:__dir__,__members__,flush,softspace,write,writelines
{'a': 1}
{'a': 1}
[]
-['a', 'b', 'c']
+['a', 'b', 'c', '7']
function('tr')
'
abcdef
line :
abcdef
-abc
+abcA
line :
-abc'
+abcB'
['a', 'dup_a']
['a', 'a']
-['a', 'b', 'c']
+['a', 'b', 'c', 'C']
[2, 2]
[2, 2]
+1
+1
+function('Put')
testdir
test86.in
src
@@ -456,7 +459,7 @@ vim.bindeval(1):TypeError:('expected str() or unicode() instance, but got int',)
vim.strwidth(1):TypeError:('expected str() or unicode() instance, but got int',)
> Dictionary
>> DictionaryConstructor
-vim.Dictionary("abc"):ValueError:('expected sequence element of size 2, but got sequence of size 1',)
+vim.Dictionary("abcI"):ValueError:('expected sequence element of size 2, but got sequence of size 1',)
>> DictionarySetattr
del d.locked:AttributeError:('cannot delete vim.Dictionary attributes',)
d.locked = FailingTrue():NotImplementedError:()
@@ -486,52 +489,52 @@ d["a"] = {1 : 1}:TypeError:('expected str() or unicode() instance, but got int',
d["a"] = {u"\0" : 1}:TypeError:('expected string without null bytes',)
d["a"] = {"\0" : 1}:TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing StringToChars using d["a"] = {"abc" : {%s : 1}}
-d["a"] = {"abc" : {1 : 1}}:TypeError:('expected str() or unicode() instance, but got int',)
-d["a"] = {"abc" : {u"\0" : 1}}:TypeError:('expected string without null bytes',)
-d["a"] = {"abc" : {"\0" : 1}}:TypeError:('expected string without null bytes',)
+>>> Testing StringToChars using d["a"] = {"abcF" : {%s : 1}}
+d["a"] = {"abcF" : {1 : 1}}:TypeError:('expected str() or unicode() instance, but got int',)
+d["a"] = {"abcF" : {u"\0" : 1}}:TypeError:('expected string without null bytes',)
+d["a"] = {"abcF" : {"\0" : 1}}:TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing StringToChars using d["a"] = {"abc" : Mapping({%s : 1})}
-d["a"] = {"abc" : Mapping({1 : 1})}:TypeError:('expected str() or unicode() instance, but got int',)
-d["a"] = {"abc" : Mapping({u"\0" : 1})}:TypeError:('expected string without null bytes',)
-d["a"] = {"abc" : Mapping({"\0" : 1})}:TypeError:('expected string without null bytes',)
+>>> Testing StringToChars using d["a"] = {"abcF" : Mapping({%s : 1})}
+d["a"] = {"abcF" : Mapping({1 : 1})}:TypeError:('expected str() or unicode() instance, but got int',)
+d["a"] = {"abcF" : Mapping({u"\0" : 1})}:TypeError:('expected string without null bytes',)
+d["a"] = {"abcF" : Mapping({"\0" : 1})}:TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing *Iter* using d["a"] = {"abc" : %s}
-d["a"] = {"abc" : FailingIter()}:TypeError:('unable to convert FailingIter to vim structure',)
-d["a"] = {"abc" : FailingIterNext()}:NotImplementedError:()
+>>> Testing *Iter* using d["a"] = {"abcF" : %s}
+d["a"] = {"abcF" : FailingIter()}:TypeError:('unable to convert FailingIter to vim structure',)
+d["a"] = {"abcF" : FailingIterNext()}:NotImplementedError:()
<<< Finished
->>> Testing ConvertFromPyObject using d["a"] = {"abc" : %s}
-d["a"] = {"abc" : None}:TypeError:('unable to convert NoneType to vim structure',)
-d["a"] = {"abc" : {"": 1}}:ValueError:('empty keys are not allowed',)
-d["a"] = {"abc" : {u"": 1}}:ValueError:('empty keys are not allowed',)
-d["a"] = {"abc" : FailingMapping()}:NotImplementedError:()
-d["a"] = {"abc" : FailingMappingKey()}:NotImplementedError:()
+>>> Testing ConvertFromPyObject using d["a"] = {"abcF" : %s}
+d["a"] = {"abcF" : None}:TypeError:('unable to convert NoneType to vim structure',)
+d["a"] = {"abcF" : {"": 1}}:ValueError:('empty keys are not allowed',)
+d["a"] = {"abcF" : {u"": 1}}:ValueError:('empty keys are not allowed',)
+d["a"] = {"abcF" : FailingMapping()}:NotImplementedError:()
+d["a"] = {"abcF" : FailingMappingKey()}:NotImplementedError:()
<<< Finished
>>> Testing StringToChars using d["a"] = Mapping({%s : 1})
d["a"] = Mapping({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
d["a"] = Mapping({u"\0" : 1}):TypeError:('expected string without null bytes',)
d["a"] = Mapping({"\0" : 1}):TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing StringToChars using d["a"] = Mapping({"abc" : {%s : 1}})
-d["a"] = Mapping({"abc" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
-d["a"] = Mapping({"abc" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
-d["a"] = Mapping({"abc" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
+>>> Testing StringToChars using d["a"] = Mapping({"abcG" : {%s : 1}})
+d["a"] = Mapping({"abcG" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
+d["a"] = Mapping({"abcG" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
+d["a"] = Mapping({"abcG" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing StringToChars using d["a"] = Mapping({"abc" : Mapping({%s : 1})})
-d["a"] = Mapping({"abc" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
-d["a"] = Mapping({"abc" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
-d["a"] = Mapping({"abc" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
+>>> Testing StringToChars using d["a"] = Mapping({"abcG" : Mapping({%s : 1})})
+d["a"] = Mapping({"abcG" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
+d["a"] = Mapping({"abcG" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
+d["a"] = Mapping({"abcG" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing *Iter* using d["a"] = Mapping({"abc" : %s})
-d["a"] = Mapping({"abc" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
-d["a"] = Mapping({"abc" : FailingIterNext()}):NotImplementedError:()
+>>> Testing *Iter* using d["a"] = Mapping({"abcG" : %s})
+d["a"] = Mapping({"abcG" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
+d["a"] = Mapping({"abcG" : FailingIterNext()}):NotImplementedError:()
<<< Finished
->>> Testing ConvertFromPyObject using d["a"] = Mapping({"abc" : %s})
-d["a"] = Mapping({"abc" : None}):TypeError:('unable to convert NoneType to vim structure',)
-d["a"] = Mapping({"abc" : {"": 1}}):ValueError:('empty keys are not allowed',)
-d["a"] = Mapping({"abc" : {u"": 1}}):ValueError:('empty keys are not allowed',)
-d["a"] = Mapping({"abc" : FailingMapping()}):NotImplementedError:()
-d["a"] = Mapping({"abc" : FailingMappingKey()}):NotImplementedError:()
+>>> Testing ConvertFromPyObject using d["a"] = Mapping({"abcG" : %s})
+d["a"] = Mapping({"abcG" : None}):TypeError:('unable to convert NoneType to vim structure',)
+d["a"] = Mapping({"abcG" : {"": 1}}):ValueError:('empty keys are not allowed',)
+d["a"] = Mapping({"abcG" : {u"": 1}}):ValueError:('empty keys are not allowed',)
+d["a"] = Mapping({"abcG" : FailingMapping()}):NotImplementedError:()
+d["a"] = Mapping({"abcG" : FailingMappingKey()}):NotImplementedError:()
<<< Finished
>>> Testing *Iter* using d["a"] = %s
d["a"] = FailingIter():TypeError:('unable to convert FailingIter to vim structure',)
@@ -554,52 +557,52 @@ d.update({1 : 1}):TypeError:('expected str() or unicode() instance, but got int'
d.update({u"\0" : 1}):TypeError:('expected string without null bytes',)
d.update({"\0" : 1}):TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing StringToChars using d.update({"abc" : {%s : 1}})
-d.update({"abc" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
-d.update({"abc" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
-d.update({"abc" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
+>>> Testing StringToChars using d.update({"abcF" : {%s : 1}})
+d.update({"abcF" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
+d.update({"abcF" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
+d.update({"abcF" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing StringToChars using d.update({"abc" : Mapping({%s : 1})})
-d.update({"abc" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
-d.update({"abc" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
-d.update({"abc" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
+>>> Testing StringToChars using d.update({"abcF" : Mapping({%s : 1})})
+d.update({"abcF" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
+d.update({"abcF" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
+d.update({"abcF" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing *Iter* using d.update({"abc" : %s})
-d.update({"abc" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
-d.update({"abc" : FailingIterNext()}):NotImplementedError:()
+>>> Testing *Iter* using d.update({"abcF" : %s})
+d.update({"abcF" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
+d.update({"abcF" : FailingIterNext()}):NotImplementedError:()
<<< Finished
->>> Testing ConvertFromPyObject using d.update({"abc" : %s})
-d.update({"abc" : None}):TypeError:('unable to convert NoneType to vim structure',)
-d.update({"abc" : {"": 1}}):ValueError:('empty keys are not allowed',)
-d.update({"abc" : {u"": 1}}):ValueError:('empty keys are not allowed',)
-d.update({"abc" : FailingMapping()}):NotImplementedError:()
-d.update({"abc" : FailingMappingKey()}):NotImplementedError:()
+>>> Testing ConvertFromPyObject using d.update({"abcF" : %s})
+d.update({"abcF" : None}):TypeError:('unable to convert NoneType to vim structure',)
+d.update({"abcF" : {"": 1}}):ValueError:('empty keys are not allowed',)
+d.update({"abcF" : {u"": 1}}):ValueError:('empty keys are not allowed',)
+d.update({"abcF" : FailingMapping()}):NotImplementedError:()
+d.update({"abcF" : FailingMappingKey()}):NotImplementedError:()
<<< Finished
>>> Testing StringToChars using d.update(Mapping({%s : 1}))
d.update(Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',)
d.update(Mapping({u"\0" : 1})):TypeError:('expected string without null bytes',)
d.update(Mapping({"\0" : 1})):TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing StringToChars using d.update(Mapping({"abc" : {%s : 1}}))
-d.update(Mapping({"abc" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',)
-d.update(Mapping({"abc" : {u"\0" : 1}})):TypeError:('expected string without null bytes',)
-d.update(Mapping({"abc" : {"\0" : 1}})):TypeError:('expected string without null bytes',)
+>>> Testing StringToChars using d.update(Mapping({"abcG" : {%s : 1}}))
+d.update(Mapping({"abcG" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',)
+d.update(Mapping({"abcG" : {u"\0" : 1}})):TypeError:('expected string without null bytes',)
+d.update(Mapping({"abcG" : {"\0" : 1}})):TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing StringToChars using d.update(Mapping({"abc" : Mapping({%s : 1})}))
-d.update(Mapping({"abc" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',)
-d.update(Mapping({"abc" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',)
-d.update(Mapping({"abc" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',)
+>>> Testing StringToChars using d.update(Mapping({"abcG" : Mapping({%s : 1})}))
+d.update(Mapping({"abcG" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',)
+d.update(Mapping({"abcG" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',)
+d.update(Mapping({"abcG" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing *Iter* using d.update(Mapping({"abc" : %s}))
-d.update(Mapping({"abc" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',)
-d.update(Mapping({"abc" : FailingIterNext()})):NotImplementedError:()
+>>> Testing *Iter* using d.update(Mapping({"abcG" : %s}))
+d.update(Mapping({"abcG" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',)
+d.update(Mapping({"abcG" : FailingIterNext()})):NotImplementedError:()
<<< Finished
->>> Testing ConvertFromPyObject using d.update(Mapping({"abc" : %s}))
-d.update(Mapping({"abc" : None})):TypeError:('unable to convert NoneType to vim structure',)
-d.update(Mapping({"abc" : {"": 1}})):ValueError:('empty keys are not allowed',)
-d.update(Mapping({"abc" : {u"": 1}})):ValueError:('empty keys are not allowed',)
-d.update(Mapping({"abc" : FailingMapping()})):NotImplementedError:()
-d.update(Mapping({"abc" : FailingMappingKey()})):NotImplementedError:()
+>>> Testing ConvertFromPyObject using d.update(Mapping({"abcG" : %s}))
+d.update(Mapping({"abcG" : None})):TypeError:('unable to convert NoneType to vim structure',)
+d.update(Mapping({"abcG" : {"": 1}})):ValueError:('empty keys are not allowed',)
+d.update(Mapping({"abcG" : {u"": 1}})):ValueError:('empty keys are not allowed',)
+d.update(Mapping({"abcG" : FailingMapping()})):NotImplementedError:()
+d.update(Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:()
<<< Finished
>>> Testing *Iter* using d.update(%s)
d.update(FailingIter()):NotImplementedError:()
@@ -622,52 +625,52 @@ d.update((("a", {1 : 1}),)):TypeError:('expected str() or unicode() instance, bu
d.update((("a", {u"\0" : 1}),)):TypeError:('expected string without null bytes',)
d.update((("a", {"\0" : 1}),)):TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing StringToChars using d.update((("a", {"abc" : {%s : 1}}),))
-d.update((("a", {"abc" : {1 : 1}}),)):TypeError:('expected str() or unicode() instance, but got int',)
-d.update((("a", {"abc" : {u"\0" : 1}}),)):TypeError:('expected string without null bytes',)
-d.update((("a", {"abc" : {"\0" : 1}}),)):TypeError:('expected string without null bytes',)
+>>> Testing StringToChars using d.update((("a", {"abcF" : {%s : 1}}),))
+d.update((("a", {"abcF" : {1 : 1}}),)):TypeError:('expected str() or unicode() instance, but got int',)
+d.update((("a", {"abcF" : {u"\0" : 1}}),)):TypeError:('expected string without null bytes',)
+d.update((("a", {"abcF" : {"\0" : 1}}),)):TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing StringToChars using d.update((("a", {"abc" : Mapping({%s : 1})}),))
-d.update((("a", {"abc" : Mapping({1 : 1})}),)):TypeError:('expected str() or unicode() instance, but got int',)
-d.update((("a", {"abc" : Mapping({u"\0" : 1})}),)):TypeError:('expected string without null bytes',)
-d.update((("a", {"abc" : Mapping({"\0" : 1})}),)):TypeError:('expected string without null bytes',)
+>>> Testing StringToChars using d.update((("a", {"abcF" : Mapping({%s : 1})}),))
+d.update((("a", {"abcF" : Mapping({1 : 1})}),)):TypeError:('expected str() or unicode() instance, but got int',)
+d.update((("a", {"abcF" : Mapping({u"\0" : 1})}),)):TypeError:('expected string without null bytes',)
+d.update((("a", {"abcF" : Mapping({"\0" : 1})}),)):TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing *Iter* using d.update((("a", {"abc" : %s}),))
-d.update((("a", {"abc" : FailingIter()}),)):TypeError:('unable to convert FailingIter to vim structure',)
-d.update((("a", {"abc" : FailingIterNext()}),)):NotImplementedError:()
+>>> Testing *Iter* using d.update((("a", {"abcF" : %s}),))
+d.update((("a", {"abcF" : FailingIter()}),)):TypeError:('unable to convert FailingIter to vim structure',)
+d.update((("a", {"abcF" : FailingIterNext()}),)):NotImplementedError:()
<<< Finished
->>> Testing ConvertFromPyObject using d.update((("a", {"abc" : %s}),))
-d.update((("a", {"abc" : None}),)):TypeError:('unable to convert NoneType to vim structure',)
-d.update((("a", {"abc" : {"": 1}}),)):ValueError:('empty keys are not allowed',)
-d.update((("a", {"abc" : {u"": 1}}),)):ValueError:('empty keys are not allowed',)
-d.update((("a", {"abc" : FailingMapping()}),)):NotImplementedError:()
-d.update((("a", {"abc" : FailingMappingKey()}),)):NotImplementedError:()
+>>> Testing ConvertFromPyObject using d.update((("a", {"abcF" : %s}),))
+d.update((("a", {"abcF" : None}),)):TypeError:('unable to convert NoneType to vim structure',)
+d.update((("a", {"abcF" : {"": 1}}),)):ValueError:('empty keys are not allowed',)
+d.update((("a", {"abcF" : {u"": 1}}),)):ValueError:('empty keys are not allowed',)
+d.update((("a", {"abcF" : FailingMapping()}),)):NotImplementedError:()
+d.update((("a", {"abcF" : FailingMappingKey()}),)):NotImplementedError:()
<<< Finished
>>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),))
d.update((("a", Mapping({1 : 1})),)):TypeError:('expected str() or unicode() instance, but got int',)
d.update((("a", Mapping({u"\0" : 1})),)):TypeError:('expected string without null bytes',)
d.update((("a", Mapping({"\0" : 1})),)):TypeError:('expected string without null bytes',)
<<< Finished
->>> Testing StringToChars using d.update((("a", Mapping({"abc" : {%s : 1}})),))
-d.update((("a", Mapping({"abc" : {1 : 1}})),)):TypeError:('expected str() or unicode() instance, but got int',)
-d.update((("a", Mapping({"abc" : {u"\0" : 1}})),)):TypeError:('expected string without null bytes',)
-d.update((("a", Mapping({"abc" : {"\0" : 1}})),)):TypeError:('expected string without null bytes',)
+>>> Testing StringToChars using d.update((("a", Mapping({"abcG" : {%s : 1}})),))
+d.update((("a", Mapping({"abcG" : {1 : 1}})),)):TypeError:('expected str() or unicode() instance, but got int',)
+d.upda