PyNBT is a tiny, liberally licenced (MIT) NBT library. It supports reading and writing compressed, uncompressed, big endian or little endian NBT files. It also includes helpers for region files and pocket detection.
The PyNBT package installs two scripts, debug-nbt and debug-region. These scripts can be used to pretty-print the NBT contents of plain NBT files and region files.
Example:
$ debug-nbt level.dat
TAG_Compound(''): 1 entries
{
TAG_Compound('Data'): 18 entries
{
...
}
}
Using the library in your own programs is simple and is capable of reading, modifying, and saving NBT files.
When writing NBT files with PyNBT, every tag should be treated as if it was immutable. This is to simplify future changes to both the library and the format. In other words, instead of modifying the value of a tag, replace it with a new tag.
NOTE: Beginning with version 1.1.0, names are optional for TAG_*'s that are added to a TAG_Compound, as they will be given the same name as their key. If you do
specify a name, it will be used instead. This breaks compatibility with old code, as the position of the name and value parameter have now swapped.
from pynbt import NBTFile, TAG_Long, TAG_List, TAG_String
value = {
'long_test': TAG_Long(104005),
'list_test': TAG_List(TAG_String, [
'Timmy',
'Billy',
'Sally'
])
}
nbt = NBTFile(value=value)
nbt.save('out.nbt')Reading is simple, and will accept any file-like object providing read() or a path to a file.
Simply pretty-printing the file created from the example under writing:
from pynbt import NBTFile
nbt = NBTFile('out.nbt')
print(nbt.pretty())This produces the output:
TAG_Compound(''): 2 entries
{
TAG_Long('long_test'): 104005
TAG_List('list_test'): 3 entries
{
TAG_String(None): 'Timmy'
TAG_String(None): 'Billy'
TAG_String(None): 'Sally'
}
}
Every tag exposes a minimum of two fields, .name and .value. Every tag's value maps to a plain Python type, such as a dict() for TAG_Compound and a list() for TAG_List. Every tag
also provides complete __repr__ methods for printing. This makes traversal very simple and familiar to existing Python developers.
nbt = NBTFile('out.nbt')
# Iterate over every TAG in the root compound as you would any other dict
for name, tag in nbt.items():
print name, tag
# Print every tag in a list
for tag in nbt['list_test']:
print tagThese changelogs are summaries only and not comprehensive. See the commit history between tags for full changes.
- TAG_List's values no longer need to be
TAG_*objects. They will be converted when the tag is saved. This allows much easier lists of native types.
- Internal code cleanup. Breaks compatibility with pocket loading and saving (to be reimplemented as helpers).
- Slight speed improvements.
- TAG_List can now be treated as a plain python list (
.valuepoints toself)
- Breaks compatibility with older code, but allows much more convienient creation of
TAG_Compound.nameandvaluehave in most cases swapped spots. nameis now the last argument of everyTAG_*, and optional for children of aTAG_Compound. Instead, they'll be given the key they're assigned to as a name.TAG_Compounds can now be treated like dictionaries for convienience..valuesimply maps to itself.
- Small bugfixes.
- Adds support for
TAG_Int_Array.
- First release.