updated for version 7.3.1061
Problem:    Python: Dictionary is not standard.
Solution:   Python patch 20: Add standard methods and fields. (ZyX)
diff --git a/src/testdir/test86.in b/src/testdir/test86.in
index cf97686..28adb70 100644
--- a/src/testdir/test86.in
+++ b/src/testdir/test86.in
@@ -31,16 +31,22 @@
 :"
 :" Extending Dictionary directly with different types
 :let d = {}
-:py d=vim.bindeval('d')
-:py d['1']='asd'
-:py d['b']=[1, 2, f]
-:py d['-1']={'a': 1}
-:let dkeys = []
-:py dk=vim.bindeval('dkeys')
-:py dkeys=d.keys()
-:py dkeys.sort()
-:py dk.extend(dkeys)
-:$put =string(dkeys)
+py << EOF
+d=vim.bindeval('d')
+d['1']='asd'
+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 =pyeval('repr(dk)')
+:$put =substitute(pyeval('repr(dv)'),'0x\x\+','','g')
+:$put =substitute(pyeval('repr(di)'),'0x\x\+','','g')
 :for [key, val] in sort(items(d))
 :  $put =string(key) . ' : ' . string(val)
 :  unlet key val
@@ -60,7 +66,20 @@
 :$put =string(l)
 :"
 :py del d['-1']
+:$put =string(pyeval('d.get(''b'', 1)'))
+:$put =string(pyeval('d.pop(''b'')'))
+:$put =string(pyeval('d.get(''b'', 1)'))
+:$put =string(pyeval('d.pop(''1'', 2)'))
+:$put =string(pyeval('d.pop(''1'', 2)'))
+:$put =pyeval('repr(d.has_key(''0''))')
+:$put =pyeval('repr(d.has_key(''1''))')
+:$put =pyeval('repr(''0'' in d)')
+:$put =pyeval('repr(''1'' in d)')
+:$put =pyeval('repr(list(iter(d)))')
 :$put =string(d)
+:$put =pyeval('repr(d.popitem(''0''))')
+:$put =pyeval('repr(d.get(''0''))')
+:$put =pyeval('repr(list(iter(d)))')
 :"
 :" removing items out of range: silently skip items that don't exist
 :let l = [0, 1, 2, 3]
@@ -198,6 +217,9 @@
 em('d[""]=1')
 em('d["a\\0b"]=1')
 em('d[u"a\\0b"]=1')
+
+em('d.pop("abc")')
+em('d.popitem("abc")')
 EOF
 :$put =messages
 :unlet messages
@@ -709,6 +731,10 @@
 del o
 EOF
 :"
+:" Test vim.*.__new__
+:$put =string(pyeval('vim.Dictionary({})'))
+:$put =string(pyeval('vim.Dictionary(a=1)'))
+:$put =string(pyeval('vim.Dictionary(((''a'', 1),))'))
 :"
 :" Test stdout/stderr
 :redir => messages
@@ -718,6 +744,16 @@
 :py sys.stderr.writelines(iter('abc'))
 :redir END
 :$put =string(substitute(messages, '\d\+', '', 'g'))
+:" Test subclassing
+py << 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'
+EOF
+:$put =string(sort(keys(pyeval('dd'))))
 :"
 :" Test exceptions
 :fun Exe(e)
diff --git a/src/testdir/test86.ok b/src/testdir/test86.ok
index fb94c3a..200af04 100644
--- a/src/testdir/test86.ok
+++ b/src/testdir/test86.ok
@@ -4,13 +4,29 @@
 Vim(put):E684:
 [0, 'as''d', [1, 2, function('strlen'), {'a': 1}]]
 [0, function('strlen'), [1, 2, function('strlen'), {'a': 1}]]
-['-1', '1', 'b']
+['-1', '0', '1', 'b']
+['asd', -1L, <vim.dictionary object at >, <vim.list object at >]
+[('-1', <vim.dictionary object at >), ('0', -1L), ('1', 'asd'), ('b', <vim.list object at >)]
 '-1' : {'a': 1}
