neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

test_python3.vim (154499B)


      1 " Test for python 3 commands.
      2 
      3 source check.vim
      4 CheckFeature python3
      5 
      6 " This function should be called first. This sets up python functions used by
      7 " the other tests.
      8 func Test_AAA_python3_setup()
      9  py3 << trim EOF
     10    import vim
     11    import sys
     12    import re
     13 
     14    py33_type_error_pattern = re.compile(r'^__call__\(\) takes (\d+) positional argument but (\d+) were given$')
     15    py37_exception_repr = re.compile(r'([^\(\),])(\)+)$')
     16    py39_type_error_pattern = re.compile(r'\w+\.([^(]+\(\) takes)')
     17    py310_type_error_pattern = re.compile(r'takes (\d+) positional argument but (\d+) were given')
     18    py314_type_error_tuple_pattern = re.compile(r'must be (\d+)-item tuple')
     19 
     20    def emsg(ei):
     21      return ei[0].__name__ + ':' + repr(ei[1].args)
     22 
     23    def ee(expr, g=globals(), l=locals()):
     24        cb = vim.current.buffer
     25        try:
     26            try:
     27                exec(expr, g, l)
     28            except Exception as e:
     29                if sys.version_info >= (3, 3) and e.__class__ is AttributeError and str(e).find('has no attribute')>=0 and not str(e).startswith("'vim."):
     30                    msg = repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1])))
     31                elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0:
     32                    msg = repr((e.__class__, ImportError(str(e).replace("'", ''))))
     33                elif sys.version_info >= (3, 6) and e.__class__ is ModuleNotFoundError:
     34                    # Python 3.6 gives ModuleNotFoundError, change it to an ImportError
     35                    msg = repr((ImportError, ImportError(str(e).replace("'", ''))))
     36                elif sys.version_info >= (3, 3) and e.__class__ is TypeError:
     37                    m = py33_type_error_pattern.search(str(e))
     38                    if m:
     39                        msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2))
     40                        msg = repr((e.__class__, TypeError(msg)))
     41                    else:
     42                        msg = repr((e.__class__, e))
     43                        # Messages changed with Python 3.6, change new to old.
     44                        newmsg1 = """'argument must be str, bytes or bytearray, not None'"""
     45                        oldmsg1 = '''"Can't convert 'NoneType' object to str implicitly"'''
     46                        if msg.find(newmsg1) > -1:
     47                            msg = msg.replace(newmsg1, oldmsg1)
     48                        newmsg2 = """'argument must be str, bytes or bytearray, not int'"""
     49                        oldmsg2 = '''"Can't convert 'int' object to str implicitly"'''
     50                        if msg.find(newmsg2) > -1:
     51                            msg = msg.replace(newmsg2, oldmsg2)
     52                        # Python 3.9 reports errors like "vim.command() takes ..." instead of "command() takes ..."
     53                        msg = py39_type_error_pattern.sub(r'\1', msg)
     54                        msg = py310_type_error_pattern.sub(r'takes exactly \1 positional argument (\2 given)', msg)
     55                        # Python 3.14 has specific error messages for Tuple's
     56                        msg = py314_type_error_tuple_pattern.sub(r'must be \1-item sequence', msg)
     57                elif sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte':
     58                    msg = repr((TypeError, TypeError('expected bytes with no null')))
     59                else:
     60                    msg = repr((e.__class__, e))
     61                    # Some Python versions say can't, others cannot.
     62                    if msg.find('can\'t') > -1:
     63                        msg = msg.replace('can\'t', 'cannot')
     64                    # Some Python versions use single quote, some double quote
     65                    if msg.find('"cannot ') > -1:
     66                        msg = msg.replace('"cannot ', '\'cannot ')
     67                    if msg.find(' attributes"') > -1:
     68                        msg = msg.replace(' attributes"', ' attributes\'')
     69                if sys.version_info >= (3, 7):
     70                    msg = py37_exception_repr.sub(r'\1,\2', msg)
     71                cb.append(expr + ':' + msg)
     72            else:
     73                cb.append(expr + ':NOT FAILED')
     74        except Exception as e:
     75            msg = repr((e.__class__, e))
     76            if sys.version_info >= (3, 7):
     77                msg = py37_exception_repr.sub(r'\1,\2', msg)
     78            cb.append(expr + '::' + msg)
     79  EOF
     80 endfunc
     81 
     82 func Test_py3do()
     83  " Check deleting lines does not trigger an ml_get error.
     84  py3 import vim
     85  new
     86  call setline(1, ['one', 'two', 'three'])
     87  py3do vim.command("%d_")
     88  bwipe!
     89 
     90  " Disabled until neovim/neovim#8554 is resolved
     91  if 0
     92    " Check switching to another buffer does not trigger an ml_get error.
     93    new
     94    let wincount = winnr('$')
     95    call setline(1, ['one', 'two', 'three'])
     96    py3do vim.command("new")
     97    call assert_equal(wincount + 1, winnr('$'))
     98    bwipe!
     99    bwipe!
    100  endif
    101 endfunc
    102 
    103 func Test_set_cursor()
    104  " Check that setting the cursor position works.
    105  py3 import vim
    106  new
    107  call setline(1, ['first line', 'second line'])
    108  normal gg
    109  py3do vim.current.window.cursor = (1, 5)
    110  call assert_equal([1, 6], [line('.'), col('.')])
    111 
    112  " Check that movement after setting cursor position keeps current column.
    113  normal j
    114  call assert_equal([2, 6], [line('.'), col('.')])
    115 endfunc
    116 
    117 func Test_vim_function()
    118  throw 'Skipped: Nvim does not support vim.bindeval()'
    119  " Check creating vim.Function object
    120  py3 import vim
    121 
    122  func s:foo()
    123    return matchstr(expand('<sfile>'), '<SNR>\zs\d\+_foo$')
    124  endfunc
    125  let name = '<SNR>' . s:foo()
    126 
    127  try
    128    py3 f = vim.bindeval('function("s:foo")')
    129    call assert_equal(name, py3eval('f.name'))
    130  catch
    131    call assert_false(v:exception)
    132  endtry
    133 
    134  try
    135    py3 f = vim.Function(b'\x80\xfdR' + vim.eval('s:foo()').encode())
    136    call assert_equal(name, 'f.name'->py3eval())
    137  catch
    138    call assert_false(v:exception)
    139  endtry
    140 
    141  let caught_vim_err = v:false
    142  try
    143    let x = py3eval('f.abc')
    144  catch
    145    call assert_match("AttributeError: 'vim.function' object has no attribute 'abc'", v:exception)
    146    let caught_vim_err = v:true
    147  endtry
    148  call assert_equal(v:true, caught_vim_err)
    149 
    150  py3 del f
    151  delfunc s:foo
    152 endfunc
    153 
    154 func Test_skipped_python3_command_does_not_affect_pyxversion()
    155  throw 'Skipped: Nvim hardcodes pyxversion=3'
    156  set pyxversion=0
    157  if 0
    158    python3 import vim
    159  endif
    160  call assert_equal(0, &pyxversion)  " This assertion would have failed with Vim 8.0.0251. (pyxversion was introduced in 8.0.0251.)
    161 endfunc
    162 
    163 func _SetUpHiddenBuffer()
    164  py3 import vim
    165  new
    166  edit hidden
    167  setlocal bufhidden=hide
    168 
    169  enew
    170  let lnum = 0
    171  while lnum < 10
    172    call append( 1, string( lnum ) )
    173    let lnum = lnum + 1
    174  endwhile
    175  normal G
    176 
    177  call assert_equal( line( '.' ), 11 )
    178 endfunc
    179 
    180 func _CleanUpHiddenBuffer()
    181  bwipe! hidden
    182  bwipe!
    183 endfunc
    184 
    185 func Test_Write_To_HiddenBuffer_Does_Not_Fix_Cursor_Clear()
    186  call _SetUpHiddenBuffer()
    187  py3 vim.buffers[ int( vim.eval( 'bufnr("hidden")' ) ) ][:] = None
    188  call assert_equal( line( '.' ), 11 )
    189  call _CleanUpHiddenBuffer()
    190 endfunc
    191 
    192 func Test_Write_To_HiddenBuffer_Does_Not_Fix_Cursor_List()
    193  call _SetUpHiddenBuffer()
    194  py3 vim.buffers[ int( vim.eval( 'bufnr("hidden")' ) ) ][:] = [ 'test' ]
    195  call assert_equal( line( '.' ), 11 )
    196  call _CleanUpHiddenBuffer()
    197 endfunc
    198 
    199 func Test_Write_To_HiddenBuffer_Does_Not_Fix_Cursor_Str()
    200  call _SetUpHiddenBuffer()
    201  py3 vim.buffers[ int( vim.eval( 'bufnr("hidden")' ) ) ][0] = 'test'
    202  call assert_equal( line( '.' ), 11 )
    203  call _CleanUpHiddenBuffer()
    204 endfunc
    205 
    206 func Test_Write_To_HiddenBuffer_Does_Not_Fix_Cursor_ClearLine()
    207  call _SetUpHiddenBuffer()
    208  py3 vim.buffers[ int( vim.eval( 'bufnr("hidden")' ) ) ][0] = None
    209  call assert_equal( line( '.' ), 11 )
    210  call _CleanUpHiddenBuffer()
    211 endfunc
    212 
    213 func _SetUpVisibleBuffer()
    214  py3 import vim
    215  new
    216  let lnum = 0
    217  while lnum < 10
    218    call append( 1, string( lnum ) )
    219    let lnum = lnum + 1
    220  endwhile
    221  normal G
    222  call assert_equal( line( '.' ), 11 )
    223 endfunc
    224 
    225 func Test_Write_To_Current_Buffer_Fixes_Cursor_Clear()
    226  call _SetUpVisibleBuffer()
    227 
    228  py3 vim.current.buffer[:] = None
    229  call assert_equal( line( '.' ), 1 )
    230 
    231  bwipe!
    232 endfunc
    233 
    234 func Test_Write_To_Current_Buffer_Fixes_Cursor_List()
    235  call _SetUpVisibleBuffer()
    236 
    237  py3 vim.current.buffer[:] = [ 'test' ]
    238  call assert_equal( line( '.' ), 1 )
    239 
    240  bwipe!
    241 endfunc
    242 
    243 func Test_Write_To_Current_Buffer_Fixes_Cursor_Str()
    244  call _SetUpVisibleBuffer()
    245 
    246  py3 vim.current.buffer[-1] = None
    247  call assert_equal( line( '.' ), 10 )
    248 
    249  bwipe!
    250 endfunc
    251 
    252 func Test_Catch_Exception_Message()
    253  try
    254    py3 raise RuntimeError( 'TEST' )
    255  catch /.*/
    256    call assert_match('^Vim(.*):.*RuntimeError: TEST.*$', v:exception )
    257  endtry
    258 endfunc
    259 
    260 func Test_unicode()
    261  " this crashed Vim once
    262  throw "Skipped: nvim does not support changing 'encoding'"
    263 
    264  set encoding=utf32
    265  py3 print('hello')
    266 
    267  if !has('win32')
    268    set encoding=debug
    269    py3 print('hello')
    270 
    271    set encoding=euc-tw
    272    py3 print('hello')
    273  endif
    274 
    275  set encoding=utf8
    276 endfunc
    277 
    278 " Test vim.eval() with various types.
    279 func Test_python3_vim_eval()
    280  call assert_equal("\n2061300532912", execute('py3 print(vim.eval("2061300532912"))'))
    281  call assert_equal("\n9223372036854775807", execute('py3 print(vim.eval("9223372036854775807"))'))
    282  call assert_equal("\n-9223372036854775807",execute('py3 print(vim.eval("-9223372036854775807"))'))
    283  call assert_equal("\n2147483648",  execute('py3 print(vim.eval("2147483648"))'))
    284  call assert_equal("\n-2147483649", execute('py3 print(vim.eval("-2147483649"))'))
    285  call assert_equal("\n8",           execute('py3 print(vim.eval("3+5"))'))
    286  if has('float')
    287    call assert_equal("\n3.1399999999999997",    execute('py3 print(vim.eval("1.01+2.13"))'))
    288    call assert_equal("\n0.0",    execute('py3 print(vim.eval("0.0/(1.0/0.0)"))'))
    289    call assert_equal("\n0.0",    execute('py3 print(vim.eval("0.0/(1.0/0.0)"))'))
    290    call assert_equal("\n-0.0",   execute('py3 print(vim.eval("0.0/(-1.0/0.0)"))'))
    291    " Commented out: output of infinity and nan depend on platforms.
    292    " call assert_equal("\ninf",         execute('py3 print(vim.eval("1.0/0.0"))'))
    293    " call assert_equal("\n-inf",        execute('py3 print(vim.eval("-1.0/0.0"))'))
    294    " call assert_equal("\n-nan",        execute('py3 print(vim.eval("0.0/0.0"))'))
    295  endif
    296  call assert_equal("\nabc",           execute('py3 print(vim.eval("\"abc\""))'))
    297  call assert_equal("\n['1', '2']",    execute('py3 print(vim.eval("[1, 2]"))'))
    298  call assert_equal("\n{'1': '2'}",    execute('py3 print(vim.eval("{1:2}"))'))
    299  call assert_equal("\nTrue",          execute('py3 print(vim.eval("v:true"))'))
    300  call assert_equal("\nFalse",         execute('py3 print(vim.eval("v:false"))'))
    301  call assert_equal("\nNone",          execute('py3 print(vim.eval("v:null"))'))
    302  " call assert_equal("\nNone",          execute('py3 print(vim.eval("v:none"))'))
    303  " call assert_equal("\nb'\\xab\\x12'", execute('py3 print(vim.eval("0zab12"))'))
    304 
    305  call assert_fails('py3 vim.eval("1+")', 'E5108:')
    306 endfunc
    307 
    308 " Test for resetting options with local values to global values
    309 func Test_python3_opt_reset_local_to_global()
    310  throw 'Skipped: Nvim does not support vim.bindeval()'
    311  new
    312 
    313  py3 curbuf = vim.current.buffer
    314  py3 curwin = vim.current.window
    315 
    316  " List of buffer-local options. Each list item has [option name, global
    317  " value, buffer-local value, buffer-local value after reset] to use in the
    318  " test.
    319  let bopts = [
    320        \ ['autoread', 1, 0, -1],
    321        \ ['equalprg', 'geprg', 'leprg', ''],
    322        \ ['keywordprg', 'gkprg', 'lkprg', ''],
    323        \ ['path', 'gpath', 'lpath', ''],
    324        \ ['backupcopy', 'yes', 'no', ''],
    325        \ ['tags', 'gtags', 'ltags', ''],
    326        \ ['tagcase', 'ignore', 'match', ''],
    327        \ ['define', 'gdef', 'ldef', ''],
    328        \ ['include', 'ginc', 'linc', ''],
    329        \ ['dict', 'gdict', 'ldict', ''],
    330        \ ['thesaurus', 'gtsr', 'ltsr', ''],
    331        \ ['formatprg', 'gfprg', 'lfprg', ''],
    332        \ ['errorformat', '%f:%l:%m', '%s-%l-%m', ''],
    333        \ ['grepprg', 'ggprg', 'lgprg', ''],
    334        \ ['makeprg', 'gmprg', 'lmprg', ''],
    335        \ ['balloonexpr', 'gbexpr', 'lbexpr', ''],
    336        \ ['cryptmethod', 'blowfish2', 'zip', ''],
    337        \ ['lispwords', 'abc', 'xyz', ''],
    338        \ ['makeencoding', 'utf-8', 'latin1', ''],
    339        \ ['undolevels', 100, 200, -123456]]
    340 
    341  " Set the global and buffer-local option values and then clear the
    342  " buffer-local option value.
    343  for opt in bopts
    344    py3 << trim END
    345      pyopt = vim.bindeval("opt")
    346      vim.options[pyopt[0]] = pyopt[1]
    347      curbuf.options[pyopt[0]] = pyopt[2]
    348    END
    349    exe "call assert_equal(opt[2], &" .. opt[0] .. ")"
    350    exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")"
    351    exe "call assert_equal(opt[2], &l:" .. opt[0] .. ")"
    352    py3 del curbuf.options[pyopt[0]]
    353    exe "call assert_equal(opt[1], &" .. opt[0] .. ")"
    354    exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")"
    355    exe "call assert_equal(opt[3], &l:" .. opt[0] .. ")"
    356    exe "set " .. opt[0] .. "&"
    357  endfor
    358 
    359  " Set the global and window-local option values and then clear the
    360  " window-local option value.
    361  let wopts = [
    362        \ ['scrolloff', 5, 10, -1],
    363        \ ['sidescrolloff', 6, 12, -1],
    364        \ ['statusline', '%<%f', '%<%F', '']]
    365  for opt in wopts
    366    py3 << trim
    367      pyopt = vim.bindeval("opt")
    368      vim.options[pyopt[0]] = pyopt[1]
    369      curwin.options[pyopt[0]] = pyopt[2]
    370    .
    371    exe "call assert_equal(opt[2], &" .. opt[0] .. ")"
    372    exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")"
    373    exe "call assert_equal(opt[2], &l:" .. opt[0] .. ")"
    374    py3 del curwin.options[pyopt[0]]
    375    exe "call assert_equal(opt[1], &" .. opt[0] .. ")"
    376    exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")"
    377    exe "call assert_equal(opt[3], &l:" .. opt[0] .. ")"
    378    exe "set " .. opt[0] .. "&"
    379  endfor
    380 
    381  close!
    382 endfunc
    383 
    384 " Test for various heredoc syntax
    385 func Test_python3_heredoc()
    386  python3 << END
    387 s='A'
    388 END
    389  python3 <<
    390 s+='B'
    391 .
    392  python3 << trim END
    393    s+='C'
    394  END
    395  python3 << trim
    396    s+='D'
    397  .
    398  python3 << trim eof
    399    s+='E'
    400  eof
    401  python3 << trimm
    402 s+='F'
    403 trimm
    404  call assert_equal('ABCDEF', pyxeval('s'))
    405 endfunc
    406 
    407 " Test for the python List object
    408 func Test_python3_list()
    409  throw 'Skipped: Nvim does not support vim.bindeval()'
    410  let l = []
    411  py3 l = vim.bindeval('l')
    412  py3 f = vim.bindeval('function("strlen")')
    413  " Extending List directly with different types
    414  py3 l += [1, "as'd", [1, 2, f, {'a': 1}]]
    415  call assert_equal([1, "as'd", [1, 2, function("strlen"), {'a': 1}]], l)
    416  call assert_equal([1, 2, function("strlen"), {'a': 1}], l[-1])
    417  call assert_fails('echo l[-4]', 'E684:')
    418 
    419  " List assignment
    420  py3 l[0] = 0
    421  call assert_equal([0, "as'd", [1, 2, function("strlen"), {'a': 1}]], l)
    422  py3 l[-2] = f
    423  call assert_equal([0, function("strlen"), [1, 2, function("strlen"), {'a': 1}]], l)
    424 endfunc
    425 
    426 " Extending Dictionary directly with different types
    427 func Test_python3_dict_extend()
    428  throw 'Skipped: Nvim does not support vim.bindeval()'
    429  let d = {}
    430  func d.f()
    431    return 1
    432  endfunc
    433 
    434  py3 f = vim.bindeval('function("strlen")')
    435  py3 << trim EOF
    436    d = vim.bindeval('d')
    437    d['1'] = 'asd'
    438    d.update()  # Must not do anything, including throwing errors
    439    d.update(b = [1, 2, f])
    440    d.update((('-1', {'a': 1}),))
    441    d.update({'0': -1})
    442    dk = d.keys()
    443    dv = d.values()
    444    di = d.items()
    445    dk.sort(key=repr)
    446    dv.sort(key=repr)
    447    di.sort(key=repr)
    448  EOF
    449 
    450  call assert_equal(1, py3eval("d['f'](self={})"))
    451  call assert_equal("[b'-1', b'0', b'1', b'b', b'f']", py3eval('repr(dk)'))
    452  call assert_equal("[-1, <vim.Function '1'>, <vim.dictionary object at >, <vim.list object at >, b'asd']", substitute(py3eval('repr(dv)'),'0x\x\+','','g'))
    453  call assert_equal("[(b'-1', <vim.dictionary object at >), (b'0', -1), (b'1', b'asd'), (b'b', <vim.list object at >), (b'f', <vim.Function '1'>)]", substitute(py3eval('repr(di)'),'0x\x\+','','g'))
    454  call assert_equal(['0', '1', 'b', 'f', '-1'], keys(d))
    455  call assert_equal("[-1, 'asd', [1, 2, function('strlen')], function('1'), {'a': 1}]", string(values(d)))
    456  py3 del dk
    457  py3 del di
    458  py3 del dv
    459 endfunc
    460 
    461 func Test_python3_list_del_items()
    462  throw 'Skipped: Nvim does not support vim.bindeval()'
    463  " removing items with del
    464  let l = [0, function("strlen"), [1, 2, function("strlen"), {'a': 1}]]
    465  py3 l = vim.bindeval('l')
    466  py3 del l[2]
    467  call assert_equal("[0, function('strlen')]", string(l))
    468 
    469  let l = range(8)
    470  py3 l = vim.bindeval('l')
    471  py3 del l[:3]
    472  py3 del l[1:]
    473  call assert_equal([3], l)
    474 
    475  " removing items out of range: silently skip items that don't exist
    476 
    477  " The following two ranges delete nothing as they match empty list:
    478  let l = [0, 1, 2, 3]
    479  py3 l = vim.bindeval('l')
    480  py3 del l[2:1]
    481  call assert_equal([0, 1, 2, 3], l)
    482  py3 del l[2:2]
    483  call assert_equal([0, 1, 2, 3], l)
    484  py3 del l[2:3]
    485  call assert_equal([0, 1, 3], l)
    486 
    487  let l = [0, 1, 2, 3]
    488  py3 l = vim.bindeval('l')
    489  py3 del l[2:4]
    490  call assert_equal([0, 1], l)
    491 
    492  let l = [0, 1, 2, 3]
    493  py3 l = vim.bindeval('l')
    494  py3 del l[2:5]
    495  call assert_equal([0, 1], l)
    496 
    497  let l = [0, 1, 2, 3]
    498  py3 l = vim.bindeval('l')
    499  py3 del l[2:6]
    500  call assert_equal([0, 1], l)
    501 
    502  " The following two ranges delete nothing as they match empty list:
    503  let l = [0, 1, 2, 3]
    504  py3 l = vim.bindeval('l')
    505  py3 del l[-1:2]
    506  call assert_equal([0, 1, 2, 3], l)
    507  py3 del l[-2:2]
    508  call assert_equal([0, 1, 2, 3], l)
    509  py3 del l[-3:2]
    510  call assert_equal([0, 2, 3], l)
    511 
    512  let l = [0, 1, 2, 3]
    513  py3 l = vim.bindeval('l')
    514  py3 del l[-4:2]
    515  call assert_equal([2, 3], l)
    516 
    517  let l = [0, 1, 2, 3]
    518  py3 l = vim.bindeval('l')
    519  py3 del l[-5:2]
    520  call assert_equal([2, 3], l)
    521 
    522  let l = [0, 1, 2, 3]
    523  py3 l = vim.bindeval('l')
    524  py3 del l[-6:2]
    525  call assert_equal([2, 3], l)
    526 
    527  let l = [0, 1, 2, 3]
    528  py3 l = vim.bindeval('l')
    529  py3 del l[::2]
    530  call assert_equal([1, 3], l)
    531 
    532  let l = [0, 1, 2, 3]
    533  py3 l = vim.bindeval('l')
    534  py3 del l[3:0:-2]
    535  call assert_equal([0, 2], l)
    536 
    537  let l = [0, 1, 2, 3]
    538  py3 l = vim.bindeval('l')
    539  py3 del l[2:4:-2]
    540  let l = [0, 1, 2, 3]
    541 endfunc
    542 
    543 func Test_python3_dict_del_items()
    544  throw 'Skipped: Nvim does not support vim.bindeval()'
    545  let d = eval("{'0' : -1, '1' : 'asd', 'b' : [1, 2, function('strlen')], 'f' : function('min'), '-1' : {'a': 1}}")
    546  py3 d = vim.bindeval('d')
    547  py3 del d['-1']
    548  py3 del d['f']
    549  call assert_equal([1, 2, function('strlen')], py3eval('d.get(''b'', 1)'))
    550  call assert_equal([1, 2, function('strlen')], py3eval('d.pop(''b'')'))
    551  call assert_equal(1, py3eval('d.get(''b'', 1)'))
    552  call assert_equal('asd', py3eval('d.pop(''1'', 2)'))
    553  call assert_equal(2, py3eval('d.pop(''1'', 2)'))
    554  call assert_equal('True', py3eval('repr(d.has_key(''0''))'))
    555  call assert_equal('False', py3eval('repr(d.has_key(''1''))'))
    556  call assert_equal('True', py3eval('repr(''0'' in d)'))
    557  call assert_equal('False', py3eval('repr(''1'' in d)'))
    558  call assert_equal("[b'0']", py3eval('repr(list(iter(d)))'))
    559  call assert_equal({'0' : -1}, d)
    560  call assert_equal("(b'0', -1)", py3eval('repr(d.popitem())'))
    561  call assert_equal('None', py3eval('repr(d.get(''0''))'))
    562  call assert_equal('[]', py3eval('repr(list(iter(d)))'))
    563 endfunc
    564 
    565 " Slice assignment to a list
    566 func Test_python3_slice_assignment()
    567  throw 'Skipped: Nvim does not support vim.bindeval()'
    568  let l = [0, 1, 2, 3]
    569  py3 l = vim.bindeval('l')
    570  py3 l[0:0] = ['a']
    571  call assert_equal(['a', 0, 1, 2, 3], l)
    572 
    573  let l = [0, 1, 2, 3]
    574  py3 l = vim.bindeval('l')
    575  py3 l[1:2] = ['b']
    576  call assert_equal([0, 'b', 2, 3], l)
    577 
    578  let l = [0, 1, 2, 3]
    579  py3 l = vim.bindeval('l')
    580  py3 l[2:4] = ['c']
    581  call assert_equal([0, 1, 'c'], l)
    582 
    583  let l = [0, 1, 2, 3]
    584  py3 l = vim.bindeval('l')
    585  py3 l[4:4] = ['d']
    586  call assert_equal([0, 1, 2, 3, 'd'], l)
    587 
    588  let l = [0, 1, 2, 3]
    589  py3 l = vim.bindeval('l')
    590  py3 l[-1:2] = ['e']
    591  call assert_equal([0, 1, 2, 'e', 3], l)
    592 
    593  let l = [0, 1, 2, 3]
    594  py3 l = vim.bindeval('l')
    595  py3 l[-10:2] = ['f']
    596  call assert_equal(['f', 2, 3], l)
    597 
    598  let l = [0, 1, 2, 3]
    599  py3 l = vim.bindeval('l')
    600  py3 l[2:-10] = ['g']
    601  call assert_equal([0, 1, 'g', 2, 3], l)
    602 
    603  let l = []
    604  py3 l = vim.bindeval('l')
    605  py3 l[0:0] = ['h']
    606  call assert_equal(['h'], l)
    607 
    608  let l = range(8)
    609  py3 l = vim.bindeval('l')
    610  py3 l[2:6:2] = [10, 20]
    611  call assert_equal([0, 1, 10, 3, 20, 5, 6, 7], l)
    612 
    613  let l = range(8)
    614  py3 l = vim.bindeval('l')
    615  py3 l[6:2:-2] = [10, 20]
    616  call assert_equal([0, 1, 2, 3, 20, 5, 10, 7], l)
    617 
    618  let l = range(8)
    619  py3 l = vim.bindeval('l')
    620  py3 l[6:2] = ()
    621  call assert_equal([0, 1, 2, 3, 4, 5, 6, 7], l)
    622 
    623  let l = range(8)
    624  py3 l = vim.bindeval('l')
    625  py3 l[6:2:1] = ()
    626  call assert_equal([0, 1, 2, 3, 4, 5, 6, 7], l)
    627 
    628  let l = range(8)
    629  py3 l = vim.bindeval('l')
    630  py3 l[2:2:1] = ()
    631  call assert_equal([0, 1, 2, 3, 4, 5, 6, 7], l)
    632 endfunc
    633 
    634 " Locked variables
    635 func Test_python3_lockedvar()
    636  throw 'Skipped: Nvim does not support vim.bindeval()'
    637  new
    638  py3 cb = vim.current.buffer
    639  let l = [0, 1, 2, 3]
    640  py3 l = vim.bindeval('l')
    641  lockvar! l
    642  py3 << trim EOF
    643    try:
    644        l[2]='i'
    645    except vim.error:
    646        cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info()))
    647  EOF
    648  call assert_equal(['', "l[2] threw vim.error: error:('list is locked',)"],
    649        \ getline(1, '$'))
    650  call assert_equal([0, 1, 2, 3], l)
    651  unlockvar! l
    652  close!
    653 endfunc
    654 
    655 " Test for calling a function
    656 func Test_python3_function_call()
    657  throw 'Skipped: Nvim does not support vim.bindeval()'
    658  func New(...)
    659    return ['NewStart'] + a:000 + ['NewEnd']
    660  endfunc
    661 
    662  func DictNew(...) dict
    663    return ['DictNewStart'] + a:000 + ['DictNewEnd', self]
    664  endfunc
    665 
    666  new
    667  let l = [function('New'), function('DictNew')]
    668  py3 l = vim.bindeval('l')
    669  py3 l.extend(list(l[0](1, 2, 3)))
    670  call assert_equal([function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd'], l)
    671  py3 l.extend(list(l[1](1, 2, 3, self={'a': 'b'})))
    672  call assert_equal([function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}], l)
    673  py3 l += [[l[0].name]]
    674  call assert_equal([function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, ['New']], l)
    675  py3 ee('l[1](1, 2, 3)')
    676  call assert_equal("l[1](1, 2, 3):(<class 'vim.error'>, error('Vim:E725: Calling dict function without Dictionary: DictNew',))", getline(2))
    677  %d
    678  py3 f = l[0]
    679  delfunction New
    680  py3 ee('f(1, 2, 3)')
    681  call assert_equal("f(1, 2, 3):(<class 'vim.error'>, error('Vim:E117: Unknown function: New',))", getline(2))
    682  close!
    683  delfunction DictNew
    684 endfunc
    685 
    686 func Test_python3_float()
    687  throw 'Skipped: Nvim does not support vim.bindeval()'
    688  CheckFeature float
    689  let l = [0.0]
    690  py3 l = vim.bindeval('l')
    691  py3 l.extend([0.0])
    692  call assert_equal([0.0, 0.0], l)
    693 endfunc
    694 
    695 " Test for Dict key errors
    696 func Test_python3_dict_key_error()
    697  throw 'Skipped: Nvim does not support vim.bindeval()'
    698  let messages = []
    699  py3 << trim EOF
    700    import sys
    701    d = vim.bindeval('{}')
    702    m = vim.bindeval('messages')
    703    def em(expr, g=globals(), l=locals()):
    704      try:
    705        exec(expr, g, l)
    706      except Exception as e:
    707        if sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte':
    708          m.extend([TypeError.__name__])
    709        else:
    710          m.extend([e.__class__.__name__])
    711 
    712    em('d["abc1"]')
    713    em('d["abc1"]="\\0"')
    714    em('d["abc1"]=vim')
    715    em('d[""]=1')
    716    em('d["a\\0b"]=1')
    717    em('d[b"a\\0b"]=1')
    718    em('d.pop("abc1")')
    719    em('d.popitem()')
    720    del em
    721    del m
    722  EOF
    723 
    724  call assert_equal(['KeyError', 'TypeError', 'TypeError', 'ValueError',
    725        \ 'TypeError', 'TypeError', 'KeyError', 'KeyError'], messages)
    726  unlet messages
    727 endfunc
    728 
    729 " Test for locked and scope attributes
    730 func Test_python3_lock_scope_attr()
    731  throw 'Skipped: Nvim does not support vim.bindeval()'
    732  let d = {} | let dl = {} | lockvar dl
    733  let res = []
    734  for s in split("d dl v: g:")
    735    let name = tr(s, ':', 's')
    736    execute 'py3 ' .. name .. ' = vim.bindeval("' .. s .. '")'
    737    call add(res, s .. ' : ' .. join(map(['locked', 'scope'],
    738          \ 'v:val .. ":" .. py3eval(name .. "." .. v:val)'), ';'))
    739  endfor
    740  call assert_equal(['d : locked:0;scope:0', 'dl : locked:1;scope:0',
    741        \ 'v: : locked:2;scope:1', 'g: : locked:0;scope:2'], res)
    742 
    743  silent! let d.abc2 = 1
    744  silent! let dl.abc3 = 1
    745  py3 d.locked = True
    746  py3 dl.locked = False
    747  silent! let d.def = 1
    748  silent! let dl.def = 1
    749  call assert_equal({'abc2': 1}, d)
    750  call assert_equal({'def': 1}, dl)
    751  unlet d dl
    752 
    753  let l = [] | let ll = [] | lockvar ll
    754  let res = []
    755  for s in split("l ll")
    756    let name = tr(s, ':', 's')
    757    execute 'py3 ' .. name .. '=vim.bindeval("' .. s .. '")'
    758    call add(res, s .. ' : locked:' .. py3eval(name .. '.locked'))
    759  endfor
    760  call assert_equal(['l : locked:0', 'll : locked:1'], res)
    761 
    762  silent! call extend(l, [0])
    763  silent! call extend(ll, [0])
    764  py3 l.locked = True
    765  py3 ll.locked = False
    766  silent! call extend(l, [1])
    767  silent! call extend(ll, [1])
    768  call assert_equal([0], l)
    769  call assert_equal([1], ll)
    770  unlet l ll
    771 endfunc
    772 
    773 " Test for py3eval()
    774 func Test_python3_pyeval()
    775  let l = py3eval('[0, 1, 2]')
    776  call assert_equal([0, 1, 2], l)
    777 
    778  let d = py3eval('{"a": "b", "c": 1, "d": ["e"]}')
    779  call assert_equal([['a', 'b'], ['c', 1], ['d', ['e']]], sort(items(d)))
    780 
    781  let v:errmsg = ''
    782  " call assert_equal(v:none, py3eval('None'))
    783  call assert_equal('', v:errmsg)
    784 
    785  if has('float')
    786    call assert_equal(0, py3eval('0.0'))
    787  endif
    788 
    789  " Invalid values:
    790  " let caught_859 = 0
    791  " try
    792  "   let v = py3eval('"\0"')
    793  " catch /E859:/
    794  "   let caught_859 = 1
    795  " endtry
    796  " call assert_equal(1, caught_859)
    797 
    798  " let caught_859 = 0
    799  " try
    800  "   let v = py3eval('{"\0" : 1}')
    801  " catch /E859:/
    802  "   let caught_859 = 1
    803  " endtry
    804  " call assert_equal(1, caught_859)
    805 
    806  let caught_nameerr = 0
    807  try
    808    let v = py3eval("undefined_name")
    809  catch /NameError: name 'undefined_name'/
    810    let caught_nameerr = 1
    811  endtry
    812  call assert_equal(1, caught_nameerr)
    813 
    814  let caught_859 = 0
    815  try
    816    let v = py3eval("vim")
    817  catch /can not serialize 'LegacyVim' object/
    818    let caught_859 = 1
    819  endtry
    820  call assert_equal(1, caught_859)
    821 endfunc
    822 
    823 " threading
    824 " Running py3do command (Test_pydo) before this test, stops the python thread
    825 " from running. So this test should be run before the pydo test
    826 func Test_aaa_python_threading()
    827  throw 'Skipped: Nvim does not support vim.bindeval()'
    828  let l = [0]
    829  py3 l = vim.bindeval('l')
    830  py3 << trim EOF
    831    import threading
    832    import time
    833 
    834    class T(threading.Thread):
    835      def __init__(self):
    836        threading.Thread.__init__(self)
    837        self.t = 0
    838        self.running = True
    839 
    840      def run(self):
    841        while self.running:
    842          self.t += 1
    843          time.sleep(0.1)
    844 
    845    t = T()
    846    del T
    847    t.start()
    848  EOF
    849 
    850  sleep 1
    851  py3 t.running = False
    852  py3 t.join()
    853 
    854  " Check if the background thread is working.  Count should be 10, but on a
    855  " busy system (AppVeyor) it can be much lower.
    856  py3 l[0] = t.t > 4
    857  py3 del time
    858  py3 del threading
    859  py3 del t
    860  call assert_equal([1], l)
    861 endfunc
    862 
    863 " settrace
    864 func Test_python3_settrace()
    865  throw 'Skipped: Nvim does not support vim.bindeval()'
    866  let l = []
    867  py3 l = vim.bindeval('l')
    868  py3 << trim EOF
    869    import sys
    870 
    871    def traceit(frame, event, arg):
    872      global l
    873      if event == "line":
    874        l += [frame.f_lineno]
    875      return traceit
    876 
    877    def trace_main():
    878      for i in range(5):
    879        pass
    880  EOF
    881  py3 sys.settrace(traceit)
    882  py3 trace_main()
    883  py3 sys.settrace(None)
    884  py3 del traceit
    885  py3 del trace_main
    886  call assert_equal([1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1], l)
    887 endfunc
    888 
    889 " Slice
    890 func Test_python3_list_slice()
    891  throw 'Skipped: Nvim does not support vim.bindeval()'
    892  py3 ll = vim.bindeval('[0, 1, 2, 3, 4, 5]')
    893  py3 l = ll[:4]
    894  call assert_equal([0, 1, 2, 3], py3eval('l'))
    895  py3 l = ll[2:]
    896  call assert_equal([2, 3, 4, 5], py3eval('l'))
    897  py3 l = ll[:-4]
    898  call assert_equal([0, 1], py3eval('l'))
    899  py3 l = ll[-2:]
    900  call assert_equal([4, 5], py3eval('l'))
    901  py3 l = ll[2:4]
    902  call assert_equal([2, 3], py3eval('l'))
    903  py3 l = ll[4:2]
    904  call assert_equal([], py3eval('l'))
    905  py3 l = ll[-4:-2]
    906  call assert_equal([2, 3], py3eval('l'))
    907  py3 l = ll[-2:-4]
    908  call assert_equal([], py3eval('l'))
    909  py3 l = ll[:]
    910  call assert_equal([0, 1, 2, 3, 4, 5], py3eval('l'))
    911  py3 l = ll[0:6]
    912  call assert_equal([0, 1, 2, 3, 4, 5], py3eval('l'))
    913  py3 l = ll[-10:10]
    914  call assert_equal([0, 1, 2, 3, 4, 5], py3eval('l'))
    915  py3 l = ll[4:2:-1]
    916  call assert_equal([4, 3], py3eval('l'))
    917  py3 l = ll[::2]
    918  call assert_equal([0, 2, 4], py3eval('l'))
    919  py3 l = ll[4:2:1]
    920  call assert_equal([], py3eval('l'))
    921  py3 del l
    922 endfunc
    923 
    924 " Vars
    925 func Test_python3_vars()
    926  let g:foo = 'bac'
    927  let w:abc3 = 'def'
    928  let b:baz = 'bar'
    929  let t:bar = 'jkl'
    930  try
    931    throw "Abc"
    932  catch /Abc/
    933    call assert_equal('Abc', py3eval('vim.vvars[''exception'']'))
    934  endtry
    935  call assert_equal('bac', py3eval('vim.vars[''foo'']'))
    936  call assert_equal('def', py3eval('vim.current.window.vars[''abc3'']'))
    937  call assert_equal('bar', py3eval('vim.current.buffer.vars[''baz'']'))
    938  call assert_equal('jkl', py3eval('vim.current.tabpage.vars[''bar'']'))
    939 endfunc
    940 
    941 " Options
    942 " paste:          boolean, global
    943 " previewheight   number,  global
    944 " operatorfunc:   string,  global
    945 " number:         boolean, window-local
    946 " numberwidth:    number,  window-local
    947 " colorcolumn:    string,  window-local
    948 " statusline:     string,  window-local/global
    949 " autoindent:     boolean, buffer-local
    950 " shiftwidth:     number,  buffer-local
    951 " omnifunc:       string,  buffer-local
    952 " preserveindent: boolean, buffer-local/global
    953 " path:           string,  buffer-local/global
    954 func Test_python3_opts()
    955  throw 'Skipped: Nvim does not support vim.bindeval()'
    956  let g:res = []
    957  let g:bufs = [bufnr('%')]
    958  new
    959  let g:bufs += [bufnr('%')]
    960  vnew
    961  let g:bufs += [bufnr('%')]
    962  wincmd j
    963  vnew
    964  let g:bufs += [bufnr('%')]
    965  wincmd l
    966 
    967  func RecVars(opt)
    968    let gval = string(eval('&g:' .. a:opt))
    969    let wvals = join(map(range(1, 4),
    970          \ 'v:val .. ":" .. string(getwinvar(v:val, "&" .. a:opt))'))
    971    let bvals = join(map(copy(g:bufs),
    972          \ 'v:val .. ":" .. string(getbufvar(v:val, "&" .. a:opt))'))
    973    call add(g:res, '  G: ' .. gval)
    974    call add(g:res, '  W: ' .. wvals)
    975    call add(g:res, '  B: ' .. wvals)
    976  endfunc
    977 
    978  py3 << trim EOF
    979    def e(s, g=globals(), l=locals()):
    980      try:
    981        exec(s, g, l)
    982      except Exception as e:
    983        vim.command('return ' + repr(e.__class__.__name__))
    984 
    985    def ev(s, g=globals(), l=locals()):
    986      try:
    987        return eval(s, g, l)
    988      except Exception as e:
    989        vim.command('let exc=' + repr(e.__class__.__name__))
    990        return 0
    991  EOF
    992 
    993  func E(s)
    994    python3 e(vim.eval('a:s'))
    995  endfunc
    996 
    997  func Ev(s)
    998    let r = py3eval('ev(vim.eval("a:s"))')
    999    if exists('exc')
   1000      throw exc
   1001    endif
   1002    return r
   1003  endfunc
   1004 
   1005  py3 gopts1 = vim.options
   1006  py3 wopts1 = vim.windows[2].options
   1007  py3 wopts2 = vim.windows[0].options
   1008  py3 wopts3 = vim.windows[1].options
   1009  py3 bopts1 = vim.buffers[vim.bindeval("g:bufs")[2]].options
   1010  py3 bopts2 = vim.buffers[vim.bindeval("g:bufs")[1]].options
   1011  py3 bopts3 = vim.buffers[vim.bindeval("g:bufs")[0]].options
   1012  call add(g:res, 'wopts iters equal: ' ..
   1013        \ py3eval('list(wopts1) == list(wopts2)'))
   1014  call add(g:res, 'bopts iters equal: ' ..
   1015        \ py3eval('list(bopts1) == list(bopts2)'))
   1016  py3 gset = set(iter(gopts1))
   1017  py3 wset = set(iter(wopts1))
   1018  py3 bset = set(iter(bopts1))
   1019 
   1020  set path=.,..,,
   1021  let lst = []
   1022  let lst += [['paste', 1, 0, 1, 2, 1, 1, 0]]
   1023  let lst += [['previewheight', 5, 1, 6, 'a', 0, 1, 0]]
   1024  let lst += [['operatorfunc', 'A', 'B', 'C', 2, 0, 1, 0]]
   1025  let lst += [['number', 0, 1, 1, 0, 1, 0, 1]]
   1026  let lst += [['numberwidth', 2, 3, 5, -100, 0, 0, 1]]
   1027  let lst += [['colorcolumn', '+1', '+2', '+3', 'abc4', 0, 0, 1]]
   1028  let lst += [['statusline', '1', '2', '4', 0, 0, 1, 1]]
   1029  let lst += [['autoindent', 0, 1, 1, 2, 1, 0, 2]]
   1030  let lst += [['shiftwidth', 0, 2, 1, 3, 0, 0, 2]]
   1031  let lst += [['omnifunc', 'A', 'B', 'C', 1, 0, 0, 2]]
   1032  let lst += [['preserveindent', 0, 1, 1, 2, 1, 1, 2]]
   1033  let lst += [['path', '.,,', ',,', '.', 0, 0, 1, 2]]
   1034  for  [oname, oval1, oval2, oval3, invval, bool, global, local] in lst
   1035    py3 oname = vim.eval('oname')
   1036    py3 oval1 = vim.bindeval('oval1')
   1037    py3 oval2 = vim.bindeval('oval2')
   1038    py3 oval3 = vim.bindeval('oval3')
   1039    if invval is 0 || invval is 1
   1040      py3 invval = bool(vim.bindeval('invval'))
   1041    else
   1042      py3 invval = vim.bindeval('invval')
   1043    endif
   1044    if bool
   1045      py3 oval1 = bool(oval1)
   1046      py3 oval2 = bool(oval2)
   1047      py3 oval3 = bool(oval3)
   1048    endif
   1049    call add(g:res, '>>> ' .. oname)
   1050    call add(g:res, '  g/w/b:' .. py3eval('oname in gset') .. '/' ..
   1051          \ py3eval('oname in wset') .. '/' .. py3eval('oname in bset'))
   1052    call add(g:res, '  g/w/b (in):' .. py3eval('oname in gopts1') .. '/' ..
   1053          \ py3eval('oname in wopts1') .. '/' .. py3eval('oname in bopts1'))
   1054    for v in ['gopts1', 'wopts1', 'bopts1']
   1055      try
   1056        call add(g:res, '  p/' .. v .. ': ' .. Ev('repr(' .. v .. '[''' .. oname .. '''])'))
   1057      catch
   1058        call add(g:res, '  p/' .. v .. '! ' .. v:exception)
   1059      endtry
   1060      let r = E(v .. '[''' .. oname .. ''']=invval')
   1061      if r isnot 0
   1062        call add(g:res, '  inv: ' .. string(invval) .. '! ' .. r)
   1063      endif
   1064      for vv in (v is# 'gopts1' ? [v] : [v, v[:-2] .. '2', v[:-2] .. '3'])
   1065        let val = substitute(vv, '^.opts', 'oval', '')
   1066        let r = E(vv .. '[''' .. oname .. ''']=' .. val)
   1067        if r isnot 0
   1068            call add(g:res, '  ' .. vv .. '! ' .. r)
   1069        endif
   1070      endfor
   1071    endfor
   1072    call RecVars(oname)
   1073    for v in ['wopts3', 'bopts3']
   1074      let r = E('del ' .. v .. '["' .. oname .. '"]')
   1075      if r isnot 0
   1076        call add(g:res, '  del ' .. v .. '! ' .. r)
   1077      endif
   1078    endfor
   1079    call RecVars(oname)
   1080  endfor
   1081  delfunction RecVars
   1082  delfunction E
   1083  delfunction Ev
   1084  py3 del ev
   1085  py3 del e
   1086  only
   1087  for buf in g:bufs[1:]
   1088    execute 'bwipeout!' buf
   1089  endfor
   1090  py3 del gopts1
   1091  py3 del wopts1
   1092  py3 del wopts2
   1093  py3 del wopts3
   1094  py3 del bopts1
   1095  py3 del bopts2
   1096  py3 del bopts3
   1097  py3 del oval1
   1098  py3 del oval2
   1099  py3 del oval3
   1100  py3 del oname
   1101  py3 del invval
   1102 
   1103  let expected =<< trim END
   1104    wopts iters equal: 1
   1105    bopts iters equal: 1
   1106    >>> paste
   1107      g/w/b:1/0/0
   1108      g/w/b (in):1/0/0
   1109      p/gopts1: False
   1110      p/wopts1! KeyError
   1111      inv: 2! KeyError
   1112      wopts1! KeyError
   1113      wopts2! KeyError
   1114      wopts3! KeyError
   1115      p/bopts1! KeyError
   1116      inv: 2! KeyError
   1117      bopts1! KeyError
   1118      bopts2! KeyError
   1119      bopts3! KeyError
   1120      G: 1
   1121      W: 1:1 2:1 3:1 4:1
   1122      B: 1:1 2:1 3:1 4:1
   1123      del wopts3! KeyError
   1124      del bopts3! KeyError
   1125      G: 1
   1126      W: 1:1 2:1 3:1 4:1
   1127      B: 1:1 2:1 3:1 4:1
   1128    >>> previewheight
   1129      g/w/b:1/0/0
   1130      g/w/b (in):1/0/0
   1131      p/gopts1: 12
   1132      inv: 'a'! TypeError
   1133      p/wopts1! KeyError
   1134      inv: 'a'! KeyError
   1135      wopts1! KeyError
   1136      wopts2! KeyError
   1137      wopts3! KeyError
   1138      p/bopts1! KeyError
   1139      inv: 'a'! KeyError
   1140      bopts1! KeyError
   1141      bopts2! KeyError
   1142      bopts3! KeyError
   1143      G: 5
   1144      W: 1:5 2:5 3:5 4:5
   1145      B: 1:5 2:5 3:5 4:5
   1146      del wopts3! KeyError
   1147      del bopts3! KeyError
   1148      G: 5
   1149      W: 1:5 2:5 3:5 4:5
   1150      B: 1:5 2:5 3:5 4:5
   1151    >>> operatorfunc
   1152      g/w/b:1/0/0
   1153      g/w/b (in):1/0/0
   1154      p/gopts1: b''
   1155      inv: 2! TypeError
   1156      p/wopts1! KeyError
   1157      inv: 2! KeyError
   1158      wopts1! KeyError
   1159      wopts2! KeyError
   1160      wopts3! KeyError
   1161      p/bopts1! KeyError
   1162      inv: 2! KeyError
   1163      bopts1! KeyError
   1164      bopts2! KeyError
   1165      bopts3! KeyError
   1166      G: 'A'
   1167      W: 1:'A' 2:'A' 3:'A' 4:'A'
   1168      B: 1:'A' 2:'A' 3:'A' 4:'A'
   1169      del wopts3! KeyError
   1170      del bopts3! KeyError
   1171      G: 'A'
   1172      W: 1:'A' 2:'A' 3:'A' 4:'A'
   1173      B: 1:'A' 2:'A' 3:'A' 4:'A'
   1174    >>> number
   1175      g/w/b:0/1/0
   1176      g/w/b (in):0/1/0
   1177      p/gopts1! KeyError
   1178      inv: 0! KeyError
   1179      gopts1! KeyError
   1180      p/wopts1: False
   1181      p/bopts1! KeyError
   1182      inv: 0! KeyError
   1183      bopts1! KeyError
   1184      bopts2! KeyError
   1185      bopts3! KeyError
   1186      G: 0
   1187      W: 1:1 2:1 3:0 4:0
   1188      B: 1:1 2:1 3:0 4:0
   1189      del wopts3! ValueError
   1190      del bopts3! KeyError
   1191      G: 0
   1192      W: 1:1 2:1 3:0 4:0
   1193      B: 1:1 2:1 3:0 4:0
   1194    >>> numberwidth
   1195      g/w/b:0/1/0
   1196      g/w/b (in):0/1/0
   1197      p/gopts1! KeyError
   1198      inv: -100! KeyError
   1199      gopts1! KeyError
   1200      p/wopts1: 4
   1201      inv: -100! error
   1202      p/bopts1! KeyError
   1203      inv: -100! KeyError
   1204      bopts1! KeyError
   1205      bopts2! KeyError
   1206      bopts3! KeyError
   1207      G: 4
   1208      W: 1:3 2:5 3:2 4:4
   1209      B: 1:3 2:5 3:2 4:4
   1210      del wopts3! ValueError
   1211      del bopts3! KeyError
   1212      G: 4
   1213      W: 1:3 2:5 3:2 4:4
   1214      B: 1:3 2:5 3:2 4:4
   1215    >>> colorcolumn
   1216      g/w/b:0/1/0
   1217      g/w/b (in):0/1/0
   1218      p/gopts1! KeyError
   1219      inv: 'abc4'! KeyError
   1220      gopts1! KeyError
   1221      p/wopts1: b''
   1222      inv: 'abc4'! error
   1223      p/bopts1! KeyError
   1224      inv: 'abc4'! KeyError
   1225      bopts1! KeyError
   1226      bopts2! KeyError
   1227      bopts3! KeyError
   1228      G: ''
   1229      W: 1:'+2' 2:'+3' 3:'+1' 4:''
   1230      B: 1:'+2' 2:'+3' 3:'+1' 4:''
   1231      del wopts3! ValueError
   1232      del bopts3! KeyError
   1233      G: ''
   1234      W: 1:'+2' 2:'+3' 3:'+1' 4:''
   1235      B: 1:'+2' 2:'+3' 3:'+1' 4:''
   1236    >>> statusline
   1237      g/w/b:1/1/0
   1238      g/w/b (in):1/1/0
   1239      p/gopts1: b''
   1240      inv: 0! TypeError
   1241      p/wopts1: None
   1242      inv: 0! TypeError
   1243      p/bopts1! KeyError
   1244      inv: 0! KeyError
   1245      bopts1! KeyError
   1246      bopts2! KeyError
   1247      bopts3! KeyError
   1248      G: '1'
   1249      W: 1:'2' 2:'4' 3:'1' 4:'1'
   1250      B: 1:'2' 2:'4' 3:'1' 4:'1'
   1251      del bopts3! KeyError
   1252      G: '1'
   1253      W: 1:'2' 2:'1' 3:'1' 4:'1'
   1254      B: 1:'2' 2:'1' 3:'1' 4:'1'
   1255    >>> autoindent
   1256      g/w/b:0/0/1
   1257      g/w/b (in):0/0/1
   1258      p/gopts1! KeyError
   1259      inv: 2! KeyError
   1260      gopts1! KeyError
   1261      p/wopts1! KeyError
   1262      inv: 2! KeyError
   1263      wopts1! KeyError
   1264      wopts2! KeyError
   1265      wopts3! KeyError
   1266      p/bopts1: False
   1267      G: 0
   1268      W: 1:0 2:1 3:0 4:1
   1269      B: 1:0 2:1 3:0 4:1
   1270      del wopts3! KeyError
   1271      del bopts3! ValueError
   1272      G: 0
   1273      W: 1:0 2:1 3:0 4:1
   1274      B: 1:0 2:1 3:0 4:1
   1275    >>> shiftwidth
   1276      g/w/b:0/0/1
   1277      g/w/b (in):0/0/1
   1278      p/gopts1! KeyError
   1279      inv: 3! KeyError
   1280      gopts1! KeyError
   1281      p/wopts1! KeyError
   1282      inv: 3! KeyError
   1283      wopts1! KeyError
   1284      wopts2! KeyError
   1285      wopts3! KeyError
   1286      p/bopts1: 8
   1287      G: 8
   1288      W: 1:0 2:2 3:8 4:1
   1289      B: 1:0 2:2 3:8 4:1
   1290      del wopts3! KeyError
   1291      del bopts3! ValueError
   1292      G: 8
   1293      W: 1:0 2:2 3:8 4:1
   1294      B: 1:0 2:2 3:8 4:1
   1295    >>> omnifunc
   1296      g/w/b:0/0/1
   1297      g/w/b (in):0/0/1
   1298      p/gopts1! KeyError
   1299      inv: 1! KeyError
   1300      gopts1! KeyError
   1301      p/wopts1! KeyError
   1302      inv: 1! KeyError
   1303      wopts1! KeyError
   1304      wopts2! KeyError
   1305      wopts3! KeyError
   1306      p/bopts1: b''
   1307      inv: 1! TypeError
   1308      G: ''
   1309      W: 1:'A' 2:'B' 3:'' 4:'C'
   1310      B: 1:'A' 2:'B' 3:'' 4:'C'
   1311      del wopts3! KeyError
   1312      del bopts3! ValueError
   1313      G: ''
   1314      W: 1:'A' 2:'B' 3:'' 4:'C'
   1315      B: 1:'A' 2:'B' 3:'' 4:'C'
   1316    >>> preserveindent
   1317      g/w/b:0/0/1
   1318      g/w/b (in):0/0/1
   1319      p/gopts1! KeyError
   1320      inv: 2! KeyError
   1321      gopts1! KeyError
   1322      p/wopts1! KeyError
   1323      inv: 2! KeyError
   1324      wopts1! KeyError
   1325      wopts2! KeyError
   1326      wopts3! KeyError
   1327      p/bopts1: False
   1328      G: 0
   1329      W: 1:0 2:1 3:0 4:1
   1330      B: 1:0 2:1 3:0 4:1
   1331      del wopts3! KeyError
   1332      del bopts3! ValueError
   1333      G: 0
   1334      W: 1:0 2:1 3:0 4:1
   1335      B: 1:0 2:1 3:0 4:1
   1336    >>> path
   1337      g/w/b:1/0/1
   1338      g/w/b (in):1/0/1
   1339      p/gopts1: b'.,..,,'
   1340      inv: 0! TypeError
   1341      p/wopts1! KeyError
   1342      inv: 0! KeyError
   1343      wopts1! KeyError
   1344      wopts2! KeyError
   1345      wopts3! KeyError
   1346      p/bopts1: None
   1347      inv: 0! TypeError
   1348      G: '.,,'
   1349      W: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
   1350      B: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
   1351      del wopts3! KeyError
   1352      G: '.,,'
   1353      W: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
   1354      B: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
   1355  END
   1356 
   1357  call assert_equal(expected, g:res)
   1358  unlet g:res
   1359 endfunc
   1360 
   1361 " Test for vim.buffer object
   1362 func Test_python3_buffer()
   1363  throw 'Skipped: TODO: '
   1364  new
   1365  call setline(1, "Hello\nWorld")
   1366  call assert_fails("let x = py3eval('vim.current.buffer[0]')", 'E859:')
   1367  %bw!
   1368 
   1369  edit Xfile1
   1370  let bnr1 = bufnr()
   1371  py3 cb = vim.current.buffer
   1372  vnew Xfile2
   1373  let bnr2 = bufnr()
   1374  call setline(1, ['First line', 'Second line', 'Third line'])
   1375  py3 b = vim.current.buffer
   1376  wincmd w
   1377 
   1378  " Tests BufferAppend and BufferItem
   1379  py3 cb.append(b[0])
   1380  call assert_equal(['First line'], getbufline(bnr1, 2))
   1381  %d
   1382 
   1383  " Tests BufferSlice and BufferAssSlice
   1384  py3 cb.append('abc5') # Will be overwritten
   1385  py3 cb[-1:] = b[:-2]
   1386  call assert_equal(['First line'], getbufline(bnr1, 2))
   1387  %d
   1388 
   1389  " Test BufferLength and BufferAssSlice
   1390  py3 cb.append('def') # Will not be overwritten
   1391  py3 cb[len(cb):] = b[:]
   1392  call assert_equal(['def', 'First line', 'Second line', 'Third line'],
   1393        \ getbufline(bnr1, 2, '$'))
   1394  %d
   1395 
   1396  " Test BufferAssItem and BufferMark
   1397  call setbufline(bnr1, 1, ['one', 'two', 'three'])
   1398  call cursor(1, 3)
   1399  normal ma
   1400  py3 cb.append('ghi') # Will be overwritten
   1401  py3 cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1]))
   1402  call assert_equal(['(3, 2)'], getbufline(bnr1, 4))
   1403  %d
   1404 
   1405  " Test BufferRepr
   1406  py3 cb.append(repr(cb) + repr(b))
   1407  call assert_equal(['<buffer Xfile1><buffer Xfile2>'], getbufline(bnr1, 2))
   1408  %d
   1409 
   1410  " Modify foreign buffer
   1411  py3 << trim EOF
   1412    b.append('foo')
   1413    b[0]='bar'
   1414    b[0:0]=['baz']
   1415    vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number)
   1416  EOF
   1417  call assert_equal(['baz', 'bar', 'Second line', 'Third line', 'foo'],
   1418        \ getbufline(bnr2, 1, '$'))
   1419  %d
   1420 
   1421  " Test assigning to name property
   1422  augroup BUFS
   1423    autocmd BufFilePost * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePost:' + vim.eval('bufnr("%")'))
   1424    autocmd BufFilePre * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePre:' + vim.eval('bufnr("%")'))
   1425  augroup END
   1426  py3 << trim EOF
   1427    import os
   1428    old_name = cb.name
   1429    cb.name = 'foo'
   1430    cb.append(cb.name[-11:].replace(os.path.sep, '/'))
   1431    b.name = 'bar'
   1432    cb.append(b.name[-11:].replace(os.path.sep, '/'))
   1433    cb.name = old_name
   1434    cb.append(cb.name[-14:].replace(os.path.sep, '/'))
   1435    del old_name
   1436  EOF
   1437  call assert_equal([bnr1 .. ':BufFilePre:' .. bnr1,
   1438        \ bnr1 .. ':BufFilePost:' .. bnr1,
   1439        \ 'testdir/foo',
   1440        \ bnr2 .. ':BufFilePre:' .. bnr2,
   1441        \ bnr2 .. ':BufFilePost:' .. bnr2,
   1442        \ 'testdir/bar',
   1443        \ bnr1 .. ':BufFilePre:' .. bnr1,
   1444        \ bnr1 .. ':BufFilePost:' .. bnr1,
   1445        \ 'testdir/Xfile1'], getbufline(bnr1, 2, '$'))
   1446  %d
   1447 
   1448  " Test CheckBuffer
   1449  py3 << trim EOF
   1450    for _b in vim.buffers:
   1451      if _b is not cb:
   1452        vim.command('bwipeout! ' + str(_b.number))
   1453    del _b
   1454    cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid)))
   1455  EOF
   1456  call assert_equal('valid: b:False, cb:True', getline(2))
   1457  %d
   1458 
   1459  py3 << trim EOF
   1460    for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")'):
   1461      try:
   1462        exec(expr)
   1463      except vim.error:
   1464        pass
   1465      else:
   1466        # Usually a SEGV here
   1467        # Should not happen in any case
   1468        cb.append('No exception for ' + expr)
   1469    vim.command('cd .')
   1470    del b
   1471  EOF
   1472  call assert_equal([''], getline(1, '$'))
   1473 
   1474  augroup BUFS
   1475    autocmd!
   1476  augroup END
   1477  augroup! BUFS
   1478  %bw!
   1479 endfunc
   1480 
   1481 " Test vim.buffers object
   1482 func Test_python3_buffers()
   1483  throw 'Skipped: TODO: '
   1484  %bw!
   1485  edit Xfile
   1486  py3 cb = vim.current.buffer
   1487  set hidden
   1488  edit a
   1489  buffer #
   1490  edit b
   1491  buffer #
   1492  edit c
   1493  buffer #
   1494  py3 << trim EOF
   1495    # Check GCing iterator that was not fully exhausted
   1496    i = iter(vim.buffers)
   1497    cb.append('i:' + str(next(i)))
   1498    # and also check creating more than one iterator at a time
   1499    i2 = iter(vim.buffers)
   1500    cb.append('i2:' + str(next(i2)))
   1501    cb.append('i:' + str(next(i)))
   1502    # The following should trigger GC and not cause any problems
   1503    del i
   1504    del i2
   1505    i3 = iter(vim.buffers)
   1506    cb.append('i3:' + str(next(i3)))
   1507    del i3
   1508  EOF
   1509  call assert_equal(['i:<buffer Xfile>',
   1510        \ 'i2:<buffer Xfile>', 'i:<buffer a>', 'i3:<buffer Xfile>'],
   1511        \ getline(2, '$'))
   1512  %d
   1513 
   1514  py3 << trim EOF
   1515    prevnum = 0
   1516    for b in vim.buffers:
   1517      # Check buffer order
   1518      if prevnum >= b.number:
   1519        cb.append('!!! Buffer numbers not in strictly ascending order')
   1520      # Check indexing: vim.buffers[number].number == number
   1521      cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + \
   1522                                                            '=' + repr(b))
   1523      prevnum = b.number
   1524    del prevnum
   1525 
   1526    cb.append(str(len(vim.buffers)))
   1527  EOF
   1528  call assert_equal([bufnr('Xfile') .. ':<buffer Xfile>=<buffer Xfile>',
   1529        \ bufnr('a') .. ':<buffer a>=<buffer a>',
   1530        \ bufnr('b') .. ':<buffer b>=<buffer b>',
   1531        \ bufnr('c') .. ':<buffer c>=<buffer c>', '4'], getline(2, '$'))
   1532  %d
   1533 
   1534  py3 << trim EOF
   1535    bnums = list(map(lambda b: b.number, vim.buffers))[1:]
   1536 
   1537    # Test wiping out buffer with existing iterator
   1538    i4 = iter(vim.buffers)
   1539    cb.append('i4:' + str(next(i4)))
   1540    vim.command('bwipeout! ' + str(bnums.pop(0)))
   1541    try:
   1542      next(i4)
   1543    except vim.error:
   1544      pass
   1545    else:
   1546      cb.append('!!!! No vim.error')
   1547    i4 = iter(vim.buffers)
   1548    vim.command('bwipeout! ' + str(bnums.pop(-1)))
   1549    vim.command('bwipeout! ' + str(bnums.pop(-1)))
   1550    cb.append('i4:' + str(next(i4)))
   1551    try:
   1552      next(i4)
   1553    except StopIteration:
   1554      cb.append('StopIteration')
   1555    del i4
   1556    del bnums
   1557  EOF
   1558  call assert_equal(['i4:<buffer Xfile>',
   1559        \ 'i4:<buffer Xfile>', 'StopIteration'], getline(2, '$'))
   1560  %bw!
   1561 endfunc
   1562 
   1563 " Test vim.{tabpage,window}list and vim.{tabpage,window} objects
   1564 func Test_python3_tabpage_window()
   1565  throw 'Skipped: TODO: '
   1566  %bw
   1567  edit Xfile
   1568  py3 cb = vim.current.buffer
   1569  tabnew 0
   1570  tabnew 1
   1571  vnew a.1
   1572  tabnew 2
   1573  vnew a.2
   1574  vnew b.2
   1575  vnew c.2
   1576 
   1577  py3 << trim EOF
   1578    cb.append('Number of tabs: ' + str(len(vim.tabpages)))
   1579    cb.append('Current tab pages:')
   1580    def W(w):
   1581      if '(unknown)' in repr(w):
   1582        return '<window object (unknown)>'
   1583      else:
   1584        return repr(w)
   1585 
   1586    def Cursor(w, start=len(cb)):
   1587      if w.buffer is cb:
   1588        return repr((start - w.cursor[0], w.cursor[1]))
   1589      else:
   1590        return repr(w.cursor)
   1591 
   1592    for t in vim.tabpages:
   1593      cb.append('  ' + repr(t) + '(' + str(t.number) + ')' + ': ' + \
   1594                str(len(t.windows)) + ' windows, current is ' + W(t.window))
   1595      cb.append('  Windows:')
   1596      for w in t.windows:
   1597        cb.append('    ' + W(w) + '(' + str(w.number) + ')' + \
   1598                                  ': displays buffer ' + repr(w.buffer) + \
   1599                                  '; cursor is at ' + Cursor(w))
   1600        # Other values depend on the size of the terminal, so they are checked
   1601        # partly:
   1602        for attr in ('height', 'row', 'width', 'col'):
   1603          try:
   1604            aval = getattr(w, attr)
   1605            if type(aval) is not int:
   1606              raise TypeError
   1607            if aval < 0:
   1608              raise ValueError
   1609          except Exception as e:
   1610            cb.append('!!!!!! Error while getting attribute ' + attr + \
   1611                                            ': ' + e.__class__.__name__)
   1612        del aval
   1613        del attr
   1614        w.cursor = (len(w.buffer), 0)
   1615    del W
   1616    del Cursor
   1617    cb.append('Number of windows in current tab page: ' + \
   1618                                                    str(len(vim.windows)))
   1619    if list(vim.windows) != list(vim.current.tabpage.windows):
   1620      cb.append('!!!!!! Windows differ')
   1621  EOF
   1622 
   1623  let expected =<< trim END
   1624    Number of tabs: 4
   1625    Current tab pages:
   1626      <tabpage 0>(1): 1 windows, current is <window object (unknown)>
   1627      Windows:
   1628        <window object (unknown)>(1): displays buffer <buffer Xfile>; cursor is at (2, 0)
   1629      <tabpage 1>(2): 1 windows, current is <window object (unknown)>
   1630      Windows:
   1631        <window object (unknown)>(1): displays buffer <buffer 0>; cursor is at (1, 0)
   1632      <tabpage 2>(3): 2 windows, current is <window object (unknown)>
   1633      Windows:
   1634        <window object (unknown)>(1): displays buffer <buffer a.1>; cursor is at (1, 0)
   1635        <window object (unknown)>(2): displays buffer <buffer 1>; cursor is at (1, 0)
   1636      <tabpage 3>(4): 4 windows, current is <window 0>
   1637      Windows:
   1638        <window 0>(1): displays buffer <buffer c.2>; cursor is at (1, 0)
   1639        <window 1>(2): displays buffer <buffer b.2>; cursor is at (1, 0)
   1640        <window 2>(3): displays buffer <buffer a.2>; cursor is at (1, 0)
   1641        <window 3>(4): displays buffer <buffer 2>; cursor is at (1, 0)
   1642    Number of windows in current tab page: 4
   1643  END
   1644  call assert_equal(expected, getbufline(bufnr('Xfile'), 2, '$'))
   1645  %bw!
   1646 endfunc
   1647 
   1648 " Test vim.current
   1649 func Test_python3_vim_current()
   1650  throw 'Skipped: TODO: '
   1651  %bw
   1652  edit Xfile
   1653  py3 cb = vim.current.buffer
   1654  tabnew 0
   1655  tabnew 1
   1656  vnew a.1
   1657  tabnew 2
   1658  vnew a.2
   1659  vnew b.2
   1660  vnew c.2
   1661 
   1662  py3 << trim EOF
   1663    def H(o):
   1664      return repr(o)
   1665    cb.append('Current tab page: ' + repr(vim.current.tabpage))
   1666    cb.append('Current window: ' + repr(vim.current.window) + ': ' + \
   1667               H(vim.current.window) + ' is ' + H(vim.current.tabpage.window))
   1668    cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + \
   1669               H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ \
   1670               ' is ' + H(vim.current.tabpage.window.buffer))
   1671    del H
   1672  EOF
   1673  let expected =<< trim END
   1674    Current tab page: <tabpage 3>
   1675    Current window: <window 0>: <window 0> is <window 0>
   1676    Current buffer: <buffer c.2>: <buffer c.2> is <buffer c.2> is <buffer c.2>
   1677  END
   1678  call assert_equal(expected, getbufline(bufnr('Xfile'), 2, '$'))
   1679  call deletebufline(bufnr('Xfile'), 1, '$')
   1680 
   1681  " Assigning: fails
   1682  py3 << trim EOF
   1683    try:
   1684      vim.current.window = vim.tabpages[0].window
   1685    except ValueError:
   1686      cb.append('ValueError at assigning foreign tab window')
   1687 
   1688    for attr in ('window', 'tabpage', 'buffer'):
   1689      try:
   1690        setattr(vim.current, attr, None)
   1691      except TypeError:
   1692        cb.append('Type error at assigning None to vim.current.' + attr)
   1693    del attr
   1694  EOF
   1695 
   1696  let expected =<< trim END
   1697    ValueError at assigning foreign tab window
   1698    Type error at assigning None to vim.current.window
   1699    Type error at assigning None to vim.current.tabpage
   1700    Type error at assigning None to vim.current.buffer
   1701  END
   1702  call assert_equal(expected, getbufline(bufnr('Xfile'), 2, '$'))
   1703  call deletebufline(bufnr('Xfile'), 1, '$')
   1704 
   1705  call setbufline(bufnr('Xfile'), 1, 'python interface')
   1706  py3 << trim EOF
   1707    # Assigning: success
   1708    vim.current.tabpage = vim.tabpages[-2]
   1709    vim.current.buffer = cb
   1710    vim.current.window = vim.windows[0]
   1711    vim.current.window.cursor = (len(vim.current.buffer), 0)
   1712    cb.append('Current tab page: ' + repr(vim.current.tabpage))
   1713    cb.append('Current window: ' + repr(vim.current.window))
   1714    cb.append('Current buffer: ' + repr(vim.current.buffer))
   1715    cb.append('Current line: ' + repr(vim.current.line))
   1716  EOF
   1717 
   1718  let expected =<< trim END
   1719    Current tab page: <tabpage 2>
   1720    Current window: <window 0>
   1721    Current buffer: <buffer Xfile>
   1722    Current line: 'python interface'
   1723  END
   1724  call assert_equal(expected, getbufline(bufnr('Xfile'), 2, '$'))
   1725  call deletebufline(bufnr('Xfile'), 1, '$')
   1726 
   1727  py3 << trim EOF
   1728    ws = list(vim.windows)
   1729    ts = list(vim.tabpages)
   1730    for b in vim.buffers:
   1731      if b is not cb:
   1732        vim.command('bwipeout! ' + str(b.number))
   1733    del b
   1734    cb.append('w.valid: ' + repr([w.valid for w in ws]))
   1735    cb.append('t.valid: ' + repr([t.valid for t in ts]))
   1736    del w
   1737    del t
   1738    del ts
   1739    del ws
   1740  EOF
   1741  let expected =<< trim END
   1742    w.valid: [True, False]
   1743    t.valid: [True, False, True, False]
   1744  END
   1745  call assert_equal(expected, getbufline(bufnr('Xfile'), 2, '$'))
   1746  %bw!
   1747 endfunc
   1748 
   1749 " Test types
   1750 func Test_python3_types()
   1751  throw 'Skipped: Nvim does not support vim.bindeval()'
   1752  %d
   1753  py3 cb = vim.current.buffer
   1754  py3 << trim EOF
   1755    for expr, attr in (
   1756      ('vim.vars',                         'Dictionary'),
   1757      ('vim.options',                      'Options'),
   1758      ('vim.bindeval("{}")',               'Dictionary'),
   1759      ('vim.bindeval("[]")',               'List'),
   1760      ('vim.bindeval("function(\'tr\')")', 'Function'),
   1761      ('vim.current.buffer',               'Buffer'),
   1762      ('vim.current.range',                'Range'),
   1763      ('vim.current.window',               'Window'),
   1764      ('vim.current.tabpage',              'TabPage'),
   1765    ):
   1766      cb.append(expr + ':' + attr + ':' + \
   1767                                repr(type(eval(expr)) is getattr(vim, attr)))
   1768    del expr
   1769    del attr
   1770  EOF
   1771  let expected =<< trim END
   1772    vim.vars:Dictionary:True
   1773    vim.options:Options:True
   1774    vim.bindeval("{}"):Dictionary:True
   1775    vim.bindeval("[]"):List:True
   1776    vim.bindeval("function('tr')"):Function:True
   1777    vim.current.buffer:Buffer:True
   1778    vim.current.range:Range:True
   1779    vim.current.window:Window:True
   1780    vim.current.tabpage:TabPage:True
   1781  END
   1782  call assert_equal(expected, getline(2, '$'))
   1783 endfunc
   1784 
   1785 " Test __dir__() method
   1786 func Test_python3_dir_method()
   1787  throw 'Skipped: Nvim does not support vim.bindeval()'
   1788  %d
   1789  py3 cb = vim.current.buffer
   1790  py3 << trim EOF
   1791    for name, o in (
   1792            ('current',    vim.current),
   1793            ('buffer',     vim.current.buffer),
   1794            ('window',     vim.current.window),
   1795            ('tabpage',    vim.current.tabpage),
   1796            ('range',      vim.current.range),
   1797            ('dictionary', vim.bindeval('{}')),
   1798            ('list',       vim.bindeval('[]')),
   1799            ('function',   vim.bindeval('function("tr")')),
   1800            ('output',     sys.stdout),
   1801        ):
   1802        cb.append(name + ':' + ','.join(dir(o)))
   1803    del name
   1804    del o
   1805  EOF
   1806  let expected =<< trim END
   1807    current:__dir__,buffer,line,range,tabpage,window
   1808    buffer:__dir__,append,mark,name,number,options,range,valid,vars
   1809    window:__dir__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars,width
   1810    tabpage:__dir__,number,valid,vars,window,windows
   1811    range:__dir__,append,end,start
   1812    dictionary:__dir__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
   1813    list:__dir__,extend,locked
   1814    function:__dir__,args,auto_rebind,self,softspace
   1815    output:__dir__,close,closed,flush,isatty,readable,seekable,softspace,writable,write,writelines
   1816  END
   1817  call assert_equal(expected, getline(2, '$'))
   1818 endfunc
   1819 
   1820 " Test vim.*.__new__
   1821 func Test_python3_new()
   1822  throw "Skipped: Nvim: 'LegacyVim' object has no attribute 'Dictionary'"
   1823  call assert_equal({}, py3eval('vim.Dictionary({})'))
   1824  call assert_equal({'a': 1}, py3eval('vim.Dictionary(a=1)'))
   1825  call assert_equal({'a': 1}, py3eval('vim.Dictionary(((''a'', 1),))'))
   1826  call assert_equal([], py3eval('vim.List()'))
   1827  call assert_equal(['a', 'b', 'c', '7'], py3eval('vim.List(iter(''abc7''))'))
   1828  call assert_equal(function('tr'), py3eval('vim.Function(''tr'')'))
   1829  call assert_equal(function('tr', [123, 3, 4]),
   1830        \ py3eval('vim.Function(''tr'', args=[123, 3, 4])'))
   1831  call assert_equal(function('tr'), py3eval('vim.Function(''tr'', args=[])'))
   1832  call assert_equal(function('tr', {}),
   1833        \ py3eval('vim.Function(''tr'', self={})'))
   1834  call assert_equal(function('tr', [123, 3, 4], {}),
   1835        \ py3eval('vim.Function(''tr'', args=[123, 3, 4], self={})'))
   1836  call assert_equal(function('tr'),
   1837        \ py3eval('vim.Function(''tr'', auto_rebind=False)'))
   1838  call assert_equal(function('tr', [123, 3, 4]),
   1839        \ py3eval('vim.Function(''tr'', args=[123, 3, 4], auto_rebind=False)'))
   1840  call assert_equal(function('tr'),
   1841        \ py3eval('vim.Function(''tr'', args=[], auto_rebind=False)'))
   1842  call assert_equal(function('tr', {}),
   1843        \ py3eval('vim.Function(''tr'', self={}, auto_rebind=False)'))
   1844  call assert_equal(function('tr', [123, 3, 4], {}),
   1845        \ py3eval('vim.Function(''tr'', args=[123, 3, 4], self={}, auto_rebind=False)'))
   1846 endfunc
   1847 
   1848 " Test vim.Function
   1849 func Test_python3_vim_func()
   1850  throw 'Skipped: Nvim does not support vim.bindeval()'
   1851  function Args(...)
   1852    return a:000
   1853  endfunc
   1854 
   1855  function SelfArgs(...) dict
   1856    return [a:000, self]
   1857  endfunc
   1858 
   1859  " The following four lines should not crash
   1860  let Pt = function('tr', [[]], {'l': []})
   1861  py3 Pt = vim.bindeval('Pt')
   1862  unlet Pt
   1863  py3 del Pt
   1864 
   1865  %bw!
   1866  py3 cb = vim.current.buffer
   1867  py3 << trim EOF
   1868    def ecall(out_prefix, func, *args, **kwargs):
   1869        line = out_prefix + ': '
   1870        try:
   1871            ret = func(*args, **kwargs)
   1872        except Exception:
   1873            line += '!exception: ' + emsg(sys.exc_info())
   1874        else:
   1875            line += '!result: ' + str(vim.Function('string')(ret), 'utf-8')
   1876        cb.append(line)
   1877    a = vim.Function('Args')
   1878    pa1 = vim.Function('Args', args=['abcArgsPA1'])
   1879    pa2 = vim.Function('Args', args=[])
   1880    pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'})
   1881    pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'})
   1882    cb.append('a: ' + repr(a))
   1883    cb.append('pa1: ' + repr(pa1))
   1884    cb.append('pa2: ' + repr(pa2))
   1885    cb.append('pa3: ' + repr(pa3))
   1886    cb.append('pa4: ' + repr(pa4))
   1887    sa = vim.Function('SelfArgs')
   1888    psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1'])
   1889    psa2 = vim.Function('SelfArgs', args=[])
   1890    psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'})
   1891    psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'})
   1892    psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0)
   1893    psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=())
   1894    psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[])
   1895    psa8 = vim.Function('SelfArgs', auto_rebind=False)
   1896    psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True)
   1897    psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1)
   1898    psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'})
   1899    psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC'])
   1900    cb.append('sa: ' + repr(sa))
   1901    cb.append('psa1: ' + repr(psa1))
   1902    cb.append('psa2: ' + repr(psa2))
   1903    cb.append('psa3: ' + repr(psa3))
   1904    cb.append('psa4: ' + repr(psa4))
   1905    cb.append('psa5: ' + repr(psa5))
   1906    cb.append('psa6: ' + repr(psa6))
   1907    cb.append('psa7: ' + repr(psa7))
   1908    cb.append('psa8: ' + repr(psa8))
   1909    cb.append('psa9: ' + repr(psa9))
   1910    cb.append('psaA: ' + repr(psaA))
   1911    cb.append('psaB: ' + repr(psaB))
   1912    cb.append('psaC: ' + repr(psaC))
   1913 
   1914    psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'})
   1915    psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]]
   1916    psar.self['rec'] = psar
   1917    psar.self['self'] = psar.self
   1918    psar.self['args'] = psar.args
   1919 
   1920    try:
   1921      cb.append('psar: ' + repr(psar))
   1922    except Exception:
   1923      cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
   1924  EOF
   1925 
   1926  let expected =<< trim END
   1927    a: <vim.Function 'Args'>
   1928    pa1: <vim.Function 'Args', args=['abcArgsPA1']>
   1929    pa2: <vim.Function 'Args'>
   1930    pa3: <vim.Function 'Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'}>
   1931    pa4: <vim.Function 'Args', self={'abcSelfPA4': 'abcSelfPA4Val'}>
   1932    sa: <vim.Function 'SelfArgs'>
   1933    psa1: <vim.Function 'SelfArgs', args=['abcArgsPSA1']>
   1934    psa2: <vim.Function 'SelfArgs'>
   1935    psa3: <vim.Function 'SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}>
   1936    psa4: <vim.Function 'SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}>
   1937    psa5: <vim.Function 'SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}>
   1938    psa6: <vim.Function 'SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}>
   1939    psa7: <vim.Function 'SelfArgs', args=['abcArgsPSA7']>
   1940    psa8: <vim.Function 'SelfArgs'>
   1941    psa9: <vim.Function 'SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True>
   1942    psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=True>
   1943    psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
   1944    psaC: <vim.Function 'SelfArgs'>
   1945    psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}]}>
   1946  END
   1947  call assert_equal(expected, getline(2, '$'))
   1948  %d
   1949 
   1950  call assert_equal(function('Args'), py3eval('a'))
   1951  call assert_equal(function('Args', ['abcArgsPA1']), py3eval('pa1'))
   1952  call assert_equal(function('Args'), py3eval('pa2'))
   1953  call assert_equal(function('Args', ['abcArgsPA3'], {'abcSelfPA3': 'abcSelfPA3Val'}), py3eval('pa3'))
   1954  call assert_equal(function('Args', {'abcSelfPA4': 'abcSelfPA4Val'}), py3eval('pa4'))
   1955  call assert_equal(function('SelfArgs'), py3eval('sa'))
   1956  call assert_equal(function('SelfArgs', ['abcArgsPSA1']), py3eval('psa1'))
   1957  call assert_equal(function('SelfArgs'), py3eval('psa2'))
   1958  call assert_equal(function('SelfArgs', ['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}), py3eval('psa3'))
   1959  call assert_equal(function('SelfArgs', {'abcSelfPSA4': 'abcSelfPSA4Val'}), py3eval('psa4'))
   1960  call assert_equal(function('SelfArgs', {'abcSelfPSA5': 'abcSelfPSA5Val'}), py3eval('psa5'))
   1961  call assert_equal(function('SelfArgs', ['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'}), py3eval('psa6'))
   1962  call assert_equal(function('SelfArgs', ['abcArgsPSA7']), py3eval('psa7'))
   1963  call assert_equal(function('SelfArgs'), py3eval('psa8'))
   1964  call assert_equal(function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'}), py3eval('psa9'))
   1965  call assert_equal(function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'}), py3eval('psaA'))
   1966  call assert_equal(function('SelfArgs', ['abcArgsPSAB']), py3eval('psaB'))
   1967  call assert_equal(function('SelfArgs'), py3eval('psaC'))
   1968 
   1969  let res = []
   1970  for v in ['sa', 'psa1', 'psa2', 'psa3', 'psa4', 'psa5', 'psa6', 'psa7',
   1971        \ 'psa8', 'psa9', 'psaA', 'psaB', 'psaC']
   1972    let d = {'f': py3eval(v)}
   1973    call add(res, 'd.' .. v .. '(): ' .. string(d.f()))
   1974  endfor
   1975 
   1976  let expected =<< trim END
   1977    d.sa(): [[], {'f': function('SelfArgs')}]
   1978    d.psa1(): [['abcArgsPSA1'], {'f': function('SelfArgs', ['abcArgsPSA1'])}]
   1979    d.psa2(): [[], {'f': function('SelfArgs')}]
   1980    d.psa3(): [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
   1981    d.psa4(): [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
   1982    d.psa5(): [[], {'abcSelfPSA5': 'abcSelfPSA5Val'}]
   1983    d.psa6(): [['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'}]
   1984    d.psa7(): [['abcArgsPSA7'], {'f': function('SelfArgs', ['abcArgsPSA7'])}]
   1985    d.psa8(): [[], {'f': function('SelfArgs')}]
   1986    d.psa9(): [[], {'f': function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'})}]
   1987    d.psaA(): [['abcArgsPSAA'], {'f': function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'})}]
   1988    d.psaB(): [['abcArgsPSAB'], {'f': function('SelfArgs', ['abcArgsPSAB'])}]
   1989    d.psaC(): [[], {'f': function('SelfArgs')}]
   1990  END
   1991  call assert_equal(expected, res)
   1992 
   1993  py3 ecall('a()', a, )
   1994  py3 ecall('pa1()', pa1, )
   1995  py3 ecall('pa2()', pa2, )
   1996  py3 ecall('pa3()', pa3, )
   1997  py3 ecall('pa4()', pa4, )
   1998  py3 ecall('sa()', sa, )
   1999  py3 ecall('psa1()', psa1, )
   2000  py3 ecall('psa2()', psa2, )
   2001  py3 ecall('psa3()', psa3, )
   2002  py3 ecall('psa4()', psa4, )
   2003 
   2004  py3 ecall('a(42, 43)', a, 42, 43)
   2005  py3 ecall('pa1(42, 43)', pa1, 42, 43)
   2006  py3 ecall('pa2(42, 43)', pa2, 42, 43)
   2007  py3 ecall('pa3(42, 43)', pa3, 42, 43)
   2008  py3 ecall('pa4(42, 43)', pa4, 42, 43)
   2009  py3 ecall('sa(42, 43)', sa, 42, 43)
   2010  py3 ecall('psa1(42, 43)', psa1, 42, 43)
   2011  py3 ecall('psa2(42, 43)', psa2, 42, 43)
   2012  py3 ecall('psa3(42, 43)', psa3, 42, 43)
   2013  py3 ecall('psa4(42, 43)', psa4, 42, 43)
   2014 
   2015  py3 ecall('a(42, self={"20": 1})', a, 42, self={'20': 1})
   2016  py3 ecall('pa1(42, self={"20": 1})', pa1, 42, self={'20': 1})
   2017  py3 ecall('pa2(42, self={"20": 1})', pa2, 42, self={'20': 1})
   2018  py3 ecall('pa3(42, self={"20": 1})', pa3, 42, self={'20': 1})
   2019  py3 ecall('pa4(42, self={"20": 1})', pa4, 42, self={'20': 1})
   2020  py3 ecall('sa(42, self={"20": 1})', sa, 42, self={'20': 1})
   2021  py3 ecall('psa1(42, self={"20": 1})', psa1, 42, self={'20': 1})
   2022  py3 ecall('psa2(42, self={"20": 1})', psa2, 42, self={'20': 1})
   2023  py3 ecall('psa3(42, self={"20": 1})', psa3, 42, self={'20': 1})
   2024  py3 ecall('psa4(42, self={"20": 1})', psa4, 42, self={'20': 1})
   2025 
   2026  py3 ecall('a(self={"20": 1})', a, self={'20': 1})
   2027  py3 ecall('pa1(self={"20": 1})', pa1, self={'20': 1})
   2028  py3 ecall('pa2(self={"20": 1})', pa2, self={'20': 1})
   2029  py3 ecall('pa3(self={"20": 1})', pa3, self={'20': 1})
   2030  py3 ecall('pa4(self={"20": 1})', pa4, self={'20': 1})
   2031  py3 ecall('sa(self={"20": 1})', sa, self={'20': 1})
   2032  py3 ecall('psa1(self={"20": 1})', psa1, self={'20': 1})
   2033  py3 ecall('psa2(self={"20": 1})', psa2, self={'20': 1})
   2034  py3 ecall('psa3(self={"20": 1})', psa3, self={'20': 1})
   2035  py3 ecall('psa4(self={"20": 1})', psa4, self={'20': 1})
   2036 
   2037  py3 << trim EOF
   2038    def s(v):
   2039        if v is None:
   2040            return repr(v)
   2041        else:
   2042            return str(vim.Function('string')(v), 'utf-8')
   2043 
   2044    cb.append('a.args: ' + s(a.args))
   2045    cb.append('pa1.args: ' + s(pa1.args))
   2046    cb.append('pa2.args: ' + s(pa2.args))
   2047    cb.append('pa3.args: ' + s(pa3.args))
   2048    cb.append('pa4.args: ' + s(pa4.args))
   2049    cb.append('sa.args: ' + s(sa.args))
   2050    cb.append('psa1.args: ' + s(psa1.args))
   2051    cb.append('psa2.args: ' + s(psa2.args))
   2052    cb.append('psa3.args: ' + s(psa3.args))
   2053    cb.append('psa4.args: ' + s(psa4.args))
   2054 
   2055    cb.append('a.self: ' + s(a.self))
   2056    cb.append('pa1.self: ' + s(pa1.self))
   2057    cb.append('pa2.self: ' + s(pa2.self))
   2058    cb.append('pa3.self: ' + s(pa3.self))
   2059    cb.append('pa4.self: ' + s(pa4.self))
   2060    cb.append('sa.self: ' + s(sa.self))
   2061    cb.append('psa1.self: ' + s(psa1.self))
   2062    cb.append('psa2.self: ' + s(psa2.self))
   2063    cb.append('psa3.self: ' + s(psa3.self))
   2064    cb.append('psa4.self: ' + s(psa4.self))
   2065 
   2066    cb.append('a.name: ' + s(a.name))
   2067    cb.append('pa1.name: ' + s(pa1.name))
   2068    cb.append('pa2.name: ' + s(pa2.name))
   2069    cb.append('pa3.name: ' + s(pa3.name))
   2070    cb.append('pa4.name: ' + s(pa4.name))
   2071    cb.append('sa.name: ' + s(sa.name))
   2072    cb.append('psa1.name: ' + s(psa1.name))
   2073    cb.append('psa2.name: ' + s(psa2.name))
   2074    cb.append('psa3.name: ' + s(psa3.name))
   2075    cb.append('psa4.name: ' + s(psa4.name))
   2076 
   2077    cb.append('a.auto_rebind: ' + s(a.auto_rebind))
   2078    cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind))
   2079    cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind))
   2080    cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind))
   2081    cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind))
   2082    cb.append('sa.auto_rebind: ' + s(sa.auto_rebind))
   2083    cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind))
   2084    cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind))
   2085    cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind))
   2086    cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind))
   2087    cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind))
   2088    cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind))
   2089    cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind))
   2090    cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind))
   2091    cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind))
   2092    cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind))
   2093    cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind))
   2094    cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind))
   2095 
   2096    del s
   2097 
   2098    del a
   2099    del pa1
   2100    del pa2
   2101    del pa3
   2102    del pa4
   2103    del sa
   2104    del psa1
   2105    del psa2
   2106    del psa3
   2107    del psa4
   2108    del psa5
   2109    del psa6
   2110    del psa7
   2111    del psa8
   2112    del psa9
   2113    del psaA
   2114    del psaB
   2115    del psaC
   2116    del psar
   2117 
   2118    del ecall
   2119  EOF
   2120 
   2121  let expected =<< trim END
   2122    a(): !result: []
   2123    pa1(): !result: ['abcArgsPA1']
   2124    pa2(): !result: []
   2125    pa3(): !result: ['abcArgsPA3']
   2126    pa4(): !result: []
   2127    sa(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
   2128    psa1(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
   2129    psa2(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
   2130    psa3(): !result: [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
   2131    psa4(): !result: [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
   2132    a(42, 43): !result: [42, 43]
   2133    pa1(42, 43): !result: ['abcArgsPA1', 42, 43]
   2134    pa2(42, 43): !result: [42, 43]
   2135    pa3(42, 43): !result: ['abcArgsPA3', 42, 43]
   2136    pa4(42, 43): !result: [42, 43]
   2137    sa(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
   2138    psa1(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
   2139    psa2(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
   2140    psa3(42, 43): !result: [['abcArgsPSA3', 42, 43], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
   2141    psa4(42, 43): !result: [[42, 43], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
   2142    a(42, self={"20": 1}): !result: [42]
   2143    pa1(42, self={"20": 1}): !result: ['abcArgsPA1', 42]
   2144    pa2(42, self={"20": 1}): !result: [42]
   2145    pa3(42, self={"20": 1}): !result: ['abcArgsPA3', 42]
   2146    pa4(42, self={"20": 1}): !result: [42]
   2147    sa(42, self={"20": 1}): !result: [[42], {'20': 1}]
   2148    psa1(42, self={"20": 1}): !result: [['abcArgsPSA1', 42], {'20': 1}]
   2149    psa2(42, self={"20": 1}): !result: [[42], {'20': 1}]
   2150    psa3(42, self={"20": 1}): !result: [['abcArgsPSA3', 42], {'20': 1}]
   2151    psa4(42, self={"20": 1}): !result: [[42], {'20': 1}]
   2152    a(self={"20": 1}): !result: []
   2153    pa1(self={"20": 1}): !result: ['abcArgsPA1']
   2154    pa2(self={"20": 1}): !result: []
   2155    pa3(self={"20": 1}): !result: ['abcArgsPA3']
   2156    pa4(self={"20": 1}): !result: []
   2157    sa(self={"20": 1}): !result: [[], {'20': 1}]
   2158    psa1(self={"20": 1}): !result: [['abcArgsPSA1'], {'20': 1}]
   2159    psa2(self={"20": 1}): !result: [[], {'20': 1}]
   2160    psa3(self={"20": 1}): !result: [['abcArgsPSA3'], {'20': 1}]
   2161    psa4(self={"20": 1}): !result: [[], {'20': 1}]
   2162    a.args: None
   2163    pa1.args: ['abcArgsPA1']
   2164    pa2.args: None
   2165    pa3.args: ['abcArgsPA3']
   2166    pa4.args: None
   2167    sa.args: None
   2168    psa1.args: ['abcArgsPSA1']
   2169    psa2.args: None
   2170    psa3.args: ['abcArgsPSA3']
   2171    psa4.args: None
   2172    a.self: None
   2173    pa1.self: None
   2174    pa2.self: None
   2175    pa3.self: {'abcSelfPA3': 'abcSelfPA3Val'}
   2176    pa4.self: {'abcSelfPA4': 'abcSelfPA4Val'}
   2177    sa.self: None
   2178    psa1.self: None
   2179    psa2.self: None
   2180    psa3.self: {'abcSelfPSA3': 'abcSelfPSA3Val'}
   2181    psa4.self: {'abcSelfPSA4': 'abcSelfPSA4Val'}
   2182    a.name: 'Args'
   2183    pa1.name: 'Args'
   2184    pa2.name: 'Args'
   2185    pa3.name: 'Args'
   2186    pa4.name: 'Args'
   2187    sa.name: 'SelfArgs'
   2188    psa1.name: 'SelfArgs'
   2189    psa2.name: 'SelfArgs'
   2190    psa3.name: 'SelfArgs'
   2191    psa4.name: 'SelfArgs'
   2192    a.auto_rebind: 1
   2193    pa1.auto_rebind: 1
   2194    pa2.auto_rebind: 1
   2195    pa3.auto_rebind: 0
   2196    pa4.auto_rebind: 0
   2197    sa.auto_rebind: 1
   2198    psa1.auto_rebind: 1
   2199    psa2.auto_rebind: 1
   2200    psa3.auto_rebind: 0
   2201    psa4.auto_rebind: 0
   2202    psa5.auto_rebind: 0
   2203    psa6.auto_rebind: 0
   2204    psa7.auto_rebind: 1
   2205    psa8.auto_rebind: 1
   2206    psa9.auto_rebind: 1
   2207    psaA.auto_rebind: 1
   2208    psaB.auto_rebind: 1
   2209    psaC.auto_rebind: 1
   2210  END
   2211  call assert_equal(expected, getline(2, '$'))
   2212  %bw!
   2213 endfunc
   2214 
   2215 " Test stdout/stderr
   2216 func Test_python3_stdin_stderr()
   2217  throw 'Skipped: TODO: '
   2218  let caught_writeerr = 0
   2219  let caught_writelineerr = 0
   2220  redir => messages
   2221  py3 sys.stdout.write('abc8') ; sys.stdout.write('def')
   2222  try
   2223    py3 sys.stderr.write('abc9') ; sys.stderr.write('def')
   2224  catch /abc9def/
   2225    let caught_writeerr = 1
   2226  endtry
   2227  py3 sys.stdout.writelines(iter('abcA'))
   2228  try
   2229    py3 sys.stderr.writelines(iter('abcB'))
   2230  catch /abcB/
   2231    let caught_writelineerr = 1
   2232  endtry
   2233  redir END
   2234  call assert_equal("\nabc8def\nabcA", messages)
   2235  call assert_equal(1, caught_writeerr)
   2236  call assert_equal(1, caught_writelineerr)
   2237 endfunc
   2238 
   2239 " Test subclassing
   2240 func Test_python3_subclass()
   2241  throw "Skipped: Nvim: 'LegacyVim' object has no attribute 'Dictionary'"
   2242  new
   2243  func Put(...)
   2244    return a:000
   2245  endfunc
   2246 
   2247  py3 << trim EOF
   2248    class DupDict(vim.Dictionary):
   2249      def __setitem__(self, key, value):
   2250        super(DupDict, self).__setitem__(key, value)
   2251        super(DupDict, self).__setitem__('dup_' + key, value)
   2252    dd = DupDict()
   2253    dd['a'] = 'b'
   2254 
   2255    class DupList(vim.List):
   2256      def __getitem__(self, idx):
   2257        return [super(DupList, self).__getitem__(idx)] * 2
   2258 
   2259    dl = DupList()
   2260    dl2 = DupList(iter('abcC'))
   2261    dl.extend(dl2[0])
   2262 
   2263    class DupFun(vim.Function):
   2264      def __call__(self, arg):
   2265        return super(DupFun, self).__call__(arg, arg)
   2266 
   2267    df = DupFun('Put')
   2268  EOF
   2269 
   2270  call assert_equal(['a', 'dup_a'], sort(keys(py3eval('dd'))))
   2271  call assert_equal(['a', 'a'], py3eval('dl'))
   2272  call assert_equal(['a', 'b', 'c', 'C'], py3eval('dl2'))
   2273  call assert_equal([2, 2], py3eval('df(2)'))
   2274  call assert_equal(1, py3eval('dl') is# py3eval('dl'))
   2275  call assert_equal(1, py3eval('dd') is# py3eval('dd'))
   2276  call assert_equal(function('Put'), py3eval('df'))
   2277  delfunction Put
   2278  py3 << trim EOF
   2279    del DupDict
   2280    del DupList
   2281    del DupFun
   2282    del dd
   2283    del dl
   2284    del dl2
   2285    del df
   2286  EOF
   2287  close!
   2288 endfunc
   2289 
   2290 " Test chdir
   2291 func Test_python3_chdir()
   2292  throw "Skipped: Nvim: 'LegacyVim' object has no attribute 'Function'"
   2293  new Xfile
   2294  py3 cb = vim.current.buffer
   2295  py3 << trim EOF
   2296    import os
   2297    fnamemodify = vim.Function('fnamemodify')
   2298    cb.append(str(fnamemodify('.', ':p:h:t')))
   2299    cb.append(vim.eval('@%'))
   2300    os.chdir('..')
   2301    path = fnamemodify('.', ':p:h:t')
   2302    if path != b'src' and path != b'src2':
   2303      # Running tests from a shadow directory, so move up another level
   2304      # This will result in @% looking like shadow/testdir/Xfile, hence the
   2305      # slicing to remove the leading path and path separator
   2306      os.chdir('..')
   2307      cb.append(str(fnamemodify('.', ':p:h:t')))
   2308      cb.append(vim.eval('@%')[len(path)+1:].replace(os.path.sep, '/'))
   2309      os.chdir(path)
   2310      del path
   2311    else:
   2312      # Also accept running from src2/testdir/ for MS-Windows CI.
   2313      cb.append(str(fnamemodify('.', ':p:h:t').replace(b'src2', b'src')))
   2314      cb.append(vim.eval('@%').replace(os.path.sep, '/'))
   2315    del path
   2316    os.chdir('testdir')
   2317    cb.append(str(fnamemodify('.', ':p:h:t')))
   2318    cb.append(vim.eval('@%'))
   2319    del fnamemodify
   2320  EOF
   2321  call assert_equal(["b'testdir'", 'Xfile', "b'src'", 'testdir/Xfile',
   2322        \"b'testdir'", 'Xfile'], getline(2, '$'))
   2323  close!
   2324 endfunc
   2325 
   2326 " Test errors
   2327 func Test_python3_errors()
   2328  throw 'Skipped: Nvim does not support vim.bindeval()'
   2329  func F() dict
   2330  endfunc
   2331 
   2332  func D()
   2333  endfunc
   2334 
   2335  new
   2336  py3 cb = vim.current.buffer
   2337 
   2338  py3 << trim EOF
   2339    import os
   2340    d = vim.Dictionary()
   2341    ned = vim.Dictionary(foo='bar', baz='abcD')
   2342    dl = vim.Dictionary(a=1)
   2343    dl.locked = True
   2344    l = vim.List()
   2345    ll = vim.List('abcE')
   2346    ll.locked = True
   2347    nel = vim.List('abcO')
   2348    f = vim.Function('string')
   2349    fd = vim.Function('F')
   2350    fdel = vim.Function('D')
   2351    vim.command('delfunction D')
   2352 
   2353    def subexpr_test(expr, name, subexprs):
   2354        cb.append('>>> Testing %s using %s' % (name, expr))
   2355        for subexpr in subexprs:
   2356            ee(expr % subexpr)
   2357        cb.append('<<< Finished')
   2358 
   2359    def stringtochars_test(expr):
   2360        return subexpr_test(expr, 'StringToChars', (
   2361            '1',       # Fail type checks
   2362            'b"\\0"',  # Fail PyString_AsStringAndSize(object, , NULL) check
   2363            '"\\0"',   # Fail PyString_AsStringAndSize(bytes, , NULL) check
   2364        ))
   2365 
   2366    class Mapping(object):
   2367        def __init__(self, d):
   2368            self.d = d
   2369 
   2370        def __getitem__(self, key):
   2371            return self.d[key]
   2372 
   2373        def keys(self):
   2374            return self.d.keys()
   2375 
   2376        def items(self):
   2377            return self.d.items()
   2378 
   2379    def convertfrompyobject_test(expr, recurse=True):
   2380        # pydict_to_tv
   2381        stringtochars_test(expr % '{%s : 1}')
   2382        if recurse:
   2383            convertfrompyobject_test(expr % '{"abcF" : %s}', False)
   2384        # pymap_to_tv
   2385        stringtochars_test(expr % 'Mapping({%s : 1})')
   2386        if recurse:
   2387            convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False)
   2388        # pyseq_to_tv
   2389        iter_test(expr)
   2390        return subexpr_test(expr, 'ConvertFromPyObject', (
   2391            'None',                 # Not conversible
   2392            '{b"": 1}',             # Empty key not allowed
   2393            '{"": 1}',              # Same, but with unicode object
   2394            'FailingMapping()',     #
   2395            'FailingMappingKey()',  #
   2396            'FailingNumber()',      #
   2397        ))
   2398 
   2399    def convertfrompymapping_test(expr):
   2400        convertfrompyobject_test(expr)
   2401        return subexpr_test(expr, 'ConvertFromPyMapping', (
   2402            '[]',
   2403        ))
   2404 
   2405    def iter_test(expr):
   2406        return subexpr_test(expr, '*Iter*', (
   2407            'FailingIter()',
   2408            'FailingIterNext()',
   2409        ))
   2410 
   2411    def number_test(expr, natural=False, unsigned=False):
   2412        if natural:
   2413            unsigned = True
   2414        return subexpr_test(expr, 'NumberToLong', (
   2415            '[]',
   2416            'None',
   2417        ) + (('-1',) if unsigned else ())
   2418        + (('0',) if natural else ()))
   2419 
   2420    class FailingTrue(object):
   2421        def __bool__(self):
   2422            raise NotImplementedError('bool')
   2423 
   2424    class FailingIter(object):
   2425        def __iter__(self):
   2426            raise NotImplementedError('iter')
   2427 
   2428    class FailingIterNext(object):
   2429        def __iter__(self):
   2430            return self
   2431 
   2432        def __next__(self):
   2433          raise NotImplementedError('next')
   2434 
   2435    class FailingIterNextN(object):
   2436        def __init__(self, n):
   2437            self.n = n
   2438 
   2439        def __iter__(self):
   2440            return self
   2441 
   2442        def __next__(self):
   2443            if self.n:
   2444                self.n -= 1
   2445                return 1
   2446            else:
   2447                raise NotImplementedError('next N')
   2448 
   2449    class FailingMappingKey(object):
   2450        def __getitem__(self, item):
   2451            raise NotImplementedError('getitem:mappingkey')
   2452 
   2453        def keys(self):
   2454            return list("abcH")
   2455 
   2456    class FailingMapping(object):
   2457        def __getitem__(self):
   2458            raise NotImplementedError('getitem:mapping')
   2459 
   2460        def keys(self):
   2461            raise NotImplementedError('keys')
   2462 
   2463    class FailingList(list):
   2464        def __getitem__(self, idx):
   2465            if i == 2:
   2466                raise NotImplementedError('getitem:list')
   2467            else:
   2468                return super(FailingList, self).__getitem__(idx)
   2469 
   2470    class NoArgsCall(object):
   2471        def __call__(self):
   2472            pass
   2473 
   2474    class FailingCall(object):
   2475        def __call__(self, path):
   2476            raise NotImplementedError('call')
   2477 
   2478    class FailingNumber(object):
   2479        def __int__(self):
   2480            raise NotImplementedError('int')
   2481 
   2482    cb.append("> Output")
   2483    cb.append(">> OutputSetattr")
   2484    ee('del sys.stdout.softspace')
   2485    number_test('sys.stdout.softspace = %s', unsigned=True)
   2486    number_test('sys.stderr.softspace = %s', unsigned=True)
   2487    ee('assert sys.stdout.isatty()==False')
   2488    ee('assert sys.stdout.seekable()==False')
   2489    ee('sys.stdout.close()')
   2490    ee('sys.stdout.flush()')
   2491    ee('assert sys.stderr.isatty()==False')
   2492    ee('assert sys.stderr.seekable()==False')
   2493    ee('sys.stderr.close()')
   2494    ee('sys.stderr.flush()')
   2495    ee('sys.stdout.attr = None')
   2496    cb.append(">> OutputWrite")
   2497    ee('assert sys.stdout.writable()==True')
   2498    ee('assert sys.stdout.readable()==False')
   2499    ee('assert sys.stderr.writable()==True')
   2500    ee('assert sys.stderr.readable()==False')
   2501    ee('assert sys.stdout.closed()==False')
   2502    ee('assert sys.stderr.closed()==False')
   2503    ee('assert sys.stdout.errors=="strict"')
   2504    ee('assert sys.stderr.errors=="strict"')
   2505    ee('assert sys.stdout.encoding==sys.stderr.encoding')
   2506    ee('sys.stdout.write(None)')
   2507    cb.append(">> OutputWriteLines")
   2508    ee('sys.stdout.writelines(None)')
   2509    ee('sys.stdout.writelines([1])')
   2510    iter_test('sys.stdout.writelines(%s)')
   2511    cb.append("> VimCommand")
   2512    stringtochars_test('vim.command(%s)')
   2513    ee('vim.command("", 2)')
   2514    #! Not checked: vim->python exceptions translating: checked later
   2515    cb.append("> VimToPython")
   2516    #! Not checked: everything: needs errors in internal python functions
   2517    cb.append("> VimEval")
   2518    stringtochars_test('vim.eval(%s)')
   2519    ee('vim.eval("", FailingTrue())')
   2520    #! Not checked: everything: needs errors in internal python functions
   2521    cb.append("> VimEvalPy")
   2522    stringtochars_test('vim.bindeval(%s)')
   2523    ee('vim.eval("", 2)')
   2524    #! Not checked: vim->python exceptions translating: checked later
   2525    cb.append("> VimStrwidth")
   2526    stringtochars_test('vim.strwidth(%s)')
   2527    cb.append("> VimForeachRTP")
   2528    ee('vim.foreach_rtp(None)')
   2529    ee('vim.foreach_rtp(NoArgsCall())')
   2530    ee('vim.foreach_rtp(FailingCall())')
   2531    ee('vim.foreach_rtp(int, 2)')
   2532    cb.append('> import')
   2533    old_rtp = vim.options['rtp']
   2534    vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,')
   2535    ee('import xxx_no_such_module_xxx')
   2536    ee('import failing_import')
   2537    ee('import failing')
   2538    vim.options['rtp'] = old_rtp
   2539    del old_rtp
   2540    cb.append("> Options")
   2541    cb.append(">> OptionsItem")
   2542    ee('vim.options["abcQ"]')
   2543    ee('vim.options[""]')
   2544    stringtochars_test('vim.options[%s]')
   2545    cb.append(">> OptionsContains")
   2546    stringtochars_test('%s in vim.options')
   2547    cb.append("> Dictionary")
   2548    cb.append(">> DictionaryConstructor")
   2549    ee('vim.Dictionary("abcI")')
   2550    ##! Not checked: py_dict_alloc failure
   2551    cb.append(">> DictionarySetattr")
   2552    ee('del d.locked')
   2553    ee('d.locked = FailingTrue()')
   2554    ee('vim.vvars.locked = False')
   2555    ee('d.scope = True')
   2556    ee('d.xxx = True')
   2557    cb.append(">> _DictionaryItem")
   2558    ee('d.get("a", 2, 3)')
   2559    stringtochars_test('d.get(%s)')
   2560    ee('d.pop("a")')
   2561    ee('dl.pop("a")')
   2562    cb.append(">> DictionaryContains")
   2563    ee('"" in d')
   2564    ee('0 in d')
   2565    cb.append(">> DictionaryIterNext")
   2566    ee('for i in ned: ned["a"] = 1')
   2567    del i
   2568    cb.append(">> DictionaryAssItem")
   2569    ee('dl["b"] = 1')
   2570    stringtochars_test('d[%s] = 1')
   2571    convertfrompyobject_test('d["a"] = %s')
   2572    cb.append(">> DictionaryUpdate")
   2573    cb.append(">>> kwargs")
   2574    cb.append(">>> iter")
   2575    ee('d.update(FailingMapping())')
   2576    ee('d.update([FailingIterNext()])')
   2577    ee('d.update([FailingIterNextN(1)])')
   2578    iter_test('d.update(%s)')
   2579    convertfrompyobject_test('d.update(%s)')
   2580    stringtochars_test('d.update(((%s, 0),))')
   2581    convertfrompyobject_test('d.update((("a", %s),))')
   2582    cb.append(">> DictionaryPopItem")
   2583    ee('d.popitem(1, 2)')
   2584    cb.append(">> DictionaryHasKey")
   2585    ee('d.has_key()')
   2586    cb.append("> List")
   2587    cb.append(">> ListConstructor")
   2588    ee('vim.List(1, 2)')
   2589    ee('vim.List(a=1)')
   2590    iter_test('vim.List(%s)')
   2591    convertfrompyobject_test('vim.List([%s])')
   2592    cb.append(">> ListItem")
   2593    ee('l[1000]')
   2594    cb.append(">> ListAssItem")
   2595    ee('ll[1] = 2')
   2596    ee('l[1000] = 3')
   2597    cb.append(">> ListAssSlice")
   2598    ee('ll[1:100] = "abcJ"')
   2599    iter_test('l[:] = %s')
   2600    ee('nel[1:10:2]  = "abcK"')
   2601    cb.append(repr(tuple(nel)))
   2602    ee('nel[1:10:2]  = "a"')
   2603    cb.append(repr(tuple(nel)))
   2604    ee('nel[1:1:-1]  = "a"')
   2605    cb.append(repr(tuple(nel)))
   2606    ee('nel[:] = FailingIterNextN(2)')
   2607    cb.append(repr(tuple(nel)))
   2608    convertfrompyobject_test('l[:] = [%s]')
   2609    cb.append(">> ListConcatInPlace")
   2610    iter_test('l.extend(%s)')
   2611    convertfrompyobject_test('l.extend([%s])')
   2612    cb.append(">> ListSetattr")
   2613    ee('del l.locked')
   2614    ee('l.locked = FailingTrue()')
   2615    ee('l.xxx = True')
   2616    cb.append("> Function")
   2617    cb.append(">> FunctionConstructor")
   2618    cb.append(">>> FunctionConstructor")
   2619    ee('vim.Function("123")')
   2620    ee('vim.Function("xxx_non_existent_function_xxx")')
   2621    ee('vim.Function("xxx#non#existent#function#xxx")')
   2622    ee('vim.Function("xxx_non_existent_function_xxx2", args=[])')
   2623    ee('vim.Function("xxx_non_existent_function_xxx3", self={})')
   2624    ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})')
   2625    cb.append(">>> FunctionNew")
   2626    ee('vim.Function("tr", self="abcFuncSelf")')
   2627    ee('vim.Function("tr", args=427423)')
   2628    ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")')
   2629    ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")')
   2630    ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")')
   2631    ee('vim.Function("tr", "")')
   2632    cb.append(">> FunctionCall")
   2633    convertfrompyobject_test('f(%s)')
   2634    convertfrompymapping_test('fd(self=%s)')
   2635    cb.append("> TabPage")
   2636    cb.append(">> TabPageAttr")
   2637    ee('vim.current.tabpage.xxx')
   2638    cb.append("> TabList")
   2639    cb.append(">> TabListItem")
   2640    ee('vim.tabpages[1000]')
   2641    cb.append("> Window")
   2642    cb.append(">> WindowAttr")
   2643    ee('vim.current.window.xxx')
   2644    cb.append(">> WindowSetattr")
   2645    ee('vim.current.window.buffer = 0')
   2646    ee('vim.current.window.cursor = (100000000, 100000000)')
   2647    ee('vim.current.window.cursor = True')
   2648    number_test('vim.current.window.height = %s', unsigned=True)
   2649    number_test('vim.current.window.width = %s', unsigned=True)
   2650    ee('vim.current.window.xxxxxx = True')
   2651    cb.append("> WinList")
   2652    cb.append(">> WinListItem")
   2653    ee('vim.windows[1000]')
   2654    cb.append("> Buffer")
   2655    cb.append(">> StringToLine (indirect)")
   2656    ee('vim.current.buffer[0] = "\\na"')
   2657    ee('vim.current.buffer[0] = b"\\na"')
   2658    cb.append(">> SetBufferLine (indirect)")
   2659    ee('vim.current.buffer[0] = True')
   2660    cb.append(">> SetBufferLineList (indirect)")
   2661    ee('vim.current.buffer[:] = True')
   2662    ee('vim.current.buffer[:] = ["\\na", "bc"]')
   2663    cb.append(">> InsertBufferLines (indirect)")
   2664    ee('vim.current.buffer.append(None)')
   2665    ee('vim.current.buffer.append(["\\na", "bc"])')
   2666    ee('vim.current.buffer.append("\\nbc")')
   2667    cb.append(">> RBItem")
   2668    ee('vim.current.buffer[100000000]')
   2669    cb.append(">> RBAsItem")
   2670    ee('vim.current.buffer[100000000] = ""')
   2671    cb.append(">> BufferAttr")
   2672    ee('vim.current.buffer.xxx')
   2673    cb.append(">> BufferSetattr")
   2674    ee('vim.current.buffer.name = True')
   2675    ee('vim.current.buffer.xxx = True')
   2676    cb.append(">> BufferMark")
   2677    ee('vim.current.buffer.mark(0)')
   2678    ee('vim.current.buffer.mark("abcM")')
   2679    ee('vim.current.buffer.mark("!")')
   2680    cb.append(">> BufferRange")
   2681    ee('vim.current.buffer.range(1, 2, 3)')
   2682    cb.append("> BufMap")
   2683    cb.append(">> BufMapItem")
   2684    ee('vim.buffers[100000000]')
   2685    number_test('vim.buffers[%s]', natural=True)
   2686    cb.append("> Current")
   2687    cb.append(">> CurrentGetattr")
   2688    ee('vim.current.xxx')
   2689    cb.append(">> CurrentSetattr")
   2690    ee('vim.current.line = True')
   2691    ee('vim.current.buffer = True')
   2692    ee('vim.current.window = True')
   2693    ee('vim.current.tabpage = True')
   2694    ee('vim.current.xxx = True')
   2695    del d
   2696    del ned
   2697    del dl
   2698    del l
   2699    del ll
   2700    del nel
   2701    del f
   2702    del fd
   2703    del fdel
   2704    del subexpr_test
   2705    del stringtochars_test
   2706    del Mapping
   2707    del convertfrompyobject_test
   2708    del convertfrompymapping_test
   2709    del iter_test
   2710    del number_test
   2711    del FailingTrue
   2712    del FailingIter
   2713    del FailingIterNext
   2714    del FailingIterNextN
   2715    del FailingMapping
   2716    del FailingMappingKey
   2717    del FailingList
   2718    del NoArgsCall
   2719    del FailingCall
   2720    del FailingNumber
   2721  EOF
   2722  delfunction F
   2723 
   2724  let expected =<< trim END
   2725    > Output
   2726    >> OutputSetattr
   2727    del sys.stdout.softspace:(<class 'AttributeError'>, AttributeError('cannot delete OutputObject attributes',))
   2728    >>> Testing NumberToLong using sys.stdout.softspace = %s
   2729    sys.stdout.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
   2730    sys.stdout.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
   2731    sys.stdout.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
   2732    <<< Finished
   2733    >>> Testing NumberToLong using sys.stderr.softspace = %s
   2734    sys.stderr.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
   2735    sys.stderr.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
   2736    sys.stderr.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
   2737    <<< Finished
   2738    assert sys.stdout.isatty()==False:NOT FAILED
   2739    assert sys.stdout.seekable()==False:NOT FAILED
   2740    sys.stdout.close():NOT FAILED
   2741    sys.stdout.flush():NOT FAILED
   2742    assert sys.stderr.isatty()==False:NOT FAILED
   2743    assert sys.stderr.seekable()==False:NOT FAILED
   2744    sys.stderr.close():NOT FAILED
   2745    sys.stderr.flush():NOT FAILED
   2746    sys.stdout.attr = None:(<class 'AttributeError'>, AttributeError('invalid attribute: attr',))
   2747    >> OutputWrite
   2748    assert sys.stdout.writable()==True:NOT FAILED
   2749    assert sys.stdout.readable()==False:NOT FAILED
   2750    assert sys.stderr.writable()==True:NOT FAILED
   2751    assert sys.stderr.readable()==False:NOT FAILED
   2752    assert sys.stdout.closed()==False:NOT FAILED
   2753    assert sys.stderr.closed()==False:NOT FAILED
   2754    assert sys.stdout.errors=="strict":NOT FAILED
   2755    assert sys.stderr.errors=="strict":NOT FAILED
   2756    assert sys.stdout.encoding==sys.stderr.encoding:NOT FAILED
   2757    sys.stdout.write(None):(<class 'TypeError'>, TypeError("Can't convert 'NoneType' object to str implicitly",))
   2758    >> OutputWriteLines
   2759    sys.stdout.writelines(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
   2760    sys.stdout.writelines([1]):(<class 'TypeError'>, TypeError("Can't convert 'int' object to str implicitly",))
   2761    >>> Testing *Iter* using sys.stdout.writelines(%s)
   2762    sys.stdout.writelines(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
   2763    sys.stdout.writelines(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
   2764    <<< Finished
   2765    > VimCommand
   2766    >>> Testing StringToChars using vim.command(%s)
   2767    vim.command(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2768    vim.command(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2769    vim.command("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2770    <<< Finished
   2771    vim.command("", 2):(<class 'TypeError'>, TypeError('command() takes exactly one argument (2 given)',))
   2772    > VimToPython
   2773    > VimEval
   2774    >>> Testing StringToChars using vim.eval(%s)
   2775    vim.eval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2776    vim.eval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2777    vim.eval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2778    <<< Finished
   2779    vim.eval("", FailingTrue()):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
   2780    > VimEvalPy
   2781    >>> Testing StringToChars using vim.bindeval(%s)
   2782    vim.bindeval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2783    vim.bindeval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2784    vim.bindeval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2785    <<< Finished
   2786    vim.eval("", 2):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
   2787    > VimStrwidth
   2788    >>> Testing StringToChars using vim.strwidth(%s)
   2789    vim.strwidth(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2790    vim.strwidth(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2791    vim.strwidth("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2792    <<< Finished
   2793    > VimForeachRTP
   2794    vim.foreach_rtp(None):(<class 'TypeError'>, TypeError("'NoneType' object is not callable",))
   2795    vim.foreach_rtp(NoArgsCall()):(<class 'TypeError'>, TypeError('__call__() takes exactly 1 positional argument (2 given)',))
   2796    vim.foreach_rtp(FailingCall()):(<class 'NotImplementedError'>, NotImplementedError('call',))
   2797    vim.foreach_rtp(int, 2):(<class 'TypeError'>, TypeError('foreach_rtp() takes exactly one argument (2 given)',))
   2798    > import
   2799    import xxx_no_such_module_xxx:(<class 'ImportError'>, ImportError('No module named xxx_no_such_module_xxx',))
   2800    import failing_import:(<class 'ImportError'>, ImportError())
   2801    import failing:(<class 'NotImplementedError'>, NotImplementedError())
   2802    > Options
   2803    >> OptionsItem
   2804    vim.options["abcQ"]:(<class 'KeyError'>, KeyError('abcQ',))
   2805    vim.options[""]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   2806    >>> Testing StringToChars using vim.options[%s]
   2807    vim.options[1]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2808    vim.options[b"\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2809    vim.options["\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2810    <<< Finished
   2811    >> OptionsContains
   2812    >>> Testing StringToChars using %s in vim.options
   2813    1 in vim.options:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2814    b"\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2815    "\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2816    <<< Finished
   2817    > Dictionary
   2818    >> DictionaryConstructor
   2819    vim.Dictionary("abcI"):(<class 'ValueError'>, ValueError('expected sequence element of size 2, but got sequence of size 1',))
   2820    >> DictionarySetattr
   2821    del d.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.Dictionary attributes',))
   2822    d.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',))
   2823    vim.vvars.locked = False:(<class 'TypeError'>, TypeError('cannot modify fixed dictionary',))
   2824    d.scope = True:(<class 'AttributeError'>, AttributeError('cannot set attribute scope',))
   2825    d.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
   2826    >> _DictionaryItem
   2827    d.get("a", 2, 3):(<class 'TypeError'>, TypeError('function takes at most 2 arguments (3 given)',))
   2828    >>> Testing StringToChars using d.get(%s)
   2829    d.get(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2830    d.get(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2831    d.get("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2832    <<< Finished
   2833    d.pop("a"):(<class 'KeyError'>, KeyError('a',))
   2834    dl.pop("a"):(<class 'vim.error'>, error('dictionary is locked',))
   2835    >> DictionaryContains
   2836    "" in d:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   2837    0 in d:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2838    >> DictionaryIterNext
   2839    for i in ned: ned["a"] = 1:(<class 'RuntimeError'>, RuntimeError('hashtab changed during iteration',))
   2840    >> DictionaryAssItem
   2841    dl["b"] = 1:(<class 'vim.error'>, error('dictionary is locked',))
   2842    >>> Testing StringToChars using d[%s] = 1
   2843    d[1] = 1:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2844    d[b"\0"] = 1:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2845    d["\0"] = 1:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2846    <<< Finished
   2847    >>> Testing StringToChars using d["a"] = {%s : 1}
   2848    d["a"] = {1 : 1}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2849    d["a"] = {b"\0" : 1}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2850    d["a"] = {"\0" : 1}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2851    <<< Finished
   2852    >>> Testing StringToChars using d["a"] = {"abcF" : {%s : 1}}
   2853    d["a"] = {"abcF" : {1 : 1}}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2854    d["a"] = {"abcF" : {b"\0" : 1}}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2855    d["a"] = {"abcF" : {"\0" : 1}}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2856    <<< Finished
   2857    >>> Testing StringToChars using d["a"] = {"abcF" : Mapping({%s : 1})}
   2858    d["a"] = {"abcF" : Mapping({1 : 1})}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2859    d["a"] = {"abcF" : Mapping({b"\0" : 1})}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2860    d["a"] = {"abcF" : Mapping({"\0" : 1})}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2861    <<< Finished
   2862    >>> Testing *Iter* using d["a"] = {"abcF" : %s}
   2863    d["a"] = {"abcF" : FailingIter()}:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   2864    d["a"] = {"abcF" : FailingIterNext()}:(<class 'NotImplementedError'>, NotImplementedError('next',))
   2865    <<< Finished
   2866    >>> Testing ConvertFromPyObject using d["a"] = {"abcF" : %s}
   2867    d["a"] = {"abcF" : None}:NOT FAILED
   2868    d["a"] = {"abcF" : {b"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   2869    d["a"] = {"abcF" : {"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   2870    d["a"] = {"abcF" : FailingMapping()}:(<class 'NotImplementedError'>, NotImplementedError('keys',))
   2871    d["a"] = {"abcF" : FailingMappingKey()}:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   2872    d["a"] = {"abcF" : FailingNumber()}:(<class 'NotImplementedError'>, NotImplementedError('int',))
   2873    <<< Finished
   2874    >>> Testing StringToChars using d["a"] = Mapping({%s : 1})
   2875    d["a"] = Mapping({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2876    d["a"] = Mapping({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2877    d["a"] = Mapping({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2878    <<< Finished
   2879    >>> Testing StringToChars using d["a"] = Mapping({"abcG" : {%s : 1}})
   2880    d["a"] = Mapping({"abcG" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2881    d["a"] = Mapping({"abcG" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2882    d["a"] = Mapping({"abcG" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2883    <<< Finished
   2884    >>> Testing StringToChars using d["a"] = Mapping({"abcG" : Mapping({%s : 1})})
   2885    d["a"] = Mapping({"abcG" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2886    d["a"] = Mapping({"abcG" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2887    d["a"] = Mapping({"abcG" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2888    <<< Finished
   2889    >>> Testing *Iter* using d["a"] = Mapping({"abcG" : %s})
   2890    d["a"] = Mapping({"abcG" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   2891    d["a"] = Mapping({"abcG" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
   2892    <<< Finished
   2893    >>> Testing ConvertFromPyObject using d["a"] = Mapping({"abcG" : %s})
   2894    d["a"] = Mapping({"abcG" : None}):NOT FAILED
   2895    d["a"] = Mapping({"abcG" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   2896    d["a"] = Mapping({"abcG" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   2897    d["a"] = Mapping({"abcG" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   2898    d["a"] = Mapping({"abcG" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   2899    d["a"] = Mapping({"abcG" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
   2900    <<< Finished
   2901    >>> Testing *Iter* using d["a"] = %s
   2902    d["a"] = FailingIter():(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   2903    d["a"] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
   2904    <<< Finished
   2905    >>> Testing ConvertFromPyObject using d["a"] = %s
   2906    d["a"] = None:NOT FAILED
   2907    d["a"] = {b"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   2908    d["a"] = {"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   2909    d["a"] = FailingMapping():(<class 'NotImplementedError'>, NotImplementedError('keys',))
   2910    d["a"] = FailingMappingKey():(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   2911    d["a"] = FailingNumber():(<class 'NotImplementedError'>, NotImplementedError('int',))
   2912    <<< Finished
   2913    >> DictionaryUpdate
   2914    >>> kwargs
   2915    >>> iter
   2916    d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   2917    d.update([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
   2918    d.update([FailingIterNextN(1)]):(<class 'NotImplementedError'>, NotImplementedError('next N',))
   2919    >>> Testing *Iter* using d.update(%s)
   2920    d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
   2921    d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
   2922    <<< Finished
   2923    >>> Testing StringToChars using d.update({%s : 1})
   2924    d.update({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2925    d.update({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2926    d.update({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2927    <<< Finished
   2928    >>> Testing StringToChars using d.update({"abcF" : {%s : 1}})
   2929    d.update({"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2930    d.update({"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2931    d.update({"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2932    <<< Finished
   2933    >>> Testing StringToChars using d.update({"abcF" : Mapping({%s : 1})})
   2934    d.update({"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2935    d.update({"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2936    d.update({"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2937    <<< Finished
   2938    >>> Testing *Iter* using d.update({"abcF" : %s})
   2939    d.update({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   2940    d.update({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
   2941    <<< Finished
   2942    >>> Testing ConvertFromPyObject using d.update({"abcF" : %s})
   2943    d.update({"abcF" : None}):NOT FAILED
   2944    d.update({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   2945    d.update({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   2946    d.update({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   2947    d.update({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   2948    d.update({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
   2949    <<< Finished
   2950    >>> Testing StringToChars using d.update(Mapping({%s : 1}))
   2951    d.update(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2952    d.update(Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2953    d.update(Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2954    <<< Finished
   2955    >>> Testing StringToChars using d.update(Mapping({"abcG" : {%s : 1}}))
   2956    d.update(Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2957    d.update(Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2958    d.update(Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2959    <<< Finished
   2960    >>> Testing StringToChars using d.update(Mapping({"abcG" : Mapping({%s : 1})}))
   2961    d.update(Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2962    d.update(Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2963    d.update(Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2964    <<< Finished
   2965    >>> Testing *Iter* using d.update(Mapping({"abcG" : %s}))
   2966    d.update(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   2967    d.update(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
   2968    <<< Finished
   2969    >>> Testing ConvertFromPyObject using d.update(Mapping({"abcG" : %s}))
   2970    d.update(Mapping({"abcG" : None})):NOT FAILED
   2971    d.update(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   2972    d.update(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   2973    d.update(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   2974    d.update(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   2975    d.update(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
   2976    <<< Finished
   2977    >>> Testing *Iter* using d.update(%s)
   2978    d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
   2979    d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
   2980    <<< Finished
   2981    >>> Testing ConvertFromPyObject using d.update(%s)
   2982    d.update(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
   2983    d.update({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   2984    d.update({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   2985    d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   2986    d.update(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   2987    d.update(FailingNumber()):(<class 'TypeError'>, TypeError("'FailingNumber' object is not iterable",))
   2988    <<< Finished
   2989    >>> Testing StringToChars using d.update(((%s, 0),))
   2990    d.update(((1, 0),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2991    d.update(((b"\0", 0),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2992    d.update((("\0", 0),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2993    <<< Finished
   2994    >>> Testing StringToChars using d.update((("a", {%s : 1}),))
   2995    d.update((("a", {1 : 1}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   2996    d.update((("a", {b"\0" : 1}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2997    d.update((("a", {"\0" : 1}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   2998    <<< Finished
   2999    >>> Testing StringToChars using d.update((("a", {"abcF" : {%s : 1}}),))
   3000    d.update((("a", {"abcF" : {1 : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3001    d.update((("a", {"abcF" : {b"\0" : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3002    d.update((("a", {"abcF" : {"\0" : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3003    <<< Finished
   3004    >>> Testing StringToChars using d.update((("a", {"abcF" : Mapping({%s : 1})}),))
   3005    d.update((("a", {"abcF" : Mapping({1 : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3006    d.update((("a", {"abcF" : Mapping({b"\0" : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3007    d.update((("a", {"abcF" : Mapping({"\0" : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3008    <<< Finished
   3009    >>> Testing *Iter* using d.update((("a", {"abcF" : %s}),))
   3010    d.update((("a", {"abcF" : FailingIter()}),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3011    d.update((("a", {"abcF" : FailingIterNext()}),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3012    <<< Finished
   3013    >>> Testing ConvertFromPyObject using d.update((("a", {"abcF" : %s}),))
   3014    d.update((("a", {"abcF" : None}),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
   3015    d.update((("a", {"abcF" : {b"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3016    d.update((("a", {"abcF" : {"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3017    d.update((("a", {"abcF" : FailingMapping()}),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3018    d.update((("a", {"abcF" : FailingMappingKey()}),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3019    d.update((("a", {"abcF" : FailingNumber()}),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
   3020    <<< Finished
   3021    >>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),))
   3022    d.update((("a", Mapping({1 : 1})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3023    d.update((("a", Mapping({b"\0" : 1})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3024    d.update((("a", Mapping({"\0" : 1})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3025    <<< Finished
   3026    >>> Testing StringToChars using d.update((("a", Mapping({"abcG" : {%s : 1}})),))
   3027    d.update((("a", Mapping({"abcG" : {1 : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3028    d.update((("a", Mapping({"abcG" : {b"\0" : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3029    d.update((("a", Mapping({"abcG" : {"\0" : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3030    <<< Finished
   3031    >>> Testing StringToChars using d.update((("a", Mapping({"abcG" : Mapping({%s : 1})})),))
   3032    d.update((("a", Mapping({"abcG" : Mapping({1 : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3033    d.update((("a", Mapping({"abcG" : Mapping({b"\0" : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3034    d.update((("a", Mapping({"abcG" : Mapping({"\0" : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3035    <<< Finished
   3036    >>> Testing *Iter* using d.update((("a", Mapping({"abcG" : %s})),))
   3037    d.update((("a", Mapping({"abcG" : FailingIter()})),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3038    d.update((("a", Mapping({"abcG" : FailingIterNext()})),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3039    <<< Finished
   3040    >>> Testing ConvertFromPyObject using d.update((("a", Mapping({"abcG" : %s})),))
   3041    d.update((("a", Mapping({"abcG" : None})),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
   3042    d.update((("a", Mapping({"abcG" : {b"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3043    d.update((("a", Mapping({"abcG" : {"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3044    d.update((("a", Mapping({"abcG" : FailingMapping()})),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3045    d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3046    d.update((("a", Mapping({"abcG" : FailingNumber()})),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
   3047    <<< Finished
   3048    >>> Testing *Iter* using d.update((("a", %s),))
   3049    d.update((("a", FailingIter()),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3050    d.update((("a", FailingIterNext()),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3051    <<< Finished
   3052    >>> Testing ConvertFromPyObject using d.update((("a", %s),))
   3053    d.update((("a", None),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
   3054    d.update((("a", {b"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3055    d.update((("a", {"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3056    d.update((("a", FailingMapping()),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3057    d.update((("a", FailingMappingKey()),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3058    d.update((("a", FailingNumber()),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
   3059    <<< Finished
   3060    >> DictionaryPopItem
   3061    d.popitem(1, 2):(<class 'TypeError'>, TypeError('popitem() takes no arguments (2 given)',))
   3062    >> DictionaryHasKey
   3063    d.has_key():(<class 'TypeError'>, TypeError('has_key() takes exactly one argument (0 given)',))
   3064    > List
   3065    >> ListConstructor
   3066    vim.List(1, 2):(<class 'TypeError'>, TypeError('function takes at most 1 argument (2 given)',))
   3067    vim.List(a=1):(<class 'TypeError'>, TypeError('list constructor does not accept keyword arguments',))
   3068    >>> Testing *Iter* using vim.List(%s)
   3069    vim.List(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
   3070    vim.List(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3071    <<< Finished
   3072    >>> Testing StringToChars using vim.List([{%s : 1}])
   3073    vim.List([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3074    vim.List([{b"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3075    vim.List([{"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3076    <<< Finished
   3077    >>> Testing StringToChars using vim.List([{"abcF" : {%s : 1}}])
   3078    vim.List([{"abcF" : {1 : 1}}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3079    vim.List([{"abcF" : {b"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3080    vim.List([{"abcF" : {"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3081    <<< Finished
   3082    >>> Testing StringToChars using vim.List([{"abcF" : Mapping({%s : 1})}])
   3083    vim.List([{"abcF" : Mapping({1 : 1})}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3084    vim.List([{"abcF" : Mapping({b"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3085    vim.List([{"abcF" : Mapping({"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3086    <<< Finished
   3087    >>> Testing *Iter* using vim.List([{"abcF" : %s}])
   3088    vim.List([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3089    vim.List([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3090    <<< Finished
   3091    >>> Testing ConvertFromPyObject using vim.List([{"abcF" : %s}])
   3092    vim.List([{"abcF" : None}]):NOT FAILED
   3093    vim.List([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3094    vim.List([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3095    vim.List([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3096    vim.List([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3097    vim.List([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',))
   3098    <<< Finished
   3099    >>> Testing StringToChars using vim.List([Mapping({%s : 1})])
   3100    vim.List([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3101    vim.List([Mapping({b"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3102    vim.List([Mapping({"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3103    <<< Finished
   3104    >>> Testing StringToChars using vim.List([Mapping({"abcG" : {%s : 1}})])
   3105    vim.List([Mapping({"abcG" : {1 : 1}})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3106    vim.List([Mapping({"abcG" : {b"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3107    vim.List([Mapping({"abcG" : {"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3108    <<< Finished
   3109    >>> Testing StringToChars using vim.List([Mapping({"abcG" : Mapping({%s : 1})})])
   3110    vim.List([Mapping({"abcG" : Mapping({1 : 1})})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3111    vim.List([Mapping({"abcG" : Mapping({b"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3112    vim.List([Mapping({"abcG" : Mapping({"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3113    <<< Finished
   3114    >>> Testing *Iter* using vim.List([Mapping({"abcG" : %s})])
   3115    vim.List([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3116    vim.List([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3117    <<< Finished
   3118    >>> Testing ConvertFromPyObject using vim.List([Mapping({"abcG" : %s})])
   3119    vim.List([Mapping({"abcG" : None})]):NOT FAILED
   3120    vim.List([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3121    vim.List([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3122    vim.List([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3123    vim.List([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3124    vim.List([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',))
   3125    <<< Finished
   3126    >>> Testing *Iter* using vim.List([%s])
   3127    vim.List([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3128    vim.List([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3129    <<< Finished
   3130    >>> Testing ConvertFromPyObject using vim.List([%s])
   3131    vim.List([None]):NOT FAILED
   3132    vim.List([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3133    vim.List([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3134    vim.List([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3135    vim.List([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3136    vim.List([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',))
   3137    <<< Finished
   3138    >> ListItem
   3139    l[1000]:(<class 'IndexError'>, IndexError('list index out of range',))
   3140    >> ListAssItem
   3141    ll[1] = 2:(<class 'vim.error'>, error('list is locked',))
   3142    l[1000] = 3:(<class 'IndexError'>, IndexError('list index out of range',))
   3143    >> ListAssSlice
   3144    ll[1:100] = "abcJ":(<class 'vim.error'>, error('list is locked',))
   3145    >>> Testing *Iter* using l[:] = %s
   3146    l[:] = FailingIter():(<class 'NotImplementedError'>, NotImplementedError('iter',))
   3147    l[:] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
   3148    <<< Finished
   3149    nel[1:10:2]  = "abcK":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater than 2 to extended slice',))
   3150    (b'a', b'b', b'c', b'O')
   3151    nel[1:10:2]  = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size 1 to extended slice of size 2',))
   3152    (b'a', b'b', b'c', b'O')
   3153    nel[1:1:-1]  = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater than 0 to extended slice',))
   3154    (b'a', b'b', b'c', b'O')
   3155    nel[:] = FailingIterNextN(2):(<class 'NotImplementedError'>, NotImplementedError('next N',))
   3156    (b'a', b'b', b'c', b'O')
   3157    >>> Testing StringToChars using l[:] = [{%s : 1}]
   3158    l[:] = [{1 : 1}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3159    l[:] = [{b"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3160    l[:] = [{"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3161    <<< Finished
   3162    >>> Testing StringToChars using l[:] = [{"abcF" : {%s : 1}}]
   3163    l[:] = [{"abcF" : {1 : 1}}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3164    l[:] = [{"abcF" : {b"\0" : 1}}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3165    l[:] = [{"abcF" : {"\0" : 1}}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3166    <<< Finished
   3167    >>> Testing StringToChars using l[:] = [{"abcF" : Mapping({%s : 1})}]
   3168    l[:] = [{"abcF" : Mapping({1 : 1})}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3169    l[:] = [{"abcF" : Mapping({b"\0" : 1})}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3170    l[:] = [{"abcF" : Mapping({"\0" : 1})}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3171    <<< Finished
   3172    >>> Testing *Iter* using l[:] = [{"abcF" : %s}]
   3173    l[:] = [{"abcF" : FailingIter()}]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3174    l[:] = [{"abcF" : FailingIterNext()}]:(<class 'NotImplementedError'>, NotImplementedError('next',))
   3175    <<< Finished
   3176    >>> Testing ConvertFromPyObject using l[:] = [{"abcF" : %s}]
   3177    l[:] = [{"abcF" : None}]:NOT FAILED
   3178    l[:] = [{"abcF" : {b"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3179    l[:] = [{"abcF" : {"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3180    l[:] = [{"abcF" : FailingMapping()}]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3181    l[:] = [{"abcF" : FailingMappingKey()}]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3182    l[:] = [{"abcF" : FailingNumber()}]:(<class 'NotImplementedError'>, NotImplementedError('int',))
   3183    <<< Finished
   3184    >>> Testing StringToChars using l[:] = [Mapping({%s : 1})]
   3185    l[:] = [Mapping({1 : 1})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3186    l[:] = [Mapping({b"\0" : 1})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3187    l[:] = [Mapping({"\0" : 1})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3188    <<< Finished
   3189    >>> Testing StringToChars using l[:] = [Mapping({"abcG" : {%s : 1}})]
   3190    l[:] = [Mapping({"abcG" : {1 : 1}})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3191    l[:] = [Mapping({"abcG" : {b"\0" : 1}})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3192    l[:] = [Mapping({"abcG" : {"\0" : 1}})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3193    <<< Finished
   3194    >>> Testing StringToChars using l[:] = [Mapping({"abcG" : Mapping({%s : 1})})]
   3195    l[:] = [Mapping({"abcG" : Mapping({1 : 1})})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3196    l[:] = [Mapping({"abcG" : Mapping({b"\0" : 1})})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3197    l[:] = [Mapping({"abcG" : Mapping({"\0" : 1})})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3198    <<< Finished
   3199    >>> Testing *Iter* using l[:] = [Mapping({"abcG" : %s})]
   3200    l[:] = [Mapping({"abcG" : FailingIter()})]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3201    l[:] = [Mapping({"abcG" : FailingIterNext()})]:(<class 'NotImplementedError'>, NotImplementedError('next',))
   3202    <<< Finished
   3203    >>> Testing ConvertFromPyObject using l[:] = [Mapping({"abcG" : %s})]
   3204    l[:] = [Mapping({"abcG" : None})]:NOT FAILED
   3205    l[:] = [Mapping({"abcG" : {b"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3206    l[:] = [Mapping({"abcG" : {"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3207    l[:] = [Mapping({"abcG" : FailingMapping()})]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3208    l[:] = [Mapping({"abcG" : FailingMappingKey()})]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3209    l[:] = [Mapping({"abcG" : FailingNumber()})]:(<class 'NotImplementedError'>, NotImplementedError('int',))
   3210    <<< Finished
   3211    >>> Testing *Iter* using l[:] = [%s]
   3212    l[:] = [FailingIter()]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3213    l[:] = [FailingIterNext()]:(<class 'NotImplementedError'>, NotImplementedError('next',))
   3214    <<< Finished
   3215    >>> Testing ConvertFromPyObject using l[:] = [%s]
   3216    l[:] = [None]:NOT FAILED
   3217    l[:] = [{b"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3218    l[:] = [{"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3219    l[:] = [FailingMapping()]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3220    l[:] = [FailingMappingKey()]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3221    l[:] = [FailingNumber()]:(<class 'NotImplementedError'>, NotImplementedError('int',))
   3222    <<< Finished
   3223    >> ListConcatInPlace
   3224    >>> Testing *Iter* using l.extend(%s)
   3225    l.extend(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
   3226    l.extend(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3227    <<< Finished
   3228    >>> Testing StringToChars using l.extend([{%s : 1}])
   3229    l.extend([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3230    l.extend([{b"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3231    l.extend([{"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3232    <<< Finished
   3233    >>> Testing StringToChars using l.extend([{"abcF" : {%s : 1}}])
   3234    l.extend([{"abcF" : {1 : 1}}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3235    l.extend([{"abcF" : {b"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3236    l.extend([{"abcF" : {"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3237    <<< Finished
   3238    >>> Testing StringToChars using l.extend([{"abcF" : Mapping({%s : 1})}])
   3239    l.extend([{"abcF" : Mapping({1 : 1})}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3240    l.extend([{"abcF" : Mapping({b"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3241    l.extend([{"abcF" : Mapping({"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3242    <<< Finished
   3243    >>> Testing *Iter* using l.extend([{"abcF" : %s}])
   3244    l.extend([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3245    l.extend([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3246    <<< Finished
   3247    >>> Testing ConvertFromPyObject using l.extend([{"abcF" : %s}])
   3248    l.extend([{"abcF" : None}]):NOT FAILED
   3249    l.extend([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3250    l.extend([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3251    l.extend([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3252    l.extend([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3253    l.extend([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',))
   3254    <<< Finished
   3255    >>> Testing StringToChars using l.extend([Mapping({%s : 1})])
   3256    l.extend([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3257    l.extend([Mapping({b"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3258    l.extend([Mapping({"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3259    <<< Finished
   3260    >>> Testing StringToChars using l.extend([Mapping({"abcG" : {%s : 1}})])
   3261    l.extend([Mapping({"abcG" : {1 : 1}})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3262    l.extend([Mapping({"abcG" : {b"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3263    l.extend([Mapping({"abcG" : {"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3264    <<< Finished
   3265    >>> Testing StringToChars using l.extend([Mapping({"abcG" : Mapping({%s : 1})})])
   3266    l.extend([Mapping({"abcG" : Mapping({1 : 1})})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3267    l.extend([Mapping({"abcG" : Mapping({b"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3268    l.extend([Mapping({"abcG" : Mapping({"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3269    <<< Finished
   3270    >>> Testing *Iter* using l.extend([Mapping({"abcG" : %s})])
   3271    l.extend([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3272    l.extend([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3273    <<< Finished
   3274    >>> Testing ConvertFromPyObject using l.extend([Mapping({"abcG" : %s})])
   3275    l.extend([Mapping({"abcG" : None})]):NOT FAILED
   3276    l.extend([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3277    l.extend([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3278    l.extend([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3279    l.extend([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3280    l.extend([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',))
   3281    <<< Finished
   3282    >>> Testing *Iter* using l.extend([%s])
   3283    l.extend([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3284    l.extend([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3285    <<< Finished
   3286    >>> Testing ConvertFromPyObject using l.extend([%s])
   3287    l.extend([None]):NOT FAILED
   3288    l.extend([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3289    l.extend([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3290    l.extend([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3291    l.extend([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3292    l.extend([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',))
   3293    <<< Finished
   3294    >> ListSetattr
   3295    del l.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.List attributes',))
   3296    l.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',))
   3297    l.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
   3298    > Function
   3299    >> FunctionConstructor
   3300    >>> FunctionConstructor
   3301    vim.Function("123"):(<class 'ValueError'>, ValueError('unnamed function 123 does not exist',))
   3302    vim.Function("xxx_non_existent_function_xxx"):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx does not exist',))
   3303    vim.Function("xxx#non#existent#function#xxx"):NOT FAILED
   3304    vim.Function("xxx_non_existent_function_xxx2", args=[]):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx2 does not exist',))
   3305    vim.Function("xxx_non_existent_function_xxx3", self={}):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx3 does not exist',))
   3306    vim.Function("xxx_non_existent_function_xxx4", args=[], self={}):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx4 does not exist',))
   3307    >>> FunctionNew
   3308    vim.Function("tr", self="abcFuncSelf"):(<class 'AttributeError'>, AttributeError('keys',))
   3309    vim.Function("tr", args=427423):(<class 'TypeError'>, TypeError('unable to convert int to a Vim list',))
   3310    vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
   3311    vim.Function(self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
   3312    vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
   3313    vim.Function("tr", ""):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
   3314    >> FunctionCall
   3315    >>> Testing StringToChars using f({%s : 1})
   3316    f({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3317    f({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3318    f({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3319    <<< Finished
   3320    >>> Testing StringToChars using f({"abcF" : {%s : 1}})
   3321    f({"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3322    f({"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3323    f({"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3324    <<< Finished
   3325    >>> Testing StringToChars using f({"abcF" : Mapping({%s : 1})})
   3326    f({"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3327    f({"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3328    f({"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3329    <<< Finished
   3330    >>> Testing *Iter* using f({"abcF" : %s})
   3331    f({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3332    f({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3333    <<< Finished
   3334    >>> Testing ConvertFromPyObject using f({"abcF" : %s})
   3335    f({"abcF" : None}):NOT FAILED
   3336    f({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3337    f({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3338    f({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3339    f({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3340    f({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
   3341    <<< Finished
   3342    >>> Testing StringToChars using f(Mapping({%s : 1}))
   3343    f(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3344    f(Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3345    f(Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3346    <<< Finished
   3347    >>> Testing StringToChars using f(Mapping({"abcG" : {%s : 1}}))
   3348    f(Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3349    f(Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3350    f(Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3351    <<< Finished
   3352    >>> Testing StringToChars using f(Mapping({"abcG" : Mapping({%s : 1})}))
   3353    f(Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3354    f(Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3355    f(Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3356    <<< Finished
   3357    >>> Testing *Iter* using f(Mapping({"abcG" : %s}))
   3358    f(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3359    f(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3360    <<< Finished
   3361    >>> Testing ConvertFromPyObject using f(Mapping({"abcG" : %s}))
   3362    f(Mapping({"abcG" : None})):NOT FAILED
   3363    f(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3364    f(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3365    f(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3366    f(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3367    f(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
   3368    <<< Finished
   3369    >>> Testing *Iter* using f(%s)
   3370    f(FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3371    f(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3372    <<< Finished
   3373    >>> Testing ConvertFromPyObject using f(%s)
   3374    f(None):NOT FAILED
   3375    f({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3376    f({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3377    f(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3378    f(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3379    f(FailingNumber()):(<class 'NotImplementedError'>, NotImplementedError('int',))
   3380    <<< Finished
   3381    >>> Testing StringToChars using fd(self={%s : 1})
   3382    fd(self={1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3383    fd(self={b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3384    fd(self={"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3385    <<< Finished
   3386    >>> Testing StringToChars using fd(self={"abcF" : {%s : 1}})
   3387    fd(self={"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3388    fd(self={"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3389    fd(self={"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3390    <<< Finished
   3391    >>> Testing StringToChars using fd(self={"abcF" : Mapping({%s : 1})})
   3392    fd(self={"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3393    fd(self={"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3394    fd(self={"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3395    <<< Finished
   3396    >>> Testing *Iter* using fd(self={"abcF" : %s})
   3397    fd(self={"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3398    fd(self={"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3399    <<< Finished
   3400    >>> Testing ConvertFromPyObject using fd(self={"abcF" : %s})
   3401    fd(self={"abcF" : None}):NOT FAILED
   3402    fd(self={"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3403    fd(self={"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3404    fd(self={"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3405    fd(self={"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3406    fd(self={"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
   3407    <<< Finished
   3408    >>> Testing StringToChars using fd(self=Mapping({%s : 1}))
   3409    fd(self=Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3410    fd(self=Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3411    fd(self=Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3412    <<< Finished
   3413    >>> Testing StringToChars using fd(self=Mapping({"abcG" : {%s : 1}}))
   3414    fd(self=Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3415    fd(self=Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3416    fd(self=Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3417    <<< Finished
   3418    >>> Testing StringToChars using fd(self=Mapping({"abcG" : Mapping({%s : 1})}))
   3419    fd(self=Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3420    fd(self=Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3421    fd(self=Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
   3422    <<< Finished
   3423    >>> Testing *Iter* using fd(self=Mapping({"abcG" : %s}))
   3424    fd(self=Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
   3425    fd(self=Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
   3426    <<< Finished
   3427    >>> Testing ConvertFromPyObject using fd(self=Mapping({"abcG" : %s}))
   3428    fd(self=Mapping({"abcG" : None})):NOT FAILED
   3429    fd(self=Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3430    fd(self=Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3431    fd(self=Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3432    fd(self=Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3433    fd(self=Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
   3434    <<< Finished
   3435    >>> Testing *Iter* using fd(self=%s)
   3436    fd(self=FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim dictionary',))
   3437    fd(self=FailingIterNext()):(<class 'TypeError'>, TypeError('unable to convert FailingIterNext to a Vim dictionary',))
   3438    <<< Finished
   3439    >>> Testing ConvertFromPyObject using fd(self=%s)
   3440    fd(self=None):(<class 'TypeError'>, TypeError('unable to convert NoneType to a Vim dictionary',))
   3441    fd(self={b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3442    fd(self={"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
   3443    fd(self=FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
   3444    fd(self=FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
   3445    fd(self=FailingNumber()):(<class 'TypeError'>, TypeError('unable to convert FailingNumber to a Vim dictionary',))
   3446    <<< Finished
   3447    >>> Testing ConvertFromPyMapping using fd(self=%s)
   3448    fd(self=[]):(<class 'AttributeError'>, AttributeError('keys',))
   3449    <<< Finished
   3450    > TabPage
   3451    >> TabPageAttr
   3452    vim.current.tabpage.xxx:(<class 'AttributeError'>, AttributeError("'vim.tabpage' object has no attribute 'xxx'",))
   3453    > TabList
   3454    >> TabListItem
   3455    vim.tabpages[1000]:(<class 'IndexError'>, IndexError('no such tab page',))
   3456    > Window
   3457    >> WindowAttr
   3458    vim.current.window.xxx:(<class 'AttributeError'>, AttributeError("'vim.window' object has no attribute 'xxx'",))
   3459    >> WindowSetattr
   3460    vim.current.window.buffer = 0:(<class 'TypeError'>, TypeError('readonly attribute: buffer',))
   3461    vim.current.window.cursor = (100000000, 100000000):(<class 'vim.error'>, error('cursor position outside buffer',))
   3462    vim.current.window.cursor = True:(<class 'TypeError'>, TypeError('argument must be 2-item sequence, not bool',))
   3463    >>> Testing NumberToLong using vim.current.window.height = %s
   3464    vim.current.window.height = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
   3465    vim.current.window.height = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
   3466    vim.current.window.height = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
   3467    <<< Finished
   3468    >>> Testing NumberToLong using vim.current.window.width = %s
   3469    vim.current.window.width = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
   3470    vim.current.window.width = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
   3471    vim.current.window.width = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
   3472    <<< Finished
   3473    vim.current.window.xxxxxx = True:(<class 'AttributeError'>, AttributeError('xxxxxx',))
   3474    > WinList
   3475    >> WinListItem
   3476    vim.windows[1000]:(<class 'IndexError'>, IndexError('no such window',))
   3477    > Buffer
   3478    >> StringToLine (indirect)
   3479    vim.current.buffer[0] = "\na":(<class 'vim.error'>, error('string cannot contain newlines',))
   3480    vim.current.buffer[0] = b"\na":(<class 'vim.error'>, error('string cannot contain newlines',))
   3481    >> SetBufferLine (indirect)
   3482    vim.current.buffer[0] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
   3483    >> SetBufferLineList (indirect)
   3484    vim.current.buffer[:] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
   3485    vim.current.buffer[:] = ["\na", "bc"]:(<class 'vim.error'>, error('string cannot contain newlines',))
   3486    >> InsertBufferLines (indirect)
   3487    vim.current.buffer.append(None):(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
   3488    vim.current.buffer.append(["\na", "bc"]):(<class 'vim.error'>, error('string cannot contain newlines',))
   3489    vim.current.buffer.append("\nbc"):(<class 'vim.error'>, error('string cannot contain newlines',))
   3490    >> RBItem
   3491    vim.current.buffer[100000000]:(<class 'IndexError'>, IndexError('line number out of range',))
   3492    >> RBAsItem
   3493    vim.current.buffer[100000000] = "":(<class 'IndexError'>, IndexError('line number out of range',))
   3494    >> BufferAttr
   3495    vim.current.buffer.xxx:(<class 'AttributeError'>, AttributeError("'vim.buffer' object has no attribute 'xxx'",))
   3496    >> BufferSetattr
   3497    vim.current.buffer.name = True:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got bool',))
   3498    vim.current.buffer.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',))
   3499    >> BufferMark
   3500    vim.current.buffer.mark(0):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
   3501    vim.current.buffer.mark("abcM"):(<class 'ValueError'>, ValueError('mark name must be a single character',))
   3502    vim.current.buffer.mark("!"):(<class 'vim.error'>, error('invalid mark name',))
   3503    >> BufferRange
   3504    vim.current.buffer.range(1, 2, 3):(<class 'TypeError'>, TypeError('function takes exactly 2 arguments (3 given)',))
   3505    > BufMap
   3506    >> BufMapItem
   3507    vim.buffers[100000000]:(<class 'KeyError'>, KeyError(100000000,))
   3508    >>> Testing NumberToLong using vim.buffers[%s]
   3509    vim.buffers[[]]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
   3510    vim.buffers[None]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
   3511    vim.buffers[-1]:(<class 'ValueError'>, ValueError('number must be greater than zero',))
   3512    vim.buffers[0]:(<class 'ValueError'>, ValueError('number must be greater than zero',))
   3513    <<< Finished
   3514    > Current
   3515    >> CurrentGetattr
   3516    vim.current.xxx:(<class 'AttributeError'>, AttributeError("'vim.currentdata' object has no attribute 'xxx'",))
   3517    >> CurrentSetattr
   3518    vim.current.line = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
   3519    vim.current.buffer = True:(<class 'TypeError'>, TypeError('expected vim.Buffer object, but got bool',))
   3520    vim.current.window = True:(<class 'TypeError'>, TypeError('expected vim.Window object, but got bool',))
   3521    vim.current.tabpage = True:(<class 'TypeError'>, TypeError('expected vim.TabPage object, but got bool',))
   3522    vim.current.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',))
   3523  END
   3524 
   3525  let actual = getline(2, '$')
   3526  let n_expected = len(expected)
   3527  let n_actual = len(actual)
   3528  call assert_equal(n_expected, n_actual, 'number of lines to compare')
   3529 
   3530  " Compare line by line so the errors are easier to understand.  Missing lines
   3531  " are compared with an empty string.
   3532  for i in range(n_expected > n_actual ? n_expected : n_actual)
   3533    call assert_equal(i >= n_expected ? '' : expected[i], i >= n_actual ? '' : actual[i])
   3534  endfor
   3535  close!
   3536 endfunc
   3537 
   3538 " Test import
   3539 func Test_python3_import()
   3540  throw 'Skipped: TODO: '
   3541  new
   3542  py3 cb = vim.current.buffer
   3543 
   3544  py3 << trim EOF
   3545    sys.path.insert(0, os.path.join(os.getcwd(), 'python_before'))
   3546    sys.path.append(os.path.join(os.getcwd(), 'python_after'))
   3547    vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
   3548    l = []
   3549    def callback(path):
   3550        l.append(os.path.relpath(path))
   3551    vim.foreach_rtp(callback)
   3552    cb.append(repr(l))
   3553    del l
   3554    def callback(path):
   3555        return os.path.relpath(path)
   3556    cb.append(repr(vim.foreach_rtp(callback)))
   3557    del callback
   3558    from module import dir as d
   3559    from modulex import ddir
   3560    cb.append(d + ',' + ddir)
   3561    import before
   3562    cb.append(before.dir)
   3563    import after
   3564    cb.append(after.dir)
   3565    import topmodule as tm
   3566    import topmodule.submodule as tms
   3567    import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss
   3568    cb.append(tm.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):])
   3569    cb.append(tms.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):])
   3570    cb.append(tmsss.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):])
   3571 
   3572    del before
   3573    del after
   3574    del d
   3575    del ddir
   3576    del tm
   3577    del tms
   3578    del tmsss
   3579  EOF
   3580 
   3581  let expected =<< trim END
   3582    ['.']
   3583    '.'
   3584    3,xx
   3585    before
   3586    after
   3587    pythonx/topmodule/__init__.py
   3588    pythonx/topmodule/submodule/__init__.py
   3589    pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
   3590  END
   3591  call assert_equal(expected, getline(2, '$'))
   3592  close!
   3593 endfunc
   3594 
   3595 " Test exceptions
   3596 func Test_python3_exception()
   3597  throw 'Skipped: Nvim does not support vim.bindeval()'
   3598  func Exe(e)
   3599    execute a:e
   3600  endfunc
   3601 
   3602  new
   3603  py3 cb = vim.current.buffer
   3604 
   3605  py3 << trim EOF
   3606    Exe = vim.bindeval('function("Exe")')
   3607    ee('vim.command("throw \'abcN\'")')
   3608    ee('Exe("throw \'def\'")')
   3609    ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")')
   3610    ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")')
   3611    ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")')
   3612    ee('vim.eval("xxx_unknown_function_xxx()")')
   3613    ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")')
   3614    del Exe
   3615  EOF
   3616  delfunction Exe
   3617 
   3618  let expected =<< trim END
   3619    vim.command("throw 'abcN'"):(<class 'vim.error'>, error('abcN',))
   3620    Exe("throw 'def'"):(<class 'vim.error'>, error('def',))
   3621    vim.eval("Exe('throw ''ghi''')"):(<class 'vim.error'>, error('ghi',))
   3622    vim.eval("Exe('echoerr ''jkl''')"):(<class 'vim.error'>, error('Vim(echoerr):jkl',))
   3623    vim.eval("Exe('xxx_non_existent_command_xxx')"):(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
   3624    vim.eval("xxx_unknown_function_xxx()"):(<class 'vim.error'>, error('Vim:E117: Unknown function: xxx_unknown_function_xxx',))
   3625    vim.bindeval("Exe('xxx_non_existent_command_xxx')"):(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
   3626  END
   3627  call assert_equal(expected, getline(2, '$'))
   3628  close!
   3629 endfunc
   3630 
   3631 " Regression: interrupting vim.command propagates to next vim.command
   3632 func Test_python3_keyboard_interrupt()
   3633  new
   3634  py3 cb = vim.current.buffer
   3635  py3 << trim EOF
   3636    def test_keyboard_interrupt():
   3637        try:
   3638            vim.command('while 1 | endwhile')
   3639        except KeyboardInterrupt:
   3640            cb.append('Caught KeyboardInterrupt')
   3641        except Exception:
   3642            cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
   3643        else:
   3644            cb.append('!!!!!!!! No exception')
   3645        try:
   3646            vim.command('$ put =\'Running :put\'')
   3647        except KeyboardInterrupt:
   3648            cb.append('!!!!!!!! Caught KeyboardInterrupt')
   3649        except Exception:
   3650            cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
   3651        else:
   3652            cb.append('No exception')
   3653  EOF
   3654 
   3655  debuggreedy
   3656  call inputsave()
   3657  call feedkeys("s\ns\ns\ns\nq\n")
   3658  redir => output
   3659  debug silent! py3 test_keyboard_interrupt()
   3660  redir END
   3661  0 debuggreedy
   3662  call inputrestore()
   3663  py3 del test_keyboard_interrupt
   3664 
   3665  let expected =<< trim END
   3666    !!!!!!!! Caught exception: NvimError:('Keyboard interrupt',)
   3667    Running :put
   3668    No exception
   3669  END
   3670  call assert_equal(expected, getline(2, '$'))
   3671  call assert_equal('', output)
   3672  close!
   3673 endfunc
   3674 
   3675 " vim: shiftwidth=2 sts=2 expandtab