diff src/testdir/test87.in @ 20045:04ef2ccf2519 v8.2.0578

patch 8.2.0578: heredoc for interfaces does not support "trim" Commit: https://github.com/vim/vim/commit/6c2b7b8055b96463f78abb70f58c4c6d6d4b9d55 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Apr 14 20:15:49 2020 +0200 patch 8.2.0578: heredoc for interfaces does not support "trim" Problem: Heredoc for interfaces does not support "trim". Solution: Update the script heredoc support to be same as the :let command. (Yegappan Lakshmanan, closes #5916)
author Bram Moolenaar <Bram@vim.org>
date Tue, 14 Apr 2020 20:30:05 +0200
parents 068337e86133
children
line wrap: on
line diff
--- a/src/testdir/test87.in
+++ b/src/testdir/test87.in
@@ -31,19 +31,19 @@ STARTTEST
 :fun d.f()
 :  return 1
 :endfun
-py3 << EOF
-d=vim.bindeval('d')
-d['1']='asd'
-d.update()  # Must not do anything, including throwing errors
-d.update(b=[1, 2, f])
-d.update((('-1', {'a': 1}),))
-d.update({'0': -1})
-dk = d.keys()
-dv = d.values()
-di = d.items()
-dk.sort(key=repr)
-dv.sort(key=repr)
-di.sort(key=repr)
+py3 << trim EOF
+  d=vim.bindeval('d')
+  d['1']='asd'
+  d.update()  # Must not do anything, including throwing errors
+  d.update(b=[1, 2, f])
+  d.update((('-1', {'a': 1}),))
+  d.update({'0': -1})
+  dk = d.keys()
+  dv = d.values()
+  di = d.items()
+  dk.sort(key=repr)
+  dv.sort(key=repr)
+  di.sort(key=repr)
 EOF
 :$put =py3eval('d[''f''](self={})')
 :$put =py3eval('repr(dk)')
@@ -201,77 +201,77 @@ EOF
 :let l = [0, 1, 2, 3]
 :py3 l=vim.bindeval('l')
 :lockvar! l
-py3 << EOF
-def emsg(ei):
-    return ei[0].__name__ + ':' + repr(ei[1].args)
+py3 << trim EOF
+  def emsg(ei):
+      return ei[0].__name__ + ':' + repr(ei[1].args)
 
-try:
-    l[2]='i'
-except vim.error:
-    cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info()))
+  try:
+      l[2]='i'
+  except vim.error:
+      cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info()))
 EOF
 :$put =string(l)
 :unlockvar! l
 :"
 :" Function calls
-py3 << EOF
-import sys
-import re
+py3 << trim EOF
+  import sys
+  import re
 
-py33_type_error_pattern = re.compile('^__call__\(\) takes (\d+) positional argument but (\d+) were given$')
-py37_exception_repr = re.compile(r'([^\(\),])(\)+)$')
+  py33_type_error_pattern = re.compile('^__call__\(\) takes (\d+) positional argument but (\d+) were given$')
+  py37_exception_repr = re.compile(r'([^\(\),])(\)+)$')
 
-def ee(expr, g=globals(), l=locals()):
-    cb = vim.current.buffer
-    try:
-        try:
-            exec(expr, g, l)
-        except Exception as e:
-            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."):
-                msg = repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1])))
-            elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0:
-                msg = repr((e.__class__, ImportError(str(e).replace("'", ''))))
-            elif sys.version_info >= (3, 6) and e.__class__ is ModuleNotFoundError:
-                # Python 3.6 gives ModuleNotFoundError, change it to an ImportError
-                msg = repr((ImportError, ImportError(str(e).replace("'", ''))))
-            elif sys.version_info >= (3, 3) and e.__class__ is TypeError:
-                m = py33_type_error_pattern.search(str(e))
-                if m:
-                    msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2))
-                    msg = repr((e.__class__, TypeError(msg)))
-                else:
-                    msg = repr((e.__class__, e))
-                    # Messages changed with Python 3.6, change new to old.
-                    newmsg1 = """'argument must be str, bytes or bytearray, not None'"""
-                    oldmsg1 = '''"Can't convert 'NoneType' object to str implicitly"'''
-                    if msg.find(newmsg1) > -1:
-                        msg = msg.replace(newmsg1, oldmsg1)
-                    newmsg2 = """'argument must be str, bytes or bytearray, not int'"""
-                    oldmsg2 = '''"Can't convert 'int' object to str implicitly"'''
-                    if msg.find(newmsg2) > -1:
-                        msg = msg.replace(newmsg2, oldmsg2)
-            elif sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte':
-                msg = repr((TypeError, TypeError('expected bytes with no null')))
-            else:
-                msg = repr((e.__class__, e))
-                # Some Python versions say can't, others cannot.
-                if msg.find('can\'t') > -1:
-                    msg = msg.replace('can\'t', 'cannot')
-                # Some Python versions use single quote, some double quote
-                if msg.find('"cannot ') > -1:
-                    msg = msg.replace('"cannot ', '\'cannot ')
-                if msg.find(' attributes"') > -1:
-                    msg = msg.replace(' attributes"', ' attributes\'')
-            if sys.version_info >= (3, 7):
-                msg = py37_exception_repr.sub(r'\1,\2', msg)
-            cb.append(expr + ':' + msg)
-        else:
-            cb.append(expr + ':NOT FAILED')
-    except Exception as e:
-        msg = repr((e.__class__, e))
-        if sys.version_info >= (3, 7):
-            msg = py37_exception_repr.sub(r'\1,\2', msg)
-        cb.append(expr + '::' + msg)
+  def ee(expr, g=globals(), l=locals()):
+      cb = vim.current.buffer
+      try:
+          try:
+              exec(expr, g, l)
+          except Exception as e:
+              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."):
+                  msg = repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1])))
+              elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0:
+                  msg = repr((e.__class__, ImportError(str(e).replace("'", ''))))
+              elif sys.version_info >= (3, 6) and e.__class__ is ModuleNotFoundError:
+                  # Python 3.6 gives ModuleNotFoundError, change it to an ImportError
+                  msg = repr((ImportError, ImportError(str(e).replace("'", ''))))
+              elif sys.version_info >= (3, 3) and e.__class__ is TypeError:
+                  m = py33_type_error_pattern.search(str(e))
+                  if m:
+                      msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2))
+                      msg = repr((e.__class__, TypeError(msg)))
+                  else:
+                      msg = repr((e.__class__, e))
+                      # Messages changed with Python 3.6, change new to old.
+                      newmsg1 = """'argument must be str, bytes or bytearray, not None'"""
+                      oldmsg1 = '''"Can't convert 'NoneType' object to str implicitly"'''
+                      if msg.find(newmsg1) > -1:
+                          msg = msg.replace(newmsg1, oldmsg1)
+                      newmsg2 = """'argument must be str, bytes or bytearray, not int'"""
+                      oldmsg2 = '''"Can't convert 'int' object to str implicitly"'''
+                      if msg.find(newmsg2) > -1:
+                          msg = msg.replace(newmsg2, oldmsg2)
+              elif sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte':
+                  msg = repr((TypeError, TypeError('expected bytes with no null')))
+              else:
+                  msg = repr((e.__class__, e))
+                  # Some Python versions say can't, others cannot.
+                  if msg.find('can\'t') > -1:
+                      msg = msg.replace('can\'t', 'cannot')
+                  # Some Python versions use single quote, some double quote
+                  if msg.find('"cannot ') > -1:
+                      msg = msg.replace('"cannot ', '\'cannot ')
+                  if msg.find(' attributes"') > -1:
+                      msg = msg.replace(' attributes"', ' attributes\'')
+              if sys.version_info >= (3, 7):
+                  msg = py37_exception_repr.sub(r'\1,\2', msg)
+              cb.append(expr + ':' + msg)
+          else:
+              cb.append(expr + ':NOT FAILED')
+      except Exception as e:
+          msg = repr((e.__class__, e))
+          if sys.version_info >= (3, 7):
+              msg = py37_exception_repr.sub(r'\1,\2', msg)
+          cb.append(expr + '::' + msg)
 EOF
 :fun New(...)
 :   return ['NewStart']+a:000+['NewEnd']
@@ -301,30 +301,30 @@ EOF
 :endif
 :let messages=[]
 :delfunction DictNew
-py3 <<EOF
-import sys
-d=vim.bindeval('{}')
-m=vim.bindeval('messages')
-def em(expr, g=globals(), l=locals()):
-    try:
-        exec(expr, g, l)
-    except Exception as e:
-        if sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte':
-            m.extend([TypeError.__name__])
-        else:
-            m.extend([e.__class__.__name__])
+py3 << trim EOF
+  import sys
+  d=vim.bindeval('{}')
+  m=vim.bindeval('messages')
+  def em(expr, g=globals(), l=locals()):
+      try:
+          exec(expr, g, l)
+      except Exception as e:
+          if sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte':
+              m.extend([TypeError.__name__])
+          else:
+              m.extend([e.__class__.__name__])
 
-em('d["abc1"]')
-em('d["abc1"]="\\0"')
-em('d["abc1"]=vim')
-em('d[""]=1')
-em('d["a\\0b"]=1')
-em('d[b"a\\0b"]=1')
+  em('d["abc1"]')
+  em('d["abc1"]="\\0"')
+  em('d["abc1"]=vim')
+  em('d[""]=1')
+  em('d["a\\0b"]=1')
+  em('d[b"a\\0b"]=1')
 