+'0' : -1
 '1' : 'asd'
 'b' : [1, 2, function('strlen')]
 [0, function('strlen')]
 [3]
-{'1': 'asd', 'b': [1, 2, function('strlen')]}
+[1, 2, function('strlen')]
+[1, 2, function('strlen')]
+1
+'asd'
+2
+True
+False
+True
+False
+['0']
+{'0': -1}
+('', -1L)
+None
+[]
 [0, 1, 2, 3]
 [0, 1, 2, 3]
 [0, 1, 3]
@@ -44,6 +60,8 @@
 ValueError
 TypeError
 TypeError
+KeyError
+KeyError
 d : locked:0;scope:0
 dl : locked:1;scope:0
 v: : locked:2;scope:1
@@ -387,10 +405,13 @@
 window:__dir__,__members__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars
 tabpage:__dir__,__members__,number,valid,vars,window,windows
 range:__dir__,__members__,append,end,start
-dictionary:__dir__,__members__,keys,locked,scope
+dictionary:__dir__,__members__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
 list:__dir__,__members__,extend,locked
 function:__call__,__dir__,__members__,softspace
 output:__dir__,__members__,flush,softspace,write,writelines
+{}
+{'a': 1}
+{'a': 1}
 '
 abcdef
 line  :
@@ -398,6 +419,7 @@
 abc
 line  :
 abc'
+['a', 'dup_a']
 (<class 'vim.error'>, error('abc',))
 (<class 'vim.error'>, error('def',))
 (<class 'vim.error'>, error('ghi',))
diff --git a/src/testdir/test87.in b/src/testdir/test87.in
index b1763ed..20f616f 100644
--- a/src/testdir/test87.in
+++ b/src/testdir/test87.in
@@ -26,16 +26,22 @@
 :"
 :" Extending Dictionary directly with different types
 :let d = {}
-:py3 d=vim.bindeval('d')
-:py3 d['1']='asd'
-:py3 d['b']=[1, 2, f]
-:py3 d['-1']={'a': 1}
-:let dkeys = []
-:py3 dk=vim.bindeval('dkeys')
-:py3 dkeys=d.keys()
-:py3 dkeys.sort()
-:py3 dk+=dkeys
-:$put =string(dkeys)
+py3 << EOF
+d=vim.bindeval('d')
+d['1']='asd'
+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('repr(dk)')
+:$put =substitute(py3eval('repr(dv)'),'0x\x\+','','g')
+:$put =substitute(py3eval('repr(di)'),'0x\x\+','','g')
 :for [key, val] in sort(items(d))
 :  $put =string(key) . ' : ' . string(val)
 :  unlet key val
@@ -55,7 +61,20 @@
 :$put =string(l)
 :"
 :py3 del d['-1']
+:$put =string(py3eval('d.get(''b'', 1)'))
+:$put =string(py3eval('d.pop(''b'')'))
+:$put =string(py3eval('d.get(''b'', 1)'))
+:$put =string(py3eval('d.pop(''1'', 2)'))
+:$put =string(py3eval('d.pop(''1'', 2)'))
+:$put =py3eval('repr(d.has_key(''0''))')
+:$put =py3eval('repr(d.has_key(''1''))')
+:$put =py3eval('repr(''0'' in d)')
+:$put =py3eval('repr(''1'' in d)')
+:$put =py3eval('repr(list(iter(d)))')
 :$put =string(d)
+:$put =py3eval('repr(d.popitem(''0''))')
+:$put =py3eval('repr(d.get(''0''))')
+:$put =py3eval('repr(list(iter(d)))')
 :"
 :" removing items out of range: silently skip items that don't exist
 :let l = [0, 1, 2, 3]
@@ -181,35 +200,21 @@
 :py3 <<EOF
 d=vim.bindeval('{}')
 m=vim.bindeval('messages')
-try:
-    d['abc']
-except Exception as e:
-    m.extend([e.__class__.__name__])
+def em(expr, g=globals(), l=locals()):
+    try:
+        exec(expr, g, l)
+    except Exception as e:
+        m.extend([e.__class__.__name__])
 
