pytreeds
A dependency-free Python library for beginners to create, inspect, modify, traverse, and print non-binary trees. Students keep only one tree variable. Node identifiers are unique strings, and all node-related operations return strings rather than mixed types.
Install
pip install pytreeds
Pyodide (from your platform's asynchronous package loader):
import micropip
await micropip.install("pytreeds")
First example
from pytreeds import Tree
org = Tree("CEO")
org.add_nodes(["CTO", "CFO", "COO"], parent="CEO")
org.add_nodes(["Engineering", "DevOps"], parent="CTO")
org.add_node("Accounting", parent="CFO")
org.show()
print(org.height()) # 2 edges
print(org.size()) # 6
print(org.children("CTO")) # ['Engineering', 'DevOps']
print(org.parent("DevOps")) # CTO
print(org.leaves())
print(list(org.dfs()))
print(list(org.bfs()))
for name in org:
print(name, "->", org.parent(name))
Text diagram:
CEO
├── CTO
│ ├── Engineering
│ └── DevOps
├── CFO
│ └── Accounting
└── COO
API reference
Build and modify
| API | Description |
|---|---|
| Tree(root=None) | Create an empty tree or one with a root |
| add_node(name, parent=None) | Create one node |
| add_nodes(names, parent) | Add several children in insertion order |
| remove_node(name) | Remove a leaf; raises an error for internal nodes |
| remove_subtree(name) | Remove a whole branch; removing root empties tree |
| move_node(name, parent) | Move a whole branch under a different parent |
| rename_node(old, new) | Rename a node without changing its location |
| copy() | Return an independent copy |
Properties and relationships
| API | Description |
|---|---|
| root | Root name, or None if empty |
| size() | Total number of nodes |
| height(name=None) | Height in edges; empty tree = -1 |
| depth(name) | Number of edges from root; root depth = 0 |
| leaf_count(name=None) | Number of leaves in tree or subtree |
| is_leaf(name) | True if the node has no children |
| contains(name) | True if this name exists |
| parent(name) | Parent name, or None at root |
| children(name) | List of child names |
| siblings(name) | List of sibling names |
| ancestors(name) | Ancestors from root to parent |
| descendants(name) | Descendant names in DFS order |
| leaves(name=None) | Leaf names in DFS order |
| path(name) | Root-to-node list of names |
Traversal and search
| API | Description |
|---|---|
| dfs(name=None) | Preorder DFS iterator of strings |
| bfs(name=None) | Level-order BFS iterator of strings |
| dfs_postorder(name=None) | Postorder DFS iterator of strings |
| nodes(name=None) | List of names in preorder |
| find(text) | Names containing a case-sensitive substring |
| for name in tree | Default preorder DFS |
Print text
| API | Description |
|---|---|
| show(name=None, style="unicode") | Print tree or subtree |
| to_text(name=None, style="unicode") | Return a diagram string |
| print(tree) | Print the full diagram |
The style option can also be "ascii".
Design and errors
- Each node has a unique nonempty string name. No UUIDs, extra node variables, overloaded subscripts, or student-defined classes.
- Parent, children, leaves, DFS, BFS, and ordinary iteration consistently use strings.
- The first node is the root. Further additions need a parent.
- Children and traversals preserve insertion order.
- Height and depth count edges, not levels.
- Duplicate names and invalid moves raise ValueError; missing names raise KeyError.
- Batch insertions validate before modifying the tree.
- Avoid modifying the tree while looping over a traversal.
Subtree example
from pytreeds import Tree
org = Tree("CEO")
org.add_nodes(["CTO", "CFO"], parent="CEO")
org.add_node("DevOps", parent="CTO")
org.move_node("DevOps", parent="CFO")
org.rename_node("DevOps", "Infrastructure")
org.show()
print(org.path("Infrastructure"))
org.remove_subtree("CFO")
Run tests locally using: python -m unittest discover -s tests -v
This repository intentionally keeps the existing publishing-only GitLab CI workflow; there is no testing CI job.
Metadata
Release files for pytreeds 0.1.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 | Actions |
|---|---|---|---|---|
| pytreeds-0.1.0.tar.gz | 7.4 kB | Without provenance | Details for pytreeds-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pytreeds-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for pytreeds-0.1.0-py3-none-any.whl |
Total release size: 14.0 kB
Release files / pytreeds-0.1.0.tar.gz
| Download URL | pytreeds-0.1.0.tar.gz |
|---|---|
| Size | 7.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f45811da5cc3dbeecd583f9b788a548be4b72b2c251238b2c003254a251ef762
|
|
BLAKE2b-256 checksum How to use checksums |
7128fa555bf135cfeca7d8ba5031fbb18a1179f4af9a0224d62ba29547cdbacf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.15
|
Release files / pytreeds-0.1.0-py3-none-any.whl
| Download URL | pytreeds-0.1.0-py3-none-any.whl |
|---|---|
| Size | 6.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b018a8c968456e73e10ed6744bf4435dbba388f4733c80e77e9595f4be7233a1
|
|
BLAKE2b-256 checksum How to use checksums |
fb57c09c7316513c5cdac738be371c73442a6de28fd0c0aa5b78db98a9d4a3b8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.15
|
Security for pytreeds 0.1.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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A 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.