-em('d.pop("abc1")')
-em('d.popitem()')
-del em
-del m
+  em('d.pop("abc1")')
+  em('d.popitem()')
+  del em
+  del m
 EOF
 :$put =messages
 :unlet messages
@@ -389,24 +389,24 @@ EOF
 :" threading
 :let l = [0]
 :py3 l=vim.bindeval('l')
-py3 <<EOF
-import threading
-import time
+py3 << trim EOF
+  import threading
+  import time
 
-class T(threading.Thread):
-    def __init__(self):
-        threading.Thread.__init__(self)
-        self.t = 0
-        self.running = True
+  class T(threading.Thread):
+      def __init__(self):
+          threading.Thread.__init__(self)
+          self.t = 0
+          self.running = True
 
-    def run(self):
-        while self.running:
-            self.t += 1
-            time.sleep(0.1)
+      def run(self):
+          while self.running:
+              self.t += 1
+              time.sleep(0.1)
 
-t = T()
-del T
-t.start()
+  t = T()
+  del T
+  t.start()
 EOF
 :sleep 1
 :py3 t.running = False
@@ -422,18 +422,18 @@ EOF
 :" settrace
 :let l = []
 :py3 l=vim.bindeval('l')
-py3 <<EOF
-import sys
+py3 << trim EOF
+  import sys
 
-def traceit(frame, event, arg):
-    global l
-    if event == "line":
-        l += [frame.f_lineno]
-    return traceit
+  def traceit(frame, event, arg):
+      global l
+      if event == "line":
+          l += [frame.f_lineno]
+      return traceit
 
-def trace_main():
-    for i in range(5):
-        pass
+  def trace_main():
+      for i in range(5):
+          pass
 EOF
 :py3 sys.settrace(traceit)
 :py3 trace_main()
@@ -519,19 +519,19 @@ EOF
 :  put ='  W: '.wvals
 :  put ='  B: '.wvals
 :endfun
-py3 << EOF
-def e(s, g=globals(), l=locals()):
-    try:
-        exec(s, g, l)
-    except Exception as e:
-        vim.command('return ' + repr(e.__class__.__name__))
+py3 << trim EOF
+  def e(s, g=globals(), l=locals()):
+      try:
+          exec(s, g, l)
+      except Exception as e:
+          vim.command('return ' + repr(e.__class__.__name__))
 
-def ev(s, g=globals(), l=locals()):
-    try:
-        return eval(s, g, l)
-    except Exception as e:
-        vim.command('let exc=' + repr(e.__class__.__name__))
-        return 0
+  def ev(s, g=globals(), l=locals()):
+      try:
+          return eval(s, g, l)
+      except Exception as e:
+          vim.command('let exc=' + repr(e.__class__.__name__))
+          return 0
 EOF
 :fun E(s)
 :   python3 e(vim.eval('a:s'))
@@ -649,52 +649,52 @@ EOF
 :   autocmd BufFilePost * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePost:' + vim.eval('bufnr("%")'))
 :   autocmd BufFilePre * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePre:' + vim.eval('bufnr("%")'))
 :augroup END
-py3 << EOF
-# Tests BufferAppend and BufferItem
-cb.append(b[0])
-# Tests BufferSlice and BufferAssSlice
-cb.append('abc5') # Will be overwritten
-cb[-1:] = b[:-2]
-# Test BufferLength and BufferAssSlice
-cb.append('def') # Will not be overwritten
-cb[len(cb):] = b[:]
-# Test BufferAssItem and BufferMark
-cb.append('ghi') # Will be overwritten
-cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1]))
-# Test BufferRepr
-cb.append(repr(cb) + repr(b))
-# Modify foreign buffer
-b.append('foo')
-b[0]='bar'
-b[0:0]=['baz']
-vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number)
-# Test assigning to name property
-import os
-old_name = cb.name
-cb.name = 'foo'
-cb.append(cb.name[-11:].replace(os.path.sep, '/'))
-b.name = 'bar'
-cb.append(b.name[-11:].replace(os.path.sep, '/'))
-cb.name = old_name
-cb.append(cb.name[-17:].replace(os.path.sep, '/'))
-del old_name
-# Test CheckBuffer
-for _b in vim.buffers:
-    if _b is not cb:
-        vim.command('bwipeout! ' + str(_b.number))
-del _b
-cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid)))
-for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")'):
-    try:
-        exec(expr)
-    except vim.error:
-        pass
-    else:
-        # Usually a SEGV here
-        # Should not happen in any case
-        cb.append('No exception for ' + expr)
-vim.command('cd .')
-del b
+py3 << trim EOF
+  # Tests BufferAppend and BufferItem
+  cb.append(b[0])
+  # Tests BufferSlice and BufferAssSlice
+  cb.append('abc5') # Will be overwritten
+  cb[-1:] = b[:-2]
+  # Test BufferLength and BufferAssSlice
+  cb.append('def') # Will not be overwritten
+  cb[len(cb):] = b[:]
+  # Test BufferAssItem and BufferMark
+  cb.append('ghi') # Will be overwritten
+  cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1]))
+  # Test BufferRepr
+  cb.append(repr(cb) + repr(b))
+  # Modify foreign buffer
+  b.append('foo')
+  b[0]='bar'
+  b[0:0]=['baz']
+  vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number)
+  # Test assigning to name property
+  import os
+  old_name = cb.name
+  cb.name = 'foo'
+  cb.append(cb.name[-11:].replace(os.path.sep, '/'))
+  b.name = 'bar'
+  cb.append(b.name[-11:].replace(os.path.sep, '/'))
+  cb.name = old_name
+  cb.append(cb.name[-17:].replace(os.path.sep, '/'))
+  del old_name
+  # Test CheckBuffer
+  for _b in vim.buffers:
+      if _b is not cb:
+          vim.command('bwipeout! ' + str(_b.number))
+  del _b
+  cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid)))
+  for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")'):
+      try:
+          exec(expr)
+      except vim.error:
+          pass
+      else:
+          # Usually a SEGV here
+          # Should not happen in any case
+          cb.append('No exception for ' + expr)
+  vim.command('cd .')
+  del b
 EOF
 :"
 :" Test vim.buffers object
@@ -705,55 +705,55 @@ EOF
 :buffer #
 :edit c
 :buffer #
-py3 << EOF
-# Check GCing iterator that was not fully exhausted
-i = iter(vim.buffers)
-cb.append('i:' + str(next(i)))
-# and also check creating more than one iterator at a time
-i2 = iter(vim.buffers)
-cb.append('i2:' + str(next(i2)))
-cb.append('i:' + str(next(i)))
-# The following should trigger GC and not cause any problems
-del i
-del i2
-i3 = iter(vim.buffers)
-cb.append('i3:' + str(next(i3)))
-del i3
+py3 << trim EOF
+  # Check GCing iterator that was not fully exhausted
+  i = iter(vim.buffers)
+  cb.append('i:' + str(next(i)))
+  # and also check creating more than one iterator at a time
+  i2 = iter(vim.buffers)
+  cb.append('i2:' + str(next(i2)))
+  cb.append('i:' + str(next(i)))
+  # The following should trigger GC and not cause any problems
+  del i
+  del i2
+  i3 = iter(vim.buffers)
+  cb.append('i3:' + str(next(i3)))
+  del i3
 
-prevnum = 0
-for b in vim.buffers:
-    # Check buffer order
-    if prevnum >= b.number:
-        cb.append('!!! Buffer numbers not in strictly ascending order')
-    # Check indexing: vim.buffers[number].number == number
-    cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b))
-    prevnum = b.number
-del prevnum
+  prevnum = 0
+  for b in vim.buffers:
+      # Check buffer order
+      if prevnum >= b.number:
+          cb.append('!!! Buffer numbers not in strictly ascending order')
+      # Check indexing: vim.buffers[number].number == number
+      cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b))
+      prevnum = b.number
+  del prevnum
 
-cb.append(str(len(vim.buffers)))
+  cb.append(str(len(vim.buffers)))
 
-bnums = list(map(lambda b: b.number, vim.buffers))[1:]
+  bnums = list(map(lambda b: b.number, vim.buffers))[1:]
 
-# Test wiping out buffer with existing iterator
-i4 = iter(vim.buffers)
-cb.append('i4:' + str(next(i4)))
-vim.command('bwipeout! ' + str(bnums.pop(0)))
-try:
-    next(i4)
-except vim.error:
-    pass
-else:
-    cb.append('!!!! No vim.error')
-i4 = iter(vim.buffers)
-vim.command('bwipeout! ' + str(bnums.pop(-1)))
-vim.command('bwipeout! ' + str(bnums.pop(-1)))
-cb.append('i4:' + str(next(i4)))
-try:
-    next(i4)
-except StopIteration:
-    cb.append('StopIteration')
-del i4
-del bnums
+  # Test wiping out buffer with existing iterator
+  i4 = iter(vim.buffers)
+  cb.append('i4:' + str(next(i4)))
+  vim.command('bwipeout! ' + str(bnums.pop(0)))
+  try:
+      next(i4)
+  except vim.error:
+      pass
+  else:
+      cb.append('!!!! No vim.error')
+  i4 = iter(vim.buffers)
+  vim.command('bwipeout! ' + str(bnums.pop(-1)))
+  vim.command('bwipeout! ' + str(bnums.pop(-1)))
+  cb.append('i4:' + str(next(i4)))
+  try:
+      next(i4)
+  except StopIteration:
+      cb.append('StopIteration')
+  del i4
+  del bnums
 EOF
 :"
 :" Test vim.{tabpage,window}list and vim.{tabpage,window} objects
