semantics Package¶
semantics
Package¶
Modules relating to NBT semantics
The modules in this package provide intermediate constructs to simplify
working with NBT. Their primary purpose is making
nbtparse.minecraft
modules less repetitive and easier to understand.
Nothing in this package directly relates to Minecraft itself, however, so you may find uses for it in other contexts.
fields
Module¶
A field is part of a TAG_Compound
that corresponds to a top-level tag.
It knows how to translate a tag or group of tags into a Pythonic value and back again, and uses the descriptor protocol to make this translation seamless.
Typical usage would be something like this:
class FooFile(NBTFile):
bar = LongField(u'Bar')
Thereafter, when saving or loading a FooFile
, the top-level
TAG_Long
called Bar
will be accessible under the attribute bar
.
The NBT version is still accessible under the FooFile.data
attribute (or
by calling the to_nbt()
method,
which is usually more correct).
Fields are a thin abstraction over the data dict in an NBTObject
;
modifying the dict may cause Fields to misbehave.
Idea shamelessly stolen from Django, but massively simplified.
-
class
nbtparse.semantics.fields.
AbstractField
(*args, default=None, **kwargs)[source]¶ Bases:
object
Root of the Field class hierarchy.
-
attach
(owner: 'nbtparse.semantics.nbtobject.NBTMeta')[source]¶ Hook called on fields declared within a given class.
Does nothing by default.
-
default
= None¶ Default value used by
set_default()
.
-
load
(obj: 'nbtparse.semantics.nbtobject.NBTObject', field_name: str)[source]¶ Hook called during
from_nbt()
.Does nothing by default.
-
save
(obj: 'nbtparse.semantics.nbtobject.NBTObject', field_name: str)[source]¶ Hook called during
to_nbt()
.Does nothing by default.
-
-
class
nbtparse.semantics.fields.
BooleanField
(nbt_name: str, *, default: bool=False)[source]¶ Bases:
nbtparse.semantics.fields.SingleField
Field for a
TAG_Byte
acting as a boolean.
-
class
nbtparse.semantics.fields.
ByteArrayField
(nbt_name: str, *, default: bytearray=None)[source]¶ Bases:
nbtparse.semantics.fields.MutableField
,nbtparse.semantics.fields.SingleField
Field for a
TAG_Byte_Array
.
-
class
nbtparse.semantics.fields.
ByteField
(nbt_name: str, *, default: int=0)[source]¶ Bases:
nbtparse.semantics.fields.SingleField
Field for a
TAG_Byte
acting as an integer.
-
class
nbtparse.semantics.fields.
DoubleField
(nbt_name: str, *, default: float=0.0)[source]¶ Bases:
nbtparse.semantics.fields.SingleField
Field for a
TAG_Double
.
-
class
nbtparse.semantics.fields.
EnumField
(nbt_name: str, enum_class: enum.EnumMeta, *, tag_type: type=<class 'nbtparse.syntax.tags.IntTag'>, default: enum.Enum=None)[source]¶ Bases:
nbtparse.semantics.fields.SingleField
Field for an enumerated type.
See
enum
.
-
class
nbtparse.semantics.fields.
FloatField
(nbt_name: str, *, default: float=0.0)[source]¶ Bases:
nbtparse.semantics.fields.SingleField
Field for a
TAG_Float
.
-
class
nbtparse.semantics.fields.
HeterogenousDictField
(nbt_name: str, schema: {<class 'str'>: <class 'nbtparse.semantics.fields.AbstractField'>}, *, default: {<class 'str'>: <class 'object'>}=None)[source]¶ Bases:
nbtparse.semantics.fields.MutableField
,nbtparse.semantics.fields.SingleField
Field for a dictionary of heterogenous values.
Keys are strings, values are arbitrary objects. The key
'data'
is reserved for storing the original value of the NBT. None of the keys may begin with underscores.-
schema
= None¶ Template for the dictionaries this field should create.
The keys are arbitrary strings, which will be duplicated verbatim. Those strings must not begin with underscores. The values are fields, which will be invoked in the normal manner to create the values of this dictionary, and to parse them when converting back to NBT.
The original NBT will be stored in the
'data'
key, which is reserved for this purpose. If the key still exists when converting back to NBT, it will be used to supply any values not specified elsewhere in the dictionary. This allows round-tripping of items not controlled by any field.
-
-
class
nbtparse.semantics.fields.
HomogenousDictField
(nbt_name: str, *, default: {<class 'str'>: <class 'object'>}=None)[source]¶ Bases:
nbtparse.semantics.fields.MutableField
,nbtparse.semantics.fields.SingleField
Field for a dictionary of homogenous values.
Abstract. Subclasses should override
item_to_python()
anditem_from_python()
.-
item_from_python
(key: str, value: object) -> (<class 'nbtparse.syntax.tags.StringTag'>, <class 'nbtparse.syntax.tags.AbstractTag'>)[source]¶
-
-
class
nbtparse.semantics.fields.
IntArrayField
(nbt_name: str, *, default: list=())[source]¶ Bases:
nbtparse.semantics.fields.MutableField
,nbtparse.semantics.fields.SingleField
Field for a
TAG_Int_Array
.
-
class
nbtparse.semantics.fields.
IntField
(nbt_name: str, *, default: int=0)[source]¶ Bases:
nbtparse.semantics.fields.SingleField
Field for a
TAG_Int
.
-
class
nbtparse.semantics.fields.
ListField
(nbt_name: str, item_to_python: function, item_from_python: function, content_id: int, *, default: list=())[source]¶ Bases:
nbtparse.semantics.fields.MutableField
,nbtparse.semantics.fields.SingleField
Field for a
TAG_List
.The ListTag will be given an id of
content_id
for the elements.
-
class
nbtparse.semantics.fields.
LongField
(nbt_name: str, *, default: int=0)[source]¶ Bases:
nbtparse.semantics.fields.SingleField
Field for a
TAG_Long
.
-
class
nbtparse.semantics.fields.
MultiField
(nbt_names: (<class 'str'>, Ellipsis), *, default: object=None)[source]¶ Bases:
nbtparse.semantics.fields.AbstractField
Field combining multiple top-level tags into one object.
Controls a series of one or more top-level tags which should be combined into a single Pythonic object. If the tags are enclosed in a
TAG_Compound
, consider using anNBTObjectField
instead.This is an abstract class.
to_python()
will be called with the same number of arguments asnbt_names
has elements, in the same order specified, and should return a value acceptable tofrom_python()
, which should produce a sequence of the same values passed as arguments toto_python()
.If a tag does not exist,
to_python()
will be passedNone
instead of the corresponding tag. Iffrom_python()
produces aNone
value, the corresponding tag will be removed.default
should be a value acceptable tofrom_python()
, which will be called when setting the field to its default value.Note
In general, these methods should not have side effects, and should not assume they are called at any particular time. The results may be cached and this class may assume that composing the two conversion methods produces the identity function. The reliable and comfortable hook for “heavy” NBT manipulation is
save()
andload()
.-
from_python
(value: object) -> (<class 'nbtparse.syntax.tags.AbstractTag'>, Ellipsis)[source]¶ Transform a single Pythonic object into several tags.
-
get_field_value
(obj: 'nbtparse.semantics.nbtobject.NBTObject', field_name: str=None) → object[source]¶
-
-
class
nbtparse.semantics.fields.
MutableField
(*args, default=None, **kwargs)[source]¶ Bases:
nbtparse.semantics.fields.AbstractField
Mutable variant of a field.
Caches the Pythonic value and holds a reference to it. Such a value can be safely mutated in-place. Needed for mutable types like lists, as well as immutable types whose contents may be mutable, such as tuples.
The value is cached in
obj.__dict__[field_name]
.This class must precede any class which overrides
__get__()
,__set__()
, and/or__delete__()
in the method resolution order. In particular, it must precedeMultiField
orSingleField
. If you do not understand what that means, just make sure your code looks like this:class FooField(MutableField, SingleField): pass
...rather than like this:
class FooField(SingleField, MutableField): pass
-
class
nbtparse.semantics.fields.
NBTObjectField
(nbt_name: str, obj_class: 'nbtparse.semantics.nbtobject.NBTMeta', *, default: 'nbtparse.semantics.nbtobject.NBTObject'=None)[source]¶ Bases:
nbtparse.semantics.fields.MutableField
,nbtparse.semantics.fields.SingleField
Field for an
NBTObject
.Usually a
TAG_Compound
but exact contents will vary.
-
class
nbtparse.semantics.fields.
ObjectListField
(nbt_name: str, obj_class: 'nbtparse.semantics.nbtobject.NBTMeta', *, default: list=())[source]¶ Bases:
nbtparse.semantics.fields.ListField
Field for a
TAG_List
ofNBTObject
s.
-
class
nbtparse.semantics.fields.
ObjectTupleField
(nbt_name: str, obj_class: 'nbtparse.semantics.nbtobject.NBTMeta', *, default: ('nbtparse.semantics.nbtobject.NBTObject', Ellipsis)=())[source]¶ Bases:
nbtparse.semantics.fields.TupleListField
Field for a
TAG_List
ofNBTObject
s, as a tuple.
-
class
nbtparse.semantics.fields.
ShortField
(nbt_name: str, *, default: int=0)[source]¶ Bases:
nbtparse.semantics.fields.SingleField
Field for a
TAG_Short
.
-
class
nbtparse.semantics.fields.
SingleField
(nbt_name: str, *, typename: str=None, default: object=None)[source]¶ Bases:
nbtparse.semantics.fields.AbstractField
Field for a single top-level tag.
This is an abstract class.
to_python()
is passed an NBT tag (seenbtparse.syntax.tags
) and should return some object. That object should be acceptable tofrom_python()
, which should return the equivalent NBT tag.Concrete implementations must override either
to_python()
orto_python_ex()
, and similarly eitherfrom_python()
orfrom_python_ex()
.Note
In general, these methods should not have side effects, and should not assume they are called at any particular time. The results may be cached and this class may assume that composing the two conversion methods produces the identity function. The reliable and comfortable hook for “heavy” NBT manipulation is
save()
andload()
.-
from_python
(value: object) → nbtparse.syntax.tags.AbstractTag[source]¶ Transform a Pythonic object into this tag.
-
from_python_ex
(value: object, obj: 'nbtparse.semantics.nbtobject.NBTObject') → nbtparse.syntax.tags.AbstractTag[source]¶ Extended form of from_python().
Takes precedence if both are defined.
-
get_field_value
(obj: 'nbtparse.semantics.nbtobject.NBTObject', field_name: str=None) → object[source]¶
-
set_field_value
(obj: 'nbtparse.semantics.nbtobject.NBTObject', field_name: str, value: object)[source]¶
-
-
class
nbtparse.semantics.fields.
TupleListField
(nbt_name: str, item_to_python: function, item_from_python: function, content_id: int, *, default: (<class 'object'>, Ellipsis)=())[source]¶ Bases:
nbtparse.semantics.fields.MutableField
,nbtparse.semantics.fields.SingleField
Field for a
TAG_List
; converts to a tuple.This should not be confused with
TupleMultiField
, which takes several top-level tags and wraps them together into a single field. This takes a singleTAG_List
and converts it into a tuple.ListField
takes a single TAG_List and converts it into a list.
-
class
nbtparse.semantics.fields.
TupleMultiField
(nbt_names: (<class 'str'>, Ellipsis), to_pythons: (<class 'function'>, Ellipsis), from_pythons: (<class 'function'>, Ellipsis), *, default: (<class 'object'>, Ellipsis)=None)[source]¶ Bases:
nbtparse.semantics.fields.MutableField
,nbtparse.semantics.fields.MultiField
Field which combines several tags into a tuple.
to_pythons
andfrom_pythons
should be sequences of functions which translate each item listed innbt_names
into its corresponding Python value.
-
class
nbtparse.semantics.fields.
UTCField
(nbt_name: str, *, default: datetime.datetime=datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc))[source]¶ Bases:
nbtparse.semantics.fields.SingleField
Field for a
TAG_Long
holding a Unix timestamp.A default of
NOW
indicates the field should default to the current time.Note
The
datetime
objects produced by this field are always aware, with a tzinfo value ofutc
. The field does accept naive objects, but it assumes they represent local time, which may not be correct for your application. In particular, the convention of using naive objects to represent UTC is not supported and will produce incorrect results unless local time is UTC.
-
class
nbtparse.semantics.fields.
UUIDField
(high_name: str, low_name: str, *, default: uuid.UUID=None)[source]¶ Bases:
nbtparse.semantics.fields.MultiField
Field which combines two
TAG_Long
‘s into a UUID.A
default
ofNEW_UUID
will generate a new UUID every time. AssigningNone
in the ordinary fashion is equivalent to deleting the field.-
static
from_python
(uuid_instance: uuid.UUID) -> (<class 'nbtparse.syntax.tags.LongTag'>, <class 'nbtparse.syntax.tags.LongTag'>)[source]¶
-
static
-
class
nbtparse.semantics.fields.
UnicodeField
(nbt_name: str, *, default: str='')[source]¶ Bases:
nbtparse.semantics.fields.SingleField
Field for a
TAG_String
.
Sentinel values¶
Some of the field classes can accept sentinel values as defaults or in other places.
Note
These sentinel values are only usable in the specific contexts they
support (for example, as default values). They are not interpreted by
__set__()
or in any other contexts. In other words, this is
illegal:
>>> foo.timestamp = NOW # Use datetime.now(timezone.utc)
>>> foo.uuid = NEW_UUID # Use uuid.uuid4()
But you can do this:
class Foo(NBTObject):
timestamp = UTCField('timestamp', default=NOW)
uuid = UUIDField('uuid1', 'uuid2', default=NEW_UUID)
-
nbtparse.semantics.fields.
SELF_REFERENCE
¶ Sentinel value for
NBTObjectField
.When passed as the obj_class argument, refers to the class in which the field is declared. If the field is not declared inside a subclass of NBTObject, undefined behavior occurs.
filetype
Module¶
Provides classes for working with NBT files as objects.
These classes extend nbtparse.semantics.nbtobject
and provide save
and load methods so the file can be easily (de)serialized.
-
class
nbtparse.semantics.filetype.
GzippedNBTFile
(*args, **kwargs)[source]¶
-
class
nbtparse.semantics.filetype.
NBTFile
(*args, **kwargs)[source]¶ Bases:
nbtparse.semantics.nbtobject.NBTObject
Simple class for handling NBT encoded files holistically.
An entire NBT file is read and decoded via
tags.decode_named
, and then converted into a Pythonic object.-
classmethod
load
(input: io.BufferedIOBase)[source]¶ Creates a new
NBTFile
from the input file-like.Returns
(rootname, NBTFile)
, whererootname
is the name of the root tag. ConventionalNBTObject
s do not make use of their external names, so if you intend to use it somewhere, you need to capture it here.
-
classmethod
nbtobject
Module¶
NBT high-level object-oriented class
NBTObject
is an object-oriented wrapper for
CompoundTag
, designed to expose its fields in a standard and
well-documented fashion.
-
class
nbtparse.semantics.nbtobject.
NBTMeta
[source]¶ Bases:
type
Metaclass for NBTObjects.
Allows NBTObjects to track their fields upon creation.
-
all_fields
() → collections.abc.Set[source]¶ Return a set of all fields attached to this class.
Includes fields whose names begin with underscores.
Note
Fields defined in classes which do not derive from
NBTObject
will not be included. This is of no concern to most developers, but may cause problems if you plan on using multiple inheritance to provide the same fields to several different classes. To avoid this issue, always derive your mixin classes from NBTObject.
-
fields
() → collections.abc.Set[source]¶ Return a set of the public fields attached to this class.
The elements of the set are strings whose names correspond to those of the fields. They are suitable arguments for
getattr()
andsetattr()
.Does not include fields whose names begin with underscores, but is otherwise equivalent to
all_fields()
.
-
-
class
nbtparse.semantics.nbtobject.
NBTObject
(*args, **kwargs)[source]¶ Bases:
object
Thin wrapper over a
TAG_Compound
.Typically houses one or more
fields
.Calling the constructor directly will create an empty object with all fields set to their default values, except for any specifically initialized as keyword arguments. Calling
from_nbt()
will populate fields from the provided NBT.Note
If the default of a field is
None
, that field will be set toNone
, which is equivalent to leaving it empty. Such fields will not be present in the generated NBT unless their values are changed by hand. In some cases, this means newly created objects will require modification before they can be meaningfully saved.-
classmethod
all_fields
() → collections.abc.Set[source]¶ Forwards to
NBTMeta.all_fields()
, which see.
-
data
= None¶ The underlying
CompoundTag
for this NBTObject.Fields store and retrieve instance data in this attribute. It is largely used as-is when calling
to_nbt()
, but some fields may customize this process in theirsave()
methods. Some NBTObjects will also alter the output by overridingto_nbt()
. For these reasons, direct manipulation of this attribute is discouraged. It may still prove useful for debugging or for cases where a key is not controlled by any field.
-
classmethod
fields
() → collections.abc.Set[source]¶ Forwards to
NBTMeta.fields()
, which see.
-
classmethod
from_bytes
(raw: bytes)[source]¶ Deserialize a new NBTObject from a
bytes
object.The name of the root tag is discarded.
-
classmethod
from_nbt
(nbt: nbtparse.syntax.tags.CompoundTag)[source]¶ Creates a new NBTObject from the given NBT representation.
Stores the given NBT in the data attribute of the newly-created object.
Also calls the
load()
methods of all the fields.
-
classmethod
prepare_load
(nbt: nbtparse.syntax.tags.CompoundTag) → nbtparse.syntax.tags.CompoundTag[source]¶ Hook called during
from_nbt()
with the loaded NBT.Should return a
CompoundTag
after (for instance) unwrapping data inside a singleton CompoundTag or performing other transformations.Unless overridden, return argument unchanged.
This hook runs before any fields’
load()
methods are called. It is the first hook after the NBT has been loaded.Note
Unlike
prepare_save()
, this method must be callable as a class method. In practice, both methods can often be implemented as static methods anyway.
-
prepare_save
(nbt: nbtparse.syntax.tags.CompoundTag) → nbtparse.syntax.tags.CompoundTag[source]¶ Hook called during
to_nbt()
with the to-be-saved NBT.Should return a
CompoundTag
after (for instance) wrapping data inside a singleton CompoundTag or performing other transformations.Unless overridden, return argument unchanged.
This hook runs after all fields’
save()
methods are called. It is the last hook before the NBT is saved.
-
classmethod