Skip to content

Commit

Permalink
Merge pull request ValvePython#22 from lasa01/master
Browse files Browse the repository at this point in the history
Added support for more unquoted characters and inline empty blocks
  • Loading branch information
rossengeorgiev committed Jan 18, 2021
2 parents 0a2a2d6 + 339f01f commit 3b9435c
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 6 deletions.
81 changes: 80 additions & 1 deletion tests/test_vdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,16 +319,27 @@ def test_hash_key(self):
self.assertEqual(vdf.loads(INPUT, escaped=False), EXPECTED)

def test_wierd_symbols_for_unquoted(self):
INPUT = 'a asd.vdf\nb language_*lol*\nc zxc_-*.sss//'
INPUT = 'a asd.vdf\nb language_*lol*\nc zxc_-*.sss//\nd<2?$% /cde/$fgh/<i>'
EXPECTED = {
'a': 'asd.vdf',
'b': 'language_*lol*',
'c': 'zxc_-*.sss',
'd<2?$%': '/cde/$fgh/<i>',
}

self.assertEqual(vdf.loads(INPUT), EXPECTED)
self.assertEqual(vdf.loads(INPUT, escaped=False), EXPECTED)

def test_space_for_unquoted(self):
INPUT = 'a b c d \n efg h i\t // j k\n'
EXPECTED= {
'a': 'b c d',
'efg': 'h i',
}

self.assertEqual(vdf.loads(INPUT), EXPECTED)
self.assertEqual(vdf.loads(INPUT, escaped=False), EXPECTED)

def test_merge_multiple_keys_on(self):
INPUT = '''
a
Expand Down Expand Up @@ -393,6 +404,74 @@ def test_escape_before_last_unescaped(self):

self.assertEqual(vdf.loads(INPUT, escaped=False), EXPECTED)

def test_single_line_empty_block(self):
INPUT = '''
"root1"
{
"key1" {}
key2 "value2"
"key3" value3
}
root2 { }
root3
{
"key1" "value1"
key2 { }
"key3" value3
}
'''

EXPECTED = {
'root1': {
'key1': {},
'key2': 'value2',
'key3': 'value3',
},
'root2': {},
'root3': {
'key1': 'value1',
'key2': {},
'key3': 'value3',
}
}

self.assertEqual(vdf.loads(INPUT), EXPECTED)
self.assertEqual(vdf.loads(INPUT, escaped=False), EXPECTED)

def test_inline_opening_bracker(self):
INPUT = '''
"root1" {
"key1" {
}
key2 "value2"
"key3" value3
}
root2 { }
root3 {
"key1" "value1"
key2 {
}
"key3" value3
}
'''

EXPECTED = {
'root1': {
'key1': {},
'key2': 'value2',
'key3': 'value3',
},
'root2': {},
'root3': {
'key1': 'value1',
'key2': {},
'key3': 'value3',
}
}

self.assertEqual(vdf.loads(INPUT), EXPECTED)
self.assertEqual(vdf.loads(INPUT, escaped=False), EXPECTED)

class testcase_VDF_other(unittest.TestCase):
def test_dumps_pretty_output(self):
Expand Down
20 changes: 15 additions & 5 deletions vdf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,11 @@ def parse(fp, mapper=dict, merge_duplicate_keys=True, escaped=True):
stack = [mapper()]
expect_bracket = False

re_keyvalue = re.compile(r'^("(?P<qkey>(?:\\.|[^\\"])+)"|(?P<key>#?[a-z0-9\-\_\\\?]+))'
re_keyvalue = re.compile(r'^("(?P<qkey>(?:\\.|[^\\"])*)"|(?P<key>#?[a-z0-9\-\_\\\?$%<>]+))'
r'([ \t]*('
r'"(?P<qval>(?:\\.|[^\\"])*)(?P<vq_end>")?'
r'|(?P<val>[a-z0-9\-\_\\\?\*\.]+)'
r'|(?P<val>(?:(?<!/)/(?!/)|[a-z0-9\-\_\\\?\*\.$<> ])+)'
r'|(?P<sblock>{[ \t]*)(?P<eblock>})?'
r'))?',
flags=re.I)

Expand Down Expand Up @@ -134,7 +135,13 @@ def parse(fp, mapper=dict, merge_duplicate_keys=True, escaped=True):
(getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 0, line))

key = match.group('key') if match.group('qkey') is None else match.group('qkey')
val = match.group('val') if match.group('qval') is None else match.group('qval')
val = match.group('qval')
if val is None:
val = match.group('val')
if val is not None:
val = val.rstrip()
if val == "":
val = None

if escaped:
key = _unescape(key)
Expand All @@ -147,8 +154,11 @@ def parse(fp, mapper=dict, merge_duplicate_keys=True, escaped=True):
_m = mapper()
stack[-1][key] = _m

stack.append(_m)
expect_bracket = True
if match.group('eblock') is None:
# only expect a bracket if it's not already closed or on the same line
stack.append(_m)
if match.group('sblock') is None:
expect_bracket = True

# we've matched a simple keyvalue pair, map it to the last dict obj in the stack
else:
Expand Down

0 comments on commit 3b9435c

Please sign in to comment.