@@ -764,127 +764,127 @@ EOF
 :vnew a.2
 :vnew b.2
 :vnew c.2
-py3 << EOF
-cb.append('Number of tabs: ' + str(len(vim.tabpages)))
-cb.append('Current tab pages:')
+py3 << trim EOF
+  cb.append('Number of tabs: ' + str(len(vim.tabpages)))
+  cb.append('Current tab pages:')
 
-def W(w):
-    if '(unknown)' in repr(w):
-        return '<window object (unknown)>'
-    else:
-        return repr(w)
+  def W(w):
+      if '(unknown)' in repr(w):
+          return '<window object (unknown)>'
+      else:
+          return repr(w)
 
-def Cursor(w, start=len(cb)):
-    if w.buffer is cb:
-        return repr((start - w.cursor[0], w.cursor[1]))
-    else:
-        return repr(w.cursor)
+  def Cursor(w, start=len(cb)):
+      if w.buffer is cb:
+          return repr((start - w.cursor[0], w.cursor[1]))
+      else:
+          return repr(w.cursor)
 
-for t in vim.tabpages:
-    cb.append('  ' + repr(t) + '(' + str(t.number) + ')' + ': ' + str(len(t.windows)) + ' windows, current is ' + W(t.window))
-    cb.append('  Windows:')
-    for w in t.windows:
-        cb.append('    ' + W(w) + '(' + str(w.number) + ')' + ': displays buffer ' + repr(w.buffer) + '; cursor is at ' + Cursor(w))
-        # Other values depend on the size of the terminal, so they are checked partly:
-        for attr in ('height', 'row', 'width', 'col'):
-            try:
-                aval = getattr(w, attr)
-                if type(aval) is not int:
-                    raise TypeError
-                if aval < 0:
-                    raise ValueError
-            except Exception as e:
-                cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + e.__class__.__name__)
-        del aval
-        del attr
-        w.cursor = (len(w.buffer), 0)
-del W
-del Cursor
-cb.append('Number of windows in current tab page: ' + str(len(vim.windows)))
-if list(vim.windows) != list(vim.current.tabpage.windows):
-    cb.append('!!!!!! Windows differ')
+  for t in vim.tabpages:
+      cb.append('  ' + repr(t) + '(' + str(t.number) + ')' + ': ' + str(len(t.windows)) + ' windows, current is ' + W(t.window))
+      cb.append('  Windows:')
+      for w in t.windows:
+          cb.append('    ' + W(w) + '(' + str(w.number) + ')' + ': displays buffer ' + repr(w.buffer) + '; cursor is at ' + Cursor(w))
+          # Other values depend on the size of the terminal, so they are checked partly:
+          for attr in ('height', 'row', 'width', 'col'):
+              try:
+                  aval = getattr(w, attr)
+                  if type(aval) is not int:
+                      raise TypeError
+                  if aval < 0:
+                      raise ValueError
+              except Exception as e:
+                  cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + e.__class__.__name__)
+          del aval
+          del attr
+          w.cursor = (len(w.buffer), 0)
+  del W
+  del Cursor
+  cb.append('Number of windows in current tab page: ' + str(len(vim.windows)))
+  if list(vim.windows) != list(vim.current.tabpage.windows):
+      cb.append('!!!!!! Windows differ')
 EOF
 :"
 :" Test vim.current
-py3 << EOF
-def H(o):
-    return repr(o)
-cb.append('Current tab page: ' + repr(vim.current.tabpage))
-cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window))
-cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ ' is ' + H(vim.current.tabpage.window.buffer))
-del H
-# Assigning: fails
-try:
-    vim.current.window = vim.tabpages[0].window
-except ValueError:
-    cb.append('ValueError at assigning foreign tab window')
+py3 << trim EOF
+  def H(o):
+      return repr(o)
+  cb.append('Current tab page: ' + repr(vim.current.tabpage))
+  cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window))
+  cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ ' is ' + H(vim.current.tabpage.window.buffer))
+  del H
+  # Assigning: fails
+  try:
+      vim.current.window = vim.tabpages[0].window
+  except ValueError:
+      cb.append('ValueError at assigning foreign tab window')
 
-for attr in ('window', 'tabpage', 'buffer'):
-    try:
-        setattr(vim.current, attr, None)
-    except TypeError:
-        cb.append('Type error at assigning None to vim.current.' + attr)
-del attr
+  for attr in ('window', 'tabpage', 'buffer'):
+      try:
+          setattr(vim.current, attr, None)
+      except TypeError:
+          cb.append('Type error at assigning None to vim.current.' + attr)
+  del attr
 
-# Assigning: success
-vim.current.tabpage = vim.tabpages[-2]
-vim.current.buffer = cb
-vim.current.window = vim.windows[0]
-vim.current.window.cursor = (len(vim.current.buffer), 0)
-cb.append('Current tab page: ' + repr(vim.current.tabpage))
-cb.append('Current window: ' + repr(vim.current.window))
-cb.append('Current buffer: ' + repr(vim.current.buffer))
-cb.append('Current line: ' + repr(vim.current.line))
-ws = list(vim.windows)
-ts = list(vim.tabpages)
-for b in vim.buffers:
-    if b is not cb:
-        vim.command('bwipeout! ' + str(b.number))
-del b
-cb.append('w.valid: ' + repr([w.valid for w in ws]))
-cb.append('t.valid: ' + repr([t.valid for t in ts]))
-del w
-del t
-del ts
-del ws
+  # Assigning: success
+  vim.current.tabpage = vim.tabpages[-2]
+  vim.current.buffer = cb
+  vim.current.window = vim.windows[0]
+  vim.current.window.cursor = (len(vim.current.buffer), 0)
+  cb.append('Current tab page: ' + repr(vim.current.tabpage))
+  cb.append('Current window: ' + repr(vim.current.window))
+  cb.append('Current buffer: ' + repr(vim.current.buffer))
+  cb.append('Current line: ' + repr(vim.current.line))
+  ws = list(vim.windows)
+  ts = list(vim.tabpages)
+  for b in vim.buffers:
+      if b is not cb:
+          vim.command('bwipeout! ' + str(b.number))
+  del b
+  cb.append('w.valid: ' + repr([w.valid for w in ws]))
+  cb.append('t.valid: ' + repr([t.valid for t in ts]))
+  del w
+  del t
+  del ts
+  del ws
 EOF
 :tabonly!
 :only!
 :"
 :" Test types
-py3 << EOF
-for expr, attr in (
-    ('vim.vars',                         'Dictionary'),
-    ('vim.options',                      'Options'),
-    ('vim.bindeval("{}")',               'Dictionary'),
-    ('vim.bindeval("[]")',               'List'),
-    ('vim.bindeval("function(\'tr\')")', 'Function'),
-    ('vim.current.buffer',               'Buffer'),
-    ('vim.current.range',                'Range'),
-    ('vim.current.window',               'Window'),
-    ('vim.current.tabpage',              'TabPage'),
-):
-    cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr)))
-del expr
-del attr
+py3 << trim EOF
+  for expr, attr in (
+      ('vim.vars',                         'Dictionary'),
+      ('vim.options',                      'Options'),
+      ('vim.bindeval("{}")',               'Dictionary'),
+      ('vim.bindeval("[]")',               'List'),
+      ('vim.bindeval("function(\'tr\')")', 'Function'),
+      ('vim.current.buffer',               'Buffer'),
+      ('vim.current.range',                'Range'),
+      ('vim.current.window',               'Window'),
+      ('vim.current.tabpage',              'TabPage'),
+  ):
+      cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr)))
+  del expr
+  del attr
 EOF
 :"
 :" Test __dir__() method
-py3 << EOF
-for name, o in (
-        ('current',    vim.current),
-        ('buffer',     vim.current.buffer),
-        ('window',     vim.current.window),
-        ('tabpage',    vim.current.tabpage),
-        ('range',      vim.current.range),
-        ('dictionary', vim.bindeval('{}')),
-        ('list',       vim.bindeval('[]')),
-        ('function',   vim.bindeval('function("tr")')),
-        ('output',     sys.stdout),
-    ):
-    cb.append(name + ':' + ','.join(dir(o)))
-del name
-del o
+py3 << trim EOF
+  for name, o in (
+          ('current',    vim.current),
+          ('buffer',     vim.current.buffer),
+          ('window',     vim.current.window),
+          ('tabpage',    vim.current.tabpage),
+          ('range',      vim.current.range),
+          ('dictionary', vim.bindeval('{}')),
+          ('list',       vim.bindeval('[]')),
+          ('function',   vim.bindeval('function("tr")')),
+          ('output',     sys.stdout),
+      ):
+      cb.append(name + ':' + ','.join(dir(o)))
+  del name
+  del o
 EOF
 :"
 :" Test vim.*.__new__
@@ -917,63 +917,63 @@ EOF
 :py3 Pt = vim.bindeval('Pt')
 :unlet Pt
 :py3 del Pt