-try:
-    d['abc']="\0"
-except Exception as e:
-    m.extend([e.__class__.__name__])
+em('d["abc"]')
+em('d["abc"]="\\0"')
+em('d["abc"]=vim')
+em('d[""]=1')
+em('d["a\\0b"]=1')
+em('d[b"a\\0b"]=1')
 
-try:
-    d['abc']=vim
-except Exception as e:
-    m.extend([e.__class__.__name__])
-
-try:
-    d['']=1
-except Exception as e:
-    m.extend([e.__class__.__name__])
-
-try:
-    d['a\0b']=1
-except Exception as e:
-    m.extend([e.__class__.__name__])
-
-try:
-    d[b'a\0b']=1
-except Exception as e:
-    m.extend([e.__class__.__name__])
+em('d.pop("abc")')
+em('d.popitem("abc")')
 EOF
 :$put =messages
 :unlet messages
@@ -687,6 +692,10 @@
 del o
 EOF
 :"
+:" Test vim.Dictionary.__new__
+:$put =string(py3eval('vim.Dictionary({})'))
+:$put =string(py3eval('vim.Dictionary(a=1)'))
+:$put =string(py3eval('vim.Dictionary(((''a'', 1),))'))
 :"
 :" Test stdout/stderr
 :redir => messages
@@ -696,6 +705,16 @@
 :py sys.stderr.writelines(iter('abc'))
 :redir END
 :$put =string(substitute(messages, '\d\+', '', 'g'))
+:" Test subclassing
+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'
+EOF
+:$put =string(sort(keys(py3eval('dd'))))
 :"
 :" Test exceptions
 :fun Exe(e)
diff --git a/src/testdir/test87.ok b/src/testdir/test87.ok
index 8ae7a8c..b92d65c 100644
--- a/src/testdir/test87.ok
+++ b/src/testdir/test87.ok
@@ -4,13 +4,29 @@
 Vim(put):E684:
 [0, 'as''d', [1, 2, function('strlen'), {'a': 1}]]
 [0, function('strlen'), [1, 2, function('strlen'), {'a': 1}]]
-['-1', '1', 'b']
+[b'-1', b'0', b'1', b'b']
+[-1, <vim.dictionary object at >, <vim.list object at >, b'asd']
+[(b'-1', <vim.dictionary object at >), (b'0', -1), (b'1', b'asd'), (b'b', <vim.list object at >)]
 '-1' : {'a': 1}
+'0' : -1
 '1' : 'asd'
 'b' : [1, 2, function('strlen')]
 [0, function('strlen')]
 [3]
-{'1': 'asd', 'b': [1, 2, function('strlen')]}
+[1, 2, function('strlen')]
+[1, 2, function('strlen')]
+1
+'asd'
+2
+True
+False
+True
+False
+[b'0']
+{'0': -1}
+(b'', -1)
+None
+[]
 [0, 1, 2, 3]
 [0, 1, 2, 3]
 [0, 1, 3]
@@ -44,6 +60,8 @@
 ValueError
 TypeError
 TypeError
+KeyError
+KeyError
 d : locked:0;scope:0
 dl : locked:1;scope:0
 v: : locked:2;scope:1
@@ -376,10 +394,13 @@
 window:__dir__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars
 tabpage:__dir__,number,valid,vars,window,windows
 range:__dir__,append,end,start
-dictionary:__dir__,keys,locked,scope
+dictionary:__dir__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
 list:__dir__,extend,locked
 function:__call__,__dir__,softspace
 output:__dir__,flush,softspace,write,writelines
+{}
+{'a': 1}
+{'a': 1}
 '
 abcdef
 line  :
@@ -387,6 +408,7 @@
 abc
 line  :
 abc'
+['a', 'dup_a']
 (<class 'vim.error'>, error('abc',))
 (<class 'vim.error'>, error('def',))
 (<class 'vim.error'>, error('ghi',))