Weftspace
Weftspace was originally written in Java, but it is now also available in Python. The Python library is slightly smaller than the Java one, but it provides all the same functionalities.
Version 2 Migration
Version 2.0.0 contains some big breaking changes that have streamlined the library and made it more versatile at the cost of removing some functionality. Namely:
- The Logger class has been removed. Methods that depended on it now throw exceptions instead; you will need to handle these exceptions in your code.
- Node flags (and, as a result, parsing options) have been removed, since they added complexity without utility. If you rely on node flags, do not update to version 2.0.0.
- The builder no longer takes context; rather than including context in error messages all error messages include a trace of the node tree that can be accessed by calling
represent()on the exception
Installation
The Weftspace Python library can be installed using pip:
pip install weftspace
You can find the full project details on PyPI.
Parser
The most common use case of Weftspace is to read data from a file into a node tree. This is accomplished by using the DataReader class.
Although the DataReader class does have several potentially useful methods, in the vast majority of cases a variation on the following three lines is all you need.
root_node: DataNode = DataNode.create_root_node() # Creates a generic root node that you'll access your parsed nodes from later
reader: DataReader = DataReader("path/to/file", root_node) # Constructs a DataReader
reader.parse() # Parses every line in the file, writing its contents as children of root_node, and automatically handling exceptions
These lines should turn your file of ES-formatted data into a node tree, ready for use!
Options
DataReader currently has the following options that can be used as *args when parsing:
IGNORE_NODE_FLAGS: Treats the keywordsaddandremoveas node names rather than flags.
Working with the Node Tree
Now that you've parsed your data, it should end up written to a (sometimes enormous) tree, with a single root node. Keep track of that root node, because it's how you access the rest of the tree!
The tree itself is made up of a whole bunch of DataNodes, each with three major properties: a name, a list of arguments, and a list of child nodes. Additionally, nodes include a reference to their parent node (if they aren't the root of a tree), and a special Flag that usually isn't all that important. Any nodes loaded using DataReader will also contain information about where they were loaded from for debug purposes.
Suppose you have the following lines in a datafile:
"some node"
description `This node is a cool node.`
attributes "short" "helpful"
When parsed, this would produce three nodes:
- A node named
some nodewith no arguments and two children (descriptionandattributes). - A node named
descriptionwith one argument (This node is a cool node.) and no children. - A node named
attributeswith two arguments (shortandhelpful) and no children.
Both the arguments and children of any given node are presented in a list, and the DataNode class contains several convenience methods to with each list.
Building Objects from Nodes
Let's face it: you probably don't want a node tree. You want to turn the nodes into objects. And you probably don't want to handle a billion exceptions that might arise if the data doesn't conform to the expected pattern. For this reason, I put together the Builder class, which allows you to convert a DataNode argument into any of several common data types, given a node, and the index of the argument to build.
Here's an example of how you could convert a node to an object:
def __init__(self, node: DataNode):
self.name = Builder.build_string(node, 0)
for child in node.children:
match child.name:
case "description": # Normal string
self.description = Builder.build_string(child, 0)
case "mass": # Non-negative integer
self.mass = Builder.build_spec_int(child, 0, Builder.IntType.NATURAL)
case "random number for fun": # A float
self.thingy = Builder.build_float(child, 0)
case "position": # From "position" x y
self.x = Builder.build_int(child, 0)
self.y = Builder.build_int(child, 1)
case _:
pass
Writing Data
Occasionally, you may find that you need to write data to a file. This can be accomplished using the DataWriter class. This can be done almost as simply as parsing, as follows:
writer: DataWriter = new DataWriter("path/to/file") # Constructs a DataWriter for the file you want to write to.
writer.open() # Opens the DataWriter so you can append to the file
writer.write(some_node) # Writes the node to the end of the file
writer.close() # Don't forget to do this, or you may have memory leaks!
Currently, it is not possible to overwrite or insert data using DataWriter.
Metadata
Release files for weftspace 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| weftspace-2.0.0.tar.gz | 23.2 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| weftspace-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 49.7 kB
Release files / weftspace-2.0.0.tar.gz
| Download URL | weftspace-2.0.0.tar.gz |
|---|---|
| Size | 23.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d3f0fcf5302495bb98e3b3a0cc8b86c79482c9d15cc4d9bd20c96bff43933265
|
|
BLAKE2b-256 checksum How to use checksums |
109e48e20e753d22790e56c43baae705c1599b7c0069eafe2d3f4df0ce5ce24c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 3, 2026.
Transparency logRelease files / weftspace-2.0.0-py3-none-any.whl
| Download URL | weftspace-2.0.0-py3-none-any.whl |
|---|---|
| Size | 26.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9a078a9e35d331d9244867bb727082634ca7e910aad7d792b80030eeccb575a6
|
|
BLAKE2b-256 checksum How to use checksums |
d5be3751640ef7109b1b16801c1ce0c775466eb4b4b2702611beb3e6d8fc34a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 3, 2026.
Transparency logSecurity for weftspace 2.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for weftspace-2.0.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 3, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.