-py3 << EOF
-def ecall(out_prefix, func, *args, **kwargs):
-    line = out_prefix + ': '
-    try:
-        ret = func(*args, **kwargs)
-    except Exception:
-        line += '!exception: ' + emsg(sys.exc_info())
-    else:
-        line += '!result: ' + str(vim.Function('string')(ret), 'utf-8')
-    cb.append(line)
-a = vim.Function('Args')
-pa1 = vim.Function('Args', args=['abcArgsPA1'])
-pa2 = vim.Function('Args', args=[])
-pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'})
-pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'})
-cb.append('a: ' + repr(a))
-cb.append('pa1: ' + repr(pa1))
-cb.append('pa2: ' + repr(pa2))
-cb.append('pa3: ' + repr(pa3))
-cb.append('pa4: ' + repr(pa4))
-sa = vim.Function('SelfArgs')
-psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1'])
-psa2 = vim.Function('SelfArgs', args=[])
-psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'})
-psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'})
-psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0)
-psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=())
-psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[])
-psa8 = vim.Function('SelfArgs', auto_rebind=False)
-psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True)
-psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1)
-psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'})
-psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC'])
-cb.append('sa: ' + repr(sa))
-cb.append('psa1: ' + repr(psa1))
-cb.append('psa2: ' + repr(psa2))
-cb.append('psa3: ' + repr(psa3))
-cb.append('psa4: ' + repr(psa4))
-cb.append('psa5: ' + repr(psa5))
-cb.append('psa6: ' + repr(psa6))
-cb.append('psa7: ' + repr(psa7))
-cb.append('psa8: ' + repr(psa8))
-cb.append('psa9: ' + repr(psa9))
-cb.append('psaA: ' + repr(psaA))
-cb.append('psaB: ' + repr(psaB))
-cb.append('psaC: ' + repr(psaC))
+py3 << trim EOF
+  def ecall(out_prefix, func, *args, **kwargs):
+      line = out_prefix + ': '
+      try:
+          ret = func(*args, **kwargs)
+      except Exception:
+          line += '!exception: ' + emsg(sys.exc_info())
+      else:
+          line += '!result: ' + str(vim.Function('string')(ret), 'utf-8')
+      cb.append(line)
+  a = vim.Function('Args')
+  pa1 = vim.Function('Args', args=['abcArgsPA1'])
+  pa2 = vim.Function('Args', args=[])
+  pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'})
+  pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'})
+  cb.append('a: ' + repr(a))
+  cb.append('pa1: ' + repr(pa1))
+  cb.append('pa2: ' + repr(pa2))
+  cb.append('pa3: ' + repr(pa3))
+  cb.append('pa4: ' + repr(pa4))
+  sa = vim.Function('SelfArgs')
+  psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1'])
+  psa2 = vim.Function('SelfArgs', args=[])
+  psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'})
+  psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'})
+  psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0)
+  psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=())
+  psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[])
+  psa8 = vim.Function('SelfArgs', auto_rebind=False)
+  psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True)
+  psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1)
+  psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'})
+  psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC'])
+  cb.append('sa: ' + repr(sa))
+  cb.append('psa1: ' + repr(psa1))
+  cb.append('psa2: ' + repr(psa2))
+  cb.append('psa3: ' + repr(psa3))
+  cb.append('psa4: ' + repr(psa4))
+  cb.append('psa5: ' + repr(psa5))
+  cb.append('psa6: ' + repr(psa6))
+  cb.append('psa7: ' + repr(psa7))
+  cb.append('psa8: ' + repr(psa8))
+  cb.append('psa9: ' + repr(psa9))
+  cb.append('psaA: ' + repr(psaA))
+  cb.append('psaB: ' + repr(psaB))
+  cb.append('psaC: ' + repr(psaC))
 
-psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'})
-psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]]
-psar.self['rec'] = psar
-psar.self['self'] = psar.self
-psar.self['args'] = psar.args
+  psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'})
+  psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]]
+  psar.self['rec'] = psar
+  psar.self['self'] = psar.self
+  psar.self['args'] = psar.args
 
-try:
-    cb.append('psar: ' + repr(psar))
-except Exception:
-    cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
+  try:
+      cb.append('psar: ' + repr(psar))
+  except Exception:
+      cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
 EOF
 :$put ='s(a): '.string(py3eval('a'))
 :$put ='s(pa1): '.string(py3eval('pa1'))
@@ -1042,88 +1042,88 @@ EOF
 :py3 ecall('psa2(self={"20": 1})', psa2, self={'20': 1})
 :py3 ecall('psa3(self={"20": 1})', psa3, self={'20': 1})
 :py3 ecall('psa4(self={"20": 1})', psa4, self={'20': 1})
-py3 << EOF
-def s(v):
-    if v is None:
-        return repr(v)
-    else:
-        return str(vim.Function('string')(v), 'utf-8')
+py3 << trim EOF
+  def s(v):
+      if v is None:
+          return repr(v)
+      else:
+          return str(vim.Function('string')(v), 'utf-8')
 
-cb.append('a.args: ' + s(a.args))
-cb.append('pa1.args: ' + s(pa1.args))
-cb.append('pa2.args: ' + s(pa2.args))
-cb.append('pa3.args: ' + s(pa3.args))
-cb.append('pa4.args: ' + s(pa4.args))
-cb.append('sa.args: ' + s(sa.args))
-cb.append('psa1.args: ' + s(psa1.args))
-cb.append('psa2.args: ' + s(psa2.args))
-cb.append('psa3.args: ' + s(psa3.args))
-cb.append('psa4.args: ' + s(psa4.args))
+  cb.append('a.args: ' + s(a.args))
+  cb.append('pa1.args: ' + s(pa1.args))
+  cb.append('pa2.args: ' + s(pa2.args))
+  cb.append('pa3.args: ' + s(pa3.args))
+  cb.append('pa4.args: ' + s(pa4.args))
+  cb.append('sa.args: ' + s(sa.args))
+  cb.append('psa1.args: ' + s(psa1.args))
+  cb.append('psa2.args: ' + s(psa2.args))
+  cb.append('psa3.args: ' + s(psa3.args))
+  cb.append('psa4.args: ' + s(psa4.args))
 
-cb.append('a.self: ' + s(a.self))
-cb.append('pa1.self: ' + s(pa1.self))
-cb.append('pa2.self: ' + s(pa2.self))
-cb.append('pa3.self: ' + s(pa3.self))
-cb.append('pa4.self: ' + s(pa4.self))
-cb.append('sa.self: ' + s(sa.self))
-cb.append('psa1.self: ' + s(psa1.self))
-cb.append('psa2.self: ' + s(psa2.self))
-cb.append('psa3.self: ' + s(psa3.self))
-cb.append('psa4.self: ' + s(psa4.self))
+  cb.append('a.self: ' + s(a.self))
+  cb.append('pa1.self: ' + s(pa1.self))
+  cb.append('pa2.self: ' + s(pa2.self))
+  cb.append('pa3.self: ' + s(pa3.self))
+  cb.append('pa4.self: ' + s(pa4.self))
+  cb.append('sa.self: ' + s(sa.self))
+  cb.append('psa1.self: ' + s(psa1.self))
+  cb.append('psa2.self: ' + s(psa2.self))
+  cb.append('psa3.self: ' + s(psa3.self))
+  cb.append('psa4.self: ' + s(psa4.self))
 
-cb.append('a.name: ' + s(a.name))
-cb.append('pa1.name: ' + s(pa1.name))
-cb.append('pa2.name: ' + s(pa2.name))
-cb.append('pa3.name: ' + s(pa3.name))
-cb.append('pa4.name: ' + s(pa4.name))
-cb.append('sa.name: ' + s(sa.name))
-cb.append('psa1.name: ' + s(psa1.name))
-cb.append('psa2.name: ' + s(psa2.name))
-cb.append('psa3.name: ' + s(psa3.name))
-cb.append('psa4.name: ' + s(psa4.name))
+  cb.append('a.name: ' + s(a.name))
+  cb.append('pa1.name: ' + s(pa1.name))
+  cb.append('pa2.name: ' + s(pa2.name))
+  cb.append('pa3.name: ' + s(pa3.name))
+  cb.append('pa4.name: ' + s(pa4.name))
+  cb.append('sa.name: ' + s(sa.name))
+  cb.append('psa1.name: ' + s(psa1.name))
+  cb.append('psa2.name: ' + s(psa2.name))
+  cb.append('psa3.name: ' + s(psa3.name))
+  cb.append('psa4.name: ' + s(psa4.name))
 
-cb.append('a.auto_rebind: ' + s(a.auto_rebind))
-cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind))
-cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind))
-cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind))
-cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind))
-cb.append('sa.auto_rebind: ' + s(sa.auto_rebind))
-cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind))
-cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind))
-cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind))
-cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind))
-cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind))
-cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind))
-cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind))
-cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind))
-cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind))
-cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind))
-cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind))
-cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind))
+  cb.append('a.auto_rebind: ' + s(a.auto_rebind))
+  cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind))
+  cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind))
+  cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind))
+  cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind))
+  cb.append('sa.auto_rebind: ' + s(sa.auto_rebind))
+  cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind))
+  cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind))
+  cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind))
+  cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind))
+  cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind))
+  cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind))
+  cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind))
+  cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind))
+  cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind))
+  cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind))
+  cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind))
+  cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind))
 
-del s
+  del s
 
