Python class for manipulation with Valve KeyValues files (VDF format). Provides the parsing of VDF files to objects with dict interface, editing of this object keys and values and writing of any object with dict interface to VDF file.
Just copy the valve_keyvalues_python folder or keyvalues.py file wherever you need, for example to your Python's site-packages: <Python>/Lib/site-packages/ and then inside your program import the class by from valve_keyvalues_python.keyvalues import KeyValues or from keyvalues import KeyValues
Requires Python 3!
To create empty KeyValues instance:
kv = KeyValues()To create KeyValues instance from VDF file:
kv = KeyValues(filename="")Now you can access KeyValues with dict interface, i.e. with kv[key] = value operations.
When you create KeyValues instance from VDF file you can specify these optional parameters:
encoding=""- input VDF file encoding. Default:utf-8mapper_type=- mapper type for storing KeyValues. It must have thedictinterface, i.e. allow to domapper[key] = valueoperations. For example you can use thedicttype. Instance's attribute. Default:collections.OrderedDict(stores the keys in the order they have been added)key_modifier=- function for modifying the key before its addition. For examplekey_modifier=str.lowerwill make all the keys to be lowercase. Instance's attribute. Default:None
To create KeyValues instance from your own object with dict interface:
kv = KeyValues(mapper=)Instance's attribute mapper_type will be set to type of passed mapper= object.
All these instantiation variants have common optional parameter key_sorter=. It's a sorting function which will be applied to keys of every subpart when you use methods dump() or write() (or print(kv), which is in fact shortcut for print(kv.dump())). For example you can use key_sorter=sorted and keys will be represented in alphabetical ascending order; key_sorter=reversed for reverse order. Instance's attribute. Default: None
-
parse(filename)- parses the VDF file todictinterface representation, i.e. KeyValues can be accessed and modified bykv[key] = valueoperations. Optional arguments:encoding=""- input VDF file encoding. Default:utf-8mapper_type=- see Instantiation section. This will override the instance's attributemapper_type. Default:collections.OrderedDict(stores the keys in the order they have been added)key_modifier=- see Instantiation section. This will override the instance's attributekey_modifier. Default:None
-
dump()- returns the string representation of stored KeyValues, i.e. string in correct VDF format. Optional parameters:mapper=- passed object will be dumped (it must have thedictinterface!). Default:Nonekey_sorter=- see Instantiation section. This will override the instance's attributekey_sorter. Default:None
-
write(filename)- writes the dump to file. Optional parameters:encoding=""- output file encoding. Default:utf-8mapper=- writes the dump of passed object (it must have thedictinterface!). Default:Nonekey_sorter=- see Instantiation section. This will override the instance's attributekey_sorter. Default:None
Of course the class KeyValues also provides the standard dict interface methods like keys() or key in d. See dict
Note: when you print(kv) your KeyValues instance, it's in fact a shortcut for print(kv.dump()) method (because magic method __str__() is defined that way).
example_01.py - basic operations
example_02.py - using the optional functions
example_03.py - "advanced" uses
Generally the checking of VDF file syntax, i.e. if brackets are closed and so on. The only check is if after "key" is a starting bracket {. So it's expected that input VDF file will have a 'clean' and valid structure:
- one key or key-value per line, if value isn't subpart:
"key" "value"
- values can be on two lines (I have to implement this because Valve do it sometimes in their VDF files):
"key" "val
ue"
- when value is a subpart, starting bracket
{is expected to be on separate line after the corresponding key:
"key"
{
"key2" "value"
}
- everything that doesn't match key or key-value regex or if line doesn't start with
{or}is ignored. So this is ok:
"key"
// some comment
{
"key2" "value"
}
- even this should be ok, but don't do it, because Valve itself won't probably parse it :)
"key"
some comment
{ comment
"key2" "value" comment
} comment
- checking of valid VDF syntax
- support for SourceMod Config (SMC) files - they seem to be the same as VDF, but supposedly not