Skip to content

Commit 7c9748b

Browse files
implemented handling of lists
works ok with one special case {0: []} would serialize to "0" { } but deserializing will return {0: {}} since we depend on the first subnode to detect if its an array, this can't be solved realiably.
1 parent 2d4f628 commit 7c9748b

1 file changed

Lines changed: 35 additions & 12 deletions

File tree

‎vdf/__init__.py‎

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# Py2 & Py3 compability
1212
if sys.version_info[0] >= 3:
1313
string_type = str
14+
iter_items = 'items'
1415
BOMS = '\ufffe\ufeff'
1516

1617
def bomlen(line):
@@ -21,6 +22,7 @@ def bomlen(line):
2122
except ImportError:
2223
from StringIO import StringIO as strIO
2324
string_type = basestring
25+
iter_items = 'iteritems'
2426
BOMS = '\xef\xbb\xbf\xff\xfe\xfe\xff'
2527
BOMS_UNICODE = '\\ufffe\\ufeff'.decode('unicode-escape')
2628

@@ -55,6 +57,7 @@ def parse(source, mapper=dict):
5557
# init
5658
obj = mapper()
5759
stack = [obj]
60+
parent_key = None
5861
expect_bracket = False
5962

6063
re_keyvalue = re.compile(r'^"(?P<key>(?:\\.|[^\\"])*)"'
@@ -93,11 +96,21 @@ def parse(source, mapper=dict):
9396
if not match:
9497
raise SyntaxError("vdf.parse: invalid syntax")
9598

99+
key = match.group('key')
100+
value = match.group('value')
101+
parent = stack[-1]
102+
103+
# if first subkey is '0' assume this an array
104+
# and turn tha parrent into a list
105+
if len(parent) == 0 and key == "0":
106+
parent = stack[-1] = list()
107+
if parent_key is not None:
108+
stack[-2][parent_key] = parent
109+
96110
# we have a key with value in parenthesis, so we make a new dict obj (level deeper)
97-
if match.group('value') is None:
98-
key = match.group('key')
99-
stack[-1][key] = mapper()
100-
stack.append(stack[-1][key])
111+
if value is None:
112+
value = mapper()
113+
stack.append(value)
101114
expect_bracket = True
102115

103116
# we've matched a simple keyvalue pair, map it to the last dict obj in the stack
@@ -108,15 +121,20 @@ def parse(source, mapper=dict):
108121
line += "\n" + next(fp).rstrip()
109122
continue
110123

111-
stack[-1][match.group('key')] = match.group('value')
124+
if isinstance(parent, list):
125+
parent.append(value)
126+
parent_key = len(parent) - 1
127+
else:
128+
parent[key] = value
129+
parent_key = key
112130

113131
# exit the loop
114132
break
115133

116134
if len(stack) != 1:
117135
raise SyntaxError("vdf.parse: unclosed parenthasis or quotes")
118136

119-
return obj
137+
return stack.pop()
120138

121139

122140
def loads(fp, **kwargs):
@@ -141,8 +159,8 @@ def dumps(data, pretty=False):
141159
"""
142160
Serialize ``obj`` to VDF formatted ``str``.
143161
"""
144-
if not isinstance(data, dict):
145-
raise TypeError("Expected data to be a dict or subclass of dict")
162+
if not isinstance(data, (dict, list)):
163+
raise TypeError("Expected data to be an instance of``dict`` or ``list``")
146164
if not isinstance(pretty, bool):
147165
raise TypeError("Expected pretty to be bool")
148166

@@ -154,8 +172,8 @@ def dump(data, fp, pretty=False):
154172
Serialize ``obj`` as a VDF formatted stream to ``fp`` (a
155173
``.write()``-supporting file-like object).
156174
"""
157-
if not isinstance(data, dict):
158-
raise TypeError("Expected data to be a dict")
175+
if not isinstance(data, (dict, list)):
176+
raise TypeError("Expected data to be an instance of``dict`` or ``list``")
159177
if not hasattr(fp, 'write'):
160178
raise TypeError("Expected fp to have write() method")
161179

@@ -170,8 +188,13 @@ def _dump_gen(data, pretty=False, level=0):
170188
if pretty:
171189
line_indent = indent * level
172190

173-
for key, value in data.items():
174-
if isinstance(value, dict):
191+
if isinstance(data, list):
192+
itr = enumerate(data)
193+
else:
194+
itr = getattr(data, iter_items)()
195+
196+
for key, value in itr:
197+
if isinstance(value, (dict, list)):
175198
yield '%s"%s"\n%s{\n' % (line_indent, key, line_indent)
176199
for chunk in _dump_gen(value, pretty, level+1):
177200
yield chunk

0 commit comments

Comments
 (0)