-del a
-del pa1
-del pa2
-del pa3
-del pa4
-del sa
-del psa1
-del psa2
-del psa3
-del psa4
-del psa5
-del psa6
-del psa7
-del psa8
-del psa9
-del psaA
-del psaB
-del psaC
-del psar
+  del a
+  del pa1
+  del pa2
+  del pa3
+  del pa4
+  del sa
+  del psa1
+  del psa2
+  del psa3
+  del psa4
+  del psa5
+  del psa6
+  del psa7
+  del psa8
+  del psa9
+  del psaA
+  del psaB
+  del psaC
+  del psar
 
-del ecall
+  del ecall
 EOF
 :"
 :" Test stdout/stderr
@@ -1139,27 +1139,27 @@ EOF
 :   $put =string(a:000)
 :   return a:000
 :endfun
-py3 << EOF
-class DupDict(vim.Dictionary):
-    def __setitem__(self, key, value):
-        super(DupDict, self).__setitem__(key, value)
-        super(DupDict, self).__setitem__('dup_' + key, value)
-dd = DupDict()
-dd['a'] = 'b'
+py3 << trim EOF
+  class DupDict(vim.Dictionary):
+      def __setitem__(self, key, value):
+          super(DupDict, self).__setitem__(key, value)
+          super(DupDict, self).__setitem__('dup_' + key, value)
+  dd = DupDict()
+  dd['a'] = 'b'
 
-class DupList(vim.List):
-    def __getitem__(self, idx):
-        return [super(DupList, self).__getitem__(idx)] * 2
+  class DupList(vim.List):
+      def __getitem__(self, idx):
+          return [super(DupList, self).__getitem__(idx)] * 2
 
-dl = DupList()
-dl2 = DupList(iter('abcC'))
-dl.extend(dl2[0])
+  dl = DupList()
+  dl2 = DupList(iter('abcC'))
+  dl.extend(dl2[0])
 
-class DupFun(vim.Function):
-    def __call__(self, arg):
-        return super(DupFun, self).__call__(arg, arg)
+  class DupFun(vim.Function):
+      def __call__(self, arg):
+          return super(DupFun, self).__call__(arg, arg)
 
-df = DupFun('Put')
+  df = DupFun('Put')
 EOF
 :$put =string(sort(keys(py3eval('dd'))))
 :$put =string(py3eval('dl'))
@@ -1169,40 +1169,40 @@ EOF
 :$put =string(py3eval('dd') is# py3eval('dd'))
 :$put =string(py3eval('df'))
 :delfunction Put
-py3 << EOF
-del DupDict
-del DupList
-del DupFun
-del dd
-del dl
-del dl2
-del df
+py3 << trim EOF
+  del DupDict
+  del DupList
+  del DupFun
+  del dd
+  del dl
+  del dl2
+  del df
 EOF
 :"
 :" Test chdir
-py3 << EOF
-import os
-fnamemodify = vim.Function('fnamemodify')
-cb.append(str(fnamemodify('.', ':p:h:t')))
-cb.append(vim.eval('@%'))
-os.chdir('..')
-path = fnamemodify('.', ':p:h:t')
-if path != b'src':
-  # Running tests from a shadow directory, so move up another level
-  # This will result in @% looking like shadow/testdir/test87.in, hence the
-  # slicing to remove the leading path and path separator
+py3 << trim EOF
+  import os
+  fnamemodify = vim.Function('fnamemodify')
+  cb.append(str(fnamemodify('.', ':p:h:t')))
+  cb.append(vim.eval('@%'))
   os.chdir('..')
-  cb.append(str(fnamemodify('.', ':p:h:t')))
-  cb.append(vim.eval('@%')[len(path)+1:].replace(os.path.sep, '/'))
-  os.chdir(path)
-else:
+  path = fnamemodify('.', ':p:h:t')
+  if path != b'src':
+    # Running tests from a shadow directory, so move up another level
+    # This will result in @% looking like shadow/testdir/test87.in, hence the
+    # slicing to remove the leading path and path separator
+    os.chdir('..')
+    cb.append(str(fnamemodify('.', ':p:h:t')))
+    cb.append(vim.eval('@%')[len(path)+1:].replace(os.path.sep, '/'))
+    os.chdir(path)
+  else:
+    cb.append(str(fnamemodify('.', ':p:h:t')))
+    cb.append(vim.eval('@%').replace(os.path.sep, '/'))
+  del path
+  os.chdir('testdir')
   cb.append(str(fnamemodify('.', ':p:h:t')))
-  cb.append(vim.eval('@%').replace(os.path.sep, '/'))
-del path
-os.chdir('testdir')
-cb.append(str(fnamemodify('.', ':p:h:t')))
-cb.append(vim.eval('@%'))
-del fnamemodify
+  cb.append(vim.eval('@%'))
+  del fnamemodify
 EOF
 :"
 :" Test errors
@@ -1210,464 +1210,464 @@ EOF
 :endfun
 :fun D()
 :endfun
-py3 << EOF
-d = vim.Dictionary()
-ned = vim.Dictionary(foo='bar', baz='abcD')
-dl = vim.Dictionary(a=1)
-dl.locked = True
-l = vim.List()
-ll = vim.List('abcE')
-ll.locked = True
-nel = vim.List('abcO')
-f = vim.Function('string')
-fd = vim.Function('F')
-fdel = vim.Function('D')
-vim.command('delfunction D')
+py3 << trim EOF
+  d = vim.Dictionary()
+  ned = vim.Dictionary(foo='bar', baz='abcD')
+  dl = vim.Dictionary(a=1)
+  dl.locked = True
+  l = vim.List()
+  ll = vim.List('abcE')
+  ll.locked = True
+  nel = vim.List('abcO')
+  f = vim.Function('string')
+  fd = vim.Function('F')
+  fdel = vim.Function('D')
+  vim.command('delfunction D')
 
-def subexpr_test(expr, name, subexprs):
-    cb.append('>>> Testing %s using %s' % (name, expr))
-    for subexpr in subexprs:
-        ee(expr % subexpr)
-    cb.append('<<< Finished')
+  def subexpr_test(expr, name, subexprs):
+      cb.append('>>> Testing %s using %s' % (name, expr))
+      for subexpr in subexprs:
+          ee(expr % subexpr)
+      cb.append('<<< Finished')
 
-def stringtochars_test(expr):
-    return subexpr_test(expr, 'StringToChars', (
-        '1',       # Fail type checks
-        'b"\\0"',  # Fail PyString_AsStringAndSize(object, , NULL) check
-        '"\\0"',   # Fail PyString_AsStringAndSize(bytes, , NULL) check
-    ))
+  def stringtochars_test(expr):
+      return subexpr_test(expr, 'StringToChars', (
+          '1',       # Fail type checks
+          'b"\\0"',  # Fail PyString_AsStringAndSize(object, , NULL) check
+          '"\\0"',   # Fail PyString_AsStringAndSize(bytes, , NULL) check
+      ))
 
-class Mapping(object):
-    def __init__(self, d):
-        self.d = d
+  class Mapping(object):
+      def __init__(self, d):
+          self.d = d
 
-    def __getitem__(self, key):
-        return self.d[key]
+      def __getitem__(self, key):
+          return self.d[key]
 
-    def keys(self):
-        return self.d.keys()
+      def keys(self):
+          return self.d.keys()
 
-    def items(self):
-        return self.d.items()
+      def items(self):
+          return self.d.items()
 
-def convertfrompyobject_test(expr, recurse=True):
-    # pydict_to_tv
-    stringtochars_test(expr % '{%s : 1}')
-    if recurse:
-        convertfrompyobject_test(expr % '{"abcF" : %s}', False)
-    # pymap_to_tv
-    stringtochars_test(expr % 'Mapping({%s : 1})')
-    if recurse:
-        convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False)
-    # pyseq_to_tv
-    iter_test(expr)
-    return subexpr_test(expr, 'ConvertFromPyObject', (
-        'None',                 # Not conversible
-        '{b"": 1}',             # Empty key not allowed
-        '{"": 1}',              # Same, but with unicode object
-        'FailingMapping()',     #
-        'FailingMappingKey()',  #
-        'FailingNumber()',      #
-    ))
+  def convertfrompyobject_test(expr, recurse=True):
+      # pydict_to_tv
+      stringtochars_test(expr % '{%s : 1}')
+      if recurse:
+          convertfrompyobject_test(expr % '{"abcF" : %s}', False)
+      # pymap_to_tv
+      stringtochars_test(expr % 'Mapping({%s : 1})')
+      if recurse:
+          convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False)
+      # pyseq_to_tv
+      iter_test(expr)
+      return subexpr_test(expr, 'ConvertFromPyObject', (
+          'None',                 # Not conversible
+          '{b"": 1}',             # Empty key not allowed
+          '{"": 1}',              # Same, but with unicode object
+          'FailingMapping()',     #
+          'FailingMappingKey()',  #
+          'FailingNumber()',      #
+      ))
 
-def convertfrompymapping_test(expr):
-    convertfrompyobject_test(expr)
-    return subexpr_test(expr, 'ConvertFromPyMapping', (
-        '[]',
-    ))
+  def convertfrompymapping_test(expr):
+      convertfrompyobject_test(expr)
+      return subexpr_test(expr, 'ConvertFromPyMapping', (
+          '[]',
+      ))
 
-def iter_test(expr):
-    return subexpr_test(expr, '*Iter*', (
-        'FailingIter()',
-        'FailingIterNext()',
-    ))
+  def iter_test(expr):
+      return subexpr_test(expr, '*Iter*', (
+          'FailingIter()',
+          'FailingIterNext()',
+      ))
 
-def number_test(expr, natural=False, unsigned=False):
-    if natural:
-        unsigned = True
-    return subexpr_test(expr, 'NumberToLong', (
-        '[]',
-        'None',
-    ) + (('-1',) if unsigned else ())
-    + (('0',) if natural else ()))
+  def number_test(expr, natural=False, unsigned=False):
+      if natural:
+          unsigned = True
+      return subexpr_test(expr, 'NumberToLong', (
+          '[]',
+          'None',
+      ) + (('-1',) if unsigned else ())
+      + (('0',) if natural else ()))
 
-class FailingTrue(object):
-    def __bool__(self):
-        raise NotImplementedError('bool')
+  class FailingTrue(object):
+      def __bool__(self):
+          raise NotImplementedError('bool')
 
-class FailingIter(object):
-    def __iter__(self):
-        raise NotImplementedError('iter')
+  class FailingIter(object):
+      def __iter__(self):
+          raise NotImplementedError('iter')
 
-class FailingIterNext(object):
-    def __iter__(self):
-        return self
+  class FailingIterNext(object):
+      def __iter__(self):
+          return self
 
-    def __next__(self):
-        raise NotImplementedError('next')
+      def __next__(self):
+          raise NotImplementedError('next')
 
-class FailingIterNextN(object):
-    def __init__(self, n):
-        self.n = n
+  class FailingIterNextN(object):
+      def __init__(self, n):
+          self.n = n
 
-    def __iter__(self):
-        return self
+      def __iter__(self):
+          return self
 
-    def __next__(self):
-        if self.n:
-            self.n -= 1
-            return 1
-        else:
-            raise NotImplementedError('next N')
+      def __next__(self):
+          if self.n:
+              self.n -= 1
+              return 1
+          else:
+              raise NotImplementedError('next N')
 
-class FailingMappingKey(object):
-    def __getitem__(self, item):
-        raise NotImplementedError('getitem:mappingkey')
+  class FailingMappingKey(object):
+      def __getitem__(self, item):
+          raise NotImplementedError('getitem:mappingkey')
 
-    def keys(self):
-        return list("abcH")
+      def keys(self):
+          return list("abcH")
 
-class FailingMapping(object):
-    def __getitem__(self):
-        raise NotImplementedError('getitem:mapping')
+  class FailingMapping(object):
+      def __getitem__(self):
+          raise NotImplementedError('getitem:mapping')
 
-    def keys(self):
-        raise NotImplementedError('keys')
+      def keys(self):
+          raise NotImplementedError('keys')
 
-class FailingList(list):
-    def __getitem__(self, idx):
-        if i == 2:
-            raise NotImplementedError('getitem:list')
-        else:
-            return super(FailingList, self).__getitem__(idx)
+  class FailingList(list):
+      def __getitem__(self, idx):
+          if i == 2:
+              raise NotImplementedError('getitem:list')
+          else:
+              return super(FailingList, self).__getitem__(idx)
 
-class NoArgsCall(object):
-    def __call__(self):
-        pass
+  class NoArgsCall(object):
+      def __call__(self):
+          pass
 
-class FailingCall(object):
-    def __call__(self, path):
-        raise NotImplementedError('call')
+  class FailingCall(object):
+      def __call__(self, path):
+          raise NotImplementedError('call')
 
-class FailingNumber(object):
-    def __int__(self):
-        raise NotImplementedError('int')
+  class FailingNumber(object):
+      def __int__(self):
+          raise NotImplementedError('int')
 
-cb.append("> Output")
-cb.append(">> OutputSetattr")
-ee('del sys.stdout.softspace')
-number_test('sys.stdout.softspace = %s', unsigned=True)
-number_test('sys.stderr.softspace = %s', unsigned=True)
-ee('assert sys.stdout.isatty()==False')
-ee('assert sys.stdout.seekable()==False')
-ee('sys.stdout.close()')
-ee('sys.stdout.flush()')
-ee('assert sys.stderr.isatty()==False')
-ee('assert sys.stderr.seekable()==False')
-ee('sys.stderr.close()')
-ee('sys.stderr.flush()')
-ee('sys.stdout.attr = None')
-cb.append(">> OutputWrite")
-ee('assert sys.stdout.writable()==True')
-ee('assert sys.stdout.readable()==False')
-ee('assert sys.stderr.writable()==True')
-ee('assert sys.stderr.readable()==False')
-ee('assert sys.stdout.closed()==False')
-ee('assert sys.stderr.closed()==False')
-ee('assert sys.stdout.errors=="strict"')
-ee('assert sys.stderr.errors=="strict"')
-ee('assert sys.stdout.encoding==sys.stderr.encoding')
-ee('sys.stdout.write(None)')
-cb.append(">> OutputWriteLines")
-ee('sys.stdout.writelines(None)')
-ee('sys.stdout.writelines([1])')
-iter_test('sys.stdout.writelines(%s)')
-cb.append("> VimCommand")
-stringtochars_test('vim.command(%s)')
-ee('vim.command("", 2)')
-#! Not checked: vim->python exceptions translating: checked later
-cb.append("> VimToPython")
-#! Not checked: everything: needs errors in internal python functions
-cb.append("> VimEval")
-stringtochars_test('vim.eval(%s)')
-ee('vim.eval("", FailingTrue())')
-#! Not checked: everything: needs errors in internal python functions
-cb.append("> VimEvalPy")
-stringtochars_test('vim.bindeval(%s)')
-ee('vim.eval("", 2)')
-#! Not checked: vim->python exceptions translating: checked later
-cb.append("> VimStrwidth")
-stringtochars_test('vim.strwidth(%s)')
-cb.append("> VimForeachRTP")
-ee('vim.foreach_rtp(None)')
-ee('vim.foreach_rtp(NoArgsCall())')
-ee('vim.foreach_rtp(FailingCall())')
-ee('vim.foreach_rtp(int, 2)')
-cb.append('> import')
-old_rtp = vim.options['rtp']
-vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,')
-ee('import xxx_no_such_module_xxx')
-ee('import failing_import')
-ee('import failing')
-vim.options['rtp'] = old_rtp
-del old_rtp
-cb.append("> Options")
-cb.append(">> OptionsItem")
-ee('vim.options["abcQ"]')
-ee('vim.options[""]')
-stringtochars_test('vim.options[%s]')
-cb.append(">> OptionsContains")
-stringtochars_test('%s in vim.options')
-cb.append("> Dictionary")
-cb.append(">> DictionaryConstructor")
-ee('vim.Dictionary("abcI")')
-##! Not checked: py_dict_alloc failure
-cb.append(">> DictionarySetattr")
-ee('del d.locked')
-ee('d.locked = FailingTrue()')
-ee('vim.vvars.locked = False')
-ee('d.scope = True')
-ee('d.xxx = True')
-cb.append(">> _DictionaryItem")
-ee('d.get("a", 2, 3)')
-stringtochars_test('d.get(%s)')
-ee('d.pop("a")')
-ee('dl.pop("a")')
-cb.append(">> DictionaryContains")
-ee('"" in d')
-ee('0 in d')
-cb.append(">> DictionaryIterNext")
-ee('for i in ned: ned["a"] = 1')
-del i
-cb.append(">> DictionaryAssItem")
-ee('dl["b"] = 1')
-stringtochars_test('d[%s] = 1')
-convertfrompyobject_test('d["a"] = %s')
-cb.append(">> DictionaryUpdate")
-cb.append(">>> kwargs")
-cb.append(">>> iter")
-ee('d.update(FailingMapping())')
-ee('d.update([FailingIterNext()])')
-ee('d.update([FailingIterNextN(1)])')
-iter_test('d.update(%s)')
-convertfrompyobject_test('d.update(%s)')
-stringtochars_test('d.update(((%s, 0),))')
-convertfrompyobject_test('d.update((("a", %s),))')
-cb.append(">> DictionaryPopItem")
-ee('d.popitem(1, 2)')
-cb.append(">> DictionaryHasKey")
-ee('d.has_key()')
-cb.append("> List")
-cb.append(">> ListConstructor")
-ee('vim.List(1, 2)')
-ee('vim.List(a=1)')
-iter_test('vim.List(%s)')
-convertfrompyobject_test('vim.List([%s])')
-cb.append(">> ListItem")
-ee('l[1000]')
-cb.append(">> ListAssItem")
-ee('ll[1] = 2')
-ee('l[1000] = 3')
-cb.append(">> ListAssSlice")
-ee('ll[1:100] = "abcJ"')
-iter_test('l[:] = %s')
-ee('nel[1:10:2]  = "abcK"')
-cb.append(repr(tuple(nel)))
-ee('nel[1:10:2]  = "a"')
-cb.append(repr(tuple(nel)))
-ee('nel[1:1:-1]  = "a"')
-cb.append(repr(tuple(nel)))
-ee('nel[:] = FailingIterNextN(2)')
-cb.append(repr(tuple(nel)))
-convertfrompyobject_test('l[:] = [%s]')
-cb.append(">> ListConcatInPlace")
-iter_test('l.extend(%s)')
-convertfrompyobject_test('l.extend([%s])')
-cb.append(">> ListSetattr")
-ee('del l.locked')
-ee('l.locked = FailingTrue()')
-ee('l.xxx = True')
-cb.append("> Function")
-cb.append(">> FunctionConstructor")
-cb.append(">>> FunctionConstructor")
-ee('vim.Function("123")')
-ee('vim.Function("xxx_non_existent_function_xxx")')
-ee('vim.Function("xxx#non#existent#function#xxx")')
-ee('vim.Function("xxx_non_existent_function_xxx2", args=[])')
-ee('vim.Function("xxx_non_existent_function_xxx3", self={})')
-ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})')
-cb.append(">>> FunctionNew")
-ee('vim.Function("tr", self="abcFuncSelf")')
-ee('vim.Function("tr", args=427423)')
-ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")')
-ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")')
-ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")')
-ee('vim.Function("tr", "")')
-cb.append(">> FunctionCall")
-convertfrompyobject_test('f(%s)')
-convertfrompymapping_test('fd(self=%s)')
-cb.append("> TabPage")
-cb.append(">> TabPageAttr")
-ee('vim.current.tabpage.xxx')
-cb.append("> TabList")
-cb.append(">> TabListItem")
-ee('vim.tabpages[1000]')
-cb.append("> Window")
-cb.append(">> WindowAttr")
-ee('vim.current.window.xxx')
-cb.append(">> WindowSetattr")
-ee('vim.current.window.buffer = 0')
-ee('vim.current.window.cursor = (100000000, 100000000)')
-ee('vim.current.window.cursor = True')
-number_test('vim.current.window.height = %s', unsigned=True)
-number_test('vim.current.window.width = %s', unsigned=True)
-ee('vim.current.window.xxxxxx = True')
-cb.append("> WinList")
-cb.append(">> WinListItem")
-ee('vim.windows[1000]')
-cb.append("> Buffer")
-cb.append(">> StringToLine (indirect)")
-ee('vim.current.buffer[0] = "\\na"')
-ee('vim.current.buffer[0] = b"\\na"')
-cb.append(">> SetBufferLine (indirect)")
-ee('vim.current.buffer[0] = True')
-cb.append(">> SetBufferLineList (indirect)")
-ee('vim.current.buffer[:] = True')
-ee('vim.current.buffer[:] = ["\\na", "bc"]')
-cb.append(">> InsertBufferLines (indirect)")
-ee('vim.current.buffer.append(None)')
-ee('vim.current.buffer.append(["\\na", "bc"])')
-ee('vim.current.buffer.append("\\nbc")')
-cb.append(">> RBItem")
-ee('vim.current.buffer[100000000]')
-cb.append(">> RBAsItem")
-ee('vim.current.buffer[100000000] = ""')
-cb.append(">> BufferAttr")
-ee('vim.current.buffer.xxx')
-cb.append(">> BufferSetattr")
-ee('vim.current.buffer.name = True')
-ee('vim.current.buffer.xxx = True')
-cb.append(">> BufferMark")
-ee('vim.current.buffer.mark(0)')
-ee('vim.current.buffer.mark("abcM")')
-ee('vim.current.buffer.mark("!")')
-cb.append(">> BufferRange")
-ee('vim.current.buffer.range(1, 2, 3)')
-cb.append("> BufMap")
-cb.append(">> BufMapItem")
-ee('vim.buffers[100000000]')
-number_test('vim.buffers[%s]', natural=True)
-cb.append("> Current")
-cb.append(">> CurrentGetattr")
-ee('vim.current.xxx')
-cb.append(">> CurrentSetattr")
-ee('vim.current.line = True')
-ee('vim.current.buffer = True')
-ee('vim.current.window = True')
-ee('vim.current.tabpage = True')
-ee('vim.current.xxx = True')
-del d
-del ned
-del dl
-del l
-del ll
-del nel
-del f
-del fd
-del fdel
-del subexpr_test
-del stringtochars_test
-del Mapping
-del convertfrompyobject_test
-del convertfrompymapping_test
-del iter_test
-del number_test
-del FailingTrue
-del FailingIter
-del FailingIterNext
-del FailingIterNextN
-del FailingMapping
-del FailingMappingKey
-del FailingList
-del NoArgsCall
-del FailingCall
-del FailingNumber
+  cb.append("> Output")
+  cb.append(">> OutputSetattr")
+  ee('del sys.stdout.softspace')
+  number_test('sys.stdout.softspace = %s', unsigned=True)
+  number_test('sys.stderr.softspace = %s', unsigned=True)
+  ee('assert sys.stdout.isatty()==False')
+  ee('assert sys.stdout.seekable()==False')
+  ee('sys.stdout.close()')
+  ee('sys.stdout.flush()')
+  ee('assert sys.stderr.isatty()==False')
+  ee('assert sys.stderr.seekable()==False')
+  ee('sys.stderr.close()')
+  ee('sys.stderr.flush()')
+  ee('sys.stdout.attr = None')
+  cb.append(">> OutputWrite")
+  ee('assert sys.stdout.writable()==True')
+  ee('assert sys.stdout.readable()==False')
+  ee('assert sys.stderr.writable()==True')
+  ee('assert sys.stderr.readable()==False')
+  ee('assert sys.stdout.closed()==False')
+  ee('assert sys.stderr.closed()==False')
+  ee('assert sys.stdout.errors=="strict"')
+  ee('assert sys.stderr.errors=="strict"')
+  ee('assert sys.stdout.encoding==sys.stderr.encoding')
+  ee('sys.stdout.write(None)')
+  cb.append(">> OutputWriteLines")
+  ee('sys.stdout.writelines(None)')
+  ee('sys.stdout.writelines([1])')
+  iter_test('sys.stdout.writelines(%s)')
+  cb.append("> VimCommand")
+  stringtochars_test('vim.command(%s)')
+  ee('vim.command("", 2)')
+  #! Not checked: vim->python exceptions translating: checked later
+  cb.append("> VimToPython")
+  #! Not checked: everything: needs errors in internal python functions
+  cb.append("> VimEval")
+  stringtochars_test('vim.eval(%s)')
+  ee('vim.eval("", FailingTrue())')
+  #! Not checked: everything: needs errors in internal python functions
+  cb.append("> VimEvalPy")
+  stringtochars_test('vim.bindeval(%s)')
+  ee('vim.eval("", 2)')
+  #! Not checked: vim->python exceptions translating: checked later
+  cb.append("> VimStrwidth")
+  stringtochars_test('vim.strwidth(%s)')
+  cb.append("> VimForeachRTP")
+  ee('vim.foreach_rtp(None)')
+  ee('vim.foreach_rtp(NoArgsCall())')
+  ee('vim.foreach_rtp(FailingCall())')
+  ee('vim.foreach_rtp(int, 2)')
+  cb.append('> import')
+  old_rtp = vim.options['rtp']
+  vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,')
+  ee('import xxx_no_such_module_xxx')
+  ee('import failing_import')
+  ee('import failing')
+  vim.options['rtp'] = old_rtp
+  del old_rtp
+  cb.append("> Options")
+  cb.append(">> OptionsItem")
+  ee('vim.options["abcQ"]')
+  ee('vim.options[""]')
+  stringtochars_test('vim.options[%s]')
+  cb.append(">> OptionsContains")
+  stringtochars_test('%s in vim.options')
+  cb.append("> Dictionary")
+  cb.append(">> DictionaryConstructor")
+  ee('vim.Dictionary("abcI")')
+  ##! Not checked: py_dict_alloc failure
+  cb.append(">> DictionarySetattr")
+  ee('del d.locked')
+  ee('d.locked = FailingTrue()')
+  ee('vim.vvars.locked = False')
+  ee('d.scope = True')
+  ee('d.xxx = True')
+  cb.append(">> _DictionaryItem")
+  ee('d.get("a", 2, 3)')
+  stringtochars_test('d.get(%s)')
+  ee('d.pop("a")')
+  ee('dl.pop("a")')
+  cb.append(">> DictionaryContains")
+  ee('"" in d')
+  ee('0 in d')
+  cb.append(">> DictionaryIterNext")
+  ee('for i in ned: ned["a"] = 1')
+  del i
+  cb.append(">> DictionaryAssItem")
+  ee('dl["b"] = 1')
+  stringtochars_test('d[%s] = 1')
+  convertfrompyobject_test('d["a"] = %s')
+  cb.append(">> DictionaryUpdate")
+  cb.append(">>> kwargs")
+  cb.append(">>> iter")
+  ee('d.update(FailingMapping())')
+  ee('d.update([FailingIterNext()])')
+  ee('d.update([FailingIterNextN(1)])')
+  iter_test('d.update(%s)')
+  convertfrompyobject_test('d.update(%s)')
+  stringtochars_test('d.update(((%s, 0),))')
+  convertfrompyobject_test('d.update((("a", %s),))')
+  cb.append(">> DictionaryPopItem")
+  ee('d.popitem(1, 2)')
+  cb.append(">> DictionaryHasKey")
+  ee('d.has_key()')
+  cb.append("> List")
+  cb.append(">> ListConstructor")
+  ee('vim.List(1, 2)')
+  ee('vim.List(a=1)')
+  iter_test('vim.List(%s)')
+  convertfrompyobject_test('vim.List([%s])')
+  cb.append(">> ListItem")
+  ee('l[1000]')
+  cb.append(">> ListAssItem")
+  ee('ll[1] = 2')
+  ee('l[1000] = 3')
+  cb.append(">> ListAssSlice")
+  ee('ll[1:100] = "abcJ"')
+  iter_test('l[:] = %s')
+  ee('nel[1:10:2]  = "abcK"')
+  cb.append(repr(tuple(nel)))
+  ee('nel[1:10:2]  = "a"')
+  cb.append(repr(tuple(nel)))
+  ee('nel[1:1:-1]  = "a"')
+  cb.append(repr(tuple(nel)))
+  ee('nel[:] = FailingIterNextN(2)')
+  cb.append(repr(tuple(nel)))
+  convertfrompyobject_test('l[:] = [%s]')
+  cb.append(">> ListConcatInPlace")
+  iter_test('l.extend(%s)')
+  convertfrompyobject_test('l.extend([%s])')
+  cb.append(">> ListSetattr")
+  ee('del l.locked')
+  ee('l.locked = FailingTrue()')
+  ee('l.xxx = True')
+  cb.append("> Function")
+  cb.append(">> FunctionConstructor")
+  cb.append(">>> FunctionConstructor")
+  ee('vim.Function("123")')
+  ee('vim.Function("xxx_non_existent_function_xxx")')
+  ee('vim.Function("xxx#non#existent#function#xxx")')
+  ee('vim.Function("xxx_non_existent_function_xxx2", args=[])')
+  ee('vim.Function("xxx_non_existent_function_xxx3", self={})')
+  ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})')
+  cb.append(">>> FunctionNew")
+  ee('vim.Function("tr", self="abcFuncSelf")')
+  ee('vim.Function("tr", args=427423)')
+  ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")')
+  ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")')
+  ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")')
+  ee('vim.Function("tr", "")')
+  cb.append(">> FunctionCall")
+  convertfrompyobject_test('f(%s)')
+  convertfrompymapping_test('fd(self=%s)')
+  cb.append("> TabPage")
+  cb.append(">> TabPageAttr")
+  ee('vim.current.tabpage.xxx')
+  cb.append("> TabList")
+  cb.append(">> TabListItem")
+  ee('vim.tabpages[1000]')
+  cb.append("> Window")
+  cb.append(">> WindowAttr")
+  ee('vim.current.window.xxx')
+  cb.append(">> WindowSetattr")
+  ee('vim.current.window.buffer = 0')
+  ee('vim.current.window.cursor = (100000000, 100000000)')
+  ee('vim.current.window.cursor = True')
+  number_test('vim.current.window.height = %s', unsigned=True)
+  number_test('vim.current.window.width = %s', unsigned=True)
+  ee('vim.current.window.xxxxxx = True')
+  cb.append("> WinList")
+  cb.append(">> WinListItem")
+  ee('vim.windows[1000]')
+  cb.append("> Buffer")
+  cb.append(">> StringToLine (indirect)")
+  ee('vim.current.buffer[0] = "\\na"')
+  ee('vim.current.buffer[0] = b"\\na"')
+  cb.append(">> SetBufferLine (indirect)")
+  ee('vim.current.buffer[0] = True')
+  cb.append(">> SetBufferLineList (indirect)")
+  ee('vim.current.buffer[:] = True')
+  ee('vim.current.buffer[:] = ["\\na", "bc"]')
+  cb.append(">> InsertBufferLines (indirect)")
+  ee('vim.current.buffer.append(None)')
+  ee('vim.current.buffer.append(["\\na", "bc"])')
+  ee('vim.current.buffer.append("\\nbc")')
+  cb.append(">> RBItem")
+  ee('vim.current.buffer[100000000]')
+  cb.append(">> RBAsItem")
+  ee('vim.current.buffer[100000000] = ""')
+  cb.append(">> BufferAttr")
+  ee('vim.current.buffer.xxx')
+  cb.append(">> BufferSetattr")
+  ee('vim.current.buffer.name = True')
+  ee('vim.current.buffer.xxx = True')
+  cb.append(">> BufferMark")
+  ee('vim.current.buffer.mark(0)')
+  ee('vim.current.buffer.mark("abcM")')
+  ee('vim.current.buffer.mark("!")')
+  cb.append(">> BufferRange")
+  ee('vim.current.buffer.range(1, 2, 3)')
+  cb.append("> BufMap")
+  cb.append(">> BufMapItem")
+  ee('vim.buffers[100000000]')
+  number_test('vim.buffers[%s]', natural=True)
+  cb.append("> Current")
+  cb.append(">> CurrentGetattr")
+  ee('vim.current.xxx')
+  cb.append(">> CurrentSetattr")
+  ee('vim.current.line = True')
+  ee('vim.current.buffer = True')
+  ee('vim.current.window = True')
+  ee('vim.current.tabpage = True')
+  ee('vim.current.xxx = True')
+  del d
+  del ned
+  del dl
+  del l
+  del ll
+  del nel
+  del f
+  del fd
+  del fdel
+  del subexpr_test
+  del stringtochars_test
+  del Mapping
+  del convertfrompyobject_test
+  del convertfrompymapping_test
+  del iter_test
+  del number_test
+  del FailingTrue
+  del FailingIter
+  del FailingIterNext
+  del FailingIterNextN
+  del FailingMapping
+  del FailingMappingKey
+  del FailingList
+  del NoArgsCall
+  del FailingCall
+  del FailingNumber
 EOF
 :delfunction F
 :"
 :" Test import
-py3 << EOF
-sys.path.insert(0, os.path.join(os.getcwd(), 'python_before'))
-sys.path.append(os.path.join(os.getcwd(), 'python_after'))
-vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
-l = []
-def callback(path):
-    l.append(os.path.relpath(path))
-vim.foreach_rtp(callback)
-cb.append(repr(l))
-del l
-def callback(path):
-    return os.path.relpath(path)
-cb.append(repr(vim.foreach_rtp(callback)))
-del callback
-from module import dir as d
-from modulex import ddir
-cb.append(d + ',' + ddir)
-import before
-cb.append(before.dir)
-import after
-cb.append(after.dir)
-import topmodule as tm
-import topmodule.submodule as tms
-import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss
-cb.append(tm.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):])
-cb.append(tms.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):])
-cb.append(tmsss.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):])
-del before
-del after
-del d
-del ddir
-del tm
-del tms
-del tmsss
+py3 << trim EOF
+  sys.path.insert(0, os.path.join(os.getcwd(), 'python_before'))
+  sys.path.append(os.path.join(os.getcwd(), 'python_after'))
+  vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
+  l = []
+  def callback(path):
+      l.append(os.path.relpath(path))
+  vim.foreach_rtp(callback)
+  cb.append(repr(l))
+  del l
+  def callback(path):
+      return os.path.relpath(path)
+  cb.append(repr(vim.foreach_rtp(callback)))
+  del callback
+  from module import dir as d
+  from modulex import ddir
+  cb.append(d + ',' + ddir)
+  import before
+  cb.append(before.dir)
+  import after
+  cb.append(after.dir)
+  import topmodule as tm
+  import topmodule.submodule as tms
+  import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss
+  cb.append(tm.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):])
+  cb.append(tms.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):])
+  cb.append(tmsss.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):])
+  del before
+  del after
+  del d
+  del ddir
+  del tm
+  del tms
+  del tmsss
 EOF
 :"
 :" Test exceptions
 :fun Exe(e)
 :   execute a:e
 :endfun
-py3 << EOF
-Exe = vim.bindeval('function("Exe")')
-ee('vim.command("throw \'abcN\'")')
-ee('Exe("throw \'def\'")')
-ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")')
-ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")')
-ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")')
-ee('vim.eval("xxx_unknown_function_xxx()")')
-ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")')
-del Exe
+py3 << trim EOF
+  Exe = vim.bindeval('function("Exe")')
+  ee('vim.command("throw \'abcN\'")')
+  ee('Exe("throw \'def\'")')
+  ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")')
+  ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")')
+  ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")')
+  ee('vim.eval("xxx_unknown_function_xxx()")')
+  ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")')
+  del Exe
 EOF
 :delfunction Exe
 :"
 :" Regression: interrupting vim.command propagates to next vim.command
-py3 << EOF
-def test_keyboard_interrupt():
-    try:
-        vim.command('while 1 | endwhile')
-    except KeyboardInterrupt:
-        cb.append('Caught KeyboardInterrupt')
-    except Exception:
-        cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
-    else:
-        cb.append('!!!!!!!! No exception')
-    try:
-        vim.command('$ put =\'Running :put\'')
-    except KeyboardInterrupt:
-        cb.append('!!!!!!!! Caught KeyboardInterrupt')
-    except Exception:
-        cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
-    else:
-        cb.append('No exception')
+py3 << trim EOF
+  def test_keyboard_interrupt():
+      try:
+          vim.command('while 1 | endwhile')
+      except KeyboardInterrupt:
+          cb.append('Caught KeyboardInterrupt')
+      except Exception:
+          cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
+      else:
+          cb.append('!!!!!!!! No exception')
+      try:
+          vim.command('$ put =\'Running :put\'')
+      except KeyboardInterrupt:
+          cb.append('!!!!!!!! Caught KeyboardInterrupt')
+      except Exception:
+          cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
+      else:
+          cb.append('No exception')
 EOF
 :debuggreedy
 :call inputsave()
@@ -1682,13 +1682,13 @@ EOF
 :py3 del test_keyboard_interrupt
 :"
 :" Cleanup
-py3 << EOF
-del cb
-del ee
-del emsg
-del sys
-del os
-del vim
+py3 << trim EOF
+  del cb
+  del ee
+  del emsg
+  del sys
+  del os
+  del vim
 EOF
 :endfun